diff --git a/LedOK/Demos/Sysolution Control.png b/LedOK/Demos/Sysolution Control.png new file mode 100644 index 0000000..aa95257 Binary files /dev/null and b/LedOK/Demos/Sysolution Control.png differ diff --git a/LedOK/Demos/Sysolution Innovation.png b/LedOK/Demos/Sysolution Innovation.png new file mode 100644 index 0000000..1aec0cc Binary files /dev/null and b/LedOK/Demos/Sysolution Innovation.png differ diff --git a/LedOK/LedOK Express.pro b/LedOK/LedOK Express.pro index 570a104..98b3c88 100644 --- a/LedOK/LedOK Express.pro +++ b/LedOK/LedOK Express.pro @@ -23,7 +23,7 @@ CONFIG += embed_translations # You can also select to disable deprecated APIs only up to a certain version of Qt. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 -VERSION = 1.4.2 +VERSION = 1.5.0 DEFINES += APP_VERSION=\\\"$$VERSION\\\" msvc { contains(QT_ARCH, i386) { @@ -40,6 +40,8 @@ win32 { RC_ICONS = res/Logo.ico } osx { + QMAKE_MACOSX_DEPLOYMENT_TARGET = 11.0 + -mmacosx-version-min=11.0 ICON = res/Logo-raw.png } @@ -48,7 +50,7 @@ copydir.files += AClock copydir.files += borders copydir.files += Demos copydir.files += translations -copydir.files += $$quote(y50 param) +copydir.files += rk_lcd_parameters copydir.files += $$quote(files) win32 { @@ -104,6 +106,7 @@ SOURCES += \ base/lodateselector.cpp \ base/loqtitlebar.cpp \ base/loqtreewidget.cpp \ + gutil/qcore.cpp \ gutil/qwaitingdlg.cpp \ basedlg.cpp \ basewin.cpp \ @@ -129,12 +132,12 @@ SOURCES += \ player/eleborder.cpp \ player/eledigiclock.cpp \ player/elegif.cpp \ - player/elemultipng.cpp \ player/elescroll.cpp \ player/eletimer.cpp \ player/elevideo.cpp \ player/playwin.cpp \ player/posdlg.cpp \ + player/srccopy.cpp \ progpanel.cpp \ synctimer.cpp \ tools.cpp \ @@ -161,7 +164,7 @@ SOURCES += \ program/progitem.cpp \ program/sendprogramdialog.cpp \ program/sendprogthread.cpp \ - program/videosplitthread.cpp \ + program/videosplitthread.cpp HEADERS += \ base/changepasswordform.h \ @@ -171,6 +174,7 @@ HEADERS += \ base/lodateselector.h \ base/loqtitlebar.h \ base/loqtreewidget.h \ + gutil/qcore.h \ gutil/qwaitingdlg.h \ basedlg.h \ basewin.h \ @@ -195,12 +199,12 @@ HEADERS += \ player/eleborder.h \ player/eledigiclock.h \ player/elegif.h \ - player/elemultipng.h \ player/elescroll.h \ player/eletimer.h \ player/elevideo.h \ player/playwin.h \ player/posdlg.h \ + player/srccopy.h \ progpanel.h \ synctimer.h \ tools.h \ @@ -227,7 +231,7 @@ HEADERS += \ program/progitem.h \ program/sendprogramdialog.h \ program/sendprogthread.h \ - program/videosplitthread.h \ + program/videosplitthread.h TRANSLATIONS += \ ts/app_zh_CN.ts \ diff --git a/LedOK/cfg.cpp b/LedOK/cfg.cpp index d88f8b9..73d5a86 100644 --- a/LedOK/cfg.cpp +++ b/LedOK/cfg.cpp @@ -5,6 +5,6 @@ const QString UpdVerUrl = "https://www.ledok.cn/download/LedOK Express Updates.json"; QString programsDir() { - static auto rtn = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/" + QApplication::applicationName() + "/NPrograms"; + static auto rtn = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/programs"; return rtn; } diff --git a/LedOK/device/ctrladvancedpanel.cpp b/LedOK/device/ctrladvancedpanel.cpp index c840e66..d6841b0 100644 --- a/LedOK/device/ctrladvancedpanel.cpp +++ b/LedOK/device/ctrladvancedpanel.cpp @@ -177,21 +177,10 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); return; } - - QString serverAddr = fdWebServerAddr->currentText(); - if(serverAddr.isEmpty()) { - QMessageBox::information(this, tr("Tip"),tr("InputWebServerAddressTip")); - fdWebServerAddr->setFocus(); - return; - } + auto serverAddr = fdWebServerAddr->currentText(); auto companyId = fdCompanyId->text(); - if(companyId.isEmpty()) { - QMessageBox::information(this, tr("Tip"),tr("InputCompanyIdTip")); - fdCompanyId->setFocus(); - return; - } - auto res = QMessageBox::question(this, tr("Tip Info"), tr("This operation will clear current program.")+"\n"+tr("Do you want to continue?")); - if(res != QMessageBox::Yes) return; +// auto res = QMessageBox::question(this, tr("Tip Info"), tr("This operation will clear current program.")+"\n"+tr("Do you want to continue?")); +// if(res != QMessageBox::Yes) return; QJsonObject json; json.insert("_id", "SetOnlineAddr"); json.insert("_type", "SetOnlineAddr"); @@ -214,12 +203,10 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { hBox->addStretch(); hBox = new HBox(vBox); - - label = new QLabel; - hBox->addWidget(label); + hBox->addWidget(lbRealtime = new QLabel); fdRealtimeServer = new QComboBox; - fdRealtimeServer->addItem(tr("www.ledokcloud.com/realtime")); + fdRealtimeServer->addItem("www.ledokcloud.com/realtime"); fdRealtimeServer->setMinimumWidth(260); fdRealtimeServer->setEditable(true); hBox->addWidget(fdRealtimeServer); @@ -635,6 +622,188 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { }); hBox->addWidget(btnGetLog); + hBox->addStretch(); + hBox = new HBox(vBox); + + auto btnViewProg = new QPushButton("View Prog JSON"); + btnViewProg->setProperty("ssType", "progManageTool"); + connect(btnViewProg, &QPushButton::clicked, this, [this] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + return; + } + JObj json{{"_type", "GetFile"}, {"name", "program"}}; + auto fd = new QTextEdit; + fd->setAttribute(Qt::WA_DeleteOnClose); + fd->setTabStopDistance(26); + auto ft = fd->font(); + ft.setFamily("Consolas"); + fd->setFont(ft); + fd->setWindowTitle("program"); + fd->resize(600, 900); + fd->show(); + for(auto &card : gSelCards) { + auto tcp = new TcpSocket; + auto cardId = card.id; + connect(fd, &QTextEdit::destroyed, tcp, &QTcpSocket::deleteLater); + connect(tcp, &QTcpSocket::connected, tcp, [=] { + tcp->stopTimer(); + tcp->write(JToBytes(json)); + tcp->startTimer(10000); + }); + connect(tcp, &QTcpSocket::readyRead, fd, [=] { + tcp->stopTimer(); + auto resp = tcp->readAll(); + tcp->close(); + tcp->deleteLater(); + fd->append(cardId+" Prog JSON"); + fd->append(resp); + fd->append(""); + }); + connect(tcp, &QTcpSocket::errorOccurred, fd, [=](QAbstractSocket::SocketError err) { + tcp->close(); + tcp->deleteLater(); + fd->append(cardId+" View Prog JSON "+socketErrKey(err)+" ("+QString::number(err)+") "+tcp->errorString()); + }); + tcp->connectToHost(card.ip, 3333); + tcp->startTimer(10000); + } + }); + hBox->addWidget(btnViewProg); + + auto btnListFiles = new QPushButton("List Prog Files"); + btnListFiles->setProperty("ssType", "progManageTool"); + connect(btnListFiles, &QPushButton::clicked, this, [this] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + return; + } + JObj json{{"_type", "ListProgFiles"}}; + auto fd = new QTextEdit; + fd->setAttribute(Qt::WA_DeleteOnClose); + auto ft = fd->font(); + ft.setFamily("Consolas"); + fd->setFont(ft); + fd->setWindowTitle("List Prog Files"); + fd->resize(600, 900); + fd->show(); + for(auto &card : gSelCards) { + auto tcp = new TcpSocket; + auto cardId = card.id; + connect(fd, &QTextEdit::destroyed, tcp, &QTcpSocket::deleteLater); + connect(tcp, &QTcpSocket::connected, tcp, [=] { + tcp->stopTimer(); + tcp->write(JToBytes(json)); + tcp->startTimer(10000); + }); + connect(tcp, &QTcpSocket::readyRead, fd, [=] { + tcp->stopTimer(); + auto resp = tcp->readAll(); + tcp->close(); + tcp->deleteLater(); + fd->append(cardId+" Prog Files"); + fd->append(resp); + fd->append(""); + }); + connect(tcp, &QTcpSocket::errorOccurred, fd, [=](QAbstractSocket::SocketError err) { + tcp->close(); + tcp->deleteLater(); + fd->append(cardId+" List Prog Files "+socketErrKey(err)+" ("+QString::number(err)+") "+tcp->errorString()); + }); + tcp->connectToHost(card.ip, 3333); + tcp->startTimer(10000); + } + }); + hBox->addWidget(btnListFiles); + + auto btnGetPlayerInfo = new QPushButton("Get Player Info"); + btnGetPlayerInfo->setProperty("ssType", "progManageTool"); + connect(btnGetPlayerInfo, &QPushButton::clicked, this, [this] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + return; + } + JObj json{{"_type", "GetInfo"}}; + auto fd = new QTextEdit; + fd->setAttribute(Qt::WA_DeleteOnClose); + auto ft = fd->font(); + ft.setFamily("Consolas"); + fd->setFont(ft); + fd->setWindowTitle("Get Player Info"); + fd->resize(600, 900); + fd->show(); + for(auto &card : gSelCards) { + auto tcp = new TcpSocket; + auto cardId = card.id; + connect(fd, &QTextEdit::destroyed, tcp, &QTcpSocket::deleteLater); + connect(tcp, &QTcpSocket::connected, tcp, [=] { + tcp->stopTimer(); + tcp->write(JToBytes(json)); + tcp->startTimer(10000); + }); + connect(tcp, &QTcpSocket::readyRead, fd, [=] { + tcp->stopTimer(); + auto resp = tcp->readAll(); + tcp->close(); + tcp->deleteLater(); + fd->append(cardId+" Player Info"); + fd->append(resp); + fd->append(""); + + }); + connect(tcp, &QTcpSocket::errorOccurred, fd, [=](QAbstractSocket::SocketError err) { + tcp->close(); + tcp->deleteLater(); + fd->append(cardId+" Get Player Info "+socketErrKey(err)+" ("+QString::number(err)+") "+tcp->errorString()); + }); + tcp->connectToHost(card.ip, 3333); + tcp->startTimer(10000); + } + }); + hBox->addWidget(btnGetPlayerInfo); + + auto GetBuf = new QPushButton("Get Player Log"); + GetBuf->setProperty("ssType", "progManageTool"); + connect(GetBuf, &QPushButton::clicked, this, [this] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + return; + } + JObj json{{"_type", "GetLog"}}; + auto fd = new QTextEdit; + fd->setAttribute(Qt::WA_DeleteOnClose); + auto ft = fd->font(); + ft.setFamily("Consolas"); + fd->setFont(ft); + fd->setWindowTitle("Get Player Log"); + fd->resize(600, 900); + fd->show(); + for(auto &card : gSelCards) { + auto tcp = new TcpSocket; + auto cardId = card.id; + connect(fd, &QTextEdit::destroyed, tcp, &QTcpSocket::deleteLater); + connect(tcp, &QTcpSocket::connected, tcp, [=] { + tcp->stopTimer(); + tcp->write(JToBytes(json)); + tcp->startTimer(5000); + }); + connect(tcp, &QTcpSocket::readyRead, fd, [=] { + tcp->stopTimer(); + auto resp = tcp->readAll(); + if(fd->document()->isEmpty()) fd->append(cardId+" Player Log"); + fd->append(resp); + }); + connect(tcp, &QTcpSocket::errorOccurred, fd, [=](QAbstractSocket::SocketError err) { + tcp->close(); + tcp->deleteLater(); + if(fd->document()->isEmpty() || err!=QAbstractSocket::SocketTimeoutError) fd->append(cardId+" Get Player Log "+socketErrKey(err)+" ("+QString::number(err)+") "+tcp->errorString()); + }); + tcp->connectToHost(card.ip, 3333); + tcp->startTimer(8000); + } + }); + hBox->addWidget(GetBuf); + hBox->addStretch(); hBox = new HBox(vBox); hBox->addWidget(lbTimingReboot = new QLabel); @@ -708,8 +877,8 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { auto hBox = new HBox(grpY50); auto fdY50Resolu = new QComboBox; - auto dirs = QDir(QApplication::applicationDirPath()+"/y50 param").entryList(QDir::Dirs | QDir::NoDotAndDotDot); - foreach(auto dir, dirs) fdY50Resolu->addItem(dir); + auto params = QDir(QApplication::applicationDirPath()+"/rk_lcd_parameters").entryList(QDir::Files); + for(auto ¶m : params) fdY50Resolu->addItem(param); fdY50Resolu->setMinimumWidth(160); hBox->addWidget(fdY50Resolu); @@ -720,14 +889,14 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); return; } - auto filePath = QApplication::applicationDirPath()+"/y50 param/"+fdY50Resolu->currentText()+"/rk_lcd_parameters"; - QFile qFile(filePath); + auto file = QApplication::applicationDirPath()+"/rk_lcd_parameters/"+fdY50Resolu->currentText(); + QFile qFile(file); if(! qFile.exists()) { QMessageBox::information(this, tr("Tip"), tr("File not exist")); return; } if(! qFile.open(QIODevice::ReadOnly)) { - QMessageBox::information(this, tr("Tip"), tr("Cannot Open File")+": "+qFile.errorString()+"\n"+filePath); + QMessageBox::information(this, tr("Tip"), tr("Cannot Open File")+": "+qFile.errorString()+"\n"+file); return; } auto fileData = qFile.readAll(); @@ -928,11 +1097,66 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnLedSet->setProperty("ssType", "progManageTool"); connect(btnLedSet, &QPushButton::clicked, btnLedSet, [] { QFileInfo file("LedSet4.0/LedSet4.0.exe"); - if(file.exists()) QProcess::startDetached(file.absoluteFilePath(), QStringList()); + if(file.exists()) QProcess::startDetached(file.absoluteFilePath(), QStringList(), file.absolutePath()); }); hBox->addWidget(btnLedSet); hBox->addStretch(); + hBox = new HBox(vBox); + + btnReceCardsGet = new QPushButton; + btnReceCardsGet->setProperty("ssType", "progManageTool"); + connect(btnReceCardsGet, &QPushButton::clicked, this, [=] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + return; + } + QJsonObject json; + json.insert("_id", "GetReceCards"); + json.insert("_type", "GetReceCards"); + if(gSelCards.count() == 1) { + auto waitingDlg = new WaitingDlg(this, btnReceCardsGet->text() + " ..."); + Def_CtrlReqPre + connect(reply, &QNetworkReply::finished, this, [=] { + Def_CtrlSingleGetReply + waitingDlg->close(); + QMessageBox::information(this, btnReceCardsGet->text(), QString::number(json["receCardNum"].toInt())); + }); + } else { + foreach(auto card, gSelCards) { + auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + auto cardId = card.id; + connect(reply, &QNetworkReply::finished, this, [=] { + QJsonDocument json; + QString err = checkReplyForJson(reply, &json); + if(err.isEmpty()) err = QString::number(json["receCardNum"].toInt()); + gFdResInfo->append(cardId+" "+btnReceCardsGet->text()+" "+err); + }); + } + } + }); + hBox->addWidget(btnReceCardsGet); + +// auto btnTool = new QPushButton("本地监控"); +// btnTool->setMinimumHeight(30); +// btnTool->setProperty("ssType", "progManageTool"); +// connect(btnTool, &QPushButton::clicked, btnTool, [] { +// QFileInfo file("EasyTool/EasyTool.exe"); +// if(file.exists()) QProcess::startDetached(file.absoluteFilePath(), QStringList(), file.absolutePath()); +// }); +// hBox->addWidget(btnTool); + +// auto btnVMS = new QPushButton("平台监控"); +// btnVMS->setMinimumHeight(30); +// btnVMS->setProperty("ssType", "progManageTool"); +// connect(btnVMS, &QPushButton::clicked, btnVMS, [] { +// QFileInfo file("EasyVMS/EasyVMS.exe"); +// if(file.exists()) QProcess::startDetached(file.absoluteFilePath(), QStringList(), file.absolutePath()); +// }); +// hBox->addWidget(btnVMS); + + hBox->addStretch(); + #ifndef Q_OS_WIN btnLedSet->setVisible(false); #endif @@ -1562,6 +1786,19 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { fdM80Resolu = new QComboBox; fdM80Resolu->setMinimumWidth(160); + fdM80Resolu->addItem("480x4096", "550x4500"); + fdM80Resolu->addItem("576x3840", "625x3960"); + fdM80Resolu->addItem("720x3200", "750x3300"); + fdM80Resolu->addItem("864x2672", "900x2750"); + fdM80Resolu->addItem("1080x1920", "1125x2200"); + fdM80Resolu->addItem("1280x1760", "1320x1850"); + fdM80Resolu->addItem("1472x1536", "1500x1650"); + fdM80Resolu->addItem("1536x1472", "1650x1500"); + fdM80Resolu->addItem("1920x1080", "2200x1125"); + fdM80Resolu->addItem("2672x864", "2750x900"); + fdM80Resolu->addItem("3200x720", "3300x750"); + fdM80Resolu->addItem("3840x576", "3960x625"); + fdM80Resolu->addItem("4096x480", "4500x550"); hBox->addWidget(fdM80Resolu); btnM80Set = new QPushButton(); @@ -2188,6 +2425,28 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { hBox->addStretch(); } vBox->addWidget(grpBoxHiddenSettings); + + hBox = new HBox(vBox); + auto btn = new QPushButton("List Card Infos"); + btn->setProperty("ssType", "progManageTool"); + connect(btn, &QPushButton::clicked, this, [this] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + return; + } + auto fd = new QTextEdit; + fd->setAttribute(Qt::WA_DeleteOnClose); + auto ft = fd->font(); + ft.setFamily("Consolas"); + fd->setFont(ft); + fd->setWindowTitle("List Card Infos"); + fd->resize(600, 900); + fd->show(); + for(auto &card : gSelCards) fd->append(card.id+", "+card.ip+", "+QString::number(card.mWidth)+" x "+QString::number(card.mHeight)+", "+card.alias+", "+QString::number(card.bright)+"%, "+(card.isScreenOn?"On":"Off")); + }); + hBox->addWidget(btn); + hBox->addStretch(); + vBox->addStretch(); if(QSettings().value("advUiPs", "888").toString().isEmpty()) isPassed = true; @@ -2260,21 +2519,21 @@ void CtrlAdvancedPanel::init() { auto isM80 = card.id.startsWith("M8", Qt::CaseInsensitive); grpM80->setVisible(isM80); - if(isM80) { - QJsonObject json; - json.insert("_id", "GetAllScreenSizeM80"); - json.insert("_type", "GetAllScreenSizeM80"); - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); - connect(reply, &QNetworkReply::finished, this, [this, reply] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); - if(! err.isEmpty()) return; - auto sizes = json["result"].toObject(); - fdM80Resolu->clear(); - auto send = sizes.constEnd(); - for(auto size=sizes.constBegin(); sizeaddItem(size.key(), size.value().toString()); - }); - } +// if(isM80) { +// QJsonObject json; +// json.insert("_id", "GetAllScreenSizeM80"); +// json.insert("_type", "GetAllScreenSizeM80"); +// auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json); +// connect(reply, &QNetworkReply::finished, this, [this, reply] { +// QJsonDocument json; +// QString err = checkReplyForJson(reply, &json); +// if(! err.isEmpty()) return; +// auto sizes = json["result"].toObject(); +// fdM80Resolu->clear(); +// auto send = sizes.constEnd(); +// for(auto size=sizes.constBegin(); sizeaddItem(size.key(), size.value().toString()); +// }); +// } auto isY50 = card.id.startsWith("st5", Qt::CaseInsensitive) || card.id.startsWith("m5h", Qt::CaseInsensitive) @@ -2289,7 +2548,7 @@ void CtrlAdvancedPanel::init() { QJsonObject json; json.insert("_id", "GetOnlineAddr"); json.insert("_type", "GetOnlineAddr"); - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json); connect(reply, &QNetworkReply::finished, this, [this, reply] { QJsonDocument json; QString err = checkReplyForJson(reply, &json); @@ -2301,10 +2560,10 @@ void CtrlAdvancedPanel::init() { json = QJsonObject(); json.insert("_id", "GetRealtimeServer"); json.insert("_type", "GetRealtimeServer"); - reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json); connect(reply, &QNetworkReply::finished, this, [this, reply] { QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + auto err = checkReplyForJson(reply, &json); if(! err.isEmpty()) return; fdRealtimeServer->setCurrentText(json["server"].toString()); }); @@ -2317,6 +2576,7 @@ void CtrlAdvancedPanel::transUi() { btnBindTaxiIc->setText(tr("Binding *.ic account indentity voucher")); btnGetTopLevel->setText(tr("Readback")); btnLedSet->setText(tr("Start LedSet4")); + btnReceCardsGet->setText(tr("Get Receive Card Num")); grpM80->setTitle("M80 "+tr("Config")); btnM80Refresh->setText(tr("Refresh")); @@ -2365,7 +2625,7 @@ void CtrlAdvancedPanel::transUi() { btnCustomJsonGet->setText(tr("Get")); grpHighForBusy->setTitle(tr("Taxi top screen configuration")); - label->setText(tr("Realtimer Server Address:")); + lbRealtime->setText(tr("Realtime Address:")); lbTitle->setText(tr("Advanced")); lbCompanyId->setText(tr("Compant ID:")); labelWebServer->setText(tr("Web Server Address:")); diff --git a/LedOK/device/ctrladvancedpanel.h b/LedOK/device/ctrladvancedpanel.h index 55024e5..80515df 100644 --- a/LedOK/device/ctrladvancedpanel.h +++ b/LedOK/device/ctrladvancedpanel.h @@ -43,7 +43,7 @@ private: QLabel *lbCompanyId; QLineEdit *fdCompanyId; QPushButton *btnWebServerSet; - QLabel *label; + QLabel *lbRealtime; QComboBox *fdRealtimeServer; QPushButton *btnRealtimeServerSet; QPushButton *btnRealtimeClear; @@ -78,7 +78,7 @@ private: QPushButton *btnHighForBusySet; QPushButton *btnGetTopLevel; QPushButton *btnLedSet; - QPushButton *btnBindTaxiIc; + QPushButton *btnReceCardsGet, *btnBindTaxiIc; QGroupBox *grpMinMaxBrightness; QLabel *lbMinBright; diff --git a/LedOK/device/ctrltestpanel.cpp b/LedOK/device/ctrltestpanel.cpp index 36fe931..95a57b3 100644 --- a/LedOK/device/ctrltestpanel.cpp +++ b/LedOK/device/ctrltestpanel.cpp @@ -177,9 +177,9 @@ CtrlTestPanel::CtrlTestPanel() { hhh = new HBox(vv); hhh->addStretch(); - pushButtonStopTest = new QPushButton; - pushButtonStopTest->setMinimumSize(QSize(60, 30)); - hhh->addWidget(pushButtonStopTest); + btnStopTest = new QPushButton; + btnStopTest->setMinimumSize(QSize(60, 30)); + hhh->addWidget(btnStopTest); hhh->addStretch(); vv->addStretch(); @@ -192,14 +192,12 @@ CtrlTestPanel::CtrlTestPanel() { vv = new VBox(hBox); - lineEdit = new QLineEdit; - lineEdit->setMinimumSize(QSize(0, 36)); - lineEdit->setMaximumSize(QSize(194, 16777215)); - lineEdit->setAutoFillBackground(false); - lineEdit->setStyleSheet(QString::fromUtf8("color: rgb(0, 255, 0);\n" - "background-color: rgb(0, 0, 0);")); - lineEdit->setAlignment(Qt::AlignCenter); - vv->addWidget(lineEdit); + fdAnycast = new QLineEdit; + fdAnycast->setValidator(new QIntValidator(0, 100, this)); + fdAnycast->setMinimumHeight(36); + fdAnycast->setStyleSheet("color: #0f0; background: #000;"); + fdAnycast->setAlignment(Qt::AlignCenter); + vv->addWidget(fdAnycast); auto gridLayout = new Grid(vv); @@ -221,20 +219,47 @@ CtrlTestPanel::CtrlTestPanel() { gridLayout->addWidget(btngrp->button(9), 2, 2); gridLayout->addWidget(btngrp->button(0), 3, 0); connect(btngrp, &QButtonGroup::idClicked, this, [=](int id) { - if(lineEdit->text().contains("-")) lineEdit->clear(); - lineEdit->setText(lineEdit->text() + QString::number(id)); + if(fdAnycast->text().contains("-")) fdAnycast->clear(); + fdAnycast->setText(fdAnycast->text() + QString::number(id)); btnAnycast->setEnabled(true); }); - pushButton_11 = new QPushButton; - pushButton_11->setFixedSize(QSize(60, 30)); - gridLayout->addWidget(pushButton_11, 3, 1, 1, 1); + btnAnycastClear = new QPushButton; + btnAnycastClear->setFixedSize(60, 30); + btnAnycastClear->setProperty("ssType", "progManageTool"); + connect(btnAnycastClear, &QPushButton::clicked, this, [=] { + fdAnycast->clear(); + btnAnycast->setEnabled(false); + }); + gridLayout->addWidget(btnAnycastClear, 3, 1, 1, 1); - pushButton_12 = new QPushButton; - pushButton_12->setFixedSize(QSize(60, 30)); - gridLayout->addWidget(pushButton_12, 3, 2, 1, 1); + btnAnycastReset = new QPushButton; + btnAnycastReset->setFixedSize(60, 30); + btnAnycastReset->setProperty("ssType", "progManageTool"); + connect(btnAnycastReset, &QPushButton::clicked, this, [=] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + return; + } + SendAnycastCmd(0); + fdAnycast->setText("- "+tr("Loop Mode")+" -"); + btnAnycast->setEnabled(false); + }); + gridLayout->addWidget(btnAnycastReset, 3, 2, 1, 1); btnAnycast = new QPushButton; + btnAnycast->setEnabled(false); + btnAnycast->setMinimumHeight(36); + btnAnycast->setProperty("ssType", "progManageTool"); + connect(btnAnycast, &QPushButton::clicked, this, [=] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + return; + } + SendAnycastCmd(fdAnycast->text().toInt()); + fdAnycast->setText(tr("Anycast")+" - "+fdAnycast->text()); + btnAnycast->setEnabled(false); + }); vv->addWidget(btnAnycast); vv->addStretch(); @@ -244,10 +269,7 @@ CtrlTestPanel::CtrlTestPanel() { pushButtonStartLine->setProperty("ssType", "progManageTool"); pushButtonStartGray->setProperty("ssType", "progManageTool"); pushButtonStartColor->setProperty("ssType", "progManageTool"); - pushButtonStopTest->setProperty("ssType", "progManageTool"); - pushButton_11->setProperty("ssType", "progManageTool"); - pushButton_12->setProperty("ssType", "progManageTool"); - btnAnycast->setProperty("ssType", "progManageTool"); + btnStopTest->setProperty("ssType", "progManageTool"); spinBoxLineSpeed->setValue(10); spinBoxLineDistance->setValue(15); @@ -371,7 +393,7 @@ CtrlTestPanel::CtrlTestPanel() { } } }); - connect(pushButtonStopTest, &QPushButton::clicked, this, [this] { + connect(btnStopTest, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); return; @@ -392,38 +414,6 @@ CtrlTestPanel::CtrlTestPanel() { } } }); - connect(pushButton_11, &QPushButton::clicked, this, [=] { - lineEdit->clear(); - btnAnycast->setEnabled(false); - }); - connect(pushButton_12, &QPushButton::clicked, this, [=] { - if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); - return; - } - int iIndex = lineEdit->text().toInt(); - if(gSelCards.count()==1) SendAnycastCmd(gSelCards[0], 0, true); - else { - foreach(auto card, gSelCards) SendAnycastCmd(card, iIndex, false); - } - lineEdit->setText("-"+tr("loopback mode")+"-"); - btnAnycast->setEnabled(false); - }); - connect(btnAnycast, &QPushButton::clicked, this, [=] { - if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); - return; - } - int iIndex = lineEdit->text().toInt(); - if(gSelCards.count()==1) SendAnycastCmd(gSelCards[0], iIndex, true); - else foreach(auto card, gSelCards) SendAnycastCmd(card, iIndex, false); - lineEdit->setText(tr("Anycast")+" - "+lineEdit->text()); - btnAnycast->setEnabled(false); - }); - - btnAnycast->setEnabled(false); - - lineEdit->setValidator(new QIntValidator(0, 100, this)); transUi(); } @@ -467,43 +457,74 @@ void CtrlTestPanel::transUi() { radioButton_Green->setText(tr("Green")); radioButton_Blue->setText(tr("Blue")); radioButton_White->setText(tr("White")); - pushButtonStopTest->setText(tr("Stop")); - pushButton_11->setText(tr("Clear")); - pushButton_12->setText(tr("Reset")); + btnStopTest->setText(tr("Stop")); + btnAnycastClear->setText(tr("Clear")); + btnAnycastReset->setText(tr("Reset")); btnAnycast->setText(tr("Anycast")); } -void CtrlTestPanel::SendAnycastCmd(LedCard card, int iProgramIndex, bool isSingle) { - QTcpSocket *send = new QTcpSocket(); - connect(send, SIGNAL(connected()), this, SLOT(connect_sucessful())); - connect(send, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(show_error(QAbstractSocket::SocketError))); - send->connectToHost(QHostAddress(card.ip),31299); - +void CtrlTestPanel::SendAnycastCmd(int progIdx) { ST_ANSY_PROGRAM_PACKET tempStreadPakcet; - tempStreadPakcet.ucCommType=0x97; - tempStreadPakcet.iBaoLiu=0; - tempStreadPakcet.iLength=4; - unsigned char uctemp[4]={0}; - uctemp[0]=iProgramIndex; - - memcpy(tempStreadPakcet.pDataBuffer,uctemp,4); - tempStreadPakcet.pDataBuffer[tempStreadPakcet.iLength]=GetCheckCodeIn8(&tempStreadPakcet.ucCommType,tempStreadPakcet.iLength+sizeof(tempStreadPakcet.iBaoLiu)+sizeof(tempStreadPakcet.ucCommType)+sizeof(tempStreadPakcet.iLength)); - int iLenPacket=3*sizeof(unsigned char)+sizeof(char)+sizeof(int)+sizeof(int)+tempStreadPakcet.iLength+sizeof(char);/////除正文外的协议结构大小; - QByteArray databuf = QByteArray(reinterpret_cast(&tempStreadPakcet), iLenPacket); - if(!send->waitForConnected(10000)) //等待连接返回 - { - if(isSingle) QMessageBox::information(this, tr("Tip"), tr("Connect timeout")); - else gFdResInfo->append(card.id+":"+tr("receive")+"<-"+tr("Connect")+":"+tr("timeout")); - send->close(); - delete send; - return; + tempStreadPakcet.ucCommType = 0x97; + tempStreadPakcet.iBaoLiu = 0; + tempStreadPakcet.iLength = 4; + unsigned char uctemp[4] = {0}; + uctemp[0] = progIdx; + memcpy(tempStreadPakcet.pDataBuffer, uctemp, 4); + tempStreadPakcet.pDataBuffer[tempStreadPakcet.iLength] = GetCheckCodeIn8(&tempStreadPakcet.ucCommType,tempStreadPakcet.iLength+sizeof(tempStreadPakcet.iBaoLiu)+sizeof(tempStreadPakcet.ucCommType)+sizeof(tempStreadPakcet.iLength)); + int iLenPacket = 3*sizeof(unsigned char) + sizeof(char) + sizeof(int) + sizeof(int) + tempStreadPakcet.iLength + sizeof(char); //除正文外的协议结构大小; + auto data = QByteArray(reinterpret_cast(&tempStreadPakcet), iLenPacket); + auto action = progIdx==0 ? tr("Reset loop mode") : tr("Anycast"); + if(gSelCards.count() == 1) { + auto waitingDlg = new WaitingDlg(this, action+" ..."); + waitingDlg->show(); + auto card = gSelCards[0]; + auto tcp = new TcpSocket; + connect(waitingDlg, &WaitingDlg::rejected, tcp, [=] { + tcp->abort(); + tcp->deleteLater(); + }); + connect(tcp, &QTcpSocket::connected, tcp, [=] { + tcp->stopTimer(); + tcp->write(data); + tcp->startTimer(10000); + }); + connect(tcp, &QTcpSocket::readyRead, tcp, [=] { + tcp->stopTimer(); + tcp->close(); + tcp->deleteLater(); + waitingDlg->success(); + }); + connect(tcp, &QTcpSocket::errorOccurred, tcp, [=](QAbstractSocket::SocketError err) { + tcp->close(); + tcp->deleteLater(); + waitingDlg->close(); + QMessageBox::critical(this, tr("Tip"), QString(socketErrKey(err))+" ("+QString::number(err)+") "+tcp->errorString()); + }); + tcp->connectToHost(card.ip, 31299); + tcp->startTimer(10000); + } else { + for(auto &card : gSelCards) { + auto tcp = new TcpSocket; + auto cardId = card.id; + connect(tcp, &QTcpSocket::connected, tcp, [=] { + tcp->stopTimer(); + tcp->write(data); + tcp->startTimer(10000); + }); + connect(tcp, &QTcpSocket::readyRead, tcp, [=] { + tcp->stopTimer(); + tcp->close(); + tcp->deleteLater(); + gFdResInfo->append(cardId+" "+action+" "+tr("Success")); + }); + connect(tcp, &QTcpSocket::errorOccurred, tcp, [=](QAbstractSocket::SocketError err) { + tcp->close(); + tcp->deleteLater(); + gFdResInfo->append(cardId+" "+action+" "+socketErrKey(err)+" ("+QString::number(err)+") "+tcp->errorString()); + }); + tcp->connectToHost(card.ip, 31299); + tcp->startTimer(10000); + } } - send->write(databuf); - if(send->waitForBytesWritten(3000)) { - send->read(send->bytesAvailable()); - if(isSingle) QMessageBox::information(this, tr("Tip"), (iProgramIndex==0 ? tr("Reset loop mode") : tr("Anycast"))+":"+tr("success")); - else gFdResInfo->append(card.id+":"+tr("receive")+"<-"+tr("Anycast")+":"+tr("success")); - } - send->close(); - delete send; } diff --git a/LedOK/device/ctrltestpanel.h b/LedOK/device/ctrltestpanel.h index 738d26b..6983533 100644 --- a/LedOK/device/ctrltestpanel.h +++ b/LedOK/device/ctrltestpanel.h @@ -1,7 +1,6 @@ #ifndef CTRLTESTPANEL_H #define CTRLTESTPANEL_H -#include "globaldefine.h" #include #include #include @@ -20,7 +19,7 @@ protected: signals: void sigSend(QJsonObject &,QString); private: - void SendAnycastCmd(LedCard, int, bool); + void SendAnycastCmd(int); QLabel *labelTestScreen; QGroupBox *groupBox; @@ -58,10 +57,10 @@ private: QRadioButton *radioButton_Blue; QRadioButton *radioButton_White; QPushButton *pushButtonStartColor; - QPushButton *pushButtonStopTest; - QLineEdit *lineEdit; - QPushButton *pushButton_11; - QPushButton *pushButton_12; + QPushButton *btnStopTest; + QLineEdit *fdAnycast; + QPushButton *btnAnycastClear; + QPushButton *btnAnycastReset; QPushButton *btnAnycast; }; diff --git a/LedOK/device/upgradeapkdialog.cpp b/LedOK/device/upgradeapkdialog.cpp index 22e2aea..a4e9d15 100644 --- a/LedOK/device/upgradeapkdialog.cpp +++ b/LedOK/device/upgradeapkdialog.cpp @@ -194,11 +194,11 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { item->fdProgress->setValue(0); NetReq req("http://"+item->text("ip")+":2016/upload?type="+(isApk ? "software":"hardware")); auto reply = req.timeout(60000).type("multipart/form-data; boundary="+Boundary).post(data); - connect(reply, &QNetworkReply::uploadProgress, item->fdProgress, [item](qint64 bytesSent, qint64 bytesTotal) { + connect(reply, &QNetworkReply::uploadProgress, item, [item](qint64 bytesSent, qint64 bytesTotal) { if(bytesTotal==0) return; item->fdProgress->setValue(bytesSent*100/bytesTotal); }); - ConnReply(reply, item->fdProgress) [=] { + ConnReply(reply, item) [=] { auto err = errStrWithData(reply); if(! err.isEmpty()) { item->setResult(tr("Upload error")+": "+err, Qt::red); @@ -206,7 +206,7 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { return; } item->fdProgress->setValue(100); - auto info = tr("Installing")+" ..."; + auto info = tr("Upgrading")+" ..."; QJsonObject json; if(isApk) { json.insert("_id", "UpgradeSoftware"); @@ -220,7 +220,7 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { } item->setResult(info); auto reply = NetReq("http://"+item->text("ip")+":2016/settings").timeout(60000).post(json); - ConnReply(reply, item->fdProgress) [=] { + ConnReply(reply, item) [=] { if(item->treeWidget()==0) return; QJsonDocument json; auto err = checkReplyForJson(reply, &json); @@ -277,7 +277,7 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { json.insert("_type", "UninstallSoftware"); json.insert("packageName", strApkName); auto reply = NetReq("http://"+item->text("ip")+":2016/settings").timeout(60000).post(json); - ConnReply(reply, item->fdOnline) [reply, item, strApkName] { + ConnReply(reply, item) [reply, item, strApkName] { QString err = checkReplyForJson(reply, "error"); if(! err.isEmpty()) { item->setResult(tr("Uninstall error")+": "+err, Qt::red); @@ -301,7 +301,7 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { json.insert("_type", "IsSoftwareRunning"); json.insert("packageName", strApkName); auto reply = NetReq("http://"+item->text("ip")+":2016/settings").timeout(60000).post(json); - ConnReply(reply, item->fdOnline) [reply, item, strApkName] { + ConnReply(reply, item) [reply, item, strApkName] { QJsonDocument json; auto err = errStrWithData(reply, &json); if(! err.isEmpty()) { @@ -365,7 +365,7 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { item->btnUnlock = new QPushButton; item->btnUnlock->setMaximumHeight(36); item->setCellWidget("encrypt", item->btnUnlock); - connect(item->btnUnlock, &QPushButton::clicked, item->btnUnlock, [=] { + connect(item->btnUnlock, &QPushButton::clicked, item, [=] { if(! item->isLocked) return; bool ok; auto pwd = QInputDialog::getText(this, tr("Input password"), tr("Input password"), QLineEdit::Password, QString(), &ok); @@ -491,7 +491,7 @@ void UpgradeApkDialog::sendProgress(UpdateApkItem *item) { json.insert("_id", "GetFpgaUpdateProgress"); json.insert("_type", "GetFpgaUpdateProgress"); auto reply = NetReq("http://"+item->text("ip")+":2016/settings").timeout(30000).post(json); - ConnReply(reply, item->fdProgress) [=] { + ConnReply(reply, item) [=] { if(item->treeWidget()==0) return; QJsonDocument json; auto err = checkReplyForJson(reply, &json); diff --git a/LedOK/device/upgradeapkdialog.h b/LedOK/device/upgradeapkdialog.h index dc3d8a3..a74911c 100644 --- a/LedOK/device/upgradeapkdialog.h +++ b/LedOK/device/upgradeapkdialog.h @@ -18,7 +18,7 @@ protected: LoQTreeWidget *table; }; -class UpdateApkItem : public TreeWidgetItem { +class UpdateApkItem : public TreeWidgetItem, public QObject { public: using TreeWidgetItem::TreeWidgetItem; void setResult(QString tip, QColor color = Qt::blue) { diff --git a/LedOK/deviceitem.h b/LedOK/deviceitem.h index d9bb999..28b027b 100644 --- a/LedOK/deviceitem.h +++ b/LedOK/deviceitem.h @@ -1,13 +1,12 @@ #ifndef DEVICEITEM_H #define DEVICEITEM_H -#include #include "base/loqtreewidget.h" #include "globaldefine.h" #include -#include +#include -class DeviceItem : public TreeWidgetItem { +class DeviceItem : public TreeWidgetItem, public QObject { public: explicit DeviceItem(LoQTreeWidget *); void init(); diff --git a/LedOK/devicepanel.cpp b/LedOK/devicepanel.cpp index 375f08c..bb810ab 100644 --- a/LedOK/devicepanel.cpp +++ b/LedOK/devicepanel.cpp @@ -258,14 +258,14 @@ QPushButton:hover {background-color: #08b;} } init(item); nDeviceNum->setText(QString::number(mDeviceTable->topLevelItemCount())); - { - QJsonObject json; - json.insert("_id", "SyncTime"); - json.insert("_type", "SyncTime"); - json.insert("time", QDateTime::currentDateTime().toMSecsSinceEpoch()); - auto reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(60000).post(json); - connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); - } +// { +// QJsonObject json; +// json.insert("_id", "SyncTime"); +// json.insert("_type", "SyncTime"); +// json.insert("time", QDateTime::currentDateTime().toMSecsSinceEpoch()); +// auto reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(60000).post(json); +// connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); +// } end:; } }); @@ -459,7 +459,10 @@ void DevicePanel::newCtrl() { auto vBox2 = new QVBoxLayout(); - fdInfo = new QTextEdit(); + fdInfo = new QTextEdit; + auto ft = fdInfo->font(); + ft.setFamily("Consolas"); + fdInfo->setFont(ft); gFdResInfo = fdInfo; fdInfo->setReadOnly(true); fdInfo->setMaximumWidth(360); @@ -502,7 +505,7 @@ void DevicePanel::init(DeviceItem *item) { json.insert("_id", "GetBuildInformation"); json.insert("_type", "GetBuildInformation"); auto reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json); - ConnReply(reply, item->fdOnline) [=] { + ConnReply(reply, item) [=] { QJsonDocument json; QString err = checkReplyForJson(reply, &json); if(! err.isEmpty()) return; @@ -520,7 +523,7 @@ void DevicePanel::init(DeviceItem *item) { json.insert("_id", "GetScreenSize"); json.insert("_type", "GetScreenSize"); reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json); - ConnReply(reply, item->fdOnline) [=] { + ConnReply(reply, item) [=] { QJsonDocument json; QString err = checkReplyForJson(reply, &json); if(! err.isEmpty()) return; @@ -534,7 +537,7 @@ void DevicePanel::init(DeviceItem *item) { json.insert("_id", "GetBrightness"); json.insert("_type", "GetBrightness"); reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json); - ConnReply(reply, item->fdOnline) [=] { + ConnReply(reply, item) [=] { QJsonDocument json; QString err = checkReplyForJson(reply, &json); if(! err.isEmpty()) return; @@ -546,7 +549,7 @@ void DevicePanel::init(DeviceItem *item) { json.insert("_id", "IsScreenOn"); json.insert("_type", "IsScreenOn"); reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json); - ConnReply(reply, item->fdOnline) [=] { + ConnReply(reply, item) [=] { QJsonDocument json; QString err = checkReplyForJson(reply, &json); if(! err.isEmpty()) return; @@ -558,7 +561,7 @@ void DevicePanel::init(DeviceItem *item) { json.insert("_id", "GetCardAlias"); json.insert("_type", "GetCardAlias"); reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json); - ConnReply(reply, item->fdOnline) [=] { + ConnReply(reply, item) [=] { QJsonDocument json; QString err = checkReplyForJson(reply, &json); if(! err.isEmpty()) return; @@ -570,7 +573,7 @@ void DevicePanel::init(DeviceItem *item) { json.insert("_id", "HasControllerPassword"); json.insert("_type", "HasControllerPassword"); reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json); - ConnReply(reply, item->fdOnline) [=] { + ConnReply(reply, item) [=] { QJsonDocument json; QString err = checkReplyForJson(reply, &json); if(! err.isEmpty()) return; diff --git a/LedOK/ffplayer.cpp b/LedOK/ffplayer.cpp index 9e4c26c..36898bd 100644 --- a/LedOK/ffplayer.cpp +++ b/LedOK/ffplayer.cpp @@ -122,18 +122,18 @@ AVFmt::AVFmt(QByteArray url) { #endif sink = new QAudioSink(audioDevice, audioFmt); sinkWriter = sink->start(); - if(sinkWriter==nullptr) { + if(sinkWriter==0) { au.idx = -1; qCritical()<<"Couldn't Start Audio Output"<error(); } else { const AVCodec *decoder = avcodec_find_decoder(codecpar->codec_id); - if(decoder==nullptr) { + if(decoder==0) { au.idx = -1; qWarning()<<"Couldn't found Audio Decoder"; } else { au.ctx = avcodec_alloc_context3(decoder); avcodec_parameters_to_context(au.ctx, codecpar); - if(avcodec_open2(au.ctx, decoder, nullptr) < 0) { + if(avcodec_open2(au.ctx, decoder, 0) < 0) { au.idx = -1; qWarning()<<"Couldn't open aCodecCtx"; } else { @@ -171,18 +171,18 @@ AVFmt::AVFmt(QByteArray url) { if(vi.idx > -1) vi.thd = new thread(&AVFmt::mainViDecode, this); } AVFmt::~AVFmt() { - if(read_thd!=nullptr) { - acts.lockAddNtf(new Act{0, nullptr, 'Q'}); + if(read_thd) { + acts.lockAddNtf(new Act{0, 0, 'Q'}); read_thd->join(); delete read_thd; qInfo() << "~ read thread"; } - if(au.thd!=nullptr) { + if(au.thd) { au.thd->join(); delete au.thd; qInfo() << "~ au thread"; } - if(vi.thd!=nullptr) { + if(vi.thd) { vi.thd->join(); delete vi.thd; qInfo() << "~ vi thread"; @@ -199,7 +199,7 @@ void AVFmt::mainRead() { int res = 0; while(true) { auto act = wait==0 ? acts.lockPoll() : acts.take(wait); - while(act!=nullptr) { + while(act) { if(act->act=='S') { if(au.idx!=-1) { unique_lock lock(au.pkts.mtx); @@ -616,12 +616,12 @@ void FFPlayer::updFrame() { } auto now_epoch = chrono::duration_cast(chrono::steady_clock::now().time_since_epoch()).count(); dur = now_epoch - last_epoch; + last_epoch = now_epoch; + if(dur>100000) return; if(dur<4000) { qWarning()<<"FFPlayer UpdFrame Fail: dur"<100000) return; ctx->checkAndUpd(this, now_epoch); viSize = ctx->vi_frms.size; auSize = ctx->au_frms.size; diff --git a/LedOK/ffplayer.h b/LedOK/ffplayer.h index 048017b..0ae80b5 100644 --- a/LedOK/ffplayer.h +++ b/LedOK/ffplayer.h @@ -25,18 +25,18 @@ public: delAll(); } void add(T *node) { - if(node==nullptr) { + if(node==0) { throw std::invalid_argument("node is null"); return; } - if(last!=nullptr) last->next = node; + if(last) last->next = node; else first = node; last = node; size++; } void remove() { - if(first==nullptr) return; - if(first==last) first = last = nullptr; + if(first==0) return; + if(first==last) first = last = 0; else first = first->next; size--; } @@ -54,7 +54,7 @@ public: return first; } void delAll() { - while(first!=nullptr) delete poll(); + while(first) delete poll(); } T *volatile first{0}; @@ -154,7 +154,6 @@ public: avcodec_free_context(&ctx); } }; -class FFPlayer; class AVFmt { friend class FFPlayer; public: diff --git a/LedOK/globaldefine.cpp b/LedOK/globaldefine.cpp index 1e9e966..3df1a0b 100644 --- a/LedOK/globaldefine.cpp +++ b/LedOK/globaldefine.cpp @@ -11,12 +11,13 @@ QString gFileHome; QString gApkHome; QList gSelCards; -bool gVideoCompress = true; -bool gVideoTranscoding = true; +bool gVideoCompress = false; +bool gVideoTranscoding = false; bool gTextAntialiasing = false; bool gWidthSplit = false; int gSendBatch = 5; bool gHideDetect = false; +bool gShowAlias = false; bool gShowLora = false; DeviceItem *findItem(QString id) { diff --git a/LedOK/globaldefine.h b/LedOK/globaldefine.h index bd970a8..efdde51 100644 --- a/LedOK/globaldefine.h +++ b/LedOK/globaldefine.h @@ -51,6 +51,7 @@ extern bool gTextAntialiasing; extern bool gWidthSplit; extern int gSendBatch; extern bool gHideDetect; +extern bool gShowAlias; extern bool gShowLora; extern quint64 dirFileSize(const QString &path); diff --git a/LedOK/gutil/qnetwork.h b/LedOK/gutil/qnetwork.h index b47264b..423951a 100644 --- a/LedOK/gutil/qnetwork.h +++ b/LedOK/gutil/qnetwork.h @@ -157,55 +157,4 @@ protected: bool connAndExec(int msecs, QEventLoop *loop); }; -struct NetReplyData { - QNetworkReply* reply; - size_t cnt = 1; - bool isDeleted = false; -}; -class NetReply { -public: - NetReply(QNetworkReply *reply) : ptr{new NetReplyData{reply}} {} - ~NetReply() { - if(ptr->cnt > 1) ptr->cnt--; - else { - if(! ptr->isDeleted) ptr->reply->deleteLater(); - delete ptr; - } - } - - NetReply(const NetReply &other) : ptr{other.ptr} { - ptr->cnt++; - } - NetReply &operator=(const NetReply &other) { - NetReply ooo(other); - auto aaa = ptr; - ptr = ooo.ptr; - ooo.ptr = aaa; - return *this; - } - NetReply(NetReply &&other) noexcept : ptr(other.ptr) { - other.ptr = 0; - } - NetReply &operator=(NetReply &&other) noexcept { - auto aaa = ptr; - ptr = other.ptr; - other.ptr = aaa; - return *this; - } - - void deleteLater() { - if(ptr->isDeleted) return; - ptr->reply->deleteLater(); - ptr->isDeleted = true; - } - - QNetworkReply *operator*() const { - return ptr->reply; - } - QNetworkReply *operator->() const { - return ptr->reply; - } - NetReplyData *ptr; -}; - #endif // QNETWORK_H diff --git a/LedOK/main.cpp b/LedOK/main.cpp index 56a0cc3..0816687 100644 --- a/LedOK/main.cpp +++ b/LedOK/main.cpp @@ -38,7 +38,7 @@ int main(int argc, char *argv[]) { QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); #endif - QApplication::setOrganizationName("Shanghai Xixun Electronic Technology Co., Ltd."); + QApplication::setOrganizationName("Sysolution"); QApplication::setOrganizationDomain("www.ledok.cn"); QApplication::setApplicationName("LedOK Express"); QApplication::setStyle("Fusion"); diff --git a/LedOK/mainwindow.cpp b/LedOK/mainwindow.cpp index 560ba7c..6e595d2 100644 --- a/LedOK/mainwindow.cpp +++ b/LedOK/mainwindow.cpp @@ -98,6 +98,16 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { }); QSettings settings; + auto MainGeo = settings.value("MainGeo"); + if(! MainGeo.isValid()) { + QSettings old("Shanghai Xixun Electronic Technology Co., Ltd.", "LedOK Express"); + MainGeo = old.value("MainGeo"); + if(MainGeo.isValid()) { + auto keys = old.allKeys(); + for(auto &key : keys) settings.setValue(key, old.value(key)); + old.remove(""); + } + } QString langName = settings.value("Language").toString(); QAction *actLan = 0; if(! langName.isEmpty()) { @@ -120,7 +130,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { emit menuLang->triggered(actLan); QCoreApplication::installTranslator(&translator); - auto geo = settings.value("MainGeo").toRect(); + auto geo = MainGeo.toRect(); if(geo.width()>=800 && geo.height()>=500 && geo.x()>=-600 && geo.x()<=1280 && geo.y()>=-200 && geo.y()<=800) setGeometry(geo); else resize(1280, 800); if(settings.value("MainIsMax", false).toBool()) setWindowState(Qt::WindowMaximized); @@ -136,16 +146,12 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { setPalette(plt); //项目保存的文档路径 - QString doc_path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); - if(!doc_path.isEmpty()) { - QDir app_dir = QDir(doc_path + "/" + QCoreApplication::applicationName()); - if(!app_dir.exists()) { - QDir doc_dir(doc_path); - doc_dir.mkdir(QCoreApplication::applicationName()); - } + auto dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + if(! dataDir.isEmpty()) { + QDir dataQDir(dataDir); + if(! dataQDir.exists()) dataQDir.mkpath(dataDir); } - //创建一个垂直布局 auto vBox = new VBox(center); vBox->setContentsMargins(0, 0, 0, 0); vBox->setSpacing(0); @@ -223,6 +229,10 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { fdHideDetect->setChecked(gHideDetect); vBox->addWidget(fdHideDetect); + auto fdShowAlias = new QCheckBox(tr("Show Alias in Terminal Control")); + fdShowAlias->setChecked(gShowAlias); + vBox->addWidget(fdShowAlias); + auto fdShowLora = new QCheckBox(tr("Show Lora Screen")); fdShowLora->setChecked(gShowLora); vBox->addWidget(fdShowLora); @@ -238,6 +248,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { settings.setValue("WidthSplit", gWidthSplit = fdWidthSplit->isChecked()); settings.setValue("SendBatch", gSendBatch = fdSendBatch->value()); settings.setValue("HideDetect", gHideDetect = fdHideDetect->isChecked()); + settings.setValue("ShowAlias", gShowAlias = fdShowAlias->isChecked()); settings.setValue("GuangYingPin", gShowLora = fdShowLora->isChecked()); dlg.accept(); }); @@ -245,6 +256,16 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { dlg.exec(); fdDetectCard->setVisible(! gHideDetect); + if(mDevicePanel->mDeviceTable->isColumnHidden(mDevicePanel->mDeviceTable->columnCount()-1)) { + if(gShowAlias) { + mDevicePanel->mDeviceTable->showColumn("alias"); + mDevicePanel->mDeviceTable->hideColumn("ip"); + } else { + mDevicePanel->mDeviceTable->hideColumn("alias"); + mDevicePanel->mDeviceTable->showColumn("ip"); + } + mDevicePanel->mDeviceTable->adjSections(-1, 0); + } mBtnGrp->button(MainPage_LoraScreen)->setVisible(gShowLora); }); menu_setting->addAction(actPreferences); @@ -351,7 +372,11 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { return; } #ifdef Q_OS_WIN + #if(QT_VERSION_MAJOR > 5) + updates = json["win-64"].toObject(); + #else updates = json["win"].toObject(); + #endif #endif #ifdef Q_OS_MAC updates = json["mac"].toObject(); @@ -470,7 +495,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { mDevicePanel->mDeviceTable->fdCheckAll->hide(); mDevicePanel->fdCardNumInfo->hide(); if(mDevicePanel->mDeviceCtrlPanel) { - for(int j="screenSize"**mDevicePanel->mDeviceTable; jmDeviceTable->columnCount(); j++) mDevicePanel->mDeviceTable->showColumn(j); + for(int j="id"**mDevicePanel->mDeviceTable+1; jmDeviceTable->columnCount(); j++) mDevicePanel->mDeviceTable->showColumn(j); mDevicePanel->mDeviceTable->setMaximumWidth(0xffffff); mDevicePanel->mDeviceCtrlPanel->hide(); } @@ -478,10 +503,11 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { mDevicePanel->mDeviceTable->showColumn("check"); mDevicePanel->mDeviceTable->fdCheckAll->show(); mDevicePanel->fdCardNumInfo->show(); - for(int j="screenSize"**mDevicePanel->mDeviceTable; jmDeviceTable->columnCount(); j++) mDevicePanel->mDeviceTable->hideColumn(j); + auto specialIdx = (gShowAlias ? "alias" : "ip")**mDevicePanel->mDeviceTable; + for(int j="id"**mDevicePanel->mDeviceTable+1; jmDeviceTable->columnCount(); j++) if(j!=specialIdx) mDevicePanel->mDeviceTable->hideColumn(j); if(mDevicePanel->mDeviceCtrlPanel) mDevicePanel->mDeviceCtrlPanel->show(); else mDevicePanel->newCtrl(); - mDevicePanel->mDeviceTable->setMaximumWidth(340); + mDevicePanel->mDeviceTable->setMaximumWidth(300); } }); @@ -527,18 +553,27 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { } }); hBox->addWidget(fdDetectCard); + + // auto btn = new QPushButton("Test"); + // connect(btn, &QPushButton::clicked, this, [=] { + // auto www = new TTTWgt; + // www->show(); + // }); + // hBox->addWidget(btn); + hBox->addStretch(); hBox->addLabel("V" APP_VERSION" - " __DATE__); gApkHome = settings.value("ApkHome").toString(); - gVideoCompress = settings.value("VideoCompress", true).toBool(); - gVideoTranscoding = settings.value("VideoTranscoding", true).toBool(); - gTextAntialiasing = settings.value("TextAntialiasing", false).toBool(); - gWidthSplit = settings.value("WidthSplit", false).toBool(); + gVideoCompress = settings.value("VideoCompress").toBool(); + gVideoTranscoding = settings.value("VideoTranscoding").toBool(); + gTextAntialiasing = settings.value("TextAntialiasing").toBool(); + gWidthSplit = settings.value("WidthSplit").toBool(); gSendBatch = settings.value("SendBatch", 5).toInt(); - gHideDetect = settings.value("HideDetect", false).toBool(); - gShowLora = settings.value("GuangYingPin", false).toBool(); + gHideDetect = settings.value("HideDetect").toBool(); + gShowAlias = settings.value("ShowAlias").toBool(); + gShowLora = settings.value("GuangYingPin").toBool(); if(gHideDetect) fdDetectCard->hide(); if(! gShowLora) mBtnGrp->button(MainPage_LoraScreen)->hide(); diff --git a/LedOK/mainwindow.h b/LedOK/mainwindow.h index f5a2ed4..fde3efc 100644 --- a/LedOK/mainwindow.h +++ b/LedOK/mainwindow.h @@ -9,6 +9,7 @@ #include "progpanel.h" #include #include +#include class MainWindow : public BaseWin { Q_OBJECT diff --git a/LedOK/player/elegif.cpp b/LedOK/player/elegif.cpp index 0702d39..cb0803d 100644 --- a/LedOK/player/elegif.cpp +++ b/LedOK/player/elegif.cpp @@ -10,10 +10,10 @@ EleGif::EleGif(QString path, QWidget *parent) : QWidget{parent} { void EleGif::paintEvent(QPaintEvent *){ QPainter painter(this); - if(movie!=nullptr) { + if(movie) { painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform); painter.drawPixmap(0, 0, width(), height(), movie->currentPixmap()); - if(timer==nullptr) { + if(timer==0) { timer = new SyncTimer(movie->nextFrameDelay()); connect(timer, &SyncTimer::timeout, this, &EleGif::sltNext, Qt::BlockingQueuedConnection); timer->start(); @@ -25,8 +25,8 @@ void EleGif::sltNext(){ movie->jumpToNextFrame(); timer->inter = movie->nextFrameDelay(); update(); - } else if(timer!=nullptr) { + } else if(timer) { timer->stop(); - timer = nullptr; + timer = 0; } } diff --git a/LedOK/player/elemultipng.cpp b/LedOK/player/elemultipng.cpp deleted file mode 100644 index 6dd2069..0000000 --- a/LedOK/player/elemultipng.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include "elemultipng.h" -#include -#include - -const QChar effTypes[] = {'l', 't', 'r', 'b'}; - -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; - 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'; - else if(effStr.endsWith("right")) effType = 'r'; - else if(effStr.endsWith("bottom")) effType = 'b'; - else if(effStr == "random") needRand = true; - else EffDur = 0; -} - -void EleMultiPng::startMove() { - if(EffDur==0) return; - if(needRand) effType = effTypes[rand.generate() % 4]; - double effDurD = EffDur; - if(effType=='l') { - imgx = width(); - imgy = 0; - effDurD /= width(); - } else if(effType=='r') { - imgx = -width(); - imgy = 0; - effDurD /= width(); - } else if(effType=='t') { - imgx = 0; - imgy = height(); - effDurD /= height(); - } else if(effType=='b') { - imgx = 0; - imgy = -height(); - effDurD /= height(); - } else return; - movePx = ceil(17/effDurD); - moveInter = effDurD*movePx; - moveTimerId = startTimer(moveInter, Qt::PreciseTimer); -} - -void EleMultiPng::paintEvent(QPaintEvent *) { - if(timerId==0 && (EffDur!=0 || imgs.size()>1)) { - timerId = startTimer(picDur, Qt::PreciseTimer); - startMove(); - } - QPainter painter(this); - painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform); - painter.drawPixmap(imgx, imgy, imgs[imgc]); -} - -void EleMultiPng::timerEvent(QTimerEvent *e) { - if(isVisible()) { - int id = e->timerId(); - if(id==timerId){ - if(imgc+2 > imgs.size()) imgc = 0; - else imgc++; - startMove(); - } else if(id==moveTimerId){ - if(effType=='l') { - imgx -= movePx; - if(imgx < 0) imgx = 0; - } else if(effType=='t') { - imgy -= movePx; - if(imgy < 0) imgy = 0; - } else if(effType=='r') { - imgx += movePx; - if(imgx > 0) imgx = 0; - } else if(effType=='b') { - imgy += movePx; - if(imgy > 0) imgy = 0; - } - if(imgx==0 && imgy==0) { - killTimer(moveTimerId); - moveTimerId = 0; - } - } - update(); - foreach(auto split, splits) split->update(); - } else { - if(timerId!=0) { - killTimer(timerId); - timerId = 0; - } - if(moveTimerId!=0) { - killTimer(moveTimerId); - moveTimerId = 0; - } - imgc = 0; - } -} - -void EleSplitPng::paintEvent(QPaintEvent *) { - QPainter painter(this); - painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform); - painter.drawPixmap(multiPng->imgx, multiPng->imgy, multiPng->imgs[multiPng->imgc]); -} diff --git a/LedOK/player/elemultipng.h b/LedOK/player/elemultipng.h deleted file mode 100644 index 2344c3f..0000000 --- a/LedOK/player/elemultipng.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef ELEMULTIPNG_H -#define ELEMULTIPNG_H - -#include "gutil/qjson.h" -#include -#include - -class EleSplitPng; -class EleMultiPng : public QWidget { - Q_OBJECT -public: - explicit EleMultiPng(QString, const JValue &, QWidget *parent); - void startMove(); - - QVector imgs; - int timerId = 0, moveTimerId = 0; - int picDur = 0, EffDur = 0, moveInter = 0, movePx = 0, imgc = 0, imgx = 0, imgy = 0; - QChar effType{0}; - QRandomGenerator rand; - bool needRand = false; - QList splits; - -protected: - void paintEvent(QPaintEvent *) override; - void timerEvent(QTimerEvent *) override; -}; - -class EleSplitPng : public QWidget { - Q_OBJECT -public: - explicit EleSplitPng(EleMultiPng *multiPng, QWidget *parent) : QWidget{parent}, multiPng(multiPng) {} - -protected: - void paintEvent(QPaintEvent *) override; - - EleMultiPng *multiPng; -}; - -#endif // ELEMULTIPNG_H diff --git a/LedOK/player/elescroll.cpp b/LedOK/player/elescroll.cpp index 6c17fdf..f7920b9 100644 --- a/LedOK/player/elescroll.cpp +++ b/LedOK/player/elescroll.cpp @@ -1,19 +1,23 @@ #include "elescroll.h" -#include +#include "playwin.h" +#include #include -#include +#include -EleScroll::EleScroll(QWidget *parent, QString dirPre, const JValue &map) : QWidget{parent} { - img.load(dirPre + map["id"].toString()); - auto effStr = map["effect"].toString(); +EleScroll::EleScroll(QWidget *parent, QString dirPre, const JValue &json, int w, int h) : QWidget{parent}, w(w), h(h) { + img.load(dirPre + json["id"].toString()); + auto effStr = json["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; + + auto scrollSpeed = json["scrollSpeed"].toDouble(); + if(scrollSpeed==0) { + auto scrollDur = json["effectSpeed"].toDouble(); + if(scrollDur==0) return; + scrollSpeed = 1000 / scrollDur; + } + interval = step = 1; + if(scrollSpeed > 60) step = (int) round(scrollSpeed/60); + else if(scrollSpeed < 60) interval = (int) round(60/scrollSpeed); int idx = effStr.lastIndexOf(' '); if(idx > -1) { effect = effStr.at(idx+1).toLatin1(); @@ -23,46 +27,65 @@ EleScroll::EleScroll(QWidget *parent, QString dirPre, const JValue &map) : QWidg else if(effect=='b') end = img.height()-step; } } -EleScroll::EleScroll(QWidget *parent, QString imgPath, char effect, double effDur) : QWidget{parent}, effect(effect) { +EleScroll::EleScroll(QWidget *parent, QString imgPath, char effect, double scrollSpeed) : QWidget{parent}, effect(effect) { img.load(imgPath); if(effect==0) return; - if(effDur==0) return; - 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(scrollSpeed==0) return; + interval = step = 1; + if(scrollSpeed > 60) step = (int) round(scrollSpeed/60); + else if(scrollSpeed < 60) interval = (int) round(60/scrollSpeed); 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 *) { - paint(this); -} -void EleScroll::paint(QPaintDevice *that) { +void EleScroll::paintEvent(QPaintEvent *e) { if(img.isNull()) return; - if(timerId==0 && effect!=0 && interval!=0) timerId = startTimer(round(interval), Qt::PreciseTimer); - QPainter painter(that); + auto rect = e->rect(); + QPainter painter(this); painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform); if(effect=='l') { - painter.drawPixmap(cur, 0, img); - painter.drawPixmap(cur+img.width(), 0, img); + int x = cur; + do { + if(x > rect.left()-img.width() && x < rect.right()+1) painter.drawPixmap(x, 0, img); + x += img.width(); + } while(x < rect.right()+1); } else if(effect=='r') { - painter.drawPixmap(cur, 0, img); - painter.drawPixmap(cur-img.width(), 0, img); + int x = cur + w; + boolean con1; + do { + x -= img.width(); + con1 = x > rect.left()-img.width(); + if(con1 && x < rect.right()+1) painter.drawPixmap(x, 0, img); + } while(con1); } else if(effect=='t') { - painter.drawPixmap(0, cur, img); - painter.drawPixmap(0, cur+img.height(), img); + int y = cur; + do { + if(y > rect.top()-img.height() && y < rect.bottom()+1) painter.drawPixmap(0, y, img); + y += img.height(); + } while(y < rect.bottom()+1); } else if(effect=='b') { - painter.drawPixmap(0, cur, img); - painter.drawPixmap(0, cur-img.height(), img); + int y = cur + h; + boolean con1; + do { + y -= img.height(); + con1 = y > rect.top()-img.height(); + if(con1 && y < rect.bottom()+1) painter.drawPixmap(0, y, img); + } while(con1); } else painter.drawPixmap(0, 0, img); + if(freshCnt==0 && effect!=0 && interval!=0) connect(PlayWin::self->gl, &QOpenGLWidget::frameSwapped, this, &EleScroll::doFrame, Qt::UniqueConnection); } -void EleScroll::timerEvent(QTimerEvent *) { - if(isVisible()) { +void EleScroll::doFrame() { + if(! isVisible()) { + freshCnt = cur = 0; + disconnect(PlayWin::self->gl, &QOpenGLWidget::frameSwapped, this, &EleScroll::doFrame); + return; + } + if(freshCnt < interval) freshCnt++; + else { + freshCnt = 1; if(effect=='t' || effect=='l') { if(cur <= end) cur -= end; else cur -= step; @@ -71,13 +94,5 @@ void EleScroll::timerEvent(QTimerEvent *) { else cur += step; } update(); - for(auto split : splits) split->update(); - } else if(timerId!=0) { - killTimer(timerId); - timerId = cur = 0; } } - -void EleSplitScroll::paintEvent(QPaintEvent *) { - scroll->paint(this); -} diff --git a/LedOK/player/elescroll.h b/LedOK/player/elescroll.h index f139855..aa5cd78 100644 --- a/LedOK/player/elescroll.h +++ b/LedOK/player/elescroll.h @@ -4,30 +4,19 @@ #include "gutil/qjson.h" #include -class EleSplitScroll; class EleScroll : public QWidget { Q_OBJECT public: - explicit EleScroll(QWidget *, QString, const JValue &); + explicit EleScroll(QWidget *, QString, const JValue &, int, int); explicit EleScroll(QWidget *, QString, char effect = 0, double effDur = 0.0); + int w = 0, h = 0; QPixmap img; char effect = 0; - int interval = 0, timerId = 0, cur = 0, end = 0, step = 1; - std::vector splits; - void paint(QPaintDevice *); + int interval = 0, freshCnt = 0, cur = 0, end = 0, step = 1; + bool noUpdate = false; + void doFrame(); protected: void paintEvent(QPaintEvent *) override; - void timerEvent(QTimerEvent *) override; }; -class EleSplitScroll : public QWidget { - Q_OBJECT -public: - explicit EleSplitScroll(QWidget *parent, EleScroll *scroll) : QWidget{parent}, scroll(scroll) {}; - -protected: - void paintEvent(QPaintEvent *) override; - - EleScroll *scroll; -}; #endif // ELESCROLL_H diff --git a/LedOK/player/playwin.cpp b/LedOK/player/playwin.cpp index 7193c7d..1df0877 100644 --- a/LedOK/player/playwin.cpp +++ b/LedOK/player/playwin.cpp @@ -3,171 +3,182 @@ #include "eleanaclock.h" #include "eleborder.h" #include "elegif.h" -#include "elemultipng.h" #include "elescroll.h" #include "eletimer.h" #include "elevideo.h" +#include "srccopy.h" #include "posdlg.h" #include #include #include #include -#include #include #include +#include PlayWin* PlayWin::self = 0; QPoint gPlayPos{0, 0}; -Page::Page(QWidget *parent) : 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 JValue &aprog, QWidget *parent) : QWidget(parent) { + self = this; setAttribute(Qt::WA_DeleteOnClose); setAttribute(Qt::WA_QuitOnClose, false); setWindowFlag(Qt::FramelessWindowHint); setWindowFlag(Qt::WindowStaysOnTopHint); - setGeometry(x, y, width, height); - QPalette plt = palette(); - plt.setColor(QPalette::Window, QColor(0,0,0)); + setGeometry(x, y, width, height+1); + auto plt = palette(); + plt.setColor(QPalette::Window, Qt::black); setPalette(plt); - connect(this, &PlayWin::sigSetVisible, this, &PlayWin::sltSetVisible); + gl = new QOpenGLWidget(this); + gl->setGeometry(0, height, width, 1); + connect(gl, &QOpenGLWidget::frameSwapped, gl, (void(QOpenGLWidget::*)())&QOpenGLWidget::update); + auto task = aprog["task"]; + auto jpages = task["items"]; - auto pageMaps = aprog["task"]["items"]; - EleBase ele; Page *page; - for(auto &pageMap : pageMaps) { + auto partLengths = task["partLengths"]; + auto isVertical = task["isVertical"].toBool(); + QWidget *box = this; + if(partLengths.size() > 1) { + box = new QWidget(this); + auto width = task["width"].toInt(); + auto height = task["height"].toInt(); + box->setGeometry(0, 0, width, height); + auto mask = new QWidget(this); + mask->setAutoFillBackground(true); + auto pal = mask->palette(); + pal.setColor(QPalette::Window, Qt::black); + mask->setPalette(pal); + auto len0 = partLengths[0].toInt(); + isVertical ? mask->setGeometry(0, len0, width, height - len0) : mask->setGeometry(len0, 0, width - len0, height); + int x = 0, y = 0; + for(int i=1; i<(int)partLengths.size(); i++) { + auto part = new SrcCopy(this, box); + if(isVertical) { + y -= partLengths[i-1].toInt(); + x += width; + part->setGeometry(x, y, width, partLengths[i].toInt() - y); + } else { + x -= partLengths[i-1].toInt(); + y += height; + part->setGeometry(x, y, partLengths[i].toInt() - x, height); + } + } + } + for(auto &pageMap : jpages) { 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); + Page page; + page.repeatTimes = pageMap["repeatTimes"].toInt(); for(int ll=(int)layers.size()-1; ll>=0; ll--) { - auto layer = layers[ll].toObj(); - auto repeat = layer["repeat"].toBool(); - auto sources = layer["sources"]; - auto border = layer["border"]; + Layer layer; + layer.isLoop = layers[ll]["repeat"].toBool(); + auto sources = layers[ll]["sources"]; + auto border = layers[ll]["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); + bdEle = new EleBorder(dir+"/"+border["img"].toString(), border["eff"].toString(), border["speed"].toInt(), box); bdWidth = bdEle->img.height(); } + Source src; for(auto &source : sources) { - ele.type = source["_type"].toString(); - if(ele.type.isEmpty()) continue; + src.type = source["_type"].toString(); + if(src.type.isEmpty()) continue; auto timeSpan = source["timeSpan"].toInt()*1000; if(timeSpan==0) continue; - 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 = 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 = source["id"].toString(); - ele.wgt = 0; - if(ele.type=="Image") { - if(source["mime"].toString().endsWith("gif")) ele.wgt = new EleGif(dir+"/"+ele.id, page); + auto x = source["left"].toInt()+bdWidth; + auto y = source["top"].toInt()+bdWidth; + auto w = source["width"].toInt()-bdWidth-bdWidth; + auto h = source["height"].toInt()-bdWidth-bdWidth; + bool notAudio = src.type!="Audio"; + if((w<=0 || h<=0) && notAudio) continue; + src.startTime = source["playTime"].toInt()*1000; + if(bdStart > src.startTime) bdStart = src.startTime; + src.endTime = src.startTime + timeSpan; + if(bdEnd < src.endTime) bdEnd = src.endTime; + if(layer.dur < src.endTime) layer.dur = src.endTime; + if(notAudio) { + if(page.sDur < src.endTime) page.sDur = src.endTime; + } else if(page.audioDur < src.endTime) page.audioDur = src.endTime; + + if(src.exitDur!=0) src.exitStart = timeSpan*60/1000 - src.exitDur; + + auto id = source["id"].toString(); + src.view = 0; + if(src.type=="Image") { + if(source["fileExt"].toString()=="gif") src.view = new EleGif(dir+"/"+id, box); else { - auto lb = new QLabel(page); - lb->setPixmap(QPixmap(dir+"/"+ele.id)); + auto lb = new QLabel(box); + lb->setPixmap(QPixmap(dir+"/"+id)); lb->setScaledContents(true); - ele.wgt = lb; + src.view = lb; } - } else if(ele.type.startsWith("Environ")) { + } else if(src.type.startsWith("Environ")) { 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()); + if(source["bSingleScroll"].toBool()) src.view = new EleScroll(box, dir+"/" + arrayPics[i]["id"].toString(), 'l', source["iScrollSpeed"].toDouble()); + else src.view = new EleScroll(box, dir+"/"+arrayPics[i]["id"].toString()); break; } - } else if(ele.type=="MultiPng") { + } else if(src.type=="MultiPng" || src.type=="SplitText") { 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") { - 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[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<(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.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<(int)splitWidths.size(); i++) { - ele.x -= splitWidths[i-1].toInt(); - ele.y += height; - auto split = new EleSplitPng(wgt, ele.wgt); - split->setGeometry(ele.x, ele.y, splitWidths[i].toInt()-ele.x, ele.h); - wgt->splits.append(split); - } - } - ele.w = 0; - } 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); + if(! imgs.empty()) src.view = new EleScroll(box, dir+"/", imgs[0], w, h); + } else if(src.type=="DigitalClockNew") src.view = new EleDigiClock(dir+"/", source, box); + else if(src.type=="AnalogClock") src.view = new EleAnaClock(w, h, dir+"/"+id, source, box); + else if(src.type=="Video" || src.type=="Audio") { + auto video = new EleVideo(dir+"/"+id, box); 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); + src.view = video; + } else if(src.type=="WebURL") { + auto web = new QWebEngineView(box); web->load(QUrl(source["url"].toString())); - ele.wgt = web; + src.view = web; } - else if(ele.type=="Timer") ele.wgt = new EleTimer(source, page); + else if(src.type=="Timer") src.view = new EleTimer(source, box); 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.emplace_back(ele); + if(src.view==0) continue; + src.view->setVisible(false); + if(w) src.view->setGeometry(x, y, w, h); + layer.srcs.push_back(src); } if(bdEle && ! sources.empty()) { auto geometry = border["geometry"]; - ele.x = geometry[0].toInt(); - ele.y = geometry[1].toInt(); - ele.w = geometry[2].toInt(); - ele.h = geometry[3].toInt(); - ele.startTime = bdStart; - ele.endTime = bdEnd; - ele.wgt = bdEle; - if(ele.startTime>0) ele.wgt->setVisible(false); - ele.wgt->setGeometry(ele.x, ele.y, ele.w, ele.h); - page->eles.emplace_back(ele); + src.startTime = bdStart; + src.endTime = bdEnd; + src.view = bdEle; + src.view->setVisible(false); + src.view->setGeometry(geometry[0].toInt(), geometry[1].toInt(), geometry[2].toInt(), geometry[3].toInt()); + layer.srcs.push_back(src); } + if(! layer.srcs.empty()) page.layers.emplace_back(std::move(layer)); } - if(page->timeSpan==0) continue; - for(int i=0; ieles.size(); i++) if(page->eles[i].repeat) page->eles[i].endTime = page->timeSpan; - pages.emplace_back(page); - } - setVisible(true); - 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)); + if(page.sDur==0) { + if(page.audioDur > 0) page.sDur = page.audioDur; + else continue; + } + page.tDur = page.sDur * page.repeatTimes; + for(auto layer=page.layers.begin(); layersrcs.begin(); srcsrcs.end(); ++src) { + if(src->startTime >= page.sDur) { + if(layer->srcs.size() > 1) layer->srcs.erase(src--); + else { + page.layers.erase(layer--); + goto conti_layer; + } + } else if(src->endTime > page.sDur) src->endTime = page.sDur; + } + if(layer->dur > page.sDur) layer->dur = page.sDur; + if(layer->dur == page.sDur) layer->isLoop = false; + conti_layer:; + } + pages.emplace_back(std::move(page)); } menu = new QMenu(this); @@ -185,46 +196,51 @@ PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const JValue if(self==this) self = nullptr; close(); }); + + setVisible(true); + if(pages.empty()) return; + pages[0].setMillis((std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count() + 999)/1000*1000); + + connect(gl, &QOpenGLWidget::frameSwapped, this, &PlayWin::doFrame, Qt::UniqueConnection); } -void PlayWin::sltNext() { - if(isVisible()) { - pages[cur]->setVisible(false); - if(cur+2 > pages.size()) cur = 0; - else cur++; - auto page = pages[cur]; - if(timer) timer->inter = page->timeSpan; - 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)); + +void PlayWin::doFrame() { + if(! isVisible()) return; + auto milli = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); + auto& lastPage = pages[curAva]; + if(milli >= lastPage.endMilli) { + lastPage.hide(); + if(curTimes < lastPage.repeatTimes) curTimes++; + else { + curTimes = 1; + curAva++; + if(curAva >= (int)pages.size()) { + curAva = 0; + auto isDiff = milli-lastPage.endMilli>=1000; + pages[curAva].setMillis(isDiff ? milli : lastPage.endMilli); + return; + } } - page->setVisible(true); - } else if(timer) { - timer->stop(); - timer = 0; - } -} -void PlayWin::timerEvent(QTimerEvent *e){ - int id = e->timerId(); - killTimer(id); - TimerValue value = timerMap[id]; - if(value.ele) { - timerMap.remove(id); - value.ele->setVisible(value.visible); - } -} -void PlayWin::paintEvent(QPaintEvent *e){ - if(timer==0 && isVisible() && ! pages.empty()) { - if(cur!=0) { - pages[cur]->setVisible(false); - cur = 0; + pages[curAva].setMillis(lastPage.endMilli); + } else { + for(auto &layer : lastPage.layers) { + for(auto &src : layer.srcs) { + if(src.view->isVisible()) { + if(milli >= src.endMilli) src.hide(); + else src.doEff(); + } else if(milli < src.endMilli && milli >= src.startMilli) src.show(); + } + if(milli >= layer.endMilli) { + layer.endMilli += layer.dur; + for(auto &src : layer.srcs) { + src.endMilli += layer.dur; + src.startMilli += layer.dur; + if(src.startTime > 0) src.hide(); + else src.show(); + } + } } - pages[cur]->setVisible(true); - timer = new SyncTimer(pages[cur]->timeSpan); - connect(timer, &SyncTimer::timeout, this, &PlayWin::sltNext, Qt::BlockingQueuedConnection); - timer->start(); } - QWidget::paintEvent(e); } void PlayWin::mousePressEvent(QMouseEvent *e) { diff --git a/LedOK/player/playwin.h b/LedOK/player/playwin.h index c125375..053fbe8 100644 --- a/LedOK/player/playwin.h +++ b/LedOK/player/playwin.h @@ -1,37 +1,204 @@ #ifndef PLAYWIN_H #define PLAYWIN_H #include "gutil/qjson.h" -#include "synctimer.h" #include #include -class EleBase { +enum Effect { + EXPAND_HOR, EXPAND_VER, EXPAND_LEFT, EXPAND_TOP, EXPAND_RIGHT, EXPAND_BOTTOM, + ZOOM, ZOOM_TL, ZOOM_TR, ZOOM_BR, ZOOM_BL, + ROTATE, ROTATE_R, + FADE, + MOVE_LEFT, MOVE_TOP, MOVE_RIGHT, MOVE_BOTTOM, + End +}; + +class Source { public: - QString id; + QWidget *view = 0; + int64_t startMilli = 0, endMilli = LLONG_MAX; + int startTime = 0, entryDur = 0, exitStart = INT_MAX, exitDur = 0, endTime = 0, ff = 0; + Effect entryEff, exitEff; QString type; - int x; - int y; - int w; - int h; - int startTime; - int endTime; - bool repeat; + bool isEntryRand = 0, isExitRand = 0; - QWidget *wgt{0}; + void show() { + if(view->isVisible()) return; + view->setVisible(true); + ff = 0; + if(isEntryRand) entryEff = (Effect) (rand() % Effect::End); + if(isExitRand) exitEff = (Effect) (rand() % Effect::End); + resetEff(); + doEff(); + } + void hide() { + if(! view->isVisible()) return; + view->setVisible(false); + } + void doEff() { + // auto w = view->width(); + // auto h = view->height(); + // if(ff < entryDur) { + // if(entryEff == Effect::EXPAND_HOR) view.setScaleX(ff / (float) entryDur); + // else if(entryEff == Effect::EXPAND_VER) view.setScaleY(ff / (float) entryDur); + // else if(entryEff == Effect::EXPAND_LEFT) { + // view.setScaleX(ff / (float) entryDur); + // view.setTranslationX((1 - view.getScaleX()) * w / 2); + // } else if(entryEff == Effect::EXPAND_TOP) { + // view.setScaleY(ff / (float) entryDur); + // view.setTranslationY((1 - view.getScaleY()) * h / 2); + // } else if(entryEff == Effect::EXPAND_RIGHT) { + // view.setScaleX(ff / (float) entryDur); + // view.setTranslationX((view.getScaleX() - 1) * w / 2); + // } else if(entryEff == Effect::EXPAND_BOTTOM) { + // view.setScaleY(ff / (float) entryDur); + // view.setTranslationY((view.getScaleY() - 1) * h / 2); + // } + // else if(entryEff == Effect::MOVE_LEFT) view.setTranslationX(w - ff*w/(float) entryDur); + // else if(entryEff == Effect::MOVE_TOP) view.setTranslationY(h - ff*h/(float) entryDur); + // else if(entryEff == Effect::MOVE_RIGHT) view.setTranslationX(ff*w/(float) entryDur - w); + // else if(entryEff == Effect::MOVE_BOTTOM) view.setTranslationY(ff*h/(float) entryDur - h); + // else if(entryEff == Effect::FADE) view.setAlpha(ff / (float) entryDur); + // else if(entryEff == Effect::ZOOM) { + // view.setScaleX(ff / (float) entryDur); + // view.setScaleY(view.getScaleX()); + // } else if(entryEff == Effect::ZOOM_TL) { + // var rate = ff / (float) entryDur; + // view.setTranslationX((rate - 1) * w / 2); + // view.setTranslationY((rate - 1) * h / 2); + // view.setScaleX(rate); + // view.setScaleY(rate); + // } else if(entryEff == Effect::ZOOM_BR) { + // var rate = ff / (float) entryDur; + // view.setTranslationX((1 - rate) * w / 2); + // view.setTranslationY((1 - rate) * h / 2); + // view.setScaleX(rate); + // view.setScaleY(rate); + // } else if(entryEff == Effect::ZOOM_TR) { + // var rate = ff / (float) entryDur; + // view.setTranslationX((1 - rate) * w / 2); + // view.setTranslationY((rate - 1) * h / 2); + // view.setScaleX(rate); + // view.setScaleY(rate); + // } else if(entryEff == Effect::ZOOM_BL) { + // var rate = ff / (float) entryDur; + // view.setTranslationX((rate - 1) * w / 2); + // view.setTranslationY((1 - rate) * h / 2); + // view.setScaleX(rate); + // view.setScaleY(rate); + // } else if(entryEff == Effect::ROTATE) { + // view.setScaleX(ff / (float) entryDur); + // view.setScaleY(view.getScaleX()); + // view.setRotation(view.getScaleX() * 360); + // } else if(entryEff == Effect::ROTATE_R) { + // view.setScaleX(ff / (float) entryDur); + // view.setScaleY(view.getScaleX()); + // view.setRotation(- view.getScaleX() * 360); + // } + // } else if(ff>=exitStart) { + // var fff = ff - exitStart; + // if(fff > exitDur) fff = exitDur; + // if(exitEff == Effect::EXPAND_HOR) view.setScaleX(1 - fff / (float) exitDur); + // else if(exitEff == Effect::EXPAND_VER) view.setScaleY(1 - fff / (float) exitDur); + // else if(exitEff == Effect::EXPAND_LEFT) { + // var rate = fff / (float) exitDur; + // view.setScaleX(1 - rate); + // view.setTranslationX(rate * w / 2); + // } else if(exitEff == Effect::EXPAND_TOP) { + // var rate = fff / (float) exitDur; + // view.setScaleY(1 - rate); + // view.setTranslationY(rate * h / 2); + // } else if(exitEff == Effect::EXPAND_RIGHT) { + // var rate = fff / (float) exitDur; + // view.setScaleX(1 - rate); + // view.setTranslationX(- rate * w / 2); + // } else if(exitEff == Effect::EXPAND_BOTTOM) { + // var rate = fff / (float) exitDur; + // view.setScaleY(1 - rate); + // view.setTranslationY(- rate * h / 2); + // } + // else if(exitEff == Effect::MOVE_LEFT) view.setTranslationX(- fff*w / (float) exitDur); + // else if(exitEff == Effect::MOVE_RIGHT) view.setTranslationX(fff*w / (float) exitDur); + // else if(exitEff == Effect::MOVE_TOP) view.setTranslationY(- fff*h / (float) exitDur); + // else if(exitEff == Effect::MOVE_BOTTOM) view.setTranslationY(fff*h / (float) exitDur); + // else if(exitEff == Effect::FADE) view.setAlpha(1 - fff / (float) exitDur); + // else if(exitEff == Effect::ZOOM) { + // view.setScaleX(1 - fff / (float) exitDur); + // view.setScaleY(view.getScaleX()); + // } else if(exitEff == Effect::ZOOM_TL) { + // var rate = fff / (float) exitDur; + // view.setTranslationX(- rate * w / 2); + // view.setTranslationY(- rate * h / 2); + // view.setScaleX(1 - rate); + // view.setScaleY(1 - rate); + // } else if(exitEff == Effect::ZOOM_BR) { + // var rate = fff / (float) exitDur; + // view.setTranslationX(rate * w / 2); + // view.setTranslationY(rate * h / 2); + // view.setScaleX(1 - rate); + // view.setScaleY(1 - rate); + // } else if(exitEff == Effect::ZOOM_TR) { + // var rate = fff / (float) exitDur; + // view.setTranslationX(rate * w / 2); + // view.setTranslationY(- rate * h / 2); + // view.setScaleX(1 - rate); + // view.setScaleY(1 - rate); + // } else if(exitEff == Effect::ZOOM_BL) { + // var rate = fff / (float) exitDur; + // view.setTranslationX(- rate * w / 2); + // view.setTranslationY(rate * h / 2); + // view.setScaleX(1 - rate); + // view.setScaleY(1 - rate); + // } else if(exitEff == Effect::ROTATE) { + // var rate = fff / (float) exitDur; + // view.setScaleX(1 - rate); + // view.setScaleY(view.getScaleX()); + // view.setRotation(rate * 360); + // } else if(exitEff == Effect::ROTATE_R) { + // var rate = fff / (float) exitDur; + // view.setScaleX(1 - rate); + // view.setScaleY(view.getScaleX()); + // view.setRotation(- rate * 360); + // } + // } else resetEff(); + ff++; + } + void resetEff() { + // view.setTranslationX(0); + // view.setTranslationY(0); + // view.setAlpha(1); + // view.setScaleX(1); + // view.setScaleY(1); + // view.setRotation(0); + } +}; +struct Layer { + std::vector srcs; + int64_t endMilli = LLONG_MAX; + int dur = 0; + bool isLoop = 0; }; -class Page : public QWidget { -public: - explicit Page(QWidget *parent = nullptr); - int timeSpan{0}; - std::vector eles; -}; +struct Page { + std::vector layers; + int64_t endMilli = LLONG_MAX; + int sDur = 0, tDur = 0, repeatTimes = 0, audioDur = 0; -class TimerValue{ -public: - TimerValue(QWidget *ele = nullptr, bool visible = false): ele(ele), visible(visible){} - QWidget* ele; - bool visible; + void hide() { + for(auto &layer : layers) for(auto &src : layer.srcs) src.hide(); + } + + void setMillis(int64_t milli) { + endMilli = milli + sDur; + for(auto &layer : layers) { + if(layer.isLoop) layer.endMilli = milli + layer.dur; + for(auto &src : layer.srcs) { + src.endMilli = milli + src.endTime; + src.startMilli = milli + src.startTime; + if(src.startTime == 0) src.show(); + } + } + } }; class PlayWin : public QWidget { @@ -41,23 +208,18 @@ public: 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; + QOpenGLWidget *gl; int cur = 0; - std::vector pages; - QMap timerMap; + std::vector pages; + std::vector avas; + int curAva = 0, curTimes = 1; + QPoint mPressRel; QMenu *menu; -public slots: - void sltNext(); - void sltSetVisible(QWidget *wgt, bool visible){ - wgt->setVisible(visible); - } -signals: - void sigSetVisible(QWidget *, bool); + void doFrame(); + protected: - void paintEvent(QPaintEvent *) override; - void timerEvent(QTimerEvent *) override; void mousePressEvent(QMouseEvent *) override; void mouseReleaseEvent(QMouseEvent *) override; void mouseMoveEvent(QMouseEvent *) override; diff --git a/LedOK/player/srccopy.cpp b/LedOK/player/srccopy.cpp new file mode 100644 index 0000000..b642142 --- /dev/null +++ b/LedOK/player/srccopy.cpp @@ -0,0 +1,11 @@ +#include "srccopy.h" +#include "playwin.h" +#include +#include + +SrcCopy::SrcCopy(QWidget *parent, QWidget *master) : QWidget{parent}, master(master) { + connect(PlayWin::self->gl, &QOpenGLWidget::frameSwapped, this, (void(SrcCopy::*)())&SrcCopy::update); +} +void SrcCopy::paintEvent(QPaintEvent *) { + master->render(backingStore()->paintDevice(), pos(), QRegion(), DrawChildren|IgnoreMask); +} diff --git a/LedOK/player/srccopy.h b/LedOK/player/srccopy.h new file mode 100644 index 0000000..8b457e8 --- /dev/null +++ b/LedOK/player/srccopy.h @@ -0,0 +1,16 @@ +#ifndef SRCCOPY_H +#define SRCCOPY_H + +#include + +class SrcCopy : public QWidget { +public: + SrcCopy(QWidget *parent, QWidget *master); + +protected: + void paintEvent(QPaintEvent *) override; + + QWidget *master; +}; + +#endif // SRCCOPY_H diff --git a/LedOK/progpanel.cpp b/LedOK/progpanel.cpp index 9a9ca07..27c6afd 100644 --- a/LedOK/progpanel.cpp +++ b/LedOK/progpanel.cpp @@ -1,4 +1,5 @@ #include "progpanel.h" +#include "program/progitem.h" #include "globaldefine.h" #include "gutil/qgui.h" #include "cfg.h" @@ -32,32 +33,32 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { bnNew->setProperty("ssType", "progManageTool"); hBox->addWidget(bnNew); connect(bnNew, &QPushButton::clicked, this, [this] { - ProgCreateDlg dlg("", 512, 256, "", "", this); + ProgCreateDlg dlg("", 512, 256, "", "", false, this); if(dlg.exec() != QDialog::Accepted) return; if(checkIfNameRepeated(dlg.fdName->text())) return; - QList widths; + std::vector widths; int max = 0; - auto width = dlg.fdWidth->value(); + auto width = dlg.fdVer->isChecked() ? dlg.fdHeight->value() : dlg.fdWidth->value(); if(dlg.fdIsUltraLong->isChecked()) { - auto splitWidths = dlg.fdSplitWidths->text().split(" ", Qt::SkipEmptyParts); + auto partLengths = dlg.fdSplitWidths->text().split(" ", Qt::SkipEmptyParts); int ttl = 0; - for(auto &splitWidth : splitWidths) { - int val = splitWidth.toInt(); + for(auto &partLength : partLengths) { + int val = partLength.toInt(); if(val==0) continue; if(max < val) max = val; - widths.append(val); ttl += val; + widths.emplace_back(val); if(ttl>=width) break; } if(max) { while(ttl < width) { - widths.append(max); ttl += max; + widths.emplace_back(max); } - if(ttl > width) widths.last() -= ttl - width; + if(ttl > width) widths.back() -= ttl - width; } } - auto item = new ProgItem(mProgsDir, dlg.fdName->text(), width, dlg.fdHeight->value(), dlg.fdRemark->toPlainText(), widths, max, mProgTree); + auto item = new ProgItem(mProgsDir, dlg.fdName->text(), dlg.fdWidth->value(), dlg.fdHeight->value(), dlg.fdRemark->toPlainText(), widths, max, dlg.fdVer->isChecked(), mProgTree); item->save();//保存pro.json if(mProgTree->fdCheckAll->checkState()==Qt::Checked) { mProgTree->fdCheckAll->blockSignals(true); @@ -129,14 +130,7 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { mProgTree->clear(); QStringList progNames = QDir(mProgsDir).entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); - foreach(QString pro_name, progNames) { - QFile jFile(mProgsDir + "/" + pro_name + "/pro.json"); - if(! jFile.exists()) continue; - if(! jFile.open(QIODevice::ReadOnly)) continue; - auto data = jFile.readAll(); - jFile.close(); - m_pwPorgramItemList.append(new ProgItem(mProgsDir, QJsonDocument::fromJson(data).object(), mProgTree)); - } + for(auto &pro_name : progNames) addProFile(mProgsDir + "/" + pro_name + "/pro.json"); }); bnExport = new QPushButton(tr("Export")); @@ -200,8 +194,8 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { 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); + if(item->partLens.empty()) PlayWin::self = PlayWin::newIns(item->mWidth, item->mHeight, dir, prog); + else PlayWin::self = item->isVer ? PlayWin::newIns(item->mWidth * item->partLens.size(), item->maxLen, dir, prog) : PlayWin::newIns(item->maxLen, item->mHeight * item->partLens.size(), dir, prog); break; } } @@ -249,27 +243,29 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { }); vBox->addWidget(mProgTree = table); - QString doc_path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation); - if(!doc_path.isEmpty()) { - QString app_path = doc_path + "/" + QApplication::applicationName(); - mProgsDir = app_path + "/NPrograms"; - if(!QFileInfo::exists(mProgsDir)) QDir(app_path).mkdir("NPrograms"); + auto dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); + if(! dataDir.isEmpty()) { + mProgsDir = dataDir + "/programs"; + if(! QFileInfo::exists(mProgsDir)) { + qDebug()<<"mkdir programs"<sortByColumn(settings.value("ProgramListSortColumn").toInt(),Qt::SortOrder::AscendingOrder); @@ -298,6 +294,35 @@ void ProgPanel::transUi() { btnPlay->setText(tr("Play")+"/"+tr("Stop")); } +void ProgPanel::addProFile(const QString &file) { + QFile qFile(file); + if(! qFile.exists()) return; + if(! qFile.open(QIODevice::ReadOnly)) return; + auto data = qFile.readAll(); + qFile.close(); + QString error; + auto json = JFrom(data, &error); + if(! error.isEmpty()) return; + auto item = new ProgItem(mProgTree); + item->mProgsDir = mProgsDir; + item->mName = json["name"].toString(); + item->mWidth = json["resolution"]["w"].toInt(); + item->mHeight = json["resolution"]["h"].toInt(); + item->mRemark = json["remarks"].toString(); + item->isVer = json["isVer"].toBool(); + auto partLengths = json["splitWidths"].toArray(); + for(auto &partLength : partLengths) { + auto len = partLength.toInt(); + if(item->maxLen < len) item->maxLen = len; + item->partLens.emplace_back(len); + } + item->m_fsize = json["file_size"].toDouble(); + item->mProgDir = item->mProgsDir + "/" + item->mName; + item->m_orgName = item->mName; + item->setText("lasttime", QFileInfo(file).lastModified().toString("yyyy-MM-dd hh:mm:ss")); + item->init(); +} + void ProgPanel::onEditClicked(bool){ int cnt = mProgTree->topLevelItemCount(); for(int i=0; i &splitWidths, int max) -{ - 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->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) { diff --git a/LedOK/progpanel.h b/LedOK/progpanel.h index 5d97524..6de2f70 100644 --- a/LedOK/progpanel.h +++ b/LedOK/progpanel.h @@ -2,7 +2,6 @@ #define PROGPANEL_H #include "base/loqtreewidget.h" -#include "program/progitem.h" #include #include #include @@ -18,15 +17,14 @@ protected: void changeEvent(QEvent *) override; void transUi(); bool checkIfNameRepeated(const QString &name, QTreeWidgetItem *skip = nullptr); + void addProFile(const QString &); public slots: void onEditClicked(bool f); void onDeleteClicked(bool f); - void onCreateNewProgramOnOpenEditProgramWidget(QString name, QSize res, QString remarks, QList &, int); private: QString mProgsDir; - QList m_pwPorgramItemList; QPushButton *bnNew; QPushButton *bnEdit; QPushButton *bnDelete; diff --git a/LedOK/program/copydirthread.cpp b/LedOK/program/copydirthread.cpp index 2e86adb..4d34047 100644 --- a/LedOK/program/copydirthread.cpp +++ b/LedOK/program/copydirthread.cpp @@ -16,7 +16,7 @@ bool CopyDirThread::copyDir(const QString &fromDir, const QString &toDir, bool c QDir targetDir(toDir); if(! targetDir.exists() && ! targetDir.mkdir(toDir)) return false; QFileInfoList fileInfos = QDir(fromDir).entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot); - foreach(QFileInfo fileInfo, fileInfos) { + for(auto &fileInfo : fileInfos) { if(fileInfo.isDir()) { //< 当为目录时,递归的进行copy if(! copyDir(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName()), coverIfExist)) return false; } else { //当允许覆盖操作时,将旧文件进行删除操作 @@ -30,3 +30,29 @@ bool CopyDirThread::copyDir(const QString &fromDir, const QString &toDir, bool c } return true; } + + +void CopyDirThread::move() { + for(; i plist; - qreal x, y, ox, oy; - qreal k; - qreal a = 0; - const qreal s = 6; - for(int i=0; i<60; i++) { - if (a < 90) { - k = a * M_PI / 180; - ox = sin(k) * r; - oy = cos(k) * r; - x = cx + ox; - y = cy - oy; - } else if (a < 180) { - k = (a - 90) * M_PI / 180; - ox = cos(k) * r; - oy = sin(k) * r; - x = cx + ox; - y = cy + oy; - } else if (a < 270) { - k = (a - 180) * M_PI / 180; - ox = sin(k) * r; - oy = cos(k) * r; - x = cx - ox; - y = cy + oy; - } else { - k = (a - 270) * M_PI / 180; - ox = cos(k) * r; - oy = sin(k) * r; - x = cx - ox; - y = cy - oy; - } - a += s; - plist.push_back(QPointF(x, y)); - } - - a = 0; + auto r = (qMin(inner.width(), inner.height()) - qMax(m_attr.minMarkSize, m_attr.hourMarkSize)) / 2; + auto cx = inner.width() / 2; + auto cy = inner.height() / 2; + painter->translate(cx, cy); for(int i=0; i<60; i++) { + auto k = i * M_PI / 30; + auto x = sin(k) * r; + auto y = -cos(k) * r; if(i % 5) { - switch (m_attr.minMark) { - case 0: drawMarkCircular (painter, plist.at(i), m_attr.minMarkColor, m_attr.minMarkSize); break; - case 1: drawMarkRectangle(painter, plist.at(i), m_attr.minMarkColor, m_attr.minMarkSize, a); break; - default: break; - } + if(m_attr.minMark==0) drawMarkCircular(painter, {x, y}, m_attr.minMarkColor, m_attr.minMarkSize); + else if(m_attr.minMark==1) drawMarkRectangle(painter, {x, y}, m_attr.minMarkColor, m_attr.minMarkSize, i*6); } else { - switch (m_attr.hourMark) { - case 0: drawMarkCircular (painter, plist.at(i), m_attr.hourMarkColor, m_attr.hourMarkSize); break; - case 1: drawMarkRectangle(painter, plist.at(i), m_attr.hourMarkColor, m_attr.hourMarkSize, a); break; - case 2: drawMarkNumber (painter, plist.at(i), m_attr.hourMarkColor, m_attr.hourMarkSize, i/5); break; - default: break; - } + if(m_attr.hourMark==0) drawMarkCircular(painter, {x, y}, m_attr.hourMarkColor, m_attr.hourMarkSize); + else if(m_attr.hourMark==1) drawMarkRectangle(painter, {x, y}, m_attr.hourMarkColor, m_attr.hourMarkSize, i*6); + else if(m_attr.hourMark==2) drawMarkNumber(painter, {x, y}, m_attr.hourMarkColor, m_attr.hourMarkSize, i/5); } - a += s; } + painter->translate(-cx, -cy); } else { auto inner = innerRect(); int wid, hei; @@ -152,45 +111,30 @@ void EAClock::paintDial(QPainter *painter) { } void EAClock::drawMarkCircular(QPainter *painter, const QPointF &pos, const QColor &color, qreal diameter) { - QPointF cp(pos.x(), pos.y()); - qreal r = diameter / 2; - painter->save(); + auto r = diameter / 2; painter->setBrush(color); painter->setPen(color); - painter->setRenderHint(QPainter::Antialiasing); - painter->drawEllipse(cp, r, r); - painter->restore(); + painter->drawEllipse(pos, r, r); } -void EAClock::drawMarkRectangle(QPainter *painter, const QPointF &pos, const QColor &color, qreal len, qreal angle) -{ - QPointF cp(pos.x(), pos.y()); +void EAClock::drawMarkRectangle(QPainter *painter, const QPointF &pos, const QColor &color, qreal len, qreal angle) { QRectF rect(-len/2, -len/2, len, len); painter->save(); painter->setBrush(color); painter->setPen(color); - painter->translate(cp); + painter->translate(pos); painter->rotate(angle); - painter->setRenderHint(QPainter::Antialiasing); painter->drawRect(rect); painter->restore(); } -void EAClock::drawMarkNumber(QPainter *painter, const QPointF &pos, const QColor &color, qreal len, int num) -{ +void EAClock::drawMarkNumber(QPainter *painter, const QPointF &pos, const QColor &color, qreal len, int num) { QRectF rect(pos.x()-len/2, pos.y()-len/2, len, len); QFont font("Arial"); font.setPixelSize(round(len)); - QTextOption opt; - opt.setAlignment(Qt::AlignCenter); - painter->save(); - painter->setPen(color); painter->setFont(font); - painter->setRenderHint(QPainter::Antialiasing); - if(num==0) - num=12; - painter->drawText(rect, QString("%1").arg(num), opt); - painter->restore(); + painter->setPen(color); + painter->drawText(rect, QString::number(num==0 ? 12 : num), QTextOption(Qt::AlignCenter)); } void EAClock::paintText(QPainter *painter){ @@ -599,32 +543,6 @@ QWidget* EAClock::attrWgt() { update(); }); hBox->addWidget(fdTextColor); - - hBox->addStretch(); - - - hBox = new HBox(vBox); - hBox->addWidget(new QLabel(tr("Play Properties"))); - - line = new QFrame(); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - hBox->addWidget(line, 1); - - - hBox = new HBox(vBox); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Play Duration"))); - - auto fdDuration = new QSpinBox(); - fdDuration->setRange(1, 99999); - fdDuration->setValue(m_attr.playDuration); - connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - m_attr.playDuration = value; - }); - hBox->addWidget(fdDuration); - - hBox->addWidget(new QLabel(tr("s"))); hBox->addStretch(); vBox->addStretch(); @@ -649,54 +567,52 @@ bool EAClock::save(const QString &pRoot){ QFile old_f(old_file); QFile new_f(new_file); if(!new_f.exists()) old_f.copy(new_file); + } else { + auto filename = QString("%1-%2-%3-%4-%5.png").arg((int)zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight); + m_attr.path = pRoot; + QRectF inner = innerRect(); + QImage img(inner.width(), inner.height(), QImage::Format_ARGB32); + img.fill(Qt::transparent); + { + QPainter painter(&img); + paintDial(&painter); + paintText(&painter); + } + img.save(pRoot+"/"+filename, "PNG"); } - m_attr.selfCreateDialName = QString("%1%2%3%4%5.png").arg((int)zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight); - m_attr.path = pRoot; - QRectF inner = innerRect(); - QImage img(inner.width(), inner.height(), QImage::Format_ARGB32); - img.fill(Qt::transparent); - { - QPainter painter(&img); - paintDial(&painter); - paintText(&painter); - } - img.save(pRoot+"/"+m_attr.selfCreateDialName, "PNG"); return true; } JObj EAClock::attrJson() const { JObj json; - addBaseAttr(json); json["elementType"] = "AClock"; - JObj widget; - widget["timeZone"] = QString::fromUtf8(m_attr.timeZone.id()); - widget["hourMark"] = m_attr.hourMark; - widget["hourMarkSize"] = m_attr.hourMarkSize; - widget["hourMarkColor"] = m_attr.hourMarkColor.name(); - widget["minMark"] = m_attr.minMark; - widget["minMarkSize"] = m_attr.minMarkSize; - widget["minMarkColor"] = m_attr.minMarkColor.name(); - widget["hourHandColor"] = m_attr.hourHandColor.name(); - widget["minHandColor"] = m_attr.minHandColor.name(); - widget["secHandColor"] = m_attr.secHandColor.name(); - widget["text"] = m_attr.text; - widget["textFontFamily"] = m_attr.textFont.family(); - widget["textFontSize"] = m_attr.textFont.pixelSize(); - widget["textFontBold"] = m_attr.textFont.bold(); - widget["textFontItalics"] = m_attr.textFont.italic(); - widget["textFontUnderline"] = m_attr.textFont.underline(); - widget["textColor"] = m_attr.textColor.name(); - widget["hhLen"] = m_attr.hhLen; - widget["mhLen"] = m_attr.mhLen; - widget["shLen"] = m_attr.shLen; - widget["hhWidth"] = m_attr.hhWidth; - widget["mhWidth"] = m_attr.mhWidth; - widget["shWidth"] = m_attr.shWidth; - widget["showSecHand"] = m_attr.showSecHand; - widget["path"] = m_attr.path; - widget["name"] = m_attr.name; - widget["selfCreateDialName"] = m_attr.selfCreateDialName; - widget["bCustomDial"] = m_attr.hasDialImg; - json["widget"] = widget; - json["play"] = JObj{{"duration", m_attr.playDuration}}; + json["timeZone"] = QString::fromUtf8(m_attr.timeZone.id()); + json["hourMark"] = m_attr.hourMark; + json["hourMarkSize"] = m_attr.hourMarkSize; + json["hourMarkColor"] = m_attr.hourMarkColor.name(); + json["minMark"] = m_attr.minMark; + json["minMarkSize"] = m_attr.minMarkSize; + json["minMarkColor"] = m_attr.minMarkColor.name(); + json["hourHandColor"] = m_attr.hourHandColor.name(); + json["minHandColor"] = m_attr.minHandColor.name(); + json["secHandColor"] = m_attr.secHandColor.name(); + json["text"] = m_attr.text; + json["textFontFamily"] = m_attr.textFont.family(); + json["textFontSize"] = m_attr.textFont.pixelSize(); + json["textFontBold"] = m_attr.textFont.bold(); + json["textFontItalics"] = m_attr.textFont.italic(); + json["textFontUnderline"] = m_attr.textFont.underline(); + json["textColor"] = m_attr.textColor.name(); + json["hhLen"] = m_attr.hhLen; + json["mhLen"] = m_attr.mhLen; + json["shLen"] = m_attr.shLen; + json["hhWidth"] = m_attr.hhWidth; + json["mhWidth"] = m_attr.mhWidth; + json["shWidth"] = m_attr.shWidth; + json["showSecHand"] = m_attr.showSecHand; + json["path"] = m_attr.path; + json["name"] = m_attr.name; + json["selfCreateDialName"] = QString("%1-%2-%3-%4-%5.png").arg((int)zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight); + json["bCustomDial"] = m_attr.hasDialImg; + addBaseAttr(json); return json; } diff --git a/LedOK/program/eaclock.h b/LedOK/program/eaclock.h index 3fe1e8f..4a1708b 100644 --- a/LedOK/program/eaclock.h +++ b/LedOK/program/eaclock.h @@ -21,16 +21,11 @@ public: QColor secHandColor;//秒针颜色 int hhLen{50}, mhLen{75}, shLen{100}; int hhWidth{15}, mhWidth{10}, shWidth{5}; - // r/2, r / 20 - // r*3/4, r / 30 - // r, r / 40 QString text;//标题 QFont textFont = qfont("Arial", 12);//标题字体 QColor textColor;//标题字体颜色 - int playDuration{10};// QString path; QString name; - QString selfCreateDialName; bool hasDialImg{false}; bool showSecHand{true}; }; @@ -52,10 +47,6 @@ protected: void paintDial(QPainter *painter); void paintText(QPainter *painter); - qreal radius() const { - return (qMin(rect().width(), rect().height()) - qMax(m_attr.minMarkSize, m_attr.hourMarkSize)) / 2; - } - void cal(); Data m_attr; diff --git a/LedOK/program/ebase.cpp b/LedOK/program/ebase.cpp index 365b503..95a967a 100644 --- a/LedOK/program/ebase.cpp +++ b/LedOK/program/ebase.cpp @@ -33,7 +33,7 @@ struct Initer { }; EBase::EBase(EBase *multiWin) : mMultiWin(multiWin) { static struct Initer aaa; - if(mMultiWin == nullptr) { + if(mMultiWin == 0) { setFlag(ItemIsMovable); setFlag(ItemIsSelectable); } @@ -43,6 +43,15 @@ EBase::EBase(EBase *multiWin) : mMultiWin(multiWin) { void EBase::setBaseAttr(const JObj &json) { mStartTime = json["startTime"].toInt(); + mDuration = json["duration"].toInt(); + if(mDuration==0) { + mDuration = json["play"]["playDuration"].toInt(); + if(mDuration==0) mDuration = json["play"]["duration"].toInt(10); + } + mEntryEffect = json["entryEffect"].toStr(); + mExitEffect = json["exitEffect"].toStr(); + mEntryDur = json["entryDur"].toInt(); + mExitDur = json["exitDur"].toInt(); auto geometry = json["geometry"]; setPos(geometry["x"].toInt(), geometry["y"].toInt()); setSize(geometry["w"].toInt(), geometry["h"].toInt()); @@ -57,24 +66,29 @@ void EBase::setBaseAttr(const JObj &json) { 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); JObj geometry; geometry["order"] = zValue(); geometry["x"] = (int)ele->x(); geometry["y"] = (int)ele->y(); geometry["w"] = (int)ele->mWidth; geometry["h"] = (int)ele->mHeight; + obj.insert("geometry", geometry); + 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); + obj.insert("startTime", mStartTime); + obj.insert("duration", mDuration); + obj.insert("entryEffect", mEntryEffect); + obj.insert("exitEffect", mExitEffect); + obj.insert("entryDur", mEntryDur); + obj.insert("exitDur", mExitDur); if(bdImgIdx>-1) { obj["border"] = borderImgs[bdImgIdx].name; obj["borderSize"] = JArray{borderImgs[bdImgIdx].img.width(), borderImgs[bdImgIdx].img.height()}; obj["borderEff"] = bdEff.isEmpty() ? JValue() : bdEff; obj["borderSpeed"] = bdSpeed; } - obj.insert("geometry", geometry); } QRectF EBase::innerRect() const { @@ -509,185 +523,338 @@ void EBase::clearSnap() { } void EBase::addBaseAttrWgt(QBoxLayout *vBox) { - if(mMultiWin!=nullptr) return; - auto hBox = new QHBoxLayout(); - hBox->addWidget(new QLabel(tr("Area"))); - - auto line = new QFrame(); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - hBox->addWidget(line,1); - - vBox->addLayout(hBox); auto spacing = vBox->spacing(); if(spacing < 0) spacing = 0; - vBox->addSpacing(-spacing-2); + if(mMultiWin==0) { + auto hBox = new HBox(vBox); + hBox->addLabel(tr("Area")); - hBox = new QHBoxLayout(); - hBox->addStretch(); - hBox->addWidget(new QLabel(tr("X")+": ")); + auto line = new QFrame; + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + hBox->addWidget(line, 1); - auto fdX = new QSpinBox(); - fdX->setRange(0, 999999); - fdX->setValue(x()); - connect(fdX, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdX](int value) { - int max = gProgItem->mWidth - mWidth; - if(value > max) { - value = max; - fdX->blockSignals(true); - fdX->setValue(value); - fdX->blockSignals(false); - } - setX(value); - }); - hBox->addWidget(fdX); + vBox->addSpacing(-spacing-2); - hBox->addSpacing(10); + hBox = new HBox(vBox); + hBox->addStretch(); + hBox->addLabel(tr("X")+": "); - hBox->addWidget(new QLabel(tr("Y")+": ")); - auto fdY = new QSpinBox(); - fdY->setRange(0, 999999); - fdY->setValue(y()); - connect(fdY, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdY](int value) { - int max = gProgItem->mHeight - mHeight; - if(value > max) { - value = max; - fdY->blockSignals(true); - fdY->setValue(value); - fdY->blockSignals(false); - } - setY(value); - }); - hBox->addWidget(fdY); - hBox->addStretch(); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addStretch(); - hBox->addWidget(new QLabel(tr("W")+": ")); - auto fdW = new QSpinBox(); - fdW->setRange(6, 999999); - fdW->setValue(mWidth); - connect(fdW, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdW](int value) { - int max = gProgItem->mWidth - x(); - if(value > max) { - value = max; - fdW->blockSignals(true); - fdW->setValue(value); - fdW->blockSignals(false); - } - setSize(value, mHeight); - }); - hBox->addWidget(fdW); - - hBox->addSpacing(10); - hBox->addWidget(new QLabel(tr("H")+": ")); - auto fdH = new QSpinBox(); - fdH->setRange(6, 999999); - fdH->setValue(mHeight); - connect(fdH, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdH](int value) { - int max = gProgItem->mHeight - y(); - if(value > max) { - value = max; - fdH->blockSignals(true); - fdH->setValue(value); - fdH->blockSignals(false); - } - setSize(mWidth, value); - }); - hBox->addWidget(fdH); - hBox->addStretch(); - - vBox->addLayout(hBox); - vBox->addSpacing(-spacing); - - connect(this, &EBase::xChanged, fdX, [this, fdX] { - fdX->blockSignals(true); + auto fdX = new QSpinBox; + fdX->setRange(0, 999999); fdX->setValue(x()); - fdX->blockSignals(false); - }); - connect(this, &EBase::yChanged, fdY, [this, fdY] { - fdY->blockSignals(true); + connect(fdX, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdX](int value) { + int max = gProgItem->mWidth - mWidth; + if(value > max) { + value = max; + fdX->blockSignals(true); + fdX->setValue(value); + fdX->blockSignals(false); + } + setX(value); + }); + hBox->addWidget(fdX); + + hBox->addSpacing(10); + + hBox->addLabel(tr("Y")+": "); + auto fdY = new QSpinBox; + fdY->setRange(0, 999999); fdY->setValue(y()); - fdY->blockSignals(false); - }); - connect(this, &EBase::sizeChanged, fdW, [this, fdW, fdH] { - fdW->blockSignals(true); + connect(fdY, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdY](int value) { + int max = gProgItem->mHeight - mHeight; + if(value > max) { + value = max; + fdY->blockSignals(true); + fdY->setValue(value); + fdY->blockSignals(false); + } + setY(value); + }); + hBox->addWidget(fdY); + hBox->addStretch(); + + hBox = new HBox(vBox); + hBox->addStretch(); + hBox->addLabel(tr("W")+": "); + + auto fdW = new QSpinBox; + fdW->setRange(6, 999999); fdW->setValue(mWidth); - fdW->blockSignals(false); - fdH->blockSignals(true); + connect(fdW, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdW](int value) { + int max = gProgItem->mWidth - x(); + if(value > max) { + value = max; + fdW->blockSignals(true); + fdW->setValue(value); + fdW->blockSignals(false); + } + setSize(value, mHeight); + }); + hBox->addWidget(fdW); + + hBox->addSpacing(10); + hBox->addLabel(tr("H")+": "); + auto fdH = new QSpinBox; + fdH->setRange(6, 999999); fdH->setValue(mHeight); - fdH->blockSignals(false); - }); + connect(fdH, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdH](int value) { + int max = gProgItem->mHeight - y(); + if(value > max) { + value = max; + fdH->blockSignals(true); + fdH->setValue(value); + fdH->blockSignals(false); + } + setSize(mWidth, value); + }); + hBox->addWidget(fdH); + hBox->addStretch(); - hBox = new QHBoxLayout(); - hBox->addWidget(new QLabel(tr("Border"))); + vBox->addSpacing(-spacing); - line = new QFrame(); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - hBox->addWidget(line, 1); + connect(this, &EBase::xChanged, fdX, [this, fdX] { + fdX->blockSignals(true); + fdX->setValue(x()); + fdX->blockSignals(false); + }); + connect(this, &EBase::yChanged, fdY, [this, fdY] { + fdY->blockSignals(true); + fdY->setValue(y()); + fdY->blockSignals(false); + }); + connect(this, &EBase::sizeChanged, fdW, [this, fdW, fdH] { + fdW->blockSignals(true); + fdW->setValue(mWidth); + fdW->blockSignals(false); + fdH->blockSignals(true); + fdH->setValue(mHeight); + fdH->blockSignals(false); + }); - vBox->addLayout(hBox); - vBox->addSpacing(-spacing-2); - hBox = new QHBoxLayout(); - hBox->setSpacing(0); + hBox = new HBox(vBox); + hBox->addLabel(tr("Border")); - hBox->addStretch(); - auto borderFd = new QComboBox; - borderFd->addItem(tr("None")); - for(int i=0; iaddItem(QIcon(borderImgs[i].img), QString::number(borderImgs[i].img.height()), borderImgs[i].name); - borderFd->setIconSize(QSize(borderImgMaxWidth, borderImgMaxHeight)); - if(bdImgIdx>-1) borderFd->setCurrentIndex(bdImgIdx+1); - connect(borderFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int idx){ - bdImgIdx = idx-1; - if(bdImgIdx==-1 && bdTimerId>0) { - killTimer(bdTimerId); - bdTimerId = 0; + line = new QFrame; + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + hBox->addWidget(line, 1); + + vBox->addSpacing(-spacing-2); + + hBox = new HBox(vBox); + hBox->setSpacing(2); + + hBox->addStretch(); + auto borderFd = new QComboBox; + borderFd->addItem(tr("None")); + for(int i=0; iaddItem(QIcon(borderImgs[i].img), QString::number(borderImgs[i].img.height()), borderImgs[i].name); + borderFd->setIconSize(QSize(borderImgMaxWidth, borderImgMaxHeight)); + if(bdImgIdx>-1) borderFd->setCurrentIndex(bdImgIdx+1); + connect(borderFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int idx){ + bdImgIdx = idx-1; + if(bdImgIdx==-1 && bdTimerId>0) { + killTimer(bdTimerId); + bdTimerId = 0; + } + bdOff = 0; + update(); + emit sizeChanged(); + }); + hBox->addWidget(borderFd); + + hBox->addStretch(); + hBox->addLabel(tr("Effect")); + + auto borderEffFd = new QComboBox; + borderEffFd->addItem(tr("Rotate"), "rotate"); + borderEffFd->addItem(tr("Blink"), "blink"); + borderEffFd->addItem(tr("None"), ""); + if(bdImgIdx>-1) SetCurData(borderEffFd, bdEff); + connect(borderEffFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, borderEffFd] { + bdEff = borderEffFd->currentData().toString(); + if(bdTimerId>0) { + killTimer(bdTimerId); + bdTimerId = 0; + } + bdOff = 0; + update(); + }); + hBox->addWidget(borderEffFd); + + hBox->addStretch(); + hBox->addLabel(tr("Speed")); + + auto borderSpeedFd = new QComboBox; + borderSpeedFd->addItem(tr("Slow"), 1); + borderSpeedFd->addItem(tr("Moderate"), 2); + borderSpeedFd->addItem(tr("Fast"), 3); + if(bdImgIdx>-1) SetCurData(borderSpeedFd, bdSpeed); + connect(borderSpeedFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, borderSpeedFd] { + bdSpeed = borderSpeedFd->currentData().toInt(); + if(bdTimerId>0) { + killTimer(bdTimerId); + bdTimerId = 0; + } + update(); + }); + hBox->addWidget(borderSpeedFd); + hBox->addStretch(); + } + + if(mType!=Window) { + auto hBox = new HBox(vBox); + hBox->addLabel(tr("Play Time")); + + auto line = new QFrame; + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + hBox->addWidget(line, 1); + + vBox->addSpacing(-spacing-2); + + hBox = new HBox(vBox); + hBox->setSpacing(4); + hBox->addStretch(); + + if(mMultiWin==0) { + hBox->addLabel(tr("Start")); + + auto fdStart = new QSpinBox; + fdStart->setRange(0, 9999); + fdStart->setValue(mStartTime); + hBox->addWidget(fdStart); + hBox->addLabel(tr("s")); + hBox->addStretch(); } - bdOff = 0; - update(); - emit sizeChanged(); - }); - hBox->addWidget(borderFd); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Effect")+":")); - auto borderEffFd = new QComboBox(); - borderEffFd->addItem(tr("Rotate"), "rotate"); - borderEffFd->addItem(tr("Blink"), "blink"); - borderEffFd->addItem(tr("None"), ""); - if(bdImgIdx>-1) SetCurData(borderEffFd, bdEff); - connect(borderEffFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, borderEffFd] { - bdEff = borderEffFd->currentData().toString(); - if(bdTimerId>0) { - killTimer(bdTimerId); - bdTimerId = 0; - } - bdOff = 0; - update(); - }); - hBox->addWidget(borderEffFd); + hBox->addLabel(tr("Duration")); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Speed")+":")); - auto borderSpeedFd = new QComboBox(); - borderSpeedFd->addItem(tr("Slow"), 1); - borderSpeedFd->addItem(tr("Moderate"), 2); - borderSpeedFd->addItem(tr("Fast"), 3); - if(bdImgIdx>-1) SetCurData(borderSpeedFd, bdSpeed); - connect(borderSpeedFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, borderSpeedFd] { - bdSpeed = borderSpeedFd->currentData().toInt(); - if(bdTimerId>0) { - killTimer(bdTimerId); - bdTimerId = 0; - } - update(); - }); - hBox->addWidget(borderSpeedFd); - hBox->addStretch(); + fdDuration = new QSpinBox; + fdDuration->setRange(1, 9999); + fdDuration->setValue(mDuration); + hBox->addWidget(fdDuration); + hBox->addLabel(tr("s")); + hBox->addStretch(); - vBox->addLayout(hBox); + + hBox = new HBox(vBox); + hBox->addLabel(tr("Effect")); + + line = new QFrame; + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); + hBox->addWidget(line, 1); + + vBox->addSpacing(-spacing-2); + + auto grid = new Grid(vBox); + grid->setSpacing(4); + int ccc = 0; + grid->setColumnStretch(ccc++, 1); + grid->addLabel(tr("Entry"), 0, ccc++, Qt::AlignRight|Qt::AlignVCenter); + + auto fdEntryEff = new QComboBox; + fdEntryEff->addItem(tr("None"), ""); + fdEntryEff->addItem(tr("Random"), "Random"); + fdEntryEff->addItem(tr("Expand horizontal"), "EXPAND_HOR"); + fdEntryEff->addItem(tr("Expand vertical"), "EXPAND_VER"); + fdEntryEff->addItem(tr("Expand to left"), "EXPAND_LEFT"); + fdEntryEff->addItem(tr("Expand to top"), "EXPAND_TOP"); + fdEntryEff->addItem(tr("Expand to right"), "EXPAND_RIGHT"); + fdEntryEff->addItem(tr("Expand to bottom"), "EXPAND_BOTTOM"); + fdEntryEff->addItem(tr("Zoom in"), "ZOOM"); + fdEntryEff->addItem(tr("Zoom in from left-top"), "ZOOM_TL"); + fdEntryEff->addItem(tr("Zoom in from right-top"), "ZOOM_TR"); + fdEntryEff->addItem(tr("Zoom in from right-bottom"), "ZOOM_BR"); + fdEntryEff->addItem(tr("Zoom in from left-bottom"), "ZOOM_BL"); + fdEntryEff->addItem(tr("Rotate zoom"), "ROTATE"); + fdEntryEff->addItem(tr("Rotate zoom reverse"), "ROTATE_R"); + fdEntryEff->addItem(tr("Fade in"), "FADE"); + fdEntryEff->addItem(tr("Move to left"), "MOVE_LEFT"); + fdEntryEff->addItem(tr("Move to top"), "MOVE_TOP"); + fdEntryEff->addItem(tr("Move to right"), "MOVE_RIGHT"); + fdEntryEff->addItem(tr("Move to bottom"), "MOVE_BOTTOM"); + SetCurData(fdEntryEff, mEntryEffect); + connect(fdEntryEff, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] { + mEntryEffect = fdEntryEff->currentData().toString(); + }); + grid->addWidget(fdEntryEff, 0, ccc++); + grid->setColumnStretch(ccc++, 1); + + grid->addLabel(tr("Dur"), 0, ccc++, Qt::AlignRight|Qt::AlignVCenter); + + auto fdEntryDur = new QSpinBox; + fdEntryDur->setRange(1, 99); + fdEntryDur->setValue(mEntryDur); + connect(fdEntryDur, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) { + mEntryDur = value; + if(mDuration < value) { + mDuration = value; + fdDuration->setValue(value); + } + }); + grid->addWidget(fdEntryDur, 0, ccc++); + grid->addLabel(tr("s"), 0, ccc++); + grid->setColumnStretch(ccc, 1); + + ccc = 1; + grid->addLabel(tr("Exit"), 1, ccc++, Qt::AlignRight|Qt::AlignVCenter); + + auto fdExitEff = new QComboBox; + fdExitEff->addItem(tr("None"), ""); + fdExitEff->addItem(tr("Random"), "Random"); + fdExitEff->addItem(tr("Expand horizontal"), "EXPAND_HOR"); + fdExitEff->addItem(tr("Expand vertical"), "EXPAND_VER"); + fdExitEff->addItem(tr("Expand to left"), "EXPAND_LEFT"); + fdExitEff->addItem(tr("Expand to top"), "EXPAND_TOP"); + fdExitEff->addItem(tr("Expand to right"), "EXPAND_RIGHT"); + fdExitEff->addItem(tr("Expand to bottom"), "EXPAND_BOTTOM"); + fdExitEff->addItem(tr("Zoom out"), "ZOOM"); + fdExitEff->addItem(tr("Zoom out to left-top"), "ZOOM_TL"); + fdExitEff->addItem(tr("Zoom out to right-top"), "ZOOM_TR"); + fdExitEff->addItem(tr("Zoom out to right-bottom"), "ZOOM_BR"); + fdExitEff->addItem(tr("Zoom out to left-bottom"), "ZOOM_BL"); + fdExitEff->addItem(tr("Rotate zoom"), "ROTATE"); + fdExitEff->addItem(tr("Rotate zoom reverse"), "ROTATE_R"); + fdExitEff->addItem(tr("Fade out"), "FADE"); + fdExitEff->addItem(tr("Move to left"), "MOVE_LEFT"); + fdExitEff->addItem(tr("Move to top"), "MOVE_TOP"); + fdExitEff->addItem(tr("Move to right"), "MOVE_RIGHT"); + fdExitEff->addItem(tr("Move to bottom"), "MOVE_BOTTOM"); + SetCurData(fdExitEff, mExitEffect); + connect(fdExitEff, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] { + mExitEffect = fdExitEff->currentData().toString(); + }); + grid->addWidget(fdExitEff, 1, ccc++); + ccc++; + + grid->addLabel(tr("Dur"), 1, ccc++, Qt::AlignRight|Qt::AlignVCenter); + + auto fdExitDur = new QSpinBox; + fdExitDur->setRange(1, 99); + fdExitDur->setValue(mExitDur); + connect(fdExitDur, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) { + mExitDur = value; + if(mDuration < value) { + mDuration = value; + fdDuration->setValue(value); + } + }); + grid->addWidget(fdExitDur, 1, ccc++); + grid->addLabel(tr("s"), 1, ccc++); + + connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) { + mDuration = value; + if(mEntryDur > value) { + mEntryDur = value; + fdEntryDur->setValue(value); + } + if(mExitDur > value) { + mExitDur = value; + fdExitDur->setValue(value); + } + }); + } } diff --git a/LedOK/program/ebase.h b/LedOK/program/ebase.h index 1488eb4..2e4cf5d 100644 --- a/LedOK/program/ebase.h +++ b/LedOK/program/ebase.h @@ -4,6 +4,7 @@ #include #include "gutil/qjson.h" #include +#include #include #include #define m_handleLen 10 @@ -13,7 +14,7 @@ class EBase : public QGraphicsObject { public: enum ElementType { Text = QGraphicsItem::UserType + 1, - Photo, Video, Gif, Audio, + Image, Video, Gif, Audio, DClock, AClock, Timer, Environ, Window, Web }; Q_ENUM(ElementType) @@ -43,10 +44,13 @@ public: QRectF innerRect() const; QRectF rect() const { return innerRect(); } - int mType{-1}; - EBase *mMultiWin{nullptr}; - qreal mWidth{0.0}, mHeight{0.0}; - int mStartTime{0}; + int mType = -1; + EBase *mMultiWin = 0; + qreal mWidth = 0, mHeight = 0; + QSpinBox *fdDuration = 0; + int mStartTime = 0, mDuration = 10; + QString mEntryEffect, mExitEffect; + int mEntryDur = 1, mExitDur = 1; signals: void sizeChanged(); diff --git a/LedOK/program/edclock.cpp b/LedOK/program/edclock.cpp index 8c3dc98..48d42b1 100644 --- a/LedOK/program/edclock.cpp +++ b/LedOK/program/edclock.cpp @@ -52,7 +52,6 @@ EDClock::EDClock(const JObj &json, EBase *multiWin) : EBase(multiWin) { m_attr.dateStyle = widget["dateStyle"].toInt(); m_attr.timeStyle = widget["timeStyle"].toInt(); m_attr.multiline = widget["multiline"].toBool(); - m_attr.playDuration = json["play"]["duration"].toInt(); isSingleMD = m_attr.dateStyle==1||m_attr.dateStyle==2||m_attr.dateStyle==4||m_attr.dateStyle==6||m_attr.dateStyle==8||m_attr.dateStyle==10||m_attr.dateStyle==12; init(); } @@ -419,35 +418,8 @@ QWidget* EDClock::attrWgt() { }); hBox->addWidget(fdColor); hBox->addStretch(); - vBox->addLayout(hBox); - hBox = new QHBoxLayout(); - hBox->addWidget(new QLabel(tr("Play Properties"))); - - line = new QFrame(); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - hBox->addWidget(line, 1); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Play Duration"))); - - auto fdDuration = new QSpinBox(); - fdDuration->setRange(1, 99999); - fdDuration->setValue(m_attr.playDuration); - connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - m_attr.playDuration = value; - }); - hBox->addWidget(fdDuration); - - hBox->addWidget(new QLabel(tr("s"))); - hBox->addStretch(); - - vBox->addLayout(hBox); vBox->addStretch(); return wgtAttr; } @@ -480,6 +452,5 @@ JObj EDClock::attrJson() const{ addBaseAttr(oRoot); oRoot["elementType"] = "DClock"; oRoot["widget"] = oWidget; - oRoot["play"] = JObj{{"duration", m_attr.playDuration}}; return oRoot; } diff --git a/LedOK/program/edclock.h b/LedOK/program/edclock.h index 1f66d26..0e9275f 100644 --- a/LedOK/program/edclock.h +++ b/LedOK/program/edclock.h @@ -29,7 +29,6 @@ public: bool multiline; int dateStyle; int timeStyle; - int playDuration = 10; }; explicit EDClock(EBase *multiWin = nullptr); diff --git a/LedOK/program/eenviron.cpp b/LedOK/program/eenviron.cpp index 4a94bfa..b114927 100644 --- a/LedOK/program/eenviron.cpp +++ b/LedOK/program/eenviron.cpp @@ -14,91 +14,97 @@ #include #include -JObj EEnviron::genProg(const JObj &json, const QString &dstDir, const QString &srcPageDir) { +JObj EEnviron::genProg(const JValue &json, const QString &dstDir, const QString &srcPageDir) { JObj res; res["_type"] = "EnvironmentalMonitoring"; res["name"] = "EnvironmentalMonitoring"; - res["id"] = ""; const auto items = json["items"].toObj(); if(! items.empty()) { - auto title = json["title"].toString(); - res["bTitle"] = ! title.isEmpty(); - res["bTemperature"] = items["temp"]["has"]; + res["backColor"] = json["backColor"]; + res["bSingleScroll"] = json["isSingleLine"]; + auto scrollSpeed = json["scrollSpeed"].toInt(); + if(scrollSpeed && json["isSingleLine"].toBool()) { + res["scrollSpeed"] = scrollSpeed; + res["iScrollSpeed"] = 1000 / scrollSpeed; + } + res["timeSpan"] = json["duration"]; + res["alignType"] = json["align"]; res["temperatureCompensation"] = json["tempCompen"]; res["temperatureStyle"] = json["useFahrenheit"].toInt(); + QColor color = json["textColor"].toString(); + auto font = qfont(json["fontFamily"].toString(), json["fontSize"].toInt(), json["fontBold"].toBool(), json["fontItalic"].toBool()); + font.setUnderline(json["fontUnderline"].toBool()); + font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias); + QFontMetrics metric(font); + res["spaceWidth"] = metric.horizontalAdvance(" "); + auto title = json["title"].toString(); + if(! title.isEmpty()) Tools::saveImg(dstDir, metric, font, color, res, title, "title"); + JObj values; + for(auto &str : str0_9) Tools::saveImg(dstDir, metric, font, color, values, str, str); + Tools::saveImg(dstDir, metric, font, color, values, ".", "."); + Tools::saveImg(dstDir, metric, font, color, values, "-", "-"); + res["values"] = values; + + JArray oitems; + std::unordered_map unitMap; + auto itemMap = genItemMap(); + for(auto &pair : items) { + if(! pair.second["has"].toBool()) continue; + oitems->push_back(JObj{{"name", pair.first}}); + auto oitem = oitems->back().toObj(); + Tools::saveImg(dstDir, metric, font, color, oitem, pair.second["label"].toString(), "label"); + auto unit = itemMap[pair.first].unit; + if(unit.isEmpty()) continue; + auto &url = unitMap[unit]; + if(url.isEmpty()) url = Tools::saveImg(dstDir, metric, font, color, unit); + oitem["unit"] = url; + } + res["items"] = oitems; + + res["以下字段用来兼容旧播放器"] = 0; + res["bTitle"] = ! title.isEmpty(); + res["bgColor"] = Tools::color2Int(json["backColor"].toString()); + res["bTemperature"] = items["temperature"]["has"]; res["bHumidity"] = items["humidity"]["has"]; res["bNoise"] = items["noise"]["has"]; res["bWindSpeed"] = items["windSpeed"]["has"]; res["bWindDirection"] = items["windDirection"]["has"]; - res["bPM25"] = items["PM2.5"]["has"]; - res["bPM10"] = items["PM10"]["has"]; - for(auto item = items.find("SO₂"); item!=items.end(); ++item) res["has"+item->first.left(1).toUpper()+item->first.mid(1)] = item->second["has"]; - res["backColor"] = json["backColor"]; - res["bgColor"] = Tools::color2Int(json["backColor"].toString()); - res["bSingleScroll"] = json["isSingleLine"]; - res["iScrollSpeed"] = json["scrollSpeed"]; - res["timeSpan"] = json["duration"]; - res["alignType"] = json["align"]; - - QColor textColor = json["textColor"].toString(); - auto font = qfont(json["fontFamily"].toString(), json["fontSize"].toInt(), json["fontBold"].toBool(), json["fontItalic"].toBool()); - font.setUnderline(json["fontUnderline"].toBool()); - font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias); - QFontMetricsF metricF(font); - res["spaceWidth"] = metricF.horizontalAdvance(" "); - QFontMetrics metric(font); - QColor color(textColor); - JArray imgs; - for(auto str : str0_9) Tools::saveImg2(dstDir, metric, font, color, imgs, str, str); - - Tools::saveImg2(dstDir, metric, font, color, imgs, title, "labeltitle"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["temp"]["label"].toString(), "labeltemperature"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["humidity"]["label"].toString(), "labelhumidity"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["noise"]["label"].toString(), "labelnoise"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["windSpeed"]["label"].toString(), "labelwindSpeed"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["windDirection"]["label"].toString(), "labelwindDirection"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["PM2.5"]["label"].toString(), "labelpm25"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["PM10"]["label"].toString(), "labelpm10"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["SO₂"]["label"].toString(), "label_SO₂"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["NO₂"]["label"].toString(), "label_NO₂"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["CO"]["label"].toString(), "label_CO"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["O₃"]["label"].toString(), "label_O₃"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["pressure"]["label"].toString(), "label_pressure"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["rainfall"]["label"].toString(), "label_rainfall"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["radiation"]["label"].toString(), "label_radiation"); - Tools::saveImg2(dstDir, metric, font, color, imgs, items["beam"]["label"].toString(), "label_beam"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "℃", "unit_celsius"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "℉", "unit_fahrenheit"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "%", "unit_humidity"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "dB", "unit_noise"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "m/s", "unit_windspeed"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "μg/m³", "unit_pm25"); - auto img = imgs->back().toObj(); - img["name"] = "unit_pm10"; - imgs.append(img); - Tools::saveImg2(dstDir, metric, font, color, imgs, "ppb", "unit_ppb"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "hpa", "unit_hpa"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "mm", "unit_mm"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "W/m²", "unit_W/m²"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "lux", "unit_lux"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "-", "minus_sign"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north"), "N"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north")+tr("east")+tr("north"), "NNE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("north"), "NE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("east")+tr("north"), "ENE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east"), "E"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("east")+tr("south"), "ESE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("south"), "SE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south")+tr("east")+tr("south"), "SSE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south"), "S"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south")+tr("west")+tr("south"), "SSW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("south"), "SW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("west")+tr("south"), "WSW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west"), "W"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("west")+tr("north"), "WNW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("north"), "NW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north")+tr("west")+tr("north"), "NNW"); - + res["bPM25"] = items["pm2.5"]["has"]; + res["bPM10"] = items["pm10"]["has"]; + JArray arrayPics; + for(auto &str : str0_9) Tools::saveImg2(dstDir, metric, font, color, arrayPics, str, str); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, title, "labeltitle"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, items["temperature"]["label"].toString(), "labeltemperature"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, items["humidity"]["label"].toString(), "labelhumidity"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, items["noise"]["label"].toString(), "labelnoise"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, items["windSpeed"]["label"].toString(), "labelwindSpeed"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, items["windDirection"]["label"].toString(), "labelwindDirection"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, items["pm10"]["label"].toString(), "labelpm10"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, items["pm2.5"]["label"].toString(), "labelpm25"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, "℃", "unit_celsius"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, "℉", "unit_fahrenheit"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, "%", "unit_humidity"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, "dB", "unit_noise"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, "m/s", "unit_windspeed"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, "μg/m³", "unit_pm10"); + arrayPics.append(arrayPics->back()); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, "-", "minus_sign"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("N"), "N"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("N")+tr("NE"), "NNE"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("NE"), "NE"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("E")+tr("NE"), "ENE"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("E"), "E"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("E")+tr("SE"), "ESE"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("SE"), "SE"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("S")+tr("SE"), "SSE"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("S"), "S"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("S")+tr("SW"), "SSW"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("SW"), "SW"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("W")+tr("SW"), "WSW"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("W"), "W"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("W")+tr("NW"), "WNW"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("NW"), "NW"); + Tools::saveImg2(dstDir, metric, font, color, arrayPics, tr("N")+tr("NW"), "NNW"); JObj arrayPic; arrayPic["name"] = "previewTmp"; QString srcFile = srcPageDir+"/previewTmp.png"; @@ -108,83 +114,9 @@ JObj EEnviron::genProg(const JObj &json, const QString &dstDir, const QString &s srcQFile.copy(dstDir+"/"+id); arrayPic["id"] = id; } - imgs.append(arrayPic); - res["iPicCount"] = (int)imgs.size(); - res["arrayPics"] = imgs; - } else { - auto widget = json["widget"]; - res["timeSpan"] = json["play"]["duration"].toInt(); - res["alignType"] = widget["alignType"].toInt(); - res["bHumidity"] = widget["bHumidity"].toBool(); - res["bNoise"] = widget["bNoise"].toBool(); - res["bPM10"] = widget["bPM10"].toBool(); - res["bPM25"] = widget["bPM25"].toBool(); - res["bTemperature"] = widget["bTemperature"].toBool(); - auto title = widget["labelTitle"].toString(); - res["bTitle"] = ! title.isEmpty(); - res["bWindDirection"] = widget["bWindDirection"].toBool(); - res["bWindSpeed"] = widget["bWindSpeed"].toBool(); - res["temperatureCompensation"] = widget["temperatureCompensation"].toInt(); - res["temperatureStyle"] = widget["temperatureStyle"].toInt(); - res["bgColor"] = widget["cBackground"].toInt(); - res["bSingleScroll"] = widget["bPaomadeng"].toBool(); - res["iScrollSpeed"] = widget["scrollSpeed"].toInt(); - - auto textColor = Tools::int2Color(widget["textColor"].toInt()); - auto font = qfont(widget["fontFamily"].toString(), widget["fontSize"].toInt(), widget["fontBold"].toBool(), widget["fontItalics"].toBool()); - font.setUnderline(widget["fontUnderline"].toBool()); - font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias); - QFontMetricsF metricF(font); - res["spaceWidth"] = metricF.horizontalAdvance(" "); - QFontMetrics metric(font); - QColor color(textColor); - JArray imgs; - for(auto str : str0_9) Tools::saveImg2(dstDir, metric, font, color, imgs, str, str); - - Tools::saveImg2(dstDir, metric, font, color, imgs, title, "labeltitle"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelTemperature"].toString(), "labeltemperature"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelHumidity"].toString(), "labelhumidity"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelNoise"].toString(), "labelnoise"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelWindSpeed"].toString(), "labelwindSpeed"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelWindDirection"].toString(), "labelwindDirection"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelPM25"].toString(), "labelpm25"); - Tools::saveImg2(dstDir, metric, font, color, imgs, widget["labelPM10"].toString(), "labelpm10"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "℃", "unit_celsius"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "℉", "unit_fahrenheit"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "%", "unit_humidity"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "dB", "unit_noise"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "m/s", "unit_windspeed"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "μg/m³", "unit_pm10"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "μg/m³", "unit_pm25"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "-", "minus_sign"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north"), "N"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north")+tr("east")+tr("north"), "NNE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("north"), "NE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("east")+tr("north"), "ENE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east"), "E"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("east")+tr("south"), "ESE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("east")+tr("south"), "SE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south")+tr("east")+tr("south"), "SSE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south"), "S"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("south")+tr("west")+tr("south"), "SSW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("south"), "SW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("west")+tr("south"), "WSW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west"), "W"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("west")+tr("north"), "WNW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("west")+tr("north"), "NW"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("north")+tr("west")+tr("north"), "NNW"); - JObj arrayPic; - arrayPic["name"] = "previewTmp"; - QString srcFile = srcPageDir+"/previewTmp.png"; - QFile srcQFile(srcFile); - if(srcQFile.exists()) { - QString id = Tools::fileMd5(srcFile); - srcQFile.copy(dstDir+"/"+id); - arrayPic["id"] = id; - } - imgs.append(arrayPic); - res["iPicCount"] = (int)imgs.size(); - res["arrayPics"] = imgs; + arrayPics.append(arrayPic); + res["arrayPics"] = arrayPics; + res["旧播放器兼容结束"] = 0; } return res; } @@ -207,7 +139,6 @@ EEnviron::EEnviron(const JObj &json, EBase *multiWin): EBase(multiWin){ iter->second.has = jitem.second["has"].toBool(); } } - duration = json["duration"].toInt(); backColor = json["backColor"].toStr("#00000000"); textColor = json["textColor"].toStr("#ff000000"); tempCompen = json["tempCompen"].toInt(); @@ -245,7 +176,6 @@ EEnviron::EEnviron(const JObj &json, EBase *multiWin): EBase(multiWin){ item->second.label = item->second.text+": "; item->second.has = false; } - duration = json["play"]["duration"].toInt(); backColor = Tools::int2Color(widget["cBackground"].toInt()); textColor = Tools::int2Color(widget["textColor"].toInt()); tempCompen = widget["temperatureCompensation"].toInt(); @@ -309,7 +239,7 @@ void EEnviron::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, if(isSingleLine) { if(timer_id==0) { scroll_off = innerRect().width(); - timer_id = startTimer(scrollSpeed, Qt::PreciseTimer); + timer_id = startTimer(1000/scrollSpeed, Qt::PreciseTimer); } } else { if(timer_id!=0) { @@ -508,7 +438,7 @@ QWidget* EEnviron::attrWgt() { }); hBox->addWidget(fdSpeed); - hBox->addWidget(new QLabel(tr("ms/pixel"))); + hBox->addLabel("px/s"); hBox->addStretch(); line = new QFrame; @@ -598,30 +528,6 @@ QWidget* EEnviron::attrWgt() { }); hBox->addWidget(fdBack); hBox->addStretch(); - - hBox = new HBox(vBox); - hBox->addWidget(new QLabel(tr("Play Properties"))); - - line = new QFrame; - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - hBox->addWidget(line, 1); - - hBox = new HBox(vBox); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Play Duration"))); - - auto fdDuration = new QSpinBox(); - fdDuration->setRange(1, 99999); - fdDuration->setValue(duration); - connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) { - duration = value; - }); - hBox->addWidget(fdDuration); - - hBox->addWidget(new QLabel(tr("s"))); - hBox->addStretch(); - vBox->addStretch(); return wgtAttr; } @@ -650,7 +556,6 @@ JObj EEnviron::attrJson() const{ json["textColor"] = textColor.name(QColor::HexArgb); json["backColor"] = backColor.name(QColor::HexArgb); json["idDir"] = QString("env-%1-%2-%3-%4-%5").arg((int) zValue()).arg((int) x()).arg((int) y()).arg((int) mWidth).arg((int) mHeight); - json["duration"] = duration; return json; } diff --git a/LedOK/program/eenviron.h b/LedOK/program/eenviron.h index 83b71b2..082766d 100644 --- a/LedOK/program/eenviron.h +++ b/LedOK/program/eenviron.h @@ -13,35 +13,38 @@ struct EnvironItem { class EEnviron : public EBase { Q_OBJECT public: - LinkedMap itemMap { - {"temp", {tr("Temperature"), "℃"}}, - {"humidity", {tr("Humidity"), "%"}}, - {"noise", {tr("Noise"), "dB"}}, - {"windSpeed", {tr("Wind Speed"), "m/s"}}, - {"windDirection", {tr("Wind Direction")}}, - {"PM2.5", {"PM2.5", "μg/m³"}}, - {"PM10", {"PM10", "μg/m³"}}, - {"SO₂", {"SO₂", "ppb"}}, - {"NO₂", {"NO₂", "ppb"}}, - {"CO", {"CO", "ppb"}}, - {"O₃", {"O₃", "ppb"}}, - {"pressure", {tr("Pressure"), "hpa"}}, - {"rainfall", {tr("Rainfall"), "mm"}}, - {"radiation", {tr("Radiation"), "W/m²"}}, - {"beam", {tr("Beam"), "lux"}} - }; + static LinkedMap genItemMap() { + return LinkedMap { + {"temperature", {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³"}}, + {"SO2", {"SO₂", "ppb"}}, + {"NO2", {"NO₂", "ppb"}}, + {"CO", {"CO", "ppb"}}, + {"O3", {"O₃", "ppb"}}, + {"pressure", {tr("Pressure"), "hPa"}}, + {"rainfall", {tr("Rainfall"), "mm"}}, + {"radiation", {tr("Radiation"), "W/m²"}}, + {"beam", {tr("Beam"), "lux"}}, + {"CO2", {"CO₂", "ppm"}} + }; + } + LinkedMap itemMap = genItemMap(); QString title; QColor textColor = Qt::red; QColor backColor = Qt::transparent; QFont font = qfont("Arial", 12); int tempCompen = 0; int align = 0; - int duration = 10; - int scrollSpeed = 33; + int scrollSpeed = 30; bool useFahrenheit = false; bool isSingleLine = false; - static JObj genProg(const JObj &, const QString &, const QString &); + static JObj genProg(const JValue &, const QString &, const QString &); explicit EEnviron(EBase *multiWin = nullptr); explicit EEnviron(const JObj &json, EBase *multiWin = nullptr); diff --git a/LedOK/program/egif.cpp b/LedOK/program/egif.cpp index 27cb995..e2957d9 100644 --- a/LedOK/program/egif.cpp +++ b/LedOK/program/egif.cpp @@ -42,9 +42,6 @@ EGif *EGif::create(const JObj &json, PageListItem *pageItem, EBase *multiWin) { movie->jumpToFrame(0); auto ins = new EGif(movie, dir, name, pageItem, multiWin); ins->setBaseAttr(json); - auto play = json["play"]; - ins->mDuration = play["playDuration"].toInt(); - ins->mPlayTimes = play["playTimes"].toInt(); return ins; } @@ -144,46 +141,6 @@ QWidget* EGif::attrWgt() { vBox->addLayout(hBox); - hBox = new QHBoxLayout(); - hBox->addWidget(new QLabel(tr("Play Properties"))); - - line = new QFrame(); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - hBox->addWidget(line, 1); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Play Duration"))); - - auto wPlayDuration = new QSpinBox(); - wPlayDuration->setRange(1, 99999); - wPlayDuration->setValue(mDuration); - connect(wPlayDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - mDuration = value; - }); - hBox->addWidget(wPlayDuration); - hBox->addWidget(new QLabel(tr("s"))); - hBox->addStretch(); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Play Times"))); - - auto wPlayTimes = new QSpinBox(); - wPlayTimes->setRange(1, 99999); - wPlayTimes->setValue(mPlayTimes); - connect(wPlayTimes, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - mPlayTimes = value; - }); - hBox->addWidget(wPlayTimes); - hBox->addStretch(); - - vBox->addLayout(hBox); vBox->addStretch(); return wgtAttr; } @@ -206,9 +163,5 @@ JObj EGif::attrJson() const { {"file", mName}, {"path", mDir} }; - oRoot["play"] = JObj{ - {"playDuration", mDuration}, - {"playTimes", mPlayTimes} - }; return oRoot; } diff --git a/LedOK/program/egif.h b/LedOK/program/egif.h index 280263d..deebfd1 100644 --- a/LedOK/program/egif.h +++ b/LedOK/program/egif.h @@ -29,9 +29,7 @@ public slots: protected: PageListItem *mPageItem; - int mDuration = 10; - int mPlayTimes = 1; - SyncTimer* timer = nullptr; + SyncTimer* timer = 0; }; #endif // EGIF_H diff --git a/LedOK/program/emultiwin.cpp b/LedOK/program/emultiwin.cpp index eebeb51..61206e6 100644 --- a/LedOK/program/emultiwin.cpp +++ b/LedOK/program/emultiwin.cpp @@ -27,13 +27,13 @@ EMultiWin::EMultiWin(const JObj &json, PageListItem *pageItem) : mPageItem(pageI setBaseAttr(json); auto elements = json["elements"].toArray(); index = json["index"].toInt(); - for(auto element : elements) { + for(auto &element : elements) { QString type = element["elementType"].toString(); EBase *inner = nullptr; if(type=="Text") inner = new EText(element.toObj(), this); - else if(type=="Photo") inner = EPhoto::create(element.toObj(), pageItem, this); + else if(type=="Image"||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=="Video"||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); @@ -127,7 +127,7 @@ QWidget* EMultiWin::attrWgt() { auto menu = new QMenu(); menu->addAction(QIcon(":/res/program/Text.png"), tr("Text"))->setData(EBase::Text); - menu->addAction(QIcon(":/res/program/Photo.png"), tr("Photo"))->setData(EBase::Photo); + menu->addAction(QIcon(":/res/program/Photo.png"), tr("Photo"))->setData(EBase::Image); menu->addAction(QIcon(":/res/program/Movie.png"), tr("Video"))->setData(EBase::Video); menu->addAction(QIcon(":/res/program/Gif.png"), tr("Gif"))->setData(EBase::Gif); menu->addAction(QIcon(":/res/program/DClock.png"), tr("DClock"))->setData(EBase::DClock); @@ -138,7 +138,7 @@ QWidget* EMultiWin::attrWgt() { int order = listWgt->count(); EBase *ele = 0; QListWidgetItem *item = 0; - if(type==EBase::Photo) { + if(type==EBase::Image) { auto files = QFileDialog::getOpenFileNames(wgtAttr, tr("Select File"), gFileHome, EPhoto::filters()); for(int i=0; itype(); if(type==EBase::Text) item = new QListWidgetItem(QIcon(":/res/program/Text.png"), tr("Text")); - else if(type==EBase::Photo) item = new QListWidgetItem(QIcon(":/res/program/Photo.png"), tr("Photo")+" "+static_cast(inner)->mName); + else if(type==EBase::Image) item = new QListWidgetItem(QIcon(":/res/program/Photo.png"), tr("Photo")+" "+static_cast(inner)->mName); else if(type==EBase::Video) item = new QListWidgetItem(QIcon(":/res/program/Movie.png"), tr("Video")+" "+static_cast(inner)->mRawName); else if(type==EBase::Gif) item = new QListWidgetItem(QIcon(":/res/program/Gif.png"), tr("Gif")+" "+static_cast(inner)->mName); else if(type==EBase::DClock) item = new QListWidgetItem(QIcon(":/res/program/DClock.png"), tr("DClock")); diff --git a/LedOK/program/ephoto.cpp b/LedOK/program/ephoto.cpp index 617562a..78258cc 100644 --- a/LedOK/program/ephoto.cpp +++ b/LedOK/program/ephoto.cpp @@ -22,8 +22,8 @@ EPhoto *EPhoto::create(const QString &file, PageListItem *pageItem, EBase *multi } EPhoto *EPhoto::create(const JObj &json, PageListItem *pageItem, EBase *multiWin) { auto widget = json["widget"]; - auto dir = widget["path"].toString(); - auto name = widget["file"].toString(); + auto dir = (widget.isNull() ? json["dir"] : widget["path"]).toString(); + auto name = (widget.isNull() ? json["name"] : widget["file"]).toString(); if(! QFileInfo(dir).isDir()) dir = pageItem->mPageDir; QString file = dir + "/" + name; QFileInfo fileInfo(file); @@ -35,35 +35,23 @@ EPhoto *EPhoto::create(const JObj &json, PageListItem *pageItem, EBase *multiWin else return nullptr; } auto img = QImage(file); - if(img.isNull()) return nullptr; + if(img.isNull()) return 0; auto ins = new EPhoto(img, dir, name, pageItem, multiWin); ins->setBaseAttr(json); - auto play = json["play"]; - ins->mDuration = play["playDuration"].toInt(); - ins->mEnterStyle = play["enterStyle"].toInt(); - ins->mEnterDuration = play["enterDuration"].toInt(); return ins; } EPhoto::EPhoto(const QImage &img, const QString &dir, const QString &name, PageListItem *pageItem, EBase *multiWin) : EBase(multiWin), img(img), mDir(dir), mName(name), mPageItem(pageItem) { - mType = EBase::Photo; + mType = EBase::Image; scaleImgIfNeed(); } JObj EPhoto::attrJson() const { - JObj oRoot; - addBaseAttr(oRoot); - oRoot["elementType"] = "Photo"; - oRoot["widget"] = JObj{ - {"path", mDir}, - {"file", mName} - }; - oRoot["play"] = JObj{ - {"playDuration", mDuration}, - {"playTimes", 1}, - {"enterStyle", mEnterStyle}, - {"enterDuration", mEnterDuration} - }; - return oRoot; + JObj json; + addBaseAttr(json); + json["elementType"] = "Image"; + json["dir"] = mDir; + json["name"] = mName; + return json; } void EPhoto::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->drawImage(innerRect(), img); @@ -95,14 +83,14 @@ bool EPhoto::save(const QString &pageDir) { } QWidget* EPhoto::attrWgt() { - auto wgtAttr = new QWidget(); - auto vBox = new QVBoxLayout(wgtAttr); + auto wgtAttr = new QWidget; + auto vBox = new VBox(wgtAttr); vBox->setContentsMargins(6, 0, 6, 0); if(mMultiWin) vBox->setSpacing(3); addBaseAttrWgt(vBox); - auto hBox = new QHBoxLayout(); + auto hBox = new HBox(vBox); hBox->addWidget(new QLabel(tr("Basic Properties"))); auto line = new QFrame(); @@ -110,9 +98,7 @@ QWidget* EPhoto::attrWgt() { line->setFrameShadow(QFrame::Sunken); hBox->addWidget(line, 1); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); hBox->addSpacing(6); hBox->addWidget(new QLabel(tr("File"))); @@ -143,86 +129,98 @@ QWidget* EPhoto::attrWgt() { }); hBox->addWidget(bnSelectFile); - vBox->addLayout(hBox); + // hBox = new HBox(vBox); + // hBox->addWidget(new QLabel(tr("Play Properties"))); - hBox = new QHBoxLayout(); - hBox->addWidget(new QLabel(tr("Play Properties"))); + // line = new QFrame(); + // line->setFrameShape(QFrame::HLine); + // line->setFrameShadow(QFrame::Sunken); + // hBox->addWidget(line, 1); - line = new QFrame(); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - hBox->addWidget(line, 1); + // hBox = new HBox(vBox); + // hBox->setSpacing(2); + // hBox->addSpacing(6); + // hBox->addWidget(new QLabel(tr("Entry Effect"))); - vBox->addLayout(hBox); + // auto fdEntryEff = new QComboBox; + // fdEntryEff->addItem(tr("None"), ""); + // fdEntryEff->addItem(tr("Move to left"), "moving_left"); + // fdEntryEff->addItem(tr("Move to top"), "moving_top"); + // fdEntryEff->addItem(tr("Move to right"), "moving_right"); + // fdEntryEff->addItem(tr("Move to bottom"), "moving_bottom"); + // fdEntryEff->addItem(tr("Alpha in"), "alpha_in"); + // fdEntryEff->addItem(tr("Zoom in"), "zoom_in"); + // fdEntryEff->addItem(tr("Zoom in from left-top"), "zoom_in_left_top"); + // fdEntryEff->addItem(tr("Zoom in from right-top"), "zoom_in_right_top"); + // fdEntryEff->addItem(tr("Zoom in from right-bottom"), "zoom_in_right_bottom"); + // fdEntryEff->addItem(tr("Zoom in from left-bottom"), "zoom_in_left_bottom"); + // fdEntryEff->addItem(tr("Rotate to right"), "rotate_right"); + // fdEntryEff->addItem(tr("Rotate to left"), "rotate_left"); + // fdEntryEff->addItem(tr("Random"), "Random"); + // SetCurData(fdEntryEff, mEntryEffect); + // connect(fdEntryEff, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] { + // mEntryEffect = fdEntryEff->currentData().toString(); + // }); + // hBox->addWidget(fdEntryEff); + // hBox->addStretch(); - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Play Duration"))); + // hBox->addLabel(tr("Dur")); - auto fdDuration = new QSpinBox(); - fdDuration->setRange(1, 99999); - fdDuration->setValue(mDuration); - hBox->addWidget(fdDuration); + // auto fdEntryDur = new QSpinBox; + // fdEntryDur->setRange(1, 99); + // fdEntryDur->setValue(mEntryDur); + // connect(fdEntryDur, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) { + // mEntryDur = value; + // if(mDuration < value) { + // mDuration = value; + // fdDuration->setValue(value); + // } + // }); + // hBox->addWidget(fdEntryDur); + // hBox->addLabel(tr("s")); - hBox->addWidget(new QLabel(tr("s"))); - hBox->addStretch(); + // hBox = new HBox(vBox); + // hBox->setSpacing(2); + // hBox->addSpacing(6); + // hBox->addWidget(new QLabel(tr("Exit Effect"))); - vBox->addLayout(hBox); + // auto fdExitEff = new QComboBox; + // fdExitEff->addItem(tr("None"), ""); + // fdExitEff->addItem(tr("Move to left"), "moving_left"); + // fdExitEff->addItem(tr("Move to top"), "moving_top"); + // fdExitEff->addItem(tr("Move to right"), "moving_right"); + // fdExitEff->addItem(tr("Move to bottom"), "moving_bottom"); + // fdExitEff->addItem(tr("Alpha out"), "alpha_out"); + // fdExitEff->addItem(tr("Zoom out"), "zoom_out"); + // fdExitEff->addItem(tr("Zoom out to left-top"), "zoom_out_left_top"); + // fdExitEff->addItem(tr("Zoom out to right-top"), "zoom_out_right_top"); + // fdExitEff->addItem(tr("Zoom out to right-bottom"), "zoom_out_right_bottom"); + // fdExitEff->addItem(tr("Zoom out to left-bottom"), "zoom_out_left_bottom"); + // fdExitEff->addItem(tr("Rotate to right"), "rotate_right"); + // fdExitEff->addItem(tr("Rotate to left"), "rotate_left"); + // fdExitEff->addItem(tr("Random"), "Random"); + // SetCurData(fdExitEff, mExitEffect); + // connect(fdExitEff, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] { + // mExitEffect = fdExitEff->currentData().toString(); + // }); + // hBox->addWidget(fdExitEff); + // hBox->addStretch(); - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Enter Style"))); + // hBox->addLabel(tr("Dur")); - auto wEnterStyle = new QComboBox(); - wEnterStyle->addItem(tr("None")); - 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("Rotate to right")); - wEnterStyle->addItem(tr("Rotate to left")); - wEnterStyle->setCurrentIndex(mEnterStyle); - connect(wEnterStyle, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int value) { - mEnterStyle = value; - }); - hBox->addWidget(wEnterStyle); - hBox->addStretch(); + // auto fdExitDur = new QSpinBox; + // fdExitDur->setRange(1, 99); + // fdExitDur->setValue(mExitDur); + // connect(fdExitDur, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) { + // mExitDur = value; + // if(mDuration < value) { + // mDuration = value; + // fdDuration->setValue(value); + // } + // }); + // hBox->addWidget(fdExitDur); + // hBox->addLabel(tr("s")); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Enter Duration"))); - - auto fdEnterDuration = new QSpinBox(); - fdEnterDuration->setRange(1, 99999); - fdEnterDuration->setValue(mEnterDuration); - connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdEnterDuration](int value){ - mDuration = value; - if(mEnterDuration > value) { - mEnterDuration = value; - fdEnterDuration->setValue(value); - } - }); - connect(fdEnterDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdDuration](int value){ - mEnterDuration = value; - if(mDuration < value) { - mDuration = value; - fdDuration->setValue(value); - } - }); - hBox->addWidget(fdEnterDuration); - - hBox->addWidget(new QLabel(tr("s"))); - hBox->addStretch(); - - vBox->addLayout(hBox); vBox->addStretch(); return wgtAttr; } diff --git a/LedOK/program/ephoto.h b/LedOK/program/ephoto.h index b3142ef..35da816 100644 --- a/LedOK/program/ephoto.h +++ b/LedOK/program/ephoto.h @@ -6,16 +6,6 @@ class EPhoto : public EBase { Q_OBJECT -public: - enum EnterStyle { - NoneStyle = 0, - Expanding2Left, - Expanding2Right, - Expanding2Top, - Expanding2Bottom, - ExpandingFromCenter - }; - public: static QString filters() { return tr("Images (*.png *.jpg *.jpeg *.bmp)"); } static EPhoto *create(const QString &file, PageListItem *pageItem, EBase *multiWin = nullptr); @@ -25,7 +15,7 @@ public: void scaleImgIfNeed(); - int type() const override { return EBase::Photo; } + int type() const override { return EBase::Image; } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; JObj attrJson() const override; void freeFiles() override; @@ -34,13 +24,9 @@ public: QWidget* attrWgt() override; QImage img; - QString mDir; - QString mName; + QString mDir, mName; protected: PageListItem *mPageItem; - int mDuration = 10; - int mEnterStyle = 0; - int mEnterDuration = 0; }; #endif // EPHOTO_H diff --git a/LedOK/program/etext.cpp b/LedOK/program/etext.cpp index 2a8db57..0129da8 100644 --- a/LedOK/program/etext.cpp +++ b/LedOK/program/etext.cpp @@ -22,40 +22,42 @@ #include static QColor charColors[]{"#fff","#f00","#f00","#f0f","#c0c","#ff0","#f80","#0f0","#0f0","#0a0","#0a0","#7b0","#00f","#00f","#0af","#0ef"}; +QString playModes[]{"Flip", "Scroll", "Static"}; EText::EText(EBase *multiWin) : EBase(multiWin) { mType = EBase::Text; - m_attr.text = ""+tr("Enter your text")+""; + text = ""+tr("Enter your text")+""; connect(this, &EText::sizeChanged, this, &EText::updImg); updImg(); } EText::EText(const JObj &json, EBase *multiWin) : EBase(multiWin) { mType = EBase::Text; setBaseAttr(json); - setElement(json, m_attr); + auto widget = json["widget"]; + if(widget.isNull()) widget = json; + text = widget["text"].toString(); + align = (Qt::Alignment) widget["align"].toInt(); + backColor = widget["backColor"].toString("#00000000"); + auto play = json["play"]; + if(play.isNull()) { + playMode = json["playMode"].toString(); + if(playMode=="Scroll") { + direction = json["direction"].toString(); + speed = json["speed"].toInt(); + headTailSpacing = json["headTailSpacing"].toInt(); + } + } else { + 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); + headTailSpacing = rolling["headTailSpacing"].toInt(); + } connect(this, &EText::sizeChanged, this, &EText::updImg); updImg(); } -void EText::setElement(const JObj &json, Data &attr) { - auto widget = json["widget"]; - attr.text = widget["text"].toString(); - attr.align = static_cast(widget["align"].toInt()); - attr.backColor = widget["backColor"].toString("#00000000"); - auto play = json["play"]; - attr.playMode = play["style"].toInt(); - auto turning = play["turning"]; - attr.flip.effect = turning["strEffect"].toString(); - attr.flip.pageDuration = turning["iEffectTime"].toInt(); - attr.flip.effectDuration = turning["iEffectSpeed"].toInt(); - auto rolling = play["rolling"]; - attr.scroll.effect = rolling["rollingStyle"].toInt(); - attr.scroll.effectSpeed = rolling["rollingSpeed"].toInt(); - attr.scroll.headTailSpacing = rolling["headTailSpacing"].toInt(); - attr.scroll.duration = rolling["playDuration"].toInt(); - attr.duration = play["static"]["playDuration"].toInt(); -} - class TTextEdit : public QTextEdit { public: TTextEdit() {} @@ -194,12 +196,12 @@ QWidget* EText::attrWgt() { }); hBox->addWidget(fdTextColor); - auto fdBackColor = new LoColorSelector("B", m_attr.backColor); + auto fdBackColor = new LoColorSelector("B", backColor); fdBackColor->setToolTip(tr("Back Color")); fdBackColor->setFixedSize(30, 30); connect(fdBackColor, &LoColorSelector::sColorChanged, this, [this](const QColor &color) { if(! color.isValid()) return; - m_attr.backColor = color; + backColor = color; updImg(); }); hBox->addWidget(fdBackColor); @@ -272,12 +274,12 @@ QWidget* EText::attrWgt() { lb->setToolTip(lb->text()); hBox->addWidget(lb); - auto fdLineSpacing = new QSpinBox(); + auto fdLineSpacing = new QSpinBox; fdLineSpacing->setRange(-99, 999); connect(fdLineSpacing, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdText](int value) { QTextBlockFormat fmt; fmt.setLineHeight(value, QTextBlockFormat::LineDistanceHeight); - QTextCursor cursor = fdText->textCursor(); + auto cursor = fdText->textCursor(); if(! cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor); cursor.mergeBlockFormat(fmt); updImg(); @@ -286,11 +288,11 @@ QWidget* EText::attrWgt() { vBox->addLayout(hBox); - auto wTextAlignH = new QButtonGroup(wgtAttr); - wTextAlignH->addButton(wTextAlignHL, Qt::AlignLeft); - wTextAlignH->addButton(wTextAlignHC, Qt::AlignHCenter); - wTextAlignH->addButton(wTextAlignHR, Qt::AlignRight); - connect(wTextAlignH, &QButtonGroup::idClicked, this, [this, fdText](int value) { + auto fdAlignH = new QButtonGroup(wgtAttr); + fdAlignH->addButton(wTextAlignHL, Qt::AlignLeft); + fdAlignH->addButton(wTextAlignHC, Qt::AlignHCenter); + fdAlignH->addButton(wTextAlignHR, Qt::AlignRight); + connect(fdAlignH, &QButtonGroup::idClicked, this, [this, fdText](int value) { QTextBlockFormat fmt; fmt.setAlignment((Qt::Alignment) value); QTextCursor cursor = fdText->textCursor(); @@ -298,16 +300,16 @@ QWidget* EText::attrWgt() { updImg(); }); - auto wTextAlignV = new QButtonGroup(wgtAttr); - wTextAlignV->addButton(wTextAlignVT, Qt::AlignTop); - wTextAlignV->addButton(wTextAlignVC, Qt::AlignVCenter); - wTextAlignV->addButton(wTextAlignVB, Qt::AlignBottom); - connect(wTextAlignV, &QButtonGroup::idClicked, this, [this](int value) { - m_attr.align = (Qt::Alignment) value; + auto fdAlignV = new QButtonGroup(wgtAttr); + fdAlignV->addButton(wTextAlignVT, Qt::AlignTop); + fdAlignV->addButton(wTextAlignVC, Qt::AlignVCenter); + fdAlignV->addButton(wTextAlignVB, Qt::AlignBottom); + connect(fdAlignV, &QButtonGroup::idClicked, this, [this](int value) { + align = (Qt::Alignment) value; updImg(); }); - auto v_align = m_attr.align & Qt::AlignVertical_Mask; + auto v_align = align & Qt::AlignVertical_Mask; if(v_align==Qt::AlignTop) wTextAlignVT->setChecked(true); if(v_align==Qt::AlignVCenter) wTextAlignVC->setChecked(true); if(v_align==Qt::AlignBottom) wTextAlignVB->setChecked(true); @@ -326,9 +328,9 @@ QWidget* EText::attrWgt() { fdText->setPalette(pal); fdText->setFrameShape(QFrame::NoFrame); fdText->setAcceptRichText(false); - fdText->setHtml(m_attr.text); + fdText->setHtml(text); connect(fdText, &QTextEdit::textChanged, this, [this, fdText] { - m_attr.text = fdText->toHtml(); + text = fdText->toHtml(); updImg(); }); connect(fdText, &QTextEdit::currentCharFormatChanged, this, [=](const QTextCharFormat &format) { @@ -339,6 +341,19 @@ QWidget* EText::attrWgt() { fdTextColor->blockSignals(true); fdTextColor->setColor(foreground.style()==Qt::NoBrush ? Qt::white : foreground.color()); fdTextColor->blockSignals(false); + + fdLetterSpacing->blockSignals(true); + fdLetterSpacing->setValue(format.fontLetterSpacing()); + fdLetterSpacing->blockSignals(false); + + auto cursor = fdText->textCursor(); + auto blockFormat = cursor.blockFormat(); + auto btn = fdAlignH->button(blockFormat.alignment() & Qt::AlignHorizontal_Mask); + if(btn) btn->setChecked(true); + + fdLineSpacing->blockSignals(true); + fdLineSpacing->setValue(blockFormat.lineHeightType()==QTextBlockFormat::LineDistanceHeight ? blockFormat.lineHeight() : 0); + fdLineSpacing->blockSignals(false); }); vBox->addWidget(fdText); @@ -424,232 +439,110 @@ QWidget* EText::attrWgt() { vBox->addLayout(hBox); auto fdPlayStyle = new QButtonGroup(wgtAttr); - fdPlayStyle->addButton(fdFlip, EText::Flip); - fdPlayStyle->addButton(fdScroll, EText::Scroll); - fdPlayStyle->addButton(fdStatic, EText::Static); - if(m_attr.playMode==EText::Flip) fdFlip->setChecked(true); - else if(m_attr.playMode==EText::Scroll) fdScroll->setChecked(true); - else if(m_attr.playMode==EText::Static) fdStatic->setChecked(true); + fdPlayStyle->addButton(fdFlip, 0); + fdPlayStyle->addButton(fdScroll, 1); + fdPlayStyle->addButton(fdStatic, 2); + if(playMode=="Flip") fdFlip->setChecked(true); + else if(playMode=="Scroll") fdScroll->setChecked(true); + else if(playMode=="Static") fdStatic->setChecked(true); - auto wgtAttrFlip = new QWidget(); - auto fdDur = new QTimeEdit(QTime::fromMSecsSinceStartOfDay(m_attr.flip.pageDuration * mImgs.size() * 1000)); - auto fdPageDur = new QTimeEdit(QTime::fromMSecsSinceStartOfDay(m_attr.flip.pageDuration * 1000)); + auto wgtAttrFlip = new QWidget; + auto wgtAttrScroll = new QWidget; { - auto vBox = new QVBoxLayout(wgtAttrFlip); + auto vBox = new VBox(wgtAttrScroll); vBox->setContentsMargins(2, 0, 2, 0); vBox->setSpacing(3); - hBox = new QHBoxLayout; - - auto label = new QLabel(tr("Play Duration")); + auto hBox = new HBox(vBox); + auto label = new QLabel(tr("Head-Tail Spacing")); label->setMinimumWidth(100); hBox->addWidget(label); - fdDur->setReadOnly(true); - fdDur->setButtonSymbols(QAbstractSpinBox::NoButtons); - fdDur->setDisplayFormat("H:mm:ss"); - fdDur->setStyleSheet("QTimeEdit{background-color:#ddd;}"); - hBox->addWidget(fdDur); - hBox->addStretch(); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - - label = new QLabel(tr("Duration/Page")); - label->setMinimumWidth(100); - hBox->addWidget(label); - - fdPageDur->setDisplayFormat("H:mm:ss"); - fdPageDur->setCurrentSection(QTimeEdit::SecondSection); - hBox->addWidget(fdPageDur); - hBox->addStretch(); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - - label = new QLabel(tr("Entrance Effect")); - label->setMinimumWidth(100); - hBox->addWidget(label); - - auto fdEff = new QComboBox(); - fdEff->addItem(tr("no"), "no"); - fdEff->addItem(tr("random"), "random"); - fdEff->addItem(tr("right to left"), "right to left"); - fdEff->addItem(tr("bottom to top"), "bottom to top"); - fdEff->addItem(tr("left to right"), "left to right"); - fdEff->addItem(tr("top to bottom"), "top to bottom"); - int idx = fdEff->findData(m_attr.flip.effect); - if(idx!=-1) fdEff->setCurrentIndex(idx); - connect(fdEff, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, fdEff] { - m_attr.flip.effect = fdEff->currentData().toString(); - update(); + auto fdHeadTailSpacing = new QSpinBox; + fdHeadTailSpacing->setRange(0, 9999); + fdHeadTailSpacing->setValue(headTailSpacing); + connect(fdHeadTailSpacing, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { + headTailSpacing = value; + updImg(); }); - hBox->addWidget(fdEff); + hBox->addWidget(fdHeadTailSpacing); hBox->addStretch(); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - - label = new QLabel(tr("Effect time")); - label->setMinimumWidth(100); - hBox->addWidget(label); - - auto wEffectSpeed = new QSpinBox(); - wEffectSpeed->setValue(m_attr.flip.effectDuration); - hBox->addWidget(wEffectSpeed); - hBox->addWidget(new QLabel(tr("s"))); - hBox->addStretch(); - - vBox->addLayout(hBox); - vBox->addStretch(); - - connect(fdPageDur, &QTimeEdit::timeChanged, this, [=](const QTime &time) { - int effDur = wEffectSpeed->value(); - int pageDur = time.msecsSinceStartOfDay()/1000; - if(pageDur < effDur) { - QMessageBox::warning(wgtAttr, tr("Tip Info"), tr("Effect time cannot be longer than duration time")); - pageDur = effDur; - fdPageDur->setTime(QTime::fromMSecsSinceStartOfDay(pageDur*1000)); - fdPageDur->setFocus(); - } - m_attr.flip.pageDuration = pageDur; - fdDur->setTime(QTime::fromMSecsSinceStartOfDay(pageDur * mImgs.size() * 1000)); - }); - connect(wEffectSpeed, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) { - int pageDur = fdPageDur->time().msecsSinceStartOfDay()/1000; - if(value > pageDur) { - QMessageBox::warning(wgtAttr, tr("Tip Info"), tr("Effect time cannot be longer than duration time")); - if(pageDur>1) value = pageDur-1; - else value = 0; - wEffectSpeed->setValue(value); - wEffectSpeed->setFocus(); - } - m_attr.flip.effectDuration = value; - }); - } - auto wgtAttrScroll = new QWidget(); - { - auto vBox = new QVBoxLayout(wgtAttrScroll); - vBox->setContentsMargins(2, 0, 2, 0); - vBox->setSpacing(3); - - auto hBox = new QHBoxLayout(); - - auto label = new QLabel(tr("Play Duration")); - label->setMinimumWidth(100); - hBox->addWidget(label); - - auto timeEdit = new QTimeEdit(QTime::fromMSecsSinceStartOfDay(m_attr.scroll.duration*1000)); - timeEdit->setDisplayFormat("H:mm:ss"); - timeEdit->setCurrentSectionIndex(2); - connect(timeEdit, &QTimeEdit::timeChanged, this, [this](const QTime &time) { - m_attr.scroll.duration = time.msecsSinceStartOfDay()/1000; - }); - hBox->addWidget(timeEdit); - hBox->addStretch(); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - - label = new QLabel(tr("Head-Tail Spacing")); - label->setMinimumWidth(100); - hBox->addWidget(label); - - auto wHeadTailSpacing = new QSpinBox; - wHeadTailSpacing->setRange(0, 9999); - wHeadTailSpacing->setValue(m_attr.scroll.headTailSpacing); - connect(wHeadTailSpacing, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - m_attr.scroll.headTailSpacing = value; - }); - hBox->addWidget(wHeadTailSpacing); - hBox->addStretch(); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); label = new QLabel(tr("Scroll Style")); label->setMinimumWidth(100); hBox->addWidget(label); - auto wRollingStyle = new QComboBox; - wRollingStyle->addItem(tr("Right -> Left")); - wRollingStyle->addItem(tr("Bottom -> Top")); - wRollingStyle->addItem(tr("Left -> Right")); - wRollingStyle->addItem(tr("Top -> Bottom")); - wRollingStyle->setCurrentIndex(m_attr.scroll.effect); - connect(wRollingStyle, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int index) { - m_attr.scroll.effect = index; + auto fdDirection = new QComboBox; + fdDirection->addItem(tr("Right -> Left"), "left"); + fdDirection->addItem(tr("Bottom -> Top"), "top"); + fdDirection->addItem(tr("Left -> Right"), "right"); + fdDirection->addItem(tr("Top -> Bottom"), "bottom"); + SetCurData(fdDirection, direction); + connect(fdDirection, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] { + direction = fdDirection->currentData().toString(); updImg(); }); - hBox->addWidget(wRollingStyle); + hBox->addWidget(fdDirection); hBox->addStretch(); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); label = new QLabel(tr("Scroll Speed")); label->setMinimumWidth(100); hBox->addWidget(label); - auto wRollingSpeed = new QSpinBox(); - wRollingSpeed->setMaximum(9999); - wRollingSpeed->setValue(m_attr.scroll.effectSpeed); - connect(wRollingSpeed, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - m_attr.scroll.effectSpeed = value; + auto fd = new QComboBox; + fd->setEditable(true); + fd->setMinimumWidth(50); + fd->addItem("600"); + fd->addItem("540"); + fd->addItem("480"); + fd->addItem("420"); + fd->addItem("360"); + fd->addItem("300"); + fd->addItem("240"); + fd->addItem("180"); + fd->addItem("120"); + fd->addItem("60"); + fd->addItem("30"); + fd->setMaxVisibleItems(fd->count()); + auto text = QString::number(speed); + if(SetCurText(fd, text)==-1) { + SetCurText(fd, "60"); + fd->setCurrentText(text); + } + connect(fd, &QComboBox::editTextChanged, this, [=](const QString &text) { + bool ok; + auto speed = text.toInt(&ok); + if(ok) this->speed = speed; }); - hBox->addWidget(wRollingSpeed); + hBox->addWidget(fd); + hBox->addLabel("px/s"); hBox->addStretch(); - vBox->addLayout(hBox); - vBox->addStretch(); - } - auto wgtAttrStatic = new QWidget(); - { - auto vBox = new QVBoxLayout(wgtAttrStatic); - vBox->setContentsMargins(2, 0, 2, 0); - vBox->setSpacing(3); - - hBox = new QHBoxLayout(); - auto label = new QLabel(tr("Play Duration")); - label->setMinimumWidth(100); - hBox->addWidget(label); - - auto timeEdit = new QTimeEdit(QTime::fromMSecsSinceStartOfDay(m_attr.duration*1000)); - timeEdit->setDisplayFormat("H:mm:ss"); - timeEdit->setCurrentSectionIndex(2); - connect(timeEdit, &QTimeEdit::timeChanged, this, [this](const QTime &time) { - m_attr.duration = time.msecsSinceStartOfDay() / 1000; - }); - hBox->addWidget(timeEdit); - hBox->addStretch(); - - vBox->addLayout(hBox); vBox->addStretch(); } auto stackBox = new QStackedLayout; vBox->addLayout(stackBox); stackBox->addWidget(wgtAttrFlip); stackBox->addWidget(wgtAttrScroll); - stackBox->addWidget(wgtAttrStatic); - stackBox->setCurrentIndex(m_attr.playMode); - connect(fdPlayStyle, &QButtonGroup::idToggled, this, [this, stackBox, pageInfoWgt](int value, bool checked) { + stackBox->addWidget(new QWidget); + auto idx = std::find(playModes, playModes+3, playMode)-playModes; + if(idx>2) idx = 0; + stackBox->setCurrentIndex(idx); + connect(fdPlayStyle, &QButtonGroup::idToggled, this, [=](int value, bool checked) { if(! checked) return; - m_attr.playMode = value; + playMode = playModes[value]; updImg(); stackBox->setCurrentIndex(value); - pageInfoWgt->setVisible(value==Flip); + pageInfoWgt->setVisible(playMode=="Flip"); }); - connect(this, &EText::updPageCnt, wgtAttr, [this, fdPageCnt, fdPageIdx, fdPageDur, fdDur] { + connect(this, &EText::updPageCnt, wgtAttr, [=] { fdPageCnt->setText(QString::number(mImgs.size())); fdPageIdx->setRange(1, mImgs.size()); fdPageIdx->setValue(1); - fdDur->setTime(QTime::fromMSecsSinceStartOfDay(fdPageDur->time().msecsSinceStartOfDay() * mImgs.size())); }); return wgtAttr; } @@ -663,41 +556,31 @@ bool EText::save(const QString &pageDir) { JObj EText::attrJson() const { JArray files; for(int i=0; isave(); auto rect = innerRect(); - if(m_attr.playMode!=EText::Flip) curIdx = 0; + if(playMode!="Flip") curIdx = 0; else if(curIdx>=mImgs.size()) curIdx = mImgs.size() - 1; else if(curIdx < 0) curIdx = 0; - if(m_attr.playMode==EText::Scroll) painter->drawImage(rect.x(), rect.y(), mImgs[0], 0, 0, rect.width(), rect.height()); + if(playMode=="Scroll") painter->drawImage(rect.x(), rect.y(), mImgs[0], 0, 0, rect.width(), rect.height()); else painter->drawImage(rect.x(), rect.y(), mImgs[curIdx]); painter->restore(); EBase::paint(painter, option, widget); @@ -716,25 +599,25 @@ void EText::updImg() { if(! gTextAntialiasing) font.setStyleStrategy(QFont::NoAntialias); doc.setDefaultFont(font); doc.setDefaultStyleSheet("body {color: #fff;}"); - doc.setHtml(m_attr.text); - if(m_attr.playMode==EText::Flip) { + if(playMode=="Flip") { + doc.setHtml(text); doc.setPageSize(innerRect.size()); auto pageHeight = height; auto pageCnt = doc.pageCount(); QImage img(width, pageHeight*pageCnt, QImage::Format_ARGB32); - img.fill(m_attr.backColor); + img.fill(backColor); { QPainter painter(&img); doc.drawContents(&painter); } if(pageCnt > 1) { check: - for(int y=pageHeight-1; y 1) { - for(int y=img.height()-pageHeight; y", "").replace("
", " ")); + width = ceil(doc.idealWidth()) + headTailSpacing; + } else { doc.setTextWidth(width); - height = doc.size().height() + m_attr.scroll.headTailSpacing; + doc.setHtml(text); + height = doc.size().height() + headTailSpacing; } QImage img(width, height, QImage::Format_ARGB32); - img.fill(m_attr.backColor); + img.fill(backColor); { QPainter painter(&img); doc.drawContents(&painter); } - if(m_attr.scroll.effect==0||m_attr.scroll.effect==2) alignV(img); + if(direction=="left" || direction=="right") { + alignV(img); + if(width < innerRect.width()) { + auto newWidth = width*2; + while(newWidthss; ee--) for(int i=0; iss; ee--) for(int i=0; i=0; ee--) for(int i=0; i=0; ee--) for(int i=0; i mImgs; int curIdx{0}; }; diff --git a/LedOK/program/etimer.cpp b/LedOK/program/etimer.cpp index 27c82c9..0d2287e 100644 --- a/LedOK/program/etimer.cpp +++ b/LedOK/program/etimer.cpp @@ -28,7 +28,6 @@ ETimer::ETimer(EBase *multiWin) : EBase(multiWin) { attr.font = qfont("Arial", 12); attr.textColor = Qt::red; attr.backColor = Qt::transparent; - attr.duration = 10; init(); } @@ -48,7 +47,6 @@ ETimer::ETimer(const JObj &json, EBase *multiWin) : EBase(multiWin){ attr.textColor = json["textColor"].toString(); auto color = json["backColor"].toString(); attr.backColor = color.isEmpty() ? QColor(0,0,0,0) : color; - attr.duration = json["duration"].toInt(); init(); } @@ -292,35 +290,8 @@ QWidget* ETimer::attrWgt() { update(); }); hBox->addWidget(fdBackColor); - vBox->addLayout(hBox); - hBox = new QHBoxLayout(); - hBox->addWidget(new QLabel(tr("Play Properties"))); - - line = new QFrame(); - line->setFrameShape(QFrame::HLine); - line->setFrameShadow(QFrame::Sunken); - hBox->addWidget(line, 1); - - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Play Duration"))); - - auto fdDuration = new QSpinBox(); - fdDuration->setRange(1, 99999); - fdDuration->setValue(attr.duration); - connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - attr.duration = value; - }); - hBox->addWidget(fdDuration); - - hBox->addWidget(new QLabel(tr("s"))); - hBox->addStretch(); - - vBox->addLayout(hBox); vBox->addStretch(); return wgtAttr; } @@ -344,6 +315,5 @@ JObj ETimer::attrJson() const { obj["fontUnderline"] = attr.font.underline(); obj["textColor"] = attr.textColor.name(); obj["backColor"] = attr.backColor.alpha()==0 ? "" : attr.backColor.name(); - obj["duration"] = attr.duration; return obj; } diff --git a/LedOK/program/etimer.h b/LedOK/program/etimer.h index f705583..ba435c1 100644 --- a/LedOK/program/etimer.h +++ b/LedOK/program/etimer.h @@ -16,13 +16,12 @@ public: QString text; QColor textColor; QColor backColor; - int duration = 10; - bool isDown; - bool isMultiline; - bool hasDay; - bool hasHour; - bool hasMin; - bool hasSec; + bool isDown; + bool isMultiline; + bool hasDay; + bool hasHour; + bool hasMin; + bool hasSec; }; explicit ETimer(EBase *multiWin = nullptr); diff --git a/LedOK/program/evideo.cpp b/LedOK/program/evideo.cpp index f498486..7b7e9bf 100644 --- a/LedOK/program/evideo.cpp +++ b/LedOK/program/evideo.cpp @@ -2,9 +2,7 @@ #include "cfg.h" #include "tools.h" #include "globaldefine.h" -#include "gutil/qwaitingdlg.h" #include "base/ffutil.h" -#include "videosplitthread.h" #include #include #include @@ -17,7 +15,7 @@ EVideo *EVideo::create(const QString &file, PageListItem *pageItem, EBase *multi int64_t dur; AVCodecID codecId; QImage img; - QString err = videoInfo(file.toUtf8(), img, &dur, &codecId); + auto err = videoInfo(file.toUtf8(), img, &dur, &codecId); if(! err.isEmpty()) { QMessageBox::critical(pageItem->listWidget(), "Video Error", err+"\n"+file); return 0; @@ -28,10 +26,13 @@ EVideo *EVideo::create(const QString &file, PageListItem *pageItem, EBase *multi if(outFile.isEmpty()) return 0; QFileInfo outInfo(outFile); if(! outInfo.isFile() || outInfo.size()==0) return 0; - return new EVideo(outInfo.absolutePath(), outInfo.fileName(), rawInfo.absolutePath(), rawName, img, dur/1000000, pageItem, multiWin); + auto ins = new EVideo(outInfo.absolutePath(), outInfo.fileName(), rawInfo.absolutePath(), rawName, img, pageItem, multiWin); + ins->mDuration = round(dur*0.000001); + return ins; } -EVideo *EVideo::create(const JObj &json, PageListItem *pageItem, EBase *multiWin) { - auto widget = json["widget"]; +EVideo *EVideo::create(const JObj &ele, PageListItem *pageItem, EBase *multiWin) { + auto widget = ele["widget"]; + if(widget.isNull()) widget = ele; auto dir = widget["path"].toString(); auto name = widget["file"].toString(); if(! QFileInfo::exists(dir)) dir = pageItem->mPageDir; @@ -41,21 +42,22 @@ EVideo *EVideo::create(const JObj &json, PageListItem *pageItem, EBase *multiWin else return 0; int64_t dur; QImage img; - QString err = videoInfo(file.toUtf8(), img, &dur, 0); + auto err = videoInfo(file.toUtf8(), img, &dur, 0); if(! err.isEmpty()) return 0; - auto ins = new EVideo(dir, name, widget["pathRaw"].toString(), widget["fileRaw"].toString(), img, dur/1000000, pageItem, multiWin); - ins->setBaseAttr(json); - auto play = json["play"]; - ins->playDuration = play["playDuration"].toInt(); - ins->playTimes = play["playTimes"].toInt(); - if(ins->playDuration < 4) ins->playDuration = dur/1000000; + dur = round(dur*0.000001); + auto ins = new EVideo(dir, name, widget["pathRaw"].toString(), widget["fileRaw"].toString(), img, pageItem, multiWin); + ins->setBaseAttr(ele); + if(ins->mDuration < 4) ins->mDuration = dur; + auto play = ele["play"]; + ins->playTimes = (play.isNull() ? ele : play)["playTimes"].toInt(1); return ins; } -JObj EVideo::genProg(const JObj &ele, const QString &dstDir, ProgItem *progItem) { +JObj EVideo::genProg(const JValue &ele, const QString &dstDir, ProgItem *progItem) { auto widget = ele["widget"]; + if(widget.isNull()) widget = ele; auto path = widget["path"].toString(); auto name = widget["file"].toString(); - if(progItem->mMaxWidth) name += "-square.mp4"; + //if(progItem->maxLen) name += "-square.mp4"; QString srcFile = path + "/" + name; QFileInfo srcInfo(srcFile); if(! srcInfo.isFile()) return JObj(); @@ -67,22 +69,13 @@ JObj EVideo::genProg(const JObj &ele, const QString &dstDir, ProgItem *progItem) oRes["id"] = id; oRes["md5"] = id; oRes["name"] = name; - oRes["size"] = srcInfo.size(); - QString suffix = srcInfo.suffix().toLower(); - oRes["fileExt"] = suffix; - oRes["mime"] = "video/"+suffix; auto play = ele["play"]; - oRes["timeSpan"] = play["playDuration"].toInt() * play["playTimes"].toInt(); - oRes["enabled"] = true; - oRes["entryEffect"] = "None"; - oRes["exitEffect"] = "None"; - oRes["entryEffectTimeSpan"] = 0; - oRes["exitEffectTimeSpan"] = 0; + oRes["timeSpan"] = play.isNull() ? ele["duration"].toInt() * ele["playTimes"].toInt() : play["playDuration"].toInt() * play["playTimes"].toInt(); return oRes; } -EVideo::EVideo(const QString &dir, const QString &name, const QString &rawDir, const QString &rawName, QImage &coverImg, int dur, PageListItem *pageItem, EBase *multiWin) - : EBase(multiWin), mDir(dir), mName(name), mRawDir(rawDir), mRawName(rawName), mCoverImg(coverImg), playDuration(dur), mPageItem(pageItem) { +EVideo::EVideo(const QString &dir, const QString &name, const QString &rawDir, const QString &rawName, QImage &coverImg, PageListItem *pageItem, EBase *multiWin) + : EBase(multiWin), mDir(dir), mName(name), mRawDir(rawDir), mRawName(rawName), mCoverImg(coverImg), mPageItem(pageItem) { mType = EBase::Video; } @@ -131,6 +124,31 @@ QWidget* EVideo::attrWgt() { auto bnSelectFile = new QPushButton("..."); bnSelectFile->setFixedWidth(30); bnSelectFile->setObjectName("bnSelectFile"); + connect(bnSelectFile, &QPushButton::clicked, this, [=] { + auto rawFile = QFileDialog::getOpenFileName(wgtAttr, tr("Select File"), gFileHome, EVideo::filters()); + if(rawFile.isEmpty()) return; + QFileInfo rawInfo(rawFile); + int64_t dur; + AVCodecID codecId; + auto err = videoInfo(rawFile.toUtf8(), mCoverImg, &dur, &codecId); + if(! err.isEmpty()) { + QMessageBox::critical(wgtAttr, "Video Error", err+"\n"+rawFile); + return; + }; + mRawDir = rawInfo.absolutePath(); + mRawName = rawInfo.fileName(); + gFileHome = mRawDir; + fdFileName->setText(mRawName); + mDuration = round(dur*0.000001); + fdDuration->setValue(mDuration); + auto outFile = transcoding(wgtAttr, rawFile, mRawName, mPageItem->mPageDir, mCoverImg.width(), mCoverImg.height(), codecId); + if(outFile.isEmpty()) return; + QFile oldfile(mDir+"/"+mName); + if(oldfile.exists()) oldfile.remove(); + QFileInfo outInfo(outFile); + mDir = outInfo.absolutePath(); + mName = outInfo.fileName(); + }); hBox->addWidget(bnSelectFile); vBox->addLayout(hBox); @@ -162,48 +180,6 @@ QWidget* EVideo::attrWgt() { vBox->addLayout(hBox); - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Play Duration"))); - - auto fdDuration = new QSpinBox(); - fdDuration->setRange(1, 99999); - fdDuration->setValue(playDuration); - connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - playDuration = value; - }); - connect(bnSelectFile, &QPushButton::clicked, this, [=] { - auto rawFile = QFileDialog::getOpenFileName(wgtAttr, tr("Select File"), gFileHome, EVideo::filters()); - if(rawFile.isEmpty()) return; - QFileInfo rawInfo(rawFile); - int64_t dur; - AVCodecID codecId; - QString err = videoInfo(rawFile.toUtf8(), mCoverImg, &dur, &codecId); - if(! err.isEmpty()) { - QMessageBox::critical(wgtAttr, "Video Error", err+"\n"+rawFile); - return; - }; - mRawDir = rawInfo.absolutePath(); - mRawName = rawInfo.fileName(); - gFileHome = mRawDir; - fdFileName->setText(mRawName); - playDuration = dur/1000000; - fdDuration->setValue(playDuration); - auto outFile = transcoding(wgtAttr, rawFile, mRawName, mPageItem->mPageDir, mCoverImg.width(), mCoverImg.height(), codecId); - if(outFile.isEmpty()) return; - QFile oldfile(mDir+"/"+mName); - if(oldfile.exists()) oldfile.remove(); - QFileInfo outInfo(outFile); - mDir = outInfo.absolutePath(); - mName = outInfo.fileName(); - }); - hBox->addWidget(fdDuration); - - hBox->addWidget(new QLabel(tr("s"))); - hBox->addStretch(); - - vBox->addLayout(hBox); - hBox = new QHBoxLayout(); hBox->addSpacing(6); hBox->addWidget(new QLabel(tr("Play Times"))); @@ -231,45 +207,41 @@ bool EVideo::save(const QString &pageDir) { else return false; QFile(oldFile).copy(saveFile); mDir = pageDir; - if(gProgItem->mMaxWidth) { - auto waitingDlg = new WaitingDlg(mPageItem->listWidget()->window(), "正在转码视频 ..."); - auto thread = new VideoSplitThread(mWidth, mHeight, gProgItem->mMaxWidth, gProgItem->mHeight, gProgItem->mSplitWidths, pos(), saveFile.toUtf8()); - connect(thread, &VideoSplitThread::emErr, this, [=](QString err) { - waitingDlg->close(); - if(! err.isEmpty()) QMessageBox::critical(mPageItem->listWidget()->window(), "Video trans error", err+"\n"+saveFile); - }); - connect(thread, &VideoSplitThread::emProgress, this, [saveFile, waitingDlg](int progress) { - waitingDlg->fdText->setText(QString("正在转码视频 %1%").arg(progress)); - }); - thread->start(); - waitingDlg->exec(); - } + // if(gProgItem->maxLen) { + // auto waitingDlg = new WaitingDlg(mPageItem->listWidget()->window(), "正在转码视频 ..."); + // auto thread = new VideoSplitThread(mWidth, mHeight, gProgItem->maxLen, gProgItem->isVer ? gProgItem->mWidth : gProgItem->mHeight, gProgItem->partLens, gProgItem->isVer, pos(), saveFile.toUtf8()); + // connect(thread, &VideoSplitThread::emErr, this, [=](QString err) { + // waitingDlg->close(); + // if(! err.isEmpty()) QMessageBox::critical(mPageItem->listWidget()->window(), "Video trans error", err+"\n"+saveFile); + // }); + // connect(thread, &VideoSplitThread::emProgress, this, [saveFile, waitingDlg](int progress) { + // waitingDlg->fdText->setText(QString("正在转码视频 %1%").arg(progress)); + // }); + // thread->start(); + // waitingDlg->exec(); + // } return true; } JObj EVideo::attrJson() const { - JObj oRoot; - addBaseAttr(oRoot); - oRoot["elementType"] = "Movie"; - oRoot["widget"] = JObj{ + JObj obj{ + {"elementType", "Video"}, {"path", mDir}, {"file", mName}, {"pathRaw", mRawDir}, - {"fileRaw", mRawName} - }; - oRoot["play"] = JObj{ - {"playDuration", playDuration}, + {"fileRaw", mRawName}, {"playTimes", playTimes} }; - return oRoot; + addBaseAttr(obj); + return obj; } QString EVideo::transcoding(QWidget *parent, QString rawFile, QString rawName, QString dir, int w, int h, AVCodecID codec_id) { - if(gProgItem->mMaxWidth) { - auto outFile = dir+"/"+rawName; - QFile::copy(rawFile, outFile); - return outFile; - } + // if(gProgItem->maxLen) { + // auto outFile = dir+"/"+rawName; + // QFile::copy(rawFile, outFile); + // return outFile; + // } QSettings settings; int rawMax = qMax(w, h); if(settings.value("VideoCompress", true).toBool() && rawMax > 1360 && (w > gProgItem->mWidth || h > gProgItem->mHeight)) { diff --git a/LedOK/program/evideo.h b/LedOK/program/evideo.h index a25cbb5..d1fbf42 100644 --- a/LedOK/program/evideo.h +++ b/LedOK/program/evideo.h @@ -21,9 +21,9 @@ 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 JObj &, PageListItem *pageItem, EBase *multiWin = nullptr); - static JObj genProg(const JObj &, const QString &, ProgItem *mProgItem); + static JObj genProg(const JValue &, const QString &, ProgItem *mProgItem); - explicit EVideo(const QString &, const QString &, const QString &, const QString &, QImage &img, int dur, PageListItem *pageItem, EBase *multiWin = nullptr); + explicit EVideo(const QString &, const QString &, const QString &, const QString &, QImage &img, PageListItem *pageItem, EBase *multiWin = nullptr); int type() const override { return EBase::Video; } void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override; @@ -38,7 +38,6 @@ public: QImage mCoverImg; protected: int aspectRatioMode = Qt::IgnoreAspectRatio; - int playDuration = 10; int playTimes = 1; PageListItem *mPageItem; }; diff --git a/LedOK/program/eweb.cpp b/LedOK/program/eweb.cpp index eeb6b08..93201af 100644 --- a/LedOK/program/eweb.cpp +++ b/LedOK/program/eweb.cpp @@ -7,13 +7,11 @@ EWeb::EWeb(EBase *multiWin) : EBase(multiWin) { mType = EBase::Web; - duration = 10; } EWeb::EWeb(const JObj &json, EBase *multiWin) : EBase(multiWin) { mType = EBase::Web; setBaseAttr(json); url = json["url"].toString(); - duration = json["duration"].toInt(10); } void EWeb::paint(QPainter *painter, const QStyleOptionGraphicsItem *a, QWidget *b) { @@ -56,23 +54,6 @@ QWidget* EWeb::attrWgt() { connect(url_fd, &QLineEdit::textChanged, this, [this](const QString &text) { url = text; }); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); - hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Play Duration")+": ")); - - auto dur_fd = new QSpinBox(); - dur_fd->setRange(1, 99999); - dur_fd->setValue(duration); - connect(dur_fd, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - duration = value; - }); - hBox->addWidget(dur_fd); - - hBox->addWidget(new QLabel(tr("s"))); - hBox->addStretch(); - vBox->addLayout(hBox); vBox->addStretch(); return wgtAttr; @@ -83,6 +64,5 @@ JObj EWeb::attrJson() const { addBaseAttr(oRoot); oRoot["elementType"] = "Web"; oRoot["url"] = url; - oRoot["duration"] = duration; return oRoot; } diff --git a/LedOK/program/eweb.h b/LedOK/program/eweb.h index c104733..c7b635f 100644 --- a/LedOK/program/eweb.h +++ b/LedOK/program/eweb.h @@ -21,7 +21,6 @@ public: JObj attrJson() const override; QString url; - int duration = 10; }; #endif // EWEB_H diff --git a/LedOK/program/gentmpthread.cpp b/LedOK/program/gentmpthread.cpp index d210f49..5462b38 100644 --- a/LedOK/program/gentmpthread.cpp +++ b/LedOK/program/gentmpthread.cpp @@ -62,19 +62,18 @@ void GenTmpThread::run() { return a["order"].toInt() < b["order"].toInt(); }); JArray items; - for(auto pageJson : pageJsons) { + for(auto &pageJson : pageJsons) { srcPageDir = srcDir + "/" + pageJson["name"].toString(); - items.append(cvtPage(pageJson, proJson)); + items.append(cvtPage(pageJson)); } 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"] = JObj{ - {"_id", QUuid::createUuid().toString(QUuid::WithoutBraces)}, {"name", prog_name}, - {"cmdId", QUuid::createUuid().toString(QUuid::WithoutBraces)}, + {"width", proJson["resolution"]["w"]}, + {"height", proJson["resolution"]["h"]}, + {"partLengths", proJson["splitWidths"]}, + {"isVertical", proJson["isVer"]}, {"items", items} }; QFile program(dstDir + "/program"); @@ -102,7 +101,7 @@ void GenTmpThread::run() { } //此处需要把幻灯片中的元素按层顺序排序,再放入layers中,每个元素对一个layer。ewindow中的多个顺序元素为一个层上的时间轴上的素材 -JObj GenTmpThread::cvtPage(const JObj &pageJson, const JObj &proJson) { +JObj GenTmpThread::cvtPage(const JObj &pageJson) { auto audios = pageJson("audios").toArray(); auto sourceRepeat = pageJson["loop"].toBool(); JArray sources; @@ -112,23 +111,19 @@ JObj GenTmpThread::cvtPage(const JObj &pageJson, const JObj &proJson) { if(dur==0) continue; auto name = audio["name"].toString(); if(name.isEmpty()) continue; - QString file = audio["dir"].toString()+"/"+name; + auto file = audio["dir"].toString()+"/"+name; QFileInfo srcInfo(file); if(! srcInfo.isFile()) continue; - QString id = Tools::fileMd5(file); + 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["name"] = name; - source["size"] = srcInfo.size(); - source["fileExt"] = srcInfo.suffix().toLower(); source["timeSpan"] = dur; source["playTime"] = start; source["vol"] = audio["vol"].toInt(); - source["enabled"] = true; source["left"] = -1; source["top"] = -1; source["width"] = 1; @@ -140,54 +135,16 @@ JObj GenTmpThread::cvtPage(const JObj &pageJson, const JObj &proJson) { if(! sources.empty()) layers.append(JObj{{"repeat", sourceRepeat}, {"sources", sources}}); auto elements = pageJson["elements"].toArray(); - for(auto &ele : elements) { + for(const auto &ele : elements) { auto type = ele["elementType"].toString(); auto geometry = ele["geometry"]; - JArray sources; - if(type=="Window") { - auto elements = ele["elements"].toArray(); - auto left = geometry["x"]; - auto top = geometry["y"]; - auto width = geometry["w"]; - auto height = geometry["h"]; - QList eles; - for(auto &value : elements) eles.append(value.toObj()); - int playTime = 0; - 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; - source["height"] = height; - source["playTime"] = playTime; - playTime += source["timeSpan"].toInt(); - sources.append(source); - } - } else { - auto source = cvtEle(type, ele.toObj()); - if(! source.empty()) { - if(mProgItem->mMaxWidth && (type=="Photo" || type=="Movie")) { - source["left"] = 0; - source["top"] = 0; - source["width"] = mProgItem->mMaxWidth; - source["height"] = mProgItem->mHeight * mProgItem->mSplitWidths.size(); - } else { - source["left"] = geometry["x"]; - source["top"] = geometry["y"]; - source["width"] = geometry["w"]; - source["height"] = geometry["h"]; - } - source["playTime"] = 0; - sources.append(source); - } - } + 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()) { - QString bdSrc = "borders/"+border; - QString id = Tools::fileMd5(bdSrc); + auto bdSrc = "borders/"+border; + auto id = Tools::fileMd5(bdSrc); QFile::copy(bdSrc, dstDir+"/"+id); auto borderSize = ele["borderSize"]; if(borderSize.isNull()){ @@ -217,7 +174,6 @@ JObj GenTmpThread::cvtPage(const JObj &pageJson, const JObj &proJson) { schedule["endDate"] = validDate["end"]; schedule["timeType"] = "All"; schedule["filterType"] = "None"; - schedule["monthFilter"] = JArray(); schedule["weekFilter"] = JArray(); schedules.append(schedule); } @@ -235,147 +191,164 @@ JObj GenTmpThread::cvtPage(const JObj &pageJson, const JObj &proJson) { auto weekly = plan["weekly"]; schedule["weekFilter"] = weekly; schedule["filterType"] = weekly.toArray().empty() ? "None" : "Week"; - schedule["monthFilter"] = JArray(); schedules.append(schedule); } } return JObj{ - {"_id", QUuid::createUuid().toString(QUuid::WithoutBraces)}, - {"priority", 0}, - {"version", 0}, + {"repeatTimes", pageJson["repeat"]}, {"schedules", schedules}, {"_program", JObj{ - {"_id", QUuid::createUuid().toString(QUuid::WithoutBraces)}, - {"totalSize", 0}, {"name", pageJson["name"].toString()}, - {"width", proJson["resolution"]["w"]}, - {"height", proJson["resolution"]["h"]}, - {"splitWidths", proJson["splitWidths"]}, - {"_company", "alahover"}, - {"_department", "alahover"}, - {"_role", "alahover"}, - {"_user", "alahover"}, - {"__v", 0}, - {"dateCreated", pageJson["last_edit"]}, {"layers", layers} - }}, - {"repeatTimes", pageJson["repeat"]} + }} }; } -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); - else if(type=="Gif") return convertGif(ele); - else if(type=="DClock") return convertDClock(ele); - else if(type=="AClock") return convertAClock(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 JObj(); +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::convertText(const JObj &json) { - EText::Data attr; - EText::setElement(json, attr); - JObj source; - auto type = mProgItem->mMaxWidth ? "SplitText" : "MultiPng"; - source["_type"] = type; - source["name"] = type; - source["id"] = res_id++; - auto widget = json["widget"]; - - 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 * (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"; - source["timeSpan"] = attr.scroll.duration; - } else if(attr.playMode==EText::Static) { - source["playMode"] = "Static"; - source["timeSpan"] = attr.duration; +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); } - JArray arrayPics; + auto filenames = widget["files"]; 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; - JObj arrayPic; - auto id = Tools::fileMd5(srcFile); - srcQFile.copy(dstDir+"/"+id); - arrayPic["id"] = id; - arrayPic["mime"] = "image/png"; - if(attr.playMode==EText::Flip) { - arrayPic["effect"] = attr.flip.effect; - arrayPic["effectSpeed"] = attr.flip.effectDuration; - arrayPic["picDuration"] = attr.flip.pageDuration; - } else if(attr.playMode==EText::Scroll) { - if(attr.scroll.effect==0) arrayPic["effect"] = "right to left"; - else if(attr.scroll.effect==1) arrayPic["effect"] = "bottom to top"; - else if(attr.scroll.effect==2) arrayPic["effect"] = "left to right"; - else if(attr.scroll.effect==3) arrayPic["effect"] = "top to bottom"; - arrayPic["effectSpeed"] = attr.scroll.effectSpeed; + + 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; - } else if(attr.playMode==EText::Static) { - arrayPic["effect"] = "no"; - arrayPic["effectSpeed"] = 0; - arrayPic["picDuration"] = attr.duration; + arrayPics.append(arrayPic); } - 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(); } - source["arrayPics"] = arrayPics; - return source; } //转换图片 -JObj GenTmpThread::convertPhoto(const JObj &ele){ +JObj GenTmpThread::genImage(const JValue &ele) { auto widget = ele["widget"]; - auto name = widget["file"].toString(); - QString srcFile = widget["path"].toString() + "/" + name; + 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 x = geometry["x"].toInt(); - auto y = geometry["y"].toInt(); auto width = geometry["w"].toInt(); auto height = geometry["h"].toInt(); - if(mProgItem->mMaxWidth) { + /*if(mProgItem->maxLen) { auto scaled = img.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); - QImage square(gProgItem->mMaxWidth, gProgItem->mHeight*gProgItem->mSplitWidths.size(), QImage::Format_ARGB32); + 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); - painter.drawImage(pos, scaled, QRectF(0, 0, gProgItem->mSplitWidths[0]-pos.x(), height)); - auto end = gProgItem->mSplitWidths.size(); - for(int i=1; imSplitWidths[i-1]; - pos.ry() += gProgItem->mHeight; - painter.drawImage(pos, scaled, QRectF(0, 0, gProgItem->mSplitWidths[i]-pos.x(), height)); + 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; ipartLens[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; ipartLens[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"); @@ -388,11 +361,7 @@ JObj GenTmpThread::convertPhoto(const JObj &ele){ file.close(); source["id"] = md5; source["md5"] = md5; - source["size"] = buf.size(); - source["name"] = srcInfo.baseName()+".png"; - source["fileExt"] = "png"; - source["mime"] = "image/png"; - } else if(img.width() > width*2 && img.height() > height*2) { + } 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); @@ -404,39 +373,20 @@ JObj GenTmpThread::convertPhoto(const JObj &ele){ file.close(); source["id"] = md5; source["md5"] = md5; - source["size"] = buf.size(); - source["name"] = srcInfo.baseName()+".png"; - source["fileExt"] = "png"; - source["mime"] = "image/png"; } else { auto md5 = Tools::fileMd5(srcFile); if(md5.isEmpty()) return source; QFile::copy(srcFile, dstDir+"/"+md5); source["id"] = md5; source["md5"] = md5; - source["size"] = srcInfo.size(); - source["name"] = name; - QString sufLower = srcInfo.suffix().toLower(); - source["fileExt"] = sufLower; - source["mime"] = "image/"+(sufLower=="jpg" ? "jpeg" : sufLower); } source["_type"] = "Image"; auto play = ele["play"]; - source["timeSpan"] = play["playDuration"]; - source["enabled"] = true; - source["enabledBy"] = ""; - source["oldFilePath"] = ""; - static const int effSize = 13; - static const int effs[effSize] = {0,1,3,4,5,6,7,9,10,11,12,17,18}; - int enterStyle = play["enterStyle"].toInt(); - source["entryEffect"] = enterStyle < effSize ? effs[enterStyle] : 0; - source["exitEffect"] = 0; - source["entryEffectTimeSpan"] = play["enterDuration"]; - source["exitEffectTimeSpan"] = 0; + source["timeSpan"] = play.isNull() ? ele["duration"] : play["playDuration"]; return source; } //转换图片 -JObj GenTmpThread::convertGif(const JObj &json) { +JObj GenTmpThread::convertGif(const JValue &json) { auto widget = json["widget"]; auto path = widget["path"].toString(); auto name = widget["file"].toString(); @@ -450,26 +400,15 @@ JObj GenTmpThread::convertGif(const JObj &json) { oRes["_type"] = "Image"; oRes["id"] = id; oRes["md5"] = id; - oRes["name"] = name; - oRes["size"] = srcInfo.size(); - QString suffix = srcInfo.suffix().toLower(); - oRes["fileExt"] = suffix; - oRes["mime"] = "image/gif"; + oRes["fileExt"] = srcInfo.suffix().toLower(); auto play = json["play"]; - oRes["timeSpan"] = play["playDuration"].toInt() * play["playTimes"].toInt(); - oRes["enabled"] = true; - oRes["entryEffect"] = "None"; - oRes["exitEffect"] = "None"; - oRes["entryEffectTimeSpan"] = 0; - oRes["exitEffectTimeSpan"] = 0; + oRes["timeSpan"] = (play.isNull() ? json["duration"] : play["playDuration"]).toInt() * play["playTimes"].toInt(1); return oRes; } -JObj GenTmpThread::convertDClock(const JObj &json){ +JObj GenTmpThread::convertDClock(const JValue &json){ JObj oRes; oRes["_type"] = "DigitalClockNew"; oRes["name"] = "DigitalClockNew"; - oRes["id"] = ""; - oRes["timeSpan"] = json["play"]["duration"]; auto widget = json["widget"]; oRes["timeZone"] = widget["timeZone"]; oRes["timezone"] = 8;//兼容旧播放器 @@ -486,11 +425,6 @@ JObj GenTmpThread::convertDClock(const JObj &json){ oRes["dateStyle"] = widget["dateStyle"]; oRes["timeStyle"] = widget["timeStyle"]; oRes["multiline"] = widget["multiline"]; - oRes["fontSize"] = widget["font"]["size"]; - oRes["entryEffect"] = "None"; - oRes["exitEffect"] = "None"; - oRes["entryEffectTimeSpan"] = 0; - oRes["exitEffectTimeSpan"] = 0; auto fontVal = widget["font"]; auto textColor = Tools::int2Color(fontVal["color"].toInt()); @@ -501,12 +435,11 @@ JObj GenTmpThread::convertDClock(const JObj &json){ font.setUnderline(fontVal["underline"].toBool()); font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias); - QFontMetricsF metricF(font); - oRes["spaceWidth"] = metricF.horizontalAdvance(" "); 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); + 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"); @@ -522,12 +455,12 @@ JObj GenTmpThread::convertDClock(const JObj &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"] = (int)imgs.size(); oRes["arrayPics"] = imgs; return oRes; } -JObj GenTmpThread::convertAClock(const JObj &json) { +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(); @@ -537,9 +470,6 @@ JObj GenTmpThread::convertAClock(const JObj &json) { oRes["_type"] = "AnalogClock"; oRes["id"] = id; oRes["md5"] = id; - oRes["mime"] = "image/png"; - oRes["name"] = "001"; - oRes["timeSpan"] = json["play"]["duration"]; oRes["shade"] = 0;//表盘形状 oRes["opacity"] = 1;//透明度 oRes["showBg"] = false;//是否显示背景色 @@ -567,35 +497,28 @@ JObj GenTmpThread::convertAClock(const JObj &json) { oRes["pinStyle"] = 1; oRes["showSecond"] = widget["showSecHand"]; oRes["timeZone"] = widget["timeZone"]; - //下同Video - oRes["entryEffect"] = "None"; - oRes["exitEffect"] = "None"; - oRes["entryEffectTimeSpan"] = 0; - oRes["exitEffectTimeSpan"] = 0 ; return oRes; } -JObj GenTmpThread::convertWeb(const JObj &res) { +JObj GenTmpThread::convertWeb(const JValue &res) { JObj dst; dst["_type"] = "WebURL"; - dst["id"] = ""; dst["name"] = "WebURL"; dst["url"] = res["url"]; - dst["timeSpan"] = res["duration"]; return dst; } -JObj GenTmpThread::convertTimer(const JObj &json) { +JObj GenTmpThread::convertTimer(const JValue &json) { JObj oRes; oRes["_type"] = "Timer"; oRes["name"] = "Timer"; - oRes["id"] = ""; oRes["targetTime"] = json["targetTime"]; oRes["isDown"] = json["isDown"]; oRes["hasDay"] = json["hasDay"]; oRes["hasHour"] = json["hasHour"]; oRes["hasMin"] = json["hasMin"]; oRes["hasSec"] = json["hasSec"]; - oRes["isMultiline"] = json["isMultiline"]; + auto isMultiline = json["isMultiline"].toBool(); + oRes["isMultiline"] = isMultiline; auto text = json["text"].toString(); oRes["text"] = text; QFont font(json["font"].toString()); @@ -611,23 +534,25 @@ JObj GenTmpThread::convertTimer(const JObj &json) { auto textColor = json["textColor"].toString(); oRes["textColor"] = textColor; oRes["backColor"] = json["backColor"]; - oRes["timeSpan"] = json["duration"]; font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias); - QFontMetricsF metricF(font); - oRes["spaceWidth"] = metricF.horizontalAdvance(" "); 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); + 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()) { - auto innerW = json["innerW"].toInt(); - auto innerH = json["innerH"].toInt(); - auto rect = metric.boundingRect(0, 0, innerW, innerH, Qt::AlignCenter | Qt::TextWordWrap, text); - QImage img(qMin(rect.width(), innerW), qMin(rect.height(), innerH), QImage::Format_ARGB32); + 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); diff --git a/LedOK/program/gentmpthread.h b/LedOK/program/gentmpthread.h index 5676bfe..9c36f37 100644 --- a/LedOK/program/gentmpthread.h +++ b/LedOK/program/gentmpthread.h @@ -14,15 +14,15 @@ public: protected: virtual void run() override; - 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); + JObj cvtPage(const JObj &); + JArray genSources(QString type, const JArray &eles, const JValue &); + JObj genText(const JValue &json, JArray &); + JObj genImage(const JValue &json); + JObj convertGif(const JValue &json); + JObj convertDClock(const JValue &json); + JObj convertAClock(const JValue &json); + JObj convertWeb(const JValue &json); + JObj convertTimer(const JValue &json); signals: void onErr(QString); private: diff --git a/LedOK/program/pagelistitem.cpp b/LedOK/program/pagelistitem.cpp index 8b1f1aa..dd30694 100644 --- a/LedOK/program/pagelistitem.cpp +++ b/LedOK/program/pagelistitem.cpp @@ -43,9 +43,9 @@ PageListItem::PageListItem(const JObj &attr, const QString &pageDir) : mAttr(att auto type = ele["elementType"].toStr(); EBase *element = 0; if(type=="Text") element = new EText(ele.toObj()); - else if(type=="Photo") element = EPhoto::create(ele.toObj(), this); + else if(type=="Image"||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=="Video"||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()); @@ -284,7 +284,7 @@ QPushButton[ssName="weeklySelector"]:checked { btnAdd->setIcon(QIcon(":/res/program/Add.png")); btnAdd->setProperty("style","multiTool"); - mAudiosList = new QListWidget(); + mAudiosList = new QListWidget; connect(btnAdd, &QPushButton::clicked, mAttrWgt, [this, fdTtlDur] { auto files = QFileDialog::getOpenFileNames(mAttrWgt, tr("Select File"), gFileHome); int durs = fdTtlDur->text().toInt(); @@ -296,7 +296,7 @@ QPushButton[ssName="weeklySelector"]:checked { continue; } QFileInfo fInfo(files[i]); - AudioInfo info{fInfo.absolutePath(), fInfo.fileName(), (int)(dur/1000000)}; + AudioInfo info{fInfo.absolutePath(), fInfo.fileName(), (int)round(dur*0.000001)}; auto item = new QListWidgetItem(QIcon(":/res/program/Audio.png"), info.name); item->setData(Qt::UserRole, QVariant::fromValue(info)); mAudiosList->addItem(item); diff --git a/LedOK/program/progeditorwin.cpp b/LedOK/program/progeditorwin.cpp index 7b17f12..dfb615b 100644 --- a/LedOK/program/progeditorwin.cpp +++ b/LedOK/program/progeditorwin.cpp @@ -64,8 +64,6 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare // }); // connect(saveThread, SIGNAL(finished()), saveThread, SLOT(deleteLater())); // connect(saveThread, &QThread::finished, this, [this] { -// mProgItem->m_last = QDateTime::currentDateTime(); -// mProgItem->m_fsize = dirFileSize(mProgItem->mProgDir); // mProgItem->onSetProgram(); // }); // saveThread->start(); @@ -81,8 +79,6 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare // connect(saveThread, SIGNAL(finished()), dlgTip, SLOT(unlock()));//显示正在保存提示对话框 // connect(saveThread, SIGNAL(finished()), saveThread, SLOT(deleteLater())); // connect(saveThread, &QThread::finished, this, [this] { -// mProgItem->m_last = QDateTime::currentDateTime(); -// mProgItem->m_fsize = dirFileSize(mProgItem->mProgDir); // mProgItem->onSetProgram(); // }); // saveThread->start(); @@ -90,43 +86,56 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare // close(); // setWindowTitle(progName); // mProgItem->mProgPanel->onCreateNewProgramOnOpenEditProgramWidget(progName, QSize(mProgItem->mWidth, mProgItem->mHeight), mProgItem->mRemark, mProgItem->mSplitWidths, mProgItem->mMaxWidth); +// void ProgPanel::onCreateNewProgramOnOpenEditProgramWidget(QString name, QSize res, QString remarks, QList &partLengths, int max) +// { +// if(checkIfNameRepeated(name)) return; +// auto item = new ProgItem(mProgsDir, name, res.width(), res.height(), remarks, partLengths, max, mProgTree); +// item->save();//保存pro.json +// 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(); +// } // }); // toolBar->addAction(action); action = new QAction(QIcon(":/res/program/Setting.png"), tr("Setting")); connect(action, &QAction::triggered, this, [this] { QString widthsStr; - for(auto &width : mProgItem->mSplitWidths) { + for(auto &width : mProgItem->partLens) { if(! widthsStr.isEmpty()) widthsStr.append(" "); widthsStr.append(QString::number(width)); } - ProgCreateDlg dlg(mProgItem->mName, mProgItem->mWidth, mProgItem->mHeight, mProgItem->mRemark, widthsStr, this); + ProgCreateDlg dlg(mProgItem->mName, mProgItem->mWidth, mProgItem->mHeight, mProgItem->mRemark, widthsStr, mProgItem->isVer, this); if(dlg.exec() != QDialog::Accepted) return; mProgItem->mWidth = dlg.fdWidth->value(); mProgItem->mHeight = dlg.fdHeight->value(); mProgItem->mRemark = dlg.fdRemark->toPlainText(); - mProgItem->mSplitWidths.clear(); - mProgItem->mMaxWidth = 0; + mProgItem->partLens.clear(); + mProgItem->maxLen = 0; + mProgItem->isVer = dlg.fdVer->isChecked(); + auto len = mProgItem->isVer ? mProgItem->mHeight : mProgItem->mWidth; if(dlg.fdIsUltraLong->isChecked()) { - auto splitWidths = dlg.fdSplitWidths->text().split(" ", Qt::SkipEmptyParts); + auto partLengths = dlg.fdSplitWidths->text().split(" ", Qt::SkipEmptyParts); int ttl = 0; - for(auto &splitWidth : splitWidths) { - int val = splitWidth.toInt(); + for(auto &partLength : partLengths) { + int val = partLength.toInt(); if(val==0) continue; - if(mProgItem->mMaxWidth < val) mProgItem->mMaxWidth = val; - mProgItem->mSplitWidths.append(val); + if(mProgItem->maxLen < val) mProgItem->maxLen = val; ttl += val; - if(ttl>=mProgItem->mWidth) break; + mProgItem->partLens.emplace_back(val); + if(ttl>=len) break; } - if(mProgItem->mMaxWidth) { - while(ttl < mProgItem->mWidth) { - mProgItem->mSplitWidths.append(mProgItem->mMaxWidth); - ttl += mProgItem->mMaxWidth; + if(mProgItem->maxLen) { + while(ttl < len) { + mProgItem->partLens.push_back(mProgItem->maxLen); + ttl += mProgItem->maxLen; } - if(ttl > mProgItem->mWidth) mProgItem->mSplitWidths.last() -= ttl - mProgItem->mWidth; + if(ttl > len) mProgItem->partLens.back() -= ttl - len; } } - mProgItem->m_last = QDateTime::currentDateTime(); - mProgItem->m_fsize = dirFileSize(mProgItem->mProgDir); mProgItem->onSetProgram(); for(int i=0; icount(); i++) { auto page = (PageListItem*) listPage->item(i); @@ -147,7 +156,7 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare toolBar->addAction(action); toolBar->addSeparator(); - if(progItem->mSplitWidths.isEmpty()) { + if(progItem->partLens.empty()) { action = new QAction(QIcon(":/res/program/Window.png"), tr("MuliContentWindow")); action->setToolTip(tr("In this window, a plurality of different program materials can be added and played according to the order of joining the list;")); action->setData(EBase::Window); @@ -158,31 +167,29 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare action->setData(EBase::Text); toolBar->addAction(action); action = new QAction(QIcon(":/res/program/Photo.png"), tr("Photo")); - action->setData(EBase::Photo); + action->setData(EBase::Image); toolBar->addAction(action); action = new QAction(QIcon(":/res/program/Movie.png"), tr("Video")); action->setData(EBase::Video); toolBar->addAction(action); - if(progItem->mSplitWidths.isEmpty()) { - action = new QAction(QIcon(":/res/program/Gif.png"), tr("Gif")); - action->setData(EBase::Gif); - toolBar->addAction(action); - action = new QAction(QIcon(":/res/program/DClock.png"), tr("Clock")); - action->setData(EBase::DClock); - toolBar->addAction(action); - action = new QAction(QIcon(":/res/program/AClock.png"), tr("Analog Clock")); - action->setData(EBase::AClock); - toolBar->addAction(action); - action = new QAction(QIcon(":/res/program/Temp.png"), tr("Environment")); - action->setData(EBase::Environ); - toolBar->addAction(action); - action = new QAction(QIcon(":/res/program/Web.png"), tr("Web")); - action->setData(EBase::Web); - toolBar->addAction(action); - action = new QAction(QIcon(":/res/program/Timer.png"), tr("Timer")); - action->setData(EBase::Timer); - toolBar->addAction(action); - } + action = new QAction(QIcon(":/res/program/Gif.png"), tr("Gif")); + action->setData(EBase::Gif); + toolBar->addAction(action); + action = new QAction(QIcon(":/res/program/DClock.png"), tr("Clock")); + action->setData(EBase::DClock); + toolBar->addAction(action); + action = new QAction(QIcon(":/res/program/AClock.png"), tr("Analog Clock")); + action->setData(EBase::AClock); + toolBar->addAction(action); + action = new QAction(QIcon(":/res/program/Temp.png"), tr("Environment")); + action->setData(EBase::Environ); + toolBar->addAction(action); + action = new QAction(QIcon(":/res/program/Web.png"), tr("Web")); + action->setData(EBase::Web); + toolBar->addAction(action); + action = new QAction(QIcon(":/res/program/Timer.png"), tr("Timer")); + action->setData(EBase::Timer); + toolBar->addAction(action); action = new QAction(QIcon(":/res/program/demo-video.png"), tr("Demos")); connect(action, &QAction::triggered, this, [this] { auto file = QFileDialog::getOpenFileName(this, tr("Open Demo"), "Demos"); @@ -238,9 +245,14 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare auto prog = JFrom(value, &jsErr); if(! jsErr.isEmpty()) return; int www = mProgItem->mWidth, hhh = mProgItem->mHeight; - if(mProgItem->mMaxWidth) { - www = mProgItem->mMaxWidth; - hhh *= mProgItem->mSplitWidths.size(); + if(mProgItem->maxLen) { + if(mProgItem->isVer) { + hhh = mProgItem->maxLen; + www *= mProgItem->partLens.size(); + } else { + www = mProgItem->maxLen; + hhh *= mProgItem->partLens.size(); + } } PlayWin::self = PlayWin::newIns(www, hhh, mProgItem->mProgDir+"_tmp", prog); } @@ -276,7 +288,7 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare if(mNewEleX+iNewWidth>mProgItem->mWidth) mNewEleX=0; if(mNewEleY+iNewHeight>mProgItem->mHeight) mNewEleY=0; auto type = data.toInt(); - if(type==EBase::Photo) { + if(type==EBase::Image) { auto files = QFileDialog::getOpenFileNames(this, tr("Select File"), gFileHome, EPhoto::filters()); for(int i=0; im_last = QDateTime::currentDateTime(); - mProgItem->m_fsize = dirFileSize(mProgItem->mProgDir); mProgItem->onSetProgram(); if(isProgChanged()) { auto res = QMessageBox::question(this, tr("Tip Info"), tr("Do you want to save the modifications?"), QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel); @@ -621,8 +631,6 @@ void ProgEditorWin::onSave() { if(save()) waitingDlg->success(); else waitingDlg->close(); waitingDlg->exec(); - mProgItem->m_last = QDateTime::currentDateTime(); - mProgItem->m_fsize = dirFileSize(mProgItem->mProgDir); mProgItem->onSetProgram(); } @@ -647,7 +655,7 @@ void ProgEditorWin::onAddPage() { if(listPage->count()==5) for(int i=0; i<4; i++) ((PageListItem*)listPage->item(i))->fdIdx->setNum(i+1); } -ProgCreateDlg::ProgCreateDlg(QString name, int width, int height, QString remarks, QString widths, QWidget *parent) : QDialog(parent) { +ProgCreateDlg::ProgCreateDlg(QString name, int width, int height, QString remarks, QString widths, bool isVer, QWidget *parent) : QDialog(parent) { #ifdef Q_OS_WIN setWindowFlag(Qt::WindowContextHelpButtonHint, 0); #endif @@ -701,7 +709,7 @@ ProgCreateDlg::ProgCreateDlg(QString name, int width, int height, QString remark hBox->addWidget(label); fdRemark = new QTextEdit(remarks); - fdRemark->setFixedSize(300, 80); + fdRemark->setFixedHeight(80); hBox->addWidget(fdRemark); vBox->addSpacing(6); @@ -710,11 +718,20 @@ ProgCreateDlg::ProgCreateDlg(QString name, int width, int height, QString remark hBox->addSpacing(72); fdIsUltraLong = new QCheckBox(tr("Ultra-Long Screen Split")); - if(! widths.isEmpty()) fdIsUltraLong->setChecked(true); hBox->addWidget(fdIsUltraLong); + fdHor = new QRadioButton(tr("Horizontal")); + hBox->addWidget(fdHor); + + fdVer = new QRadioButton(tr("Vertical")); + hBox->addWidget(fdVer); + hBox->addStretch(); + + if(isVer) fdVer->setChecked(true); + else fdHor->setChecked(true); + hBox = new HBox(vBox); - auto lbSplitWidth = new QLabel(tr("Part Width")); + auto lbSplitWidth = new QLabel(tr("Lengths of Parts")); lbSplitWidth->setMinimumWidth(90); lbSplitWidth->setAlignment(Qt::AlignRight | Qt::AlignVCenter); hBox->addWidget(lbSplitWidth); @@ -722,6 +739,16 @@ ProgCreateDlg::ProgCreateDlg(QString name, int width, int height, QString remark fdSplitWidths = new QLineEdit(widths.isEmpty() ? "1920" : widths); fdSplitWidths->setPlaceholderText("1920"); hBox->addWidget(fdSplitWidths); + + connect(fdIsUltraLong, &QCheckBox::toggled, this, [=](bool checked) { + fdHor->setVisible(checked); + fdVer->setVisible(checked); + lbSplitWidth->setVisible(checked); + fdSplitWidths->setVisible(checked); + }); + if(widths.isEmpty()) fdIsUltraLong->toggled(false); + else fdIsUltraLong->setChecked(true); + if(! gWidthSplit) { fdIsUltraLong->setVisible(false); lbSplitWidth->setVisible(false); diff --git a/LedOK/program/progeditorwin.h b/LedOK/program/progeditorwin.h index 71e43ed..fff4175 100644 --- a/LedOK/program/progeditorwin.h +++ b/LedOK/program/progeditorwin.h @@ -2,6 +2,7 @@ #define PROGEDITORWIN_H #include "program/pageeditor.h" #include +#include #include #include #include @@ -36,12 +37,13 @@ private: class ProgCreateDlg : public QDialog { Q_OBJECT public: - ProgCreateDlg(QString name, int width, int height, QString remarks, QString, QWidget *parent = nullptr); + ProgCreateDlg(QString name, int width, int height, QString remarks, QString, bool isVer, QWidget *parent = nullptr); QLineEdit *fdName; QSpinBox *fdWidth; QSpinBox *fdHeight; QTextEdit *fdRemark; QCheckBox *fdIsUltraLong; + QRadioButton *fdHor, *fdVer; QLineEdit *fdSplitWidths; }; diff --git a/LedOK/program/progitem.cpp b/LedOK/program/progitem.cpp index 4a6d15b..0508ca4 100644 --- a/LedOK/program/progitem.cpp +++ b/LedOK/program/progitem.cpp @@ -13,27 +13,9 @@ #include #include -ProgItem::ProgItem(const QString &progsDir, const QString &name, int w, int h, const QString &remarks, QList &splitWidths, int maxWidth, LoQTreeWidget *tree) : TreeWidgetItem(tree), - mName(name), mWidth(w), mHeight(h), mRemark(remarks), mSplitWidths(splitWidths), mMaxWidth(maxWidth), mProgsDir(progsDir) { - m_last = QDateTime::currentDateTime(); - mProgDir = progsDir + "/" + mName; - m_orgName = mName; - init(); -} - -ProgItem::ProgItem(const QString &progsDir, const QJsonObject &json, LoQTreeWidget *tree) : TreeWidgetItem(tree), mProgsDir(progsDir) { - mName = json["name"].toString(); - mWidth = json["resolution"]["w"].toInt(); - mHeight = json["resolution"]["h"].toInt(); - mRemark = json["remarks"].toString(); - auto splitWidths = json["splitWidths"].toArray(); - foreach(auto splitWidth, splitWidths) { - int width = splitWidth.toInt(); - if(mMaxWidth < width) mMaxWidth = width; - mSplitWidths.append(width); - } - m_fsize = json["file_size"].toDouble(); - m_last = QDateTime::fromString(json["last_edit"].toString(), "yyyy-MM-dd hh:mm:ss"); +ProgItem::ProgItem(const QString &progsDir, const QString &name, int w, int h, const QString &remarks, std::vector &partLens, int maxLen, bool isVer, LoQTreeWidget *tree) : TreeWidgetItem(tree), + mName(name), mWidth(w), mHeight(h), mRemark(remarks), partLens(partLens), maxLen(maxLen), isVer(isVer), mProgsDir(progsDir) { + setText("lasttime", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); mProgDir = progsDir + "/" + mName; m_orgName = mName; init(); @@ -52,23 +34,22 @@ void ProgItem::init() { setText("name", mName); setText("resolution", QString("%1 x %2").arg(mWidth).arg(mHeight)); setText("size", m_fsize<=0 ? "100B" : byteSizeStr(m_fsize)); - setText("lasttime", m_last.toString("yyyy-MM-dd hh:mm:ss")); - m_bnName = new QPushButton(mName); - m_bnName->setFont(ft); - m_bnName->setCursor(QCursor(Qt::PointingHandCursor)); - m_bnName->setStyleSheet(R"delimiter( + btnName = new QPushButton(mName); + btnName->setFont(ft); + btnName->setCursor(QCursor(Qt::PointingHandCursor)); + btnName->setStyleSheet(R"delimiter( QPushButton{border-radius: 4px;} QPushButton:hover { background-color: #ccc; text-decoration: underline; } )delimiter"); - QObject::connect(m_bnName, &QPushButton::clicked, treeWidget(), [=] { + QObject::connect(btnName, &QPushButton::clicked, treeWidget(), [=] { auto editor = new ProgEditorWin(this, treeWidget()->parentWidget()); editor->show(); }); - setCellWidget("name", m_bnName); + setCellWidget("name", btnName); auto btnExport = new QPushButton; btnExport->setCursor(QCursor(Qt::PointingHandCursor)); @@ -177,19 +158,20 @@ void ProgItem::save() { dRoot = QDir(mProgDir); if(dRoot.exists()) { - QJsonObject obj; - obj["name"] = mName; - obj["resolution"] = QJsonObject{{"w", mWidth}, {"h", mHeight}}; - obj["remarks"] = mRemark; - QJsonArray splitWidths; - foreach(auto splitWidth, mSplitWidths) splitWidths.append(splitWidth); - obj["splitWidths"] = splitWidths; - obj["file_size"] = m_fsize; - obj["last_edit"] = m_last.toString("yyyy-MM-dd hh:mm:ss"); - QFile f(mProgDir + "/pro.json"); - f.open(QIODevice::WriteOnly); - f.write(QJsonDocument(obj).toJson()); - f.close(); + JObj json; + json["name"] = mName; + json["resolution"] = JObj{{"w", mWidth}, {"h", mHeight}}; + json["remarks"] = mRemark; + json["isVer"] = isVer; + JArray partLens; + for(auto partLen : this->partLens) partLens.append(partLen); + json["splitWidths"] = partLens; + json["file_size"] = m_fsize; + QFile file(mProgDir + "/pro.json"); + if(file.open(QIODevice::WriteOnly)) { + file.write(JToBytes(json, "\n")); + file.close(); + } } } @@ -199,9 +181,10 @@ void ProgItem::del() { } //设置列表项的值 void ProgItem::onSetProgram() { - m_bnName->setText(mName); + btnName->setText(mName); + m_fsize = dirFileSize(mProgDir); setText("resolution", QString("%1 x %2").arg(mWidth).arg(mHeight)); setText("size", byteSizeStr(m_fsize<=0 ? 100 : m_fsize)); - setText("lasttime", m_last.toString("yyyy-MM-dd hh:mm:ss")); + setText("lasttime", QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")); save(); } diff --git a/LedOK/program/progitem.h b/LedOK/program/progitem.h index b6ced69..380c425 100644 --- a/LedOK/program/progitem.h +++ b/LedOK/program/progitem.h @@ -8,8 +8,8 @@ class ProgPanel; class ProgItem : public TreeWidgetItem { public: - explicit ProgItem(const QString &progsDir, const QString &name, int w, int h, const QString & remarks, QList &splitWidths, int, LoQTreeWidget *parent); - explicit ProgItem(const QString &progsDir, const QJsonObject &json, LoQTreeWidget *parent); + using TreeWidgetItem::TreeWidgetItem; + explicit ProgItem(const QString &progsDir, const QString &name, int w, int h, const QString & remarks, std::vector &, int, bool isVer, LoQTreeWidget *parent); void save(); void del(); @@ -19,14 +19,13 @@ public: int mWidth; int mHeight; QString mRemark; - QList mSplitWidths; - int mMaxWidth{0}; + std::vector partLens; + int maxLen = 0; + bool isVer = false; QString mProgsDir; QString mProgDir; - qint64 m_fsize{0}; - QDateTime m_last; - QPushButton *m_bnName; -private: + qint64 m_fsize = 0; + QPushButton *btnName; void init(); QString m_orgName; }; diff --git a/LedOK/program/sendprogramdialog.cpp b/LedOK/program/sendprogramdialog.cpp index 130d44e..a61ccd9 100644 --- a/LedOK/program/sendprogramdialog.cpp +++ b/LedOK/program/sendprogramdialog.cpp @@ -50,7 +50,7 @@ SendProgramDialog::SendProgramDialog(QString progName, QWidget *parent) : QDialo item->isSending = true; item->setText(remarks, ""); auto sendProg = new SendProgThread(programsDir()+"/"+mProgName+"_tmp", item->text("ip"), 3333); - connect(sendProg, &SendProgThread::emErr, item->fdProgress, [=](QString strTip) { + connect(sendProg, &SendProgThread::emErr, item, [=](QString strTip) { item->isSending = false; if(strTip=="OK") { item->setCheckState("id", Qt::Unchecked); @@ -112,7 +112,7 @@ SendProgramDialog::SendProgramDialog(QString progName, QWidget *parent) : QDialo item->btnUnlock = new QPushButton; item->btnUnlock->setMaximumHeight(36); item->setCellWidget("encrypt", item->btnUnlock); - connect(item->btnUnlock, &QPushButton::clicked, item->btnUnlock, [=] { + connect(item->btnUnlock, &QPushButton::clicked, item, [=] { if(! item->isLocked) return; bool ok; auto pwd = QInputDialog::getText(this, tr("Input password"), tr("Input password"), QLineEdit::Password, QString(), &ok); @@ -206,7 +206,7 @@ void SendProgramDialog::sendNext() { item->isSending = true; mWaitCnt--; auto sendProg = new SendProgThread(programsDir()+"/"+mProgName+"_tmp", item->text("ip"), 3333); - connect(sendProg, &SendProgThread::emErr, item->fdProgress, [=](QString strTip) { + connect(sendProg, &SendProgThread::emErr, item, [=](QString strTip) { item->isSending = false; if(strTip=="OK") { item->setCheckState("id", Qt::Unchecked); diff --git a/LedOK/program/sendprogramdialog.h b/LedOK/program/sendprogramdialog.h index cecb812..8f1380e 100644 --- a/LedOK/program/sendprogramdialog.h +++ b/LedOK/program/sendprogramdialog.h @@ -23,7 +23,7 @@ protected: QString m_strUrl; }; -class SendProgramItem : public TreeWidgetItem { +class SendProgramItem : public TreeWidgetItem, public QObject { public: using TreeWidgetItem::TreeWidgetItem; void setResult(QString tip, QColor color) { diff --git a/LedOK/program/sendprogthread.cpp b/LedOK/program/sendprogthread.cpp index 50fab34..5e17eeb 100644 --- a/LedOK/program/sendprogthread.cpp +++ b/LedOK/program/sendprogthread.cpp @@ -121,7 +121,7 @@ void SendProgThread::run() { return; } //4.发送协商列表应答里的文件 - long long sentBytes = 0; + int64_t sentBytes = 0; char buf[8192]; for(auto &info : fileInfos) if(info.isFile()) { auto baseName = info.baseName(); diff --git a/LedOK/program/videosplitthread.cpp b/LedOK/program/videosplitthread.cpp index 123106c..d0a4295 100644 --- a/LedOK/program/videosplitthread.cpp +++ b/LedOK/program/videosplitthread.cpp @@ -12,7 +12,7 @@ static void imgCleanupHandler(void *info) { delete [] (uchar*)info; } -VideoSplitThread::VideoSplitThread(int elew, int eleh, int dpw, int sph, QList &widths, QPointF pos, QByteArray file) : mEleW(elew), mEleH(eleh), mDPW(dpw), mSPH(sph), mWidths(widths), pos(pos), file(file) { +VideoSplitThread::VideoSplitThread(int elew, int eleh, int maxLen, int sph, std::vector &widths, bool isVer, QPointF pos, QByteArray file) : mEleW(elew), mEleH(eleh), maxLen(maxLen), mSPH(sph), mWidths(widths), pos(pos), file(file), isVer(isVer) { connect(this, &QThread::finished, this, &QThread::deleteLater); } @@ -80,8 +80,13 @@ void VideoSplitThread::run() { outPar->codec_type = AVMEDIA_TYPE_VIDEO; outPar->codec_id = AV_CODEC_ID_H264; outPar->format = AV_PIX_FMT_YUV420P; - outPar->width = mDPW; - outPar->height = mSPH*mWidths.size(); + if(isVer) { + outPar->height = maxLen; + outPar->width = mSPH*mWidths.size(); + } else { + outPar->width = maxLen; + outPar->height = mSPH*mWidths.size(); + } auto encoder = avcodec_find_encoder(outPar->codec_id); if(encoder==0) { @@ -150,11 +155,20 @@ void VideoSplitThread::run() { } else { sws_scale(sws_ctx, frm->data, frm->linesize, 0, de_ctx->height, img_data, img_linesize); auto apos = pos; - painter.drawImage(apos, img, QRectF(0, 0, mWidths[0]-apos.x(), img.height())); - for(int i=1; ipts; auto dur = frm->pkt_duration; diff --git a/LedOK/program/videosplitthread.h b/LedOK/program/videosplitthread.h index ac7fa79..69f8763 100644 --- a/LedOK/program/videosplitthread.h +++ b/LedOK/program/videosplitthread.h @@ -7,11 +7,12 @@ class VideoSplitThread : public QThread { Q_OBJECT public: - VideoSplitThread(int elew, int eleh, int dpw, int sph, QList &, QPointF pos, QByteArray file); - int mEleW, mEleH, mDPW, mSPH; - QList mWidths; + VideoSplitThread(int elew, int eleh, int maxLen, int sph, std::vector &, bool, QPointF pos, QByteArray file); + int mEleW, mEleH, maxLen, mSPH; + std::vector mWidths; QPointF pos; QByteArray file; + bool isVer; protected: void run(); diff --git a/LedOK/rk_lcd_parameters/1024x1280 (60hz) b/LedOK/rk_lcd_parameters/1024x1280 (60hz) new file mode 100644 index 0000000..67c6901 --- /dev/null +++ b/LedOK/rk_lcd_parameters/1024x1280 (60hz) @@ -0,0 +1,35 @@ +##ע +#ע +# 0 - DSI; 1 - EDP; 2 - LVDS; 3 - RGB +panel-type = 3; + +# panel info +unprepare-delay-ms = 20; +enable-delay-ms = 20; +disable-delay-ms = 20; +prepare-delay-ms = 20; +reset-delay-ms = 100; +init-delay-ms = 100; +width-mm = 150; +height-mm = 120; + +# panel timing +clock-frequency = 81120000; +hactive = 1024; +hfront-porch = 5; +hsync-len = 5; +hback-porch = 6; +vactive = 1280; +vfront-porch = 5; +vsync-len = 5; +vback-porch = 10; +hsync-active = 0; +vsync-active = 0; +de-active = 0; +pixelclk-active = 0; + +# for dsi panel +#dsi,flags = 0; +#dsi,format = 0; +#dsi,lanes = 4; +#panel-init-sequence = 29 00 06 14 01 08 00 00 00 ff aa 01 02 03 04 05 06 07 ff aa AA bb ff; \ No newline at end of file diff --git a/LedOK/y50 param/1080x1920(30hz)/rk_lcd_parameters b/LedOK/rk_lcd_parameters/1080x1920 (30hz) similarity index 100% rename from LedOK/y50 param/1080x1920(30hz)/rk_lcd_parameters rename to LedOK/rk_lcd_parameters/1080x1920 (30hz) diff --git a/LedOK/rk_lcd_parameters/1280x1024 (60hz) b/LedOK/rk_lcd_parameters/1280x1024 (60hz) new file mode 100644 index 0000000..466d9ca --- /dev/null +++ b/LedOK/rk_lcd_parameters/1280x1024 (60hz) @@ -0,0 +1,35 @@ +##ע +#ע +# 0 - DSI; 1 - EDP; 2 - LVDS; 3 - RGB +panel-type = 3; + +# panel info +unprepare-delay-ms = 20; +enable-delay-ms = 20; +disable-delay-ms = 20; +prepare-delay-ms = 20; +reset-delay-ms = 100; +init-delay-ms = 100; +width-mm = 150; +height-mm = 120; + +# panel timing +clock-frequency = 81120000; +hactive = 1280; +hfront-porch = 5; +hsync-len = 5; +hback-porch = 10; +vactive = 1024; +vfront-porch = 5; +vsync-len = 5; +vback-porch = 6; +hsync-active = 0; +vsync-active = 0; +de-active = 0; +pixelclk-active = 0; + +# for dsi panel +#dsi,flags = 0; +#dsi,format = 0; +#dsi,lanes = 4; +#panel-init-sequence = 29 00 06 14 01 08 00 00 00 ff aa 01 02 03 04 05 06 07 ff aa AA bb ff; \ No newline at end of file diff --git a/LedOK/y50 param/1280x720(60hz)/rk_lcd_parameters b/LedOK/rk_lcd_parameters/1280x720 (60hz) similarity index 100% rename from LedOK/y50 param/1280x720(60hz)/rk_lcd_parameters rename to LedOK/rk_lcd_parameters/1280x720 (60hz) diff --git a/LedOK/rk_lcd_parameters/1536x768 (60hz) b/LedOK/rk_lcd_parameters/1536x768 (60hz) new file mode 100644 index 0000000..7abe2ac --- /dev/null +++ b/LedOK/rk_lcd_parameters/1536x768 (60hz) @@ -0,0 +1,35 @@ +##ע +#ע +# 0 - DSI; 1 - EDP; 2 - LVDS; 3 - RGB +panel-type = 3; + +# panel info +unprepare-delay-ms = 20; +enable-delay-ms = 20; +disable-delay-ms = 20; +prepare-delay-ms = 20; +reset-delay-ms = 100; +init-delay-ms = 100; +width-mm = 154; +height-mm = 86; + +# panel timing +clock-frequency = 80250000; +hactive = 1536; +hfront-porch = 48; +hsync-len = 32; +hback-porch = 80; +vactive = 768; +vfront-porch = 3; +vsync-len = 10; +vback-porch = 9; +hsync-active = 0; +vsync-active = 0; +de-active = 0; +pixelclk-active = 0; + +# for dsi panel +#dsi,flags = 0; +#dsi,format = 0; +#dsi,lanes = 4; +#panel-init-sequence = 29 00 06 14 01 08 00 00 00 ff aa 01 02 03 04 05 06 07 ff aa AA bb ff; \ No newline at end of file diff --git a/LedOK/y50 param/1920x1080(30hz)/rk_lcd_parameters b/LedOK/rk_lcd_parameters/1920x1080 (30hz) similarity index 100% rename from LedOK/y50 param/1920x1080(30hz)/rk_lcd_parameters rename to LedOK/rk_lcd_parameters/1920x1080 (30hz) diff --git a/LedOK/y50 param/1920x512(60hz)/rk_lcd_parameters b/LedOK/rk_lcd_parameters/1920x512 (60hz) similarity index 100% rename from LedOK/y50 param/1920x512(60hz)/rk_lcd_parameters rename to LedOK/rk_lcd_parameters/1920x512 (60hz) diff --git a/LedOK/y50 param/512x1920(60hz)/rk_lcd_parameters b/LedOK/rk_lcd_parameters/512x1920 (60hz) similarity index 100% rename from LedOK/y50 param/512x1920(60hz)/rk_lcd_parameters rename to LedOK/rk_lcd_parameters/512x1920 (60hz) diff --git a/LedOK/y50 param/720x1280(60hz)/rk_lcd_parameters b/LedOK/rk_lcd_parameters/720x1280 (60hz) similarity index 100% rename from LedOK/y50 param/720x1280(60hz)/rk_lcd_parameters rename to LedOK/rk_lcd_parameters/720x1280 (60hz) diff --git a/LedOK/y50 param/768x1280(60hz)/rk_lcd_parameters b/LedOK/rk_lcd_parameters/768x1280 (60hz) similarity index 100% rename from LedOK/y50 param/768x1280(60hz)/rk_lcd_parameters rename to LedOK/rk_lcd_parameters/768x1280 (60hz) diff --git a/LedOK/tools.cpp b/LedOK/tools.cpp index e67ea39..aa4f40d 100644 --- a/LedOK/tools.cpp +++ b/LedOK/tools.cpp @@ -58,6 +58,31 @@ void Tools::mergeFormat(QTextEdit *textEdit, const QTextCharFormat &fmt) { if(! cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor); cursor.mergeCharFormat(fmt); } +QString Tools::saveImg(const QString& dir, const QFontMetrics& metric, const QFont& font, const QColor& color, const QString& str) { + if(str.isEmpty()) return QString(); + QImage img(metric.horizontalAdvance(str), metric.lineSpacing(), QImage::Format_ARGB32); + img.fill(Qt::transparent); + { + QPainter painter(&img); + painter.setFont(font); + painter.setPen(color); + QTextOption opt(Qt::AlignCenter); + opt.setWrapMode(QTextOption::NoWrap); + painter.drawText(QRectF(0, 0, img.width(), img.height()), str, opt); + } + QByteArray data; + QBuffer buffer(&data); + buffer.open(QIODevice::WriteOnly); + if(! img.save(&buffer, "PNG")) return QString(); + QCryptographicHash cryptoHash(QCryptographicHash::Md5); + cryptoHash.addData(data); + auto md5 = QString::fromLatin1(cryptoHash.result().toHex()); + QFile file(dir+"/"+md5); + if(! file.open(QFile::WriteOnly)) return QString(); + file.write(data); + file.close(); + return md5; +} void Tools::saveImg(const QString& dir, const QFontMetrics& metric, const QFont& font, const QColor& color, JObj& imgs, const QString& str, const QString& name) { if(str.isEmpty()) return; QImage img(metric.horizontalAdvance(str), metric.lineSpacing(), QImage::Format_ARGB32); @@ -85,11 +110,12 @@ void Tools::saveImg(const QString& dir, const QFontMetrics& metric, const QFont& } void Tools::saveImg2(const QString& dir, const QFontMetrics& metric, const QFont& font, const QColor& color, JArray& imgs, const QString& str, const QString& name) { JObj obj{ - {"name", name}, - {"mime", "image/png"} + {"name", name} }; if(! str.isEmpty()) { QImage img(metric.horizontalAdvance(str), metric.lineSpacing(), QImage::Format_ARGB32); + obj.insert("picWidth", img.width()); + obj.insert("picHeight", img.height()); img.fill(Qt::transparent); { QPainter painter(&img); @@ -103,16 +129,14 @@ void Tools::saveImg2(const QString& dir, const QFontMetrics& metric, const QFont QBuffer buffer(&data); buffer.open(QIODevice::WriteOnly); if(img.save(&buffer, "PNG")) { - obj.insert("picWidth", img.width()); - obj.insert("picHeight", img.height()); QCryptographicHash cryptoHash(QCryptographicHash::Md5); cryptoHash.addData(data); auto md5 = QString::fromLatin1(cryptoHash.result().toHex()); + obj.insert("id", md5); QFile file(dir+"/"+md5); if(file.open(QFile::WriteOnly)) { file.write(data); file.close(); - obj.insert("id", md5); } } } diff --git a/LedOK/tools.h b/LedOK/tools.h index 9cff685..3411881 100644 --- a/LedOK/tools.h +++ b/LedOK/tools.h @@ -30,6 +30,7 @@ public: static void mergeFormat(QTextEdit *textEdit, const QTextCharFormat &format); static QString readErrStr(QImageReader::ImageReaderError); static QString fileMd5(QString); + static QString saveImg(const QString&, const QFontMetrics&, const QFont&, const QColor&, const QString&); static void saveImg(const QString&, const QFontMetrics&, const QFont&, const QColor&, JObj&, const QString&, const QString&); static void saveImg2(const QString&, const QFontMetrics&, const QFont&, const QColor&, JArray&, const QString&, const QString&); static QColor int2Color(int value); @@ -44,7 +45,7 @@ signals: protected: virtual void timerEvent(QTimerEvent *event); private: - Tools(QObject *parent = nullptr) : QObject(parent) { + Tools(QObject *parent = 0) : QObject(parent) { timer_id = startTimer(500, Qt::PreciseTimer); }; int timer_id; diff --git a/LedOK/ts/app_en.ts b/LedOK/ts/app_en.ts index 7b21d67..b9cc4f6 100644 --- a/LedOK/ts/app_en.ts +++ b/LedOK/ts/app_en.ts @@ -56,235 +56,230 @@ CtrlAdvancedPanel - + Advanced Advanced - + Screen Width(pixel) Screen Width(pixel) - + Width Width - - + + Height Height - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + Set Set - + Alias Alias - + Web Server Address: Web Server Address: - + MCU Uploading - + Setting - + Traffic screen settings - + Setting protocol ... - + Set protocol - + Getting protocol ... - + Get protocol - - + + Port - - Realtimer Server Address: - Realtimer Server Address: + + Realtime Address: + - + Firmware Management - + update or uninstall - + Clear Clear - + Check Apk Check Apk - + Uninstall Uninstall - + Running check Running check - + Restart Restart - + Check Log Check Log - + Start LedSet4 Start LedSet4.0 (Apk Display2.0 and higher) - + Open ADB Open ADB debugging function - + Post Custom JSON Post Custom JSON - - - - - - + + + + + + Clear Program Clear Program - - www.ledokcloud.com/realtime - - - - + Config Config - + Refresh Refresh - + Restore to default Restore to default - + Taxi top screen configuration Taxi top screen configuration - - + + Service:High Out of service:Low Service:High Out of service:Low - - + + Service:Low Out of service:High Service:Low Out of service:High - + Binding *.ic account indentity voucher Binding *.ic account indentity voucher - + Rotate Rotate - + Min brightness Min brightness - - - + + + Readback Readback - + Send Send - + Max brightness Max brightness @@ -295,607 +290,587 @@ Set Screen Size - - - - - + + + + + Success Success - + Compant ID: Company ID - + Compant ID Company ID - - InputWebServerAddressTip - Please enter web server address - - - - InputCompanyIdTip - Please enter company ID - - - - + + SetOnlineAddr Set Web server address - - + + ClearRealtimeServer Clear - - + + SetRealtimeServer Set realtimer address - - Tip Info - Tip Info - - - - + + RestartAndroid Restart - - + + running running - - + + no running no running - + Check Apk Version Check Apk Version - - + + UninstallSoftware Uninstall - - + + Check apk running status - - + + OpenAdb Open ADB debugging function - + indentity voucher (*.ic) indentity voucher (*.ic) - - - - - + + + + + InvokeTaxiAppFunction Binding certificate - - + + AliIotSetting - + Software Version Info - + Package - + Version - - + + Package name is null - + Clearing Program - - + + Timeout Timeout - - - - + + + + Failed - + Getting Log - - - - - - - - - - - - - + + + + + + + + + + + + + Error Error - + Setting Timing Reboot - + Set Timing Reboot - + Getting Timing Reboot - + Get Timing Reboot - + totalResolution FPGA total resoltuion - + strCurDisplayResolution Cur display resolution - - + + File not exist - + Getting Player State - - - + + + Get Player State - - + + Player State - - This operation will clear current program. - - - - - Do you want to continue? - - - - - + + Cannot Open File - + Uploading - + Update Update - - + + Set Display Mode - - + + Get Display Mode - - + + Set Screen Offset - - + + Get Screen Offset - + Open file Failed Open file Failed - + Setting Wallpaper - - + + Set Wallpaper - + System Updating - - + + System Update - + Getting MCU Version - - + + MCU Version - + Select File Select File - + Setting player background - - + + Set player background - + Clearing player background - - - - - - - - + + + + + + + + Clear player background - - + + GetScreenRotation Get Screen Rotation - - - + + + Charging Station - + Setting Baud Rate - + Set Baud Rate - + Getting Baud Rate - + Get Baud Rate - - + + Text is empty - - + + Json Parse Error - - + + Json isn't an Object - + Info - + Setting card work mode ... - + Set card work mode - + Getting card work mode ... - + Get card work mode - + Input password Input password - + Change Password Change Password - + + Get Receive Card Num + + + + Resolution Config - + Full screen - + Part - + Display Mode - + Screen Position - + Offset - + Hidden Settings - + Click right button to hide - - + + Update MCU - + Get MCU Version - + Baud Config - + Model - + Uart - + Baud - - - - - - - - + + + + + + + + Get - + Timing Reboot - + Protocol - + Server - + Client - - + + SetScreenRotation Set screen rotation - - + + SetMinBrightness Set min brightness value - - + + SetMaxBrightness Set maximum brightness value - - + + GetMinBrightness Get min brightness - - + + GetMaxBrightness Get maximum brightness - - + + Card work mode - - + + SetSpecialResolution Set Special Resolution - - + + GetSpecialResolution Get Special Resolution - - + + CleanDisplayScreenSize Restore to default relolution - - + + SetHighForBusy Set level for busy - - + + GetStateForBusy Get level of busy @@ -911,76 +886,80 @@ - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tip Tip @@ -988,50 +967,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + NoSelectedController Please select screen first @@ -1046,7 +1031,7 @@ Please enter the correct height pixel value - + Password is error Password is error @@ -2427,209 +2412,185 @@ CtrlTestPanel - + Test Screen Test Screen - + Line test Line test - - + + + - Red Red - - + + + - Green Green - - + + + - Blue Blue - - + + + - White White - + Vertical Vertical - + Slash Oblique line - - + + Horizontal Horizontal - - + + Speed Speed - + ms(>10) - + Line Distance Line Distance + + - - Test Test - + Gradation test Gradation test - + Only the gray value is displayed Only the gray value is displayed - + GrayValue Gray value - + Color test Color test - + Gradient Gradient - + Clear Clear - + Reset Loop - - - - + + Success + Success + + + + + Anycast Anycast - + Stop Stop - - - - - - - - + + + + + + + Tip Tip - - - - - - + + + + + + NoSelectedController Please select screen first - - - - - - + + + + + + StartTest Start test - - + + StopTest Stop test - - loopback mode - loopback mode + + Loop Mode + - - Connect timeout - Connect timeout - - - - - receive - Receive - - - - Connect - Connect - - - - timeout - timeout - - - + Reset loop mode Reset loop mode - - - - success - success - CtrlVerifyClockPanel @@ -3097,29 +3058,29 @@ Def - - - - + + + - - - + + + + Device replied - + - + Success Success - - + + Fail Fail @@ -3128,236 +3089,236 @@ DevicePanel - + All ALL ALL - + Online Online Online - - + + Refresh Refresh Refresh - - - + + + Specify IP Specify IP Specify IP - - - - - + + + + + Current Screen Current screen - - - + + + none none - + Current Brightness - + Android Version - + FPGA Version FPGA Version - + Brightness Level Brightness Level - + Android OS Resolution Android OS Resolution - + Firmware Version Firmware Version - - + - + + Player Version - + Detail Info Detail Info - + Getting - + Specify IP list - + Search Search - - + + Attention Attention - - + + Please input IP address! Please input IP address! - + Cancel Cancel - + Screen ID Screen ID - + Screen Size Screen Size - + Alias - + Screenshot Screenshot - - + + On ON - - + + Off OFF - + Brightness Adj. Brightness Adj. - + Power Control Power Control - + Net Config Network Config - + Time Sync Time Sync - + Video source Video Source - + Password Password - + Advanced Advanced - + Volume Adj. Volume - + Test Test - - + + Multi screen operation Multi screen operation - - + + selected num Selected number - - + + Clear Clear - + More Info More Info - + Screen Brightness Screen Brightness - + Power Status Power Status - + Security encryption @@ -3396,549 +3357,643 @@ EAClock - + Basic Properties Basic properties - + Time Zone Time Zone - + Custom Dial Custom Dial - + Select Select - + Select Dail file Select dial file - + Hour Mark Hour Scale - - + + Circular Circle - - + + Rectangle Rectangle - + Number Number - + Min Mark Minute Scale - + Color - + Length - + Width Width - + Hour Hand - + Min Hand - + Sec Hand - + Show - + Text Text - - - Play Properties - - - - - Play Duration - Play Duration - - - - s - s - EBase - + Area Area(px) - + X X - + Y Y - + W W - + H H - + Border Border - - + + + + None None - + + Effect Effect - + Rotate Rotate - + Blink Blink - + Speed Speed - + Slow Slow - + Moderate Moderate - + Fast Fast + + + Play Time + + + + + Start + + + + + + + + s + + + + + Duration + + + + + Entry + + + + + + Random + + + + + + Expand horizontal + + + + + + Expand vertical + + + + + + Expand to left + + + + + + Expand to top + + + + + + Expand to right + + + + + + Expand to bottom + + + + + Zoom in + + + + + Zoom in from left-top + + + + + Zoom in from right-top + + + + + Zoom in from right-bottom + + + + + Zoom in from left-bottom + + + + + + Rotate zoom + + + + + + Rotate zoom reverse + + + + + Fade in + + + + + + Move to left + + + + + + Move to top + + + + + + Move to right + + + + + + Move to bottom + + + + + + Dur + + + + + Exit + + + + + Zoom out + + + + + Zoom out to left-top + + + + + Zoom out to right-top + + + + + Zoom out to right-bottom + + + + + Zoom out to left-bottom + + + + + Fade out + + EDClock - + MON MON - + TUE TUE - + WED WED - + THU THU - + FRI FRI - + SAT SAT - + SUN SUN - - + + AM AM - - + + PM PM - + Basic Properties Basic properties - + Time Zone Time Zone - + Year Year - + Month Month - + Day Day - + Hour Hour - + Min. Min. - + Sec. Sec. - + Weekly Day of Week - + Full Year 4-Digit Year - + 12-Hour 12-Hour - + Date Style Date Format - + Time Style Time format - + Display Style Display style - + Multiline Multiline - - - Play Properties - - - - - Play Duration - Play Duration - - - - s - s - EEnviron - - - - - - - - - - - - - - - north - north - - - - - - - - - - - - - - - - - east - east - - - - - - - - - - - - - - - - - south - south - - - - - - - - - - - - - - - - - west - west - - - + Temperature Temperature - + Humidity Humidity - + Noise Noise - + Wind Speed Wind Speed - + Wind Direction Wind Direction - + Pressure - + Rainfall - + Radiation - + Beam - + + + + N + + + + + + + NE + + + + + + + E + + + + + + + SE + + + + + + + S + + + + + + + SW + + + + + + + W + W + + + + + + NW + + + + Basic Properties Basic properties - + Title Title - + Compensation Compensation - + Left Left - + Center Center - + Right Right - + Single scroll Single scroll - + Speed Speed - - ms/pixel - ms/pixel - - - + Back Color Back Color - - - Play Properties - - - - - Play Duration - Play Duration - - - - s - s - EGif - + Basic Properties Basic properties - + File File - + Select File Select File - - - Play Properties - - - - - Play Duration - Play Duration - - - - s - s - - - - Play Times - Play Times - EMultiWin @@ -4017,118 +4072,27 @@ EPhoto - + Basic Properties Basic properties - + File File - + Select File Select File - + Image Read Error Image Read Error - - Play Properties - - - - - Play Duration - Play Duration - - - - - s - s - - - - Enter Style - Entrance Effect - - - - None - None - - - - Alpha In - - - - - Moving to left - - - - - Moving to right - - - - - Moving to top - - - - - Move to bottom - - - - - Zoom In - - - - - Zoom In to left_bottom - - - - - Zoom In to left_top - - - - - Zoom In to right_top - - - - - Zoom In to right bottom - - - - - Rotate to right - - - - - Rotate to left - - - - - Enter Duration - Effect Duration - - - + Images (*.png *.jpg *.jpeg *.bmp) @@ -4136,191 +4100,122 @@ EText - + Enter your text Enter your text - + Basic Properties Basic properties - + Back Color Back Color - + Kerning Kerning - + Line Spacing Line Spacing - + PageCount: PageCount: - + page Page - + Import txt File - + Select File Select File - + Fail Fail - + Cannot Open File - + Play Properties - + Flip Flip - + Scroll Scroll - + Static Static - - - - Play Duration - Play Duration - - - - Duration/Page - Duration/Page - - - - Effect time - effect duration - - - - - Tip Info - Tip Info - - - - - Effect time cannot be longer than duration time - Effect time cannot be longer than duration time - - - - s - s - - - + Text Color - + Colorful Text - - - Entrance Effect - Entrance Effect - - no - no - - - - random - random - - - - right to left - right to left - - - - bottom to top - bottom to top - - - - left to right - left to right - - - - top to bottom - top to bottom - - - Head-Tail Spacing Spacing - + Scroll Style Direction - + Right -> Left From right to left - + Bottom -> Top From bottom to top - + Left -> Right From left to right - + Top -> Bottom Frome top to bottom - + Scroll Speed Scrolling speed @@ -4328,142 +4223,117 @@ ETimer - + day Days - + hour Hours - + min Mins - + sec Secs - + Basic Properties Basic properties - + Count Down Count Down - + Count Up Count Up - + Time Target Time - + Day Day - + Hour Hour - + Min Min - + Sec Sec - + Multiline Multiline - + Text Text - - - Play Properties - - - - - Play Duration - Play Duration - - - - s - s - EVideo - + Basic Properties Basic properties - + File File - + Play Properties - - Play Duration - Play Duration - - - + Select File Select File - - s - s - - - + Play Times Play Times - + Video Transcoding - - + + Video Transcoding Progress - - + + Error Error @@ -4481,40 +4351,30 @@ EWeb - + Basic Properties Basic properties - - - Play Duration - Play Duration - - - - s - s - EleTimer - + day Days - + hour Hours - + min Mins - + sec Secs @@ -4522,67 +4382,67 @@ GenTmpThread - + MON MON - + TUE TUE - + WED WED - + THU THU - + FRI FRI - + SAT SAT - + SUN SUN - + AM AM - + PM PM - + day Days - + hour Hours - + min Mins - + sec Secs @@ -4590,7 +4450,7 @@ ImgDlg - + Screenshot @@ -4641,177 +4501,182 @@ MainWindow - + Language Language - + Help Help - - + + Check for updates Check for updates - - + + firmware manager Firmware management - - - + + + Preferences - - + + Info - - - + + + About About - - + + Setting Setting - + Software Update Software Update - + CurVersion CurVersion - + Latest Version - + Update Log - + The current version is already the latest version The current version is already the latest version - + Video compress to - + Video transcoding to - + Text antialiasing - + TextAntilaTip (Note: this option is suitable for screens with small spacing and large size. If this option is selected, the shadow on the edge of the text will be smooth; it is not recommended for small size screens and single and double color screens.) - + Ultra-Long Screen Split - + Program Send Batch - + Hide Detect Button - + + Show Alias in Terminal Control + + + + Show Lora Screen - + Download - + Fail Fail - + Cannot Save File - - - + + + Downloading updates Downloading updates - + Error Error - + Device Terminals - + Program Solutions - + Control Terminal Control - + Lora Screen - + Check card Detect - + Tip Info Tip Info - + RestoreLedCardIpByUdpTip This operation will fix all the control cards in the LAN that are not in the same network segment as the computer IP. Please be careful! @@ -4825,6 +4690,7 @@ + Error Error @@ -4935,84 +4801,84 @@ PageListItem - + times Times - + Page name Program name - + New New - + Play times Play times - + Sources Repeat - + Audios - + Total Dur - - + + s s - + Select File Select File - + Duration - + Vol - + Valid Date Valid date - - + + Warning Warning - + Start Time can't be later than End Time - + End Time can't be earlier than Start Time - + Plan Plan @@ -5020,37 +4886,37 @@ PlanItemWgt - + M M - + Tu Tu - + W W - + Th Th - + F F - + Sa Sa - + Su Su @@ -5058,17 +4924,17 @@ PlayWin - + Move to Top Left Move to Top Left - + Set Position - + Close Close @@ -5076,12 +4942,12 @@ PlayerBackSendThread - + Open file failed Open file failed - + Read file failed Read file failed @@ -5102,43 +4968,53 @@ ProgCreateDlg - + Resolution Resolution - + Solution Information Solution Information - + Solution Name Solution Name - + Width Width - + Height Height - + Remarks Remarks - + Ultra-Long Screen Split - - Part Width + + Horizontal + Horizontal + + + + Vertical + Vertical + + + + Lengths of Parts @@ -5150,192 +5026,192 @@ Save - + Setting Setting - + Text Text - + Photo Photo - + Video Video - + Gif Gif - + Clock Clock - + Analog Clock Analog Clock - + Environment Environmental Monitoring - + Web Web page - + MuliContentWindow Multi material window - + In this window, a plurality of different program materials can be added and played according to the order of joining the list; In this window, a plurality of different program materials can be added and played according to the order of joining the list - + Timer Timer - + Play - + Stop Stop - + Publish Publish - - - + + + Select File Select File - + program Program - + Add page Add page - + Copy page Copy page - + Delete page Delete page - - + + Tip Info Tip Info - + Are you sure you want to delete this program page? Are you sure you want to delete this program page? - + Move up Move up - + Move down Move down - + widget properties Widget properties - + Page properties Program properties - + Do you want to save the modifications? Do you want to save the modifications? - + Create Dir failed - + Saving... Saving... - + Success Success - + Convertering Convertering - + Demos - + Open Demo - + Generate preview data Generate preview data - - - + + + Error Error - + Rename fail when saving - + Remove Recursively fail when saving @@ -5343,124 +5219,124 @@ ProgPanel - - + + New New - - + + Edit Edit - - + + Delete Delete - - - + + + Import Import - - - + + + Export Export - - + + Send Send - + Publish Publish - + Name Name - - + + Choose Directory Choose Directory - + Tip Tip - + The imported directory is already in the working directory, so there is no need to import it again! The imported directory is already in the working directory, so there is no need to import it again! - + :solution(s) already exist.are you sure you want to overwrite the existing solution(s)? :solution(s) already exist.are you sure you want to overwrite the existing solution(s)? - - + + Play - - + + Stop Stop - + Resolution Resolution - + File Size File Size - + Last Modify Last Modified - + USB Update - + Program name conflicted Program name conflicted - + Warning Warning - + You will delete the selected solution(s),are you sure? You will delete the selected solution(s),are you sure? - - + + Tip Info Tip Info @@ -5468,17 +5344,17 @@ ProgPortDlg - + Solution Name Solution Name - + Progress Progress - + Done Done @@ -5494,12 +5370,12 @@ QObject - + Setting up the LedOK Express... Setting up the LedOK Express... - + Input password Input password @@ -5509,34 +5385,34 @@ Error - + USB Update Program - + Password Password - - + + Convertering Convertering - - + + Tip Tip - + No checked USB device No checked USB device - + please select usb device in list please select usb device in list @@ -5550,12 +5426,12 @@ Program is empty - + Open file failed Open file failed - + Read file failed Read file failed @@ -5678,7 +5554,7 @@ - Installing + Upgrading diff --git a/LedOK/ts/app_ja.ts b/LedOK/ts/app_ja.ts index 7ce851e..2965428 100644 --- a/LedOK/ts/app_ja.ts +++ b/LedOK/ts/app_ja.ts @@ -56,235 +56,230 @@ CtrlAdvancedPanel - + Advanced 上級パラメータ - + Screen Width(pixel) 画面幅(ピクセル) - + Width - - + + Height 高さ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + Set セット - + Alias 別名 - + Web Server Address: Webサーバのアドレス: - + MCU Uploading - + Setting - + Traffic screen settings - + Setting protocol ... - + Set protocol - + Getting protocol ... - + Get protocol - - + + Port ポート - - Realtimer Server Address: - Realtimerアドレス: - - - + Firmware Management ファームウェア管理 - + update or uninstall 更新またはアンインストール - + Clear クリア - + Check Apk APKを検出 - + Uninstall アンマウント - + Running check 運転状態モニタ - + Restart 再起動 - + Check Log ログを見る - + Start LedSet4 - + Open ADB ADBデバッグ機能を開く - + Post Custom JSON Post Custom JSON - - - - - - + + + + + + Clear Program 番組をクリア - - www.ledokcloud.com/realtime - - - - + Config の設定 - + Refresh 更新 - + Restore to default 標準の値を復元 - + Taxi top screen configuration タクシートップ画面の設定 - - + + Service:High Out of service:Low 客がいます:高 客がいません:低 - - + + Service:Low Out of service:High 客がいます:低 客がいません:高 - + Binding *.ic account indentity voucher テーピングtaxihubプラットフォームのユーザーID証明書 - + Rotate 回転 - + + Realtime Address: + + + + Min brightness 最低輝度 - - - + + + Readback 読み戻し - + Send 送信 - + Max brightness 最高輝度 @@ -295,607 +290,587 @@ スクリーンのピクセルサイズを設定 - - - - - + + + + + Success 成功 - + Compant ID: 会社ID: - + Compant ID 会社ID - - InputWebServerAddressTip - Webサーバのアドレスを入力してください - - - - InputCompanyIdTip - 会社IDを入力してください - - - - + + SetOnlineAddr ウェブサーバのアドレスを設定 - - + + ClearRealtimeServer クリア - - + + SetRealtimeServer RealTimerアドレスを設定 - - Tip Info - ヒント - - - - + + RestartAndroid 再起動 - - + + running 実行中 - - + + no running 実行されていません - + Check Apk Version チェック APK バージョン - - + + UninstallSoftware アンマウント - - + + Check apk running status APK運転状態監視 - - + + OpenAdb ADBデバッグ機能を開く - + indentity voucher (*.ic) 身分証明書(*.ic) - - - - - + + + + + InvokeTaxiAppFunction 証明書をバインド - - + + AliIotSetting - + Software Version Info - + Package - + Version バージョン - - + + Package name is null パッケージ名は空です - + Clearing Program プログラムクリア - - + + Timeout タイムアウト - - - - + + + + Failed 失敗 - + Getting Log ログを取得中 - - - - - - - - - - - - - + + + + + + + + + + + + + Error エラー - + Setting Timing Reboot スケジュール再起動を設定中 - + Set Timing Reboot スケジュール再起動の設定 - + Getting Timing Reboot スケジュール再起動を取得中 - + Get Timing Reboot スケジュール再起動の取得 - + totalResolution トータル解像度 - + strCurDisplayResolution 表示解像度 - - + + File not exist ファイルが存在しません - + Getting Player State プレーヤーの状態を取得しています - - - + + + Get Player State プレーヤーの状態の取得 - - + + Player State プレーヤーの状態 - - This operation will clear current program. - これにより、現在のプログラムが消去されます - - - - Do you want to continue? - 続行しますか? - - - - + + Cannot Open File ファイルのオープンに失敗しました - + Uploading アップロード中 - + Update 更新 - - + + Set Display Mode - - + + Get Display Mode - - + + Set Screen Offset - - + + Get Screen Offset - + Open file Failed ファイルのオープンに失敗しました - + Setting Wallpaper - - + + Set Wallpaper - + System Updating - - + + System Update - + Getting MCU Version - - + + MCU Version - + Select File ファイルを選択 - + Setting player background - - + + Set player background - + Clearing player background - - - - - - - - + + + + + + + + Clear player background - - + + GetScreenRotation 画面回転の取得 - - - + + + Charging Station じゅうでんぐい - + Setting Baud Rate - + Set Baud Rate - + Getting Baud Rate - + Get Baud Rate - - + + Text is empty - - + + Json Parse Error - - + + Json isn't an Object - + Info 情報 - + Setting card work mode ... - + Set card work mode - + Getting card work mode ... - + Get card work mode - + Input password パスワードを入力 - + Change Password パスワード変更 - + + Get Receive Card Num + 受信カード数の取得 + + + Resolution Config 解像度設定 - + Full screen フルスクリーン - + Part セクション - + Display Mode 表示モード - + Screen Position - + Offset - + Hidden Settings - + Click right button to hide - - + + Update MCU - + Get MCU Version - + Baud Config - + Model - + Uart - + Baud - - - - - - - - + + + + + + + + Get 得る - + Timing Reboot スケジュール再起動 - + Protocol プロトコル - + Server サービス - + Client クライアント - - + + SetScreenRotation 画面の回転を設定する - - + + SetMinBrightness 最小輝度値を設定します - - + + SetMaxBrightness 輝度最大値を設定 - - + + GetMinBrightness 輝度最小値を取得 - - + + GetMaxBrightness 輝度最大値を取得 - - + + Card work mode - - + + SetSpecialResolution 解像度を設定 - - + + GetSpecialResolution 読み込み解像度 - - + + CleanDisplayScreenSize デフォルトの解像度を復元 - - + + SetHighForBusy 客レベルの設定 - - + + GetStateForBusy ゲストレベルを取得 @@ -911,76 +886,80 @@ - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tip 提示 @@ -988,50 +967,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + NoSelectedController 先に大きいスクリーンを選んでください @@ -1046,7 +1031,7 @@ 正しい高さのピクセル値を入力してください - + Password is error パスワード @@ -2427,209 +2412,185 @@ CtrlTestPanel - + Test Screen テスト画面 - + Line test 線テスト - - + + + - Red - - + + + - Green - - + + + - Blue - - + + + - White - + Vertical 縦線 - + Slash 斜線 - - + + Horizontal 水平線 - - + + Speed スピード - + ms(>10) ミリ秒(>10) - + Line Distance 線の間隔 + + - - Test テスト - + Gradation test グレースケールテスト - + Only the gray value is displayed 色の値のみを表示 - + GrayValue グレースケール値 - + Color test カラーテスト - + Gradient グラデーション - + Clear クリア - + Reset ループ - - - - + + Success + 成功 + + + + + Anycast リクエスト - + Stop 停止 - - - - - - - - + + + + + + + Tip 提示 - - - - - - + + + + + + NoSelectedController 先に大きいスクリーンを選んでください - - - - - - + + + + + + StartTest テストを開始します - - + + StopTest テストを中止します - - loopback mode + + Loop Mode サイクルモード - - Connect timeout - 接続タイムアウト - - - - - receive - 受信 - - - - Connect - 接続 - - - - timeout - タイムアウト - - - + Reset loop mode ループを設定 - - - - success - 成功 - CtrlVerifyClockPanel @@ -3097,29 +3058,29 @@ Def - - - - + + + - - - + + + + Device replied デバイス応答 - + - + Success 成功 - - + + Fail 失敗 @@ -3128,235 +3089,235 @@ DevicePanel - + All トータル トータル - + Online オンライン中 - - + + Refresh 更新 更新 - - - + + + Specify IP 指定IP 指定IP - - - - - + + + + + Current Screen 現在のスクリーン - - - + + + none なし - + Current Brightness 現在の明るさ - + Android Version Androidバージョン - + FPGA Version FPGAバージョン - + Brightness Level 輝度レベル - + Android OS Resolution Androidの解像度 - + Firmware Version ファームウェアバージョン - - + - + + Player Version プレーヤーファームウェアバージョン - + Detail Info 詳細 - + Getting 取得中 - + Specify IP list 指定 IP リスト - + Search 検索 - - + + Attention 注意 - - + + Please input IP address! IPアドレスを入力してください! - + Cancel キャンセル - + Screen ID ターミナルID - + Screen Size スクリーンサイズ - + Alias 別名 - + Screenshot スクリーンショット - - + + On オン - - + + Off オフ - + Brightness Adj. 輝度設定 - + Power Control 電源コントロール - + Net Config ネット配置 - + Time Sync タイマ配置 - + Video source ビデオソース - + Password ひそかに言う - + Advanced 上級パラメータ - + Volume Adj. 音量調節 - + Test テスト - - + + Multi screen operation マルチスクリーン操作 - - + + selected num 選択された数 - - + + Clear クリア - + More Info 詳細 - + Screen Brightness 画面の明るさ - + Power Status 画面切り替えステータス - + Security 暗号化 @@ -3395,549 +3356,643 @@ EAClock - + Basic Properties 基本的な属性 - + Time Zone タイムゾーン - + Custom Dial ユーザー定義の文字盤 - + Select 選択 - + Select Dail file 文字盤の画像を選択 - + Hour Mark 時間目盛り - - + + Circular 円形 - - + + Rectangle 矩形 - + Number デジタル - + Min Mark 分目盛り - + Color カラー - + Length 長さ - + Width - + Hour Hand 時針 - + Min Hand 分針 - + Sec Hand 秒針 - + Show 表示 - + Text テキスト - - - Play Properties - 再生方法 - - - - Play Duration - 再生時間 - - - - s - - EBase - + Area 領域(px) - + X X - + Y Y - + W W - + H H - + Border ボーダー - - + + + + None なし - + + Effect 特効 - + Rotate 回転 - + Blink きらめき - + Speed スピード - + Slow 遅い - + Moderate - + Fast 速い + + + Play Time + 再生時間 + + + + Start + スタート + + + + + + + s + + + + + Duration + 期間 + + + + Entry + 入場する + + + + + Random + ランダム + + + + + Expand horizontal + 水平展開 + + + + + Expand vertical + 垂直展開 + + + + + Expand to left + 左に展開 + + + + + Expand to top + 上へ展開 + + + + + Expand to right + 右に展開 + + + + + Expand to bottom + 下へ展開 + + + + Zoom in + 拡大 + + + + Zoom in from left-top + 左上から拡大 + + + + Zoom in from right-top + 右上から拡大 + + + + Zoom in from right-bottom + 右下から拡大 + + + + Zoom in from left-bottom + 左下から拡大 + + + + + Rotate zoom + 回転拡大 + + + + + Rotate zoom reverse + 逆回転拡大 + + + + Fade in + フェードイン + + + + + Move to left + 左に移動 + + + + + Move to top + 上へ移動 + + + + + Move to right + 右に移動 + + + + + Move to bottom + 下へ移動 + + + + + Dur + 時間 + + + + Exit + 出場する + + + + Zoom out + 縮小 + + + + Zoom out to left-top + 左上に縮小 + + + + Zoom out to right-top + 右上に縮小 + + + + Zoom out to right-bottom + 右下に縮小 + + + + Zoom out to left-bottom + 左下に縮小 + + + + Fade out + フェードアウト + EDClock - + MON 月曜日 - + TUE 火曜日 - + WED 水曜日 - + THU 木曜日 - + FRI 金曜日 - + SAT 土曜日 - + SUN 日曜日 - - + + AM 午前 - - + + PM 午後 - + Basic Properties 基本的な属性 - + Time Zone タイムゾーン - + Year - + Month - + Day - + Hour - + Min. - + Sec. - + Weekly 曜日 - + Full Year 四桁数の年 - + 12-Hour 12時 - + Date Style 日付スタイル - + Time Style タイムスタイル - + Display Style 表示スタイル - + Multiline 複数行表示 - - - Play Properties - 再生方法 - - - - Play Duration - 再生時間 - - - - s - - EEnviron - - - - - - - - - - - - - - - north - 北の方 - - - - - - - - - - - - - - - - - east - - - - - - - - - - - - - - - - - - south - 南の方 - - - - - - - - - - - - - - - - - west - 西の方 - - - + Temperature 温度 - + Humidity 湿度 - + Noise ノイズ - + Wind Speed 風速 - + Wind Direction 風向 - + Pressure 気圧 - + Rainfall うりょう - + Radiation ふく射 - + Beam ひかりのつよさ - + + + + N + + + + + + + NE + + + + + + + E + + + + + + + SE + + + + + + + S + + + + + + + SW + + + + + + + W + + + + + + + NW + + + + Basic Properties 基本的な属性 - + Title タイトル - + Compensation 補償 - + Left 左に寄る - + Center 中央にある - + Right 右に寄る - + Single scroll 1行スクロール - + Speed スピード - - ms/pixel - ミリ秒/ピクセル - - - + Back Color 背景色 - - - Play Properties - 再生方法 - - - - Play Duration - 再生時間 - - - - s - - EGif - + Basic Properties 基本的な属性 - + File ファイル - + Select File ファイルを選択 - - - Play Properties - 再生方法 - - - - Play Duration - 再生時間 - - - - s - - - - - Play Times - 再生回数 - EMultiWin @@ -4016,118 +4071,27 @@ EPhoto - + Basic Properties 基本的な属性 - + File ファイル - + Select File ファイルを選択 - + Image Read Error 画像読み込みエラー - - Play Properties - 再生方法 - - - - Play Duration - 再生時間 - - - - - s - - - - - Enter Style - 開始効果 - - - - None - なし - - - - Alpha In - 淡入 - - - - Moving to left - 連続する左シフト - - - - Moving to right - 連続右シフト - - - - Moving to top - 連続アップコンバート - - - - Move to bottom - 連続的下向 - - - - Zoom In - 拡大 - - - - Zoom In to left_bottom - 左下の拡大 - - - - Zoom In to left_top - 左上の角を大きく - - - - Zoom In to right_top - 右上拡大 - - - - Zoom In to right bottom - 右下隅を大きく - - - - Rotate to right - 右回り - - - - Rotate to left - 左回り - - - - Enter Duration - 効果時間 - - - + Images (*.png *.jpg *.jpeg *.bmp) 写真(*.png *.jpg *.jpeg *.bmp) @@ -4135,191 +4099,122 @@ EText - + Enter your text 内容を入力してください - + Basic Properties 基本的な属性 - + Back Color 背景色 - + Kerning 字の間隔 - + Line Spacing 間隔 - + PageCount: 総ページ数: - + page ページ - + Import txt File インポート txt ファイル - + Select File ファイルを選択 - + Fail 失敗 - + Cannot Open File ファイルのオープンに失敗しました - + Play Properties 再生方法 - + Flip 次頁 - + Scroll スクロール - + Static スタティック - - - - Play Duration - 再生時間 - - - - Duration/Page - ページごとの再生時間 - - - - Effect time - 効果時間 - - - - - Tip Info - ヒント - - - - - Effect time cannot be longer than duration time - 効果の長さはプレイ時間より長くできません - - - - s - - - - + Text Color テキスト色 - + Colorful Text まばゆい文字 - - - Entrance Effect - 開始効果 - - no - なし - - - - random - ランダム - - - - right to left - 左へ連続移動 - - - - bottom to top - 連続して上に移動 - - - - left to right - 右へ連続移動 - - - - top to bottom - 連続して下に移動 - - - Head-Tail Spacing 首尾間隔 - + Scroll Style スクロール方向 - + Right -> Left 左へ - + Bottom -> Top 上へ - + Left -> Right 右へ - + Top -> Bottom 下へ - + Scroll Speed スクロールスピード @@ -4327,142 +4222,117 @@ ETimer - + day - + hour - + min - + sec - + Basic Properties 基本的な属性 - + Count Down カウントダウン - + Count Up カウントアップ - + Time 目標時間 - + Day - + Hour - + Min - + Sec - + Multiline 複数行表示 - + Text テキスト - - - Play Properties - 再生方法 - - - - Play Duration - 再生時間 - - - - s - - EVideo - + Basic Properties 基本的な属性 - + File ファイル - + Play Properties 再生方法 - - Play Duration - 再生時間 - - - + Select File ファイルを選択 - - s - - - - + Play Times 再生回数 - + Video Transcoding - - + + Video Transcoding Progress ビデオ変換の進歩 - - + + Error エラー @@ -4480,40 +4350,30 @@ EWeb - + Basic Properties 基本的な属性 - - - Play Duration - 再生時間 - - - - s - - EleTimer - + day - + hour - + min - + sec @@ -4521,67 +4381,67 @@ GenTmpThread - + MON 月曜日 - + TUE 火曜日 - + WED 水曜日 - + THU 木曜日 - + FRI 金曜日 - + SAT 土曜日 - + SUN 日曜日 - + AM 午前 - + PM 午後 - + day - + hour - + min - + sec @@ -4589,7 +4449,7 @@ ImgDlg - + Screenshot スクリーンショット @@ -4640,177 +4500,182 @@ MainWindow - + Language 言語 - + Help ヘルプ - - + + Check for updates アップデートをチェック - - + + firmware manager ファームウェア管理 - - - + + + Preferences プリファレンス設定 - - + + Info 情報 - - - + + + About 当ソフトウェアについて - - + + Setting 設置 - + Software Update ソフトウェアの更新 - + CurVersion 現在のバージョン - + Latest Version 最新バージョン - + Update Log 更新ログ - + The current version is already the latest version すでに最新バージョンです。 - + Video compress to ビデオ圧縮 to - + Video transcoding to トランスコード to - + Text antialiasing 文字のアンチエイリアス - + TextAntilaTip (ヒント:小さい間隔の大きい画面に適しています。このオプションを有効にすると、文字の端に影がフォントのエッジの滑らかさに達します。小さいサイズのスクリーンと単色のスクリーンは使用を推奨しません) - + Ultra-Long Screen Split 超ロングスクリーン分割 - + Program Send Batch - + Hide Detect Button - + + Show Alias in Terminal Control + 端末制御に別名を表示 + + + Show Lora Screen - + Download ダウンロード - + Fail 失敗 - + Cannot Save File ファイルの保存に失敗しました - - - + + + Downloading updates 更新をダウンロード - + Error エラー - + Device 端末管理 - + Program コンテンツ管理 - + Control ターミナルコントロール - + Lora Screen - + Check card ワンタッチ修復 - + Tip Info ヒント - + RestoreLedCardIpByUdpTip この操作はLAN内のすべてのコンピュータIPと同じセグメントにないコントロールカードを固定IPに修正します。慎重に操作してください。 @@ -4824,6 +4689,7 @@ + Error エラー @@ -4934,84 +4800,84 @@ PageListItem - + times - + Page name プログラム名 - + New 新規 - + Play times 再生回数 - + Sources Repeat ソースの繰り返し - + Audios オーディオ - + Total Dur 全期間 - - + + s - + Select File ファイルを選択 - + Duration 期間 - + Vol 音量 - + Valid Date 有効期間 - - + + Warning 警告 - + Start Time can't be later than End Time 開始時間は終了時間より後にようにしてください - + End Time can't be earlier than Start Time 終了時間は開始時間より遅いようにしてください - + Plan タイムスケジュール @@ -5019,37 +4885,37 @@ PlanItemWgt - + M - + Tu - + W - + Th - + F - + Sa - + Su @@ -5057,17 +4923,17 @@ PlayWin - + Move to Top Left 左上隅に移動 - + Set Position 設定位置 - + Close 閉じる @@ -5075,12 +4941,12 @@ PlayerBackSendThread - + Open file failed ファイルのオープンに失敗しました - + Read file failed ファイルの読み込みに失敗しました @@ -5101,44 +4967,54 @@ ProgCreateDlg - + Resolution 解像度 - + Solution Information スケジュール情報 - + Solution Name リスト名 - + Width - + Height 高さ - + Remarks 備考 - + Ultra-Long Screen Split 超ロングスクリーン分割 - - Part Width - + + Horizontal + 水平 + + + + Vertical + 垂直 + + + + Lengths of Parts + 部分の長さ @@ -5149,192 +5025,192 @@ 保存 - + Setting 設置 - + Text テキスト - + Photo 写真 - + Video ビデオ - + Gif アニメーション - + Clock デジタル時計 - + Analog Clock アナログ時計 - + Environment 環境モニタリング - + Web ウェブページ - + MuliContentWindow マルチ素材ウィンドウ - + In this window, a plurality of different program materials can be added and played according to the order of joining the list; このウィンドウには、複数の異なる番組素材を追加して、リストに追加した順に再生することができます - + Timer タイマー - + Play 再生 - + Stop 停止 - + Publish 転送 - - - + + + Select File ファイルを選択 - + program 番組リスト - + Add page ページを追加 - + Copy page コピーページ - + Delete page ページを削除 - - + + Tip Info ヒント - + Are you sure you want to delete this program page? 本当にこの番組ページを削除しますか? - + Move up 前へ - + Move down 次頁 - + widget properties パッケージプロパティ - + Page properties プログラムのプロパティ - + Do you want to save the modifications? 変更された内容を保存してもよろしいですか? - + Create Dir failed ディレクトリの作成に失敗しました - + Saving... 保存中、少々お待ちください... - + Success 成功 - + Convertering データを整理する - + Demos テスト素材 - + Open Demo テスト素材を開く - + Generate preview data プレビューデータの生成 - - - + + + Error エラー - + Rename fail when saving - + Remove Recursively fail when saving @@ -5342,124 +5218,124 @@ ProgPanel - - + + New 新規 - - + + Edit 編集 - - + + Delete 削除 - - - + + + Import インポート - - - + + + Export 出力 - - + + Send 送信 - + Publish 転送 - + Name 名前 - - + + Choose Directory ディレクトリを選択 - + Tip 提示 - + The imported directory is already in the working directory, so there is no need to import it again! このインポートしたディレクトリはすでにワークディレクトリの下にあります。再インポートする必要はありません! - + :solution(s) already exist.are you sure you want to overwrite the existing solution(s)? 解決策は既に存在します。既存の解決策を上書きしたいと思いますか? - - + + Play 再生 - - + + Stop 停止 - + Resolution 解像度 - + File Size サイズ - + Last Modify 最終更新日 - + USB Update USB更新 - + Program name conflicted 番組名が重なる - + Warning 警告 - + You will delete the selected solution(s),are you sure? 是否确认删除选中的节目? - - + + Tip Info ヒント @@ -5467,17 +5343,17 @@ ProgPortDlg - + Solution Name リスト名 - + Progress 程度 - + Done 完了 @@ -5493,12 +5369,12 @@ QObject - + Setting up the LedOK Express... 初期化LedOK Express… - + Input password パスワードを入力 @@ -5508,34 +5384,34 @@ エラー - + USB Update Program USB更新プログラム - + Password パスワード - - + + Convertering データを整理する - - + + Tip 提示 - + No checked USB device チェックUSBデバイス - + please select usb device in list リスト内のUSBデバイスを選択してください @@ -5549,12 +5425,12 @@ プログラムは空です - + Open file failed ファイルのオープンに失敗しました - + Read file failed ファイルの読み込みに失敗しました @@ -5677,8 +5553,8 @@ - Installing - インストール中 + Upgrading + アップグレード中 diff --git a/LedOK/ts/app_pt.ts b/LedOK/ts/app_pt.ts index 2879d85..91758fc 100644 --- a/LedOK/ts/app_pt.ts +++ b/LedOK/ts/app_pt.ts @@ -56,240 +56,235 @@ CtrlAdvancedPanel - + Advanced Avançado - + Screen Width(pixel) Largura do display(pixel) - + Width Largura - - + + Height Altura - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + Set Config - + Alias Apelido - + Web Server Address: Endereço do Web Server: - + MCU Uploading - + Setting - + Getting Baud Rate - + Traffic screen settings - + Setting protocol ... - + Set protocol - + Getting protocol ... - + Get protocol - - + + Port - + Model - - Realtimer Server Address: - Servidor de horário: + + Realtime Address: + Servidor de Realtime: - + update or uninstall - + Clear Limpar - + Check Apk Conferi Apk - + Uninstall Desinstalar - + Running check Conferir - + Restart Reiniciar - + Check Log Conferir Log - + Start LedSet4 Iniciar LedSet4.0 (Apk Display2.0 and higher) - + Open ADB Abri ADB debug - + Post Custom JSON Publicar JSON - - - - - - + + + + + + Clear Program Limpar Programa - - www.ledokcloud.com/realtime - - - - + Config Config - + Refresh Atualizar - + Restore to default Restaurar padrão - + Taxi top screen configuration Taxi top screen configuration - - + + Service:High Out of service:Low Service:Altura fora do pardão:Diminuir - - + + Service:Low Out of service:High Service:Altura fora do padrão:Aumentar - + Binding *.ic account indentity voucher Vincular *.identificação da conta - + Rotate Rotacionar - + Min brightness Brilho minimo - - - + + + Readback Ler - + Send Enviar - + Max brightness Brilho Maximo @@ -300,602 +295,582 @@ Conf. tamanho do painel - - - - - + + + + + Success Successo - + Compant ID: ID da empresa - + Compant ID ID da empresa - - InputWebServerAddressTip - Entre com endereço WebServer - - - - InputCompanyIdTip - Entre com a ID da empresa - - - - + + SetOnlineAddr Config o webserver - - + + ClearRealtimeServer Limpar - - + + SetRealtimeServer Config o server de realtimer - - Tip Info - Dica - - - - + + RestartAndroid Reiniciar - - + + running Rodar - - + + no running não rodar - + Check Apk Version Checar a versão da APK - - + + UninstallSoftware Desistalar - - + + Check apk running status Checar status do APK - - + + OpenAdb Abrir o debug - + indentity voucher (*.ic) Comprovante de ID (*.ic) - - - - - + + + + + InvokeTaxiAppFunction Vincular certificado - - + + AliIotSetting - + Software Version Info - + Package - + Version - - + + Package name is null - + Clearing Program - - + + Timeout Tempo esgotado - - - - + + + + Failed Falhou - + Getting Log Obtendo log - - - - - - - - - - - - - + + + + + + + + + + + + + Error Erro - + Getting Player State - - + + Player State - - - + + + Get Player State - + Setting Timing Reboot Config tempo de reiniciar - + Set Timing Reboot Config tempo de reiniciar - + Getting Timing Reboot Config tempo de reiniciar - + Get Timing Reboot Obtendo tempo de reinicialização - - + + Get Display Mode - - + + Set Screen Offset - + totalResolution Resolução total de FPGA - + strCurDisplayResolution Resolução do display - - + + File not exist Arquivo não encontrado - - This operation will clear current program. - - - - - Do you want to continue? - Continuar? - - - - + + Cannot Open File Não pode abrir arquivo - + Uploading Atualizando - + Update Atualizar - - + + Set Display Mode Config Display - - + + Get Screen Offset Obter display Offset - + Open file Failed Falaha em abrir - + Setting Wallpaper Config plano fundo - - + + Set Wallpaper Config plano fundo - + System Updating Atualizando - - + + System Update Sistema atualizado - + Getting MCU Version Obtendo versão - - + + MCU Version Verão de MCU - + Select File Arquivo selecionado - + Setting player background Config plano de fundo - - + + Set player background Config plano de fundo - + Clearing player background Apagar plano de fundo - - - - - - - - + + + + + + + + Clear player background Apagar plano de fundo - - + + GetScreenRotation Rotação do display - - - + + + Charging Station - + Setting Baud Rate Config Baud Rate - + Set Baud Rate Config Baud Rate - + Get Baud Rate Config Baud Rate - - + + Text is empty Testo em branco - - + + Json Parse Error Erro Json - - + + Json isn't an Object - + Info Info - + Setting card work mode ... - + Set card work mode - + Getting card work mode ... - + Get card work mode - + Input password Entre com a senha - + Change Password Troque a senha - + + Get Receive Card Num + Obter o número de cartões receptores + + + Resolution Config Config de resolução - + Full screen Full screen - + Part Parte - + Display Mode Modo do display - + Screen Position Posição da tela - + Offset Offset - + Hidden Settings Esconder Config - + Click right button to hide Clique com o botão direito para esconder - - + + Update MCU - + Get MCU Version Versão de MCU - + Baud Config Config Baudrate - + Uart Uart - + Baud Baud - - - - - - - - + + + + + + + + Get Obter - + Firmware Management - + Timing Reboot Reiniciando - + Protocol Protocolo - + Server Servidor - + Client Cliente - - + + SetScreenRotation Config a rotação do display - - + + SetMinBrightness Config brilho minimo - - + + SetMaxBrightness Config brilho maximo - - + + GetMinBrightness Obter bilho - - + + GetMaxBrightness Obter brilho - - + + Card work mode - - + + SetSpecialResolution Config resolução especial - - + + GetSpecialResolution Ler resolução especial - - + + CleanDisplayScreenSize Restaurar resolução - - + + SetHighForBusy Set level for busy - - + + GetStateForBusy Get level of busy @@ -911,76 +886,80 @@ - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tip Dica @@ -988,50 +967,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + NoSelectedController Selecionar o display @@ -1046,7 +1031,7 @@ Entre com a correta altura - + Password is error Senha esta errada @@ -2427,209 +2412,185 @@ CtrlTestPanel - + Test Screen Teste o display - + Line test Teste de linha - - + + + - Red Vermelho - - + + + - Green Verde - - + + + - Blue Azul - - + + + - White Branco - + Vertical Vertical - + Slash Linha diagonal - - + + Horizontal Horizontal - - + + Speed Velocidade - + ms(>10) - + Line Distance Distancia entre linhas + + - - Test Teste - + Gradation test Teste de graduação - + Only the gray value is displayed Apenas graduação de cinza - + GrayValue Valor de cinza - + Color test Teste de cores - + Gradient Gradiente - + Clear Limpar - + Reset Loop - - - - + + Success + Successo + + + + + Anycast Anycast - + Stop Parar - - - - - - - - + + + + + + + Tip TDicas - - - - - - + + + + + + NoSelectedController Selecione o display - - - - - - + + + + + + StartTest Inicie teste - - + + StopTest Parar teste - - loopback mode + + Loop Mode Mode loop - - Connect timeout - Esgotado tempo de conexão - - - - - receive - Recebido - - - - Connect - Conectado - - - - timeout - Tempo esgotado - - - + Reset loop mode Mode de loop reset - - - - success - successo - CtrlVerifyClockPanel @@ -3097,29 +3058,29 @@ Def - - - - + + + - - - + + + + Device replied Equipamento replicado - + - + Success Successo - - + + Fail Falhou @@ -3128,236 +3089,236 @@ DevicePanel - + All ALL Todos - + Online Online Online - - + + Refresh Refresh Atializar - - - + + + Specify IP Specify IP Definir IP - - - - - + + + + + Current Screen Display atual - - - + + + none none - + Current Brightness Brilho atual - + Android Version Android - + FPGA Version Versão FPGA - + Brightness Level Nivel brilho - + Android OS Resolution Resolução Android - + Firmware Version Versão de Firmware - - + - + + Player Version Versão do player - + Detail Info Detalhe de informação - + Getting Obtendo info - + Specify IP list Definir IP - + Search Procurar - - + + Attention Atenção - - + + Please input IP address! Entre com endereço IP! - + Cancel Cancelar - + Screen ID ID do display - + Screen Size Tamanho do display - + Screenshot Capturar tela - - + + On Ligado - - + + Off Desligado - + Brightness Adj. Brilho Adj. - + Power Control Controle de energia - + Net Config Config de rede - + Time Sync Hora Sinc - + Video source Entrada video - + Password Senha - + Advanced Avançado - + Volume Adj. Volume - + Test Teste - - + + Multi screen operation Operação de multi display - - + + selected num Selecionar numero - - + + Clear Limpar - + More Info Mais Info - + Alias Apelido - + Screen Brightness Brilho do display - + Power Status Estatus de funcionam - + Security encriptação @@ -3396,548 +3357,678 @@ EAClock - + Basic Properties Propriedade basica - + Time Zone Fuso horário - + Custom Dial Customizar - + Select Selecionar - + Select Dail file Selecionar dial - + Hour Mark Escala de hora - - + + Circular Circulo - - + + Rectangle Retangulo - + Number Numero - + Min Mark Escala de minuto - + Color Cores - + Length Comprimento - + Width Largura - + Hour Hand Ponteiro hora - + Min Hand Ponteiro min - + Sec Hand Ponteiro seg - + Show Apresentar - + Text Texto - - - Play Properties - Propriedades - - - - Play Duration - Duração - - - - s - s - EBase - + Area Area(px) - + X X - + Y Y - + W L - + H A - + Border Borda - - + + + + None None - + + Effect Efeito - + Rotate Rotacionar - + Blink Piscar - + Speed Velocidade - + Slow Devagar - + Moderate Moderado - + Fast Rapido + + + Play Time + + + + + Start + + + + + + + + s + s + + + + Duration + Duração + + + + Entry + + + + + + Random + + + + + + Expand horizontal + + + + + + Expand vertical + + + + + + Expand to left + + + + + + Expand to top + + + + + + Expand to right + + + + + + Expand to bottom + + + + + Zoom in + + + + + Zoom in from left-top + + + + + Zoom in from right-top + + + + + Zoom in from right-bottom + + + + + Zoom in from left-bottom + + + + + + Rotate zoom + + + + + + Rotate zoom reverse + + + + + Fade in + + + + + + Move to left + + + + + + Move to top + + + + + + Move to right + + + + + + Move to bottom + Mover para baixo + + + + + Dur + + + + + Exit + + + + + Zoom out + + + + + Zoom out to left-top + + + + + Zoom out to right-top + + + + + Zoom out to right-bottom + + + + + Zoom out to left-bottom + + + + + Fade out + + EDClock - + MON Seg - + TUE Ter - + WED Qua - + THU Qui - + FRI Sex - + SAT Sab - + SUN Dom - - + + AM AM - - + + PM PM - + Basic Properties Propiedades basicas - + Time Zone Fuso - + Year YAno - + Month Mês - + Day Dia - + Hour Hora - + Min. Min. - + Sec. Seg. - + Weekly Dia da semana - + Full Year 4-Digitos Ano - + 12-Hour 12-Houras - + Date Style Formato data - + Time Style Formato hora - + Display Style Estilo display - + Multiline Multilinha - - Play Properties - - - - Play Duration - Duração + Duração - s - s + s EEnviron - - - - - - - - - - - - - - - north - north - - - - - - - - - - - - - - - - - east - leste - - - - - - - - - - - - - - - - - south - sul - - - - - - - - - - - - - - - - - west - west - - - + Temperature Temperatura - + Humidity Umidade - + Noise Ruido - + Wind Speed Velocidade vento - + Wind Direction Direção do vento - + Pressure Pressão - + Rainfall Chuva - + Radiation Radiação - + Beam Luminosa - + + + + N + + + + + + + NE + + + + + + + E + + + + + + + SE + + + + + + + S + + + + + + + SW + + + + + + + W + + + + + + + NW + + + + Basic Properties Basic properties - + Title Titulo - + Compensation Compensação - + Left Esquerda - + Center Centro - + Right Direita - + Single scroll Rolar simples - + Speed Velocidade - - ms/pixel - ms/pixel - - - + Back Color Cor fundo - Play Properties - Propriedades + Propriedades - Play Duration - Duração + Duração - s - s + s EGif - + Basic Properties Propriedades - + File Arquivo - + Select File Selecionar arq. - Play Properties - Propriedades + Propriedades - Play Duration - Duração + Duração - s - s + s - Play Times - Repetições + Repetições @@ -4017,118 +4108,91 @@ EPhoto - + Basic Properties Propriedades - + File Arquivo - + Select File Selec Arquivo - + Image Read Error Erro ao ler iamgem - - Play Properties - - - - Play Duration - Duração + Duração - - s - s + s - Enter Style - Efeito de entrada + Efeito de entrada - None - None + None - - Alpha In - - - - Moving to left - Mover esuqerda + Mover esuqerda - Moving to right - Mover direita + Mover direita - Moving to top - Mover para cima + Mover para cima - Move to bottom - Mover para baixo + Mover para baixo - Zoom In - ZOOM_IN + ZOOM_IN - Zoom In to left_bottom - ZOOM_IN_esquerda_inferior + ZOOM_IN_esquerda_inferior - Zoom In to left_top - ZOOM_IN_esquerda superior + ZOOM_IN_esquerda superior - Zoom In to right_top - ZOOM_IN_direita superior + ZOOM_IN_direita superior - Zoom In to right bottom - ZOOM_IN_direita inferior + ZOOM_IN_direita inferior - Rotate to right - Rotacionar_para_direita + Rotacionar_para_direita - Rotate to left - Rotacionar_para_esquerda + Rotacionar_para_esquerda - Enter Duration - Duração do efeito + Duração do efeito - + Images (*.png *.jpg *.jpeg *.bmp) Imagens(*.png *.jpg *.jpeg *.bmp) @@ -4136,191 +4200,174 @@ EText - + Enter your text Entre com o texto - + Basic Properties Propriedades - + Back Color Cor de fundo - + Kerning Kerning - + Line Spacing Espaços - + PageCount: Paginas: - + page Pagina - + Import txt File Importar arquivo - + Select File Selecionar arquivo - + Fail Falhou - + Cannot Open File Não pode abrir - + Play Properties Propriedades - + Flip Virar - + Scroll Rodar - + Static Estático - - - Play Duration - Duração + Duração - Duration/Page - Duração/Pagina + Duração/Pagina - Effect time - Duração do efeito + Duração do efeito - - Tip Info - Info + Info - - Effect time cannot be longer than duration time - O tempo de efeito não pode ser mais longo que a duração + O tempo de efeito não pode ser mais longo que a duração - s - s + s - + Text Color Cor do texto - + Colorful Text Texto colorido - Entrance Effect - Efeito de entrada + Efeito de entrada + + + no + Não + + + random + Aleatório + + + right to left + Da direita para esquerda + + + bottom to top + De baixo para cima + + + left to right + Da esquerda para direita + + + top to bottom + De cima para baixo - no - Não - - - - random - Aleatório - - - - right to left - Da direita para esquerda - - - - bottom to top - De baixo para cima - - - - left to right - Da esquerda para direita - - - - top to bottom - De cima para baixo - - - Head-Tail Spacing Espaçado - + Scroll Style Direção - + Right -> Left Da direita para esquerda - + Bottom -> Top de baixo para cima - + Left -> Right Da esquerda para direita - + Top -> Bottom De cima para baixo - + Scroll Speed Velocidade de rotação @@ -4328,142 +4375,133 @@ ETimer - + day Dias - + hour Horas - + min Min - + sec Seg - + Basic Properties Propriedades - + Count Down Contador regressivo - + Count Up Contador progressivo - + Time Target Time - + Day Dia - + Hour Hora - + Min Min - + Sec Seg - + Multiline Multilinha - + Text Texto - - Play Properties - - - - Play Duration - Duração + Duração - s - s + s EVideo - + Basic Properties Propriedades - + File Arquivo - + Play Properties - Play Duration - Tempo duração + Tempo duração - + Select File Selecionar arquivo - s - s + s - + Play Times Repetições - + Video Transcoding Transcodificação de video - - + + Video Transcoding Progress Processando - - + + Error Erro @@ -4481,40 +4519,38 @@ EWeb - + Basic Properties Propriedades - Play Duration - Duração + Duração - s - s + s EleTimer - + day Dias - + hour Horas - + min Mins - + sec Segs @@ -4522,67 +4558,67 @@ GenTmpThread - + MON Seg - + TUE Ter - + WED Qua - + THU Qui - + FRI Sex - + SAT Sab - + SUN Dom - + AM AM - + PM PM - + day Dias - + hour Horas - + min Mins - + sec Segs @@ -4590,7 +4626,7 @@ ImgDlg - + Screenshot Captura da tela @@ -4641,177 +4677,182 @@ MainWindow - + Language Idioma - + Help Ajuda - - + + Check for updates Checar atualizações - - + + firmware manager Gerenciador Firmware - - - + + + Preferences Preferencias - - + + Info Info - - - + + + About Sobre - - + + Setting Config - + Software Update Atualização deSoftware - + CurVersion Versão atual - + Latest Version Ultima versão - + Update Log Atualização de log - + The current version is already the latest version The current version is already the latest version - + Video compress to - + Video transcoding to - + Text antialiasing - + TextAntilaTip (Info:Não indicado para pequenos displays - + Ultra-Long Screen Split Dividir o Ecrã Ultralongo - + Program Send Batch - + Hide Detect Button - + + Show Alias in Terminal Control + Mostrar os aliases no controlo do terminal + + + Show Lora Screen - + Download - + Fail Falhou - + Cannot Save File Não pode salvar - - - + + + Downloading updates Atualizando - + Error Erro - + Device Painéis - + Program Editor - + Control Config - + Lora Screen Display LORA - + Check card Detectar - + Tip Info Info - + RestoreLedCardIpByUdpTip Esta operação irá fixar todos os painéis na LAN que não estão na mesma faixa de IP do seu PC. Atenção! @@ -4825,6 +4866,7 @@ + Error Erro @@ -4935,84 +4977,84 @@ PageListItem - + times Repetições - + Page name Nome programa - + New Novo - + Play times Repetições - + Sources Repeat - + Audios Audios - + Total Dur Duração total - - + + s s - + Select File Selecionar arquivos - + Duration Duração - + Vol Vol - + Valid Date Data de validade - - + + Warning Aviso - + Start Time can't be later than End Time Tempo de inicio não pode ser maior que o tempo final - + End Time can't be earlier than Start Time Tempo final não pode ser anter do tempo inicial - + Plan Plan @@ -5020,37 +5062,37 @@ PlanItemWgt - + M Seg - + Tu Ter - + W Qua - + Th Qui - + F Sex - + Sa Sab - + Su Dom @@ -5058,17 +5100,17 @@ PlayWin - + Move to Top Left Mover superior esquerdo - + Set Position Config posição - + Close Fechar @@ -5076,12 +5118,12 @@ PlayerBackSendThread - + Open file failed Abrir aqrquivo - + Read file failed Ler arquivo @@ -5102,44 +5144,54 @@ ProgCreateDlg - + Resolution Resolução - + Solution Information ID - + Solution Name Nome - + Width Largura - + Height Altura - + Remarks Observações - + Ultra-Long Screen Split Dividir o Ecrã Ultralongo - - Part Width - Largura da Parte + + Horizontal + + + + + Vertical + + + + + Lengths of Parts + Comprimento das peças @@ -5150,192 +5202,192 @@ Salvar - + Setting Configuração - + Text Texto - + Photo Foto - + Video Video - + Gif Gif - + Clock Relógio - + Analog Clock Relógio analogico - + Environment Monitoramento ambiente - + Web Web page - + MuliContentWindow Janela para varias midias - + In this window, a plurality of different program materials can be added and played according to the order of joining the list; Nesta janela, podem ser adicionados varios tipos de midia, sendo apresentados de acordo com a ordem da lista - + Timer Timer - + Play Tocar - + Stop Parar - + Publish Publicar - - - + + + Select File Selecionar arquivo - + program Programa - + Add page Adicionar pag - + Copy page Copiar pag - + Delete page Deletar pag - - + + Tip Info Info - + Are you sure you want to delete this program page? Você quer deletar esta pagina? - + Move up Mover para cima - + Move down Mover para baixo - + widget properties Propriedade - + Page properties Propriedades do programa - + Do you want to save the modifications? Você quer salvar esta modificação? - + Create Dir failed Criação falhou - + Saving... Salvando... - + Success Successo - + Convertering Convertendo - + Demos - + Open Demo - + Generate preview data Gerar dados de visualização - - - + + + Error Erro - + Rename fail when saving Falha em renomear - + Remove Recursively fail when saving Falha ao remover @@ -5343,124 +5395,124 @@ ProgPanel - - + + New Novo - - + + Edit Editar - - + + Delete Deletar - - - + + + Import Importar - - - + + + Export Exportar - - + + Send Enviar - + USB Update - + Publish Publicar - + Name Nome - - + + Choose Directory Escolha o diretorio - + Tip Dica - + The imported directory is already in the working directory, so there is no need to import it again! Este aquivo ja foi importado, não precisa realizar novamente! - + :solution(s) already exist.are you sure you want to overwrite the existing solution(s)? :Arquivo ja criado.Você quer sobrescrever? - - + + Play Tocar - - + + Stop Parar - + Resolution Resolução - + File Size Tamanho do arquivo - + Last Modify Ultima modificação - + Program name conflicted Conflito de nome - + Warning Aviso - + You will delete the selected solution(s),are you sure? Você quer deletar este arquivo? - - + + Tip Info Info @@ -5468,17 +5520,17 @@ ProgPortDlg - + Solution Name Nome - + Progress Progresso - + Done Concluido @@ -5494,12 +5546,12 @@ QObject - + Setting up the LedOK Express... Configurando... - + Input password Digite a senha @@ -5509,34 +5561,34 @@ Erro - + USB Update Program Actualizar do programa por USB - + Password Senha - - + + Convertering Convertendo - - + + Tip Dica - + No checked USB device USB não checado - + please select usb device in list Selecione o USB na lista @@ -5550,12 +5602,12 @@ Programa em branco - + Open file failed Falaha ao abrir - + Read file failed Ler arquivo com falha @@ -5678,8 +5730,8 @@ - Installing - Instalando + Upgrading + Actualização diff --git a/LedOK/ts/app_zh_CN.ts b/LedOK/ts/app_zh_CN.ts index 43f9ba6..5b53516 100644 --- a/LedOK/ts/app_zh_CN.ts +++ b/LedOK/ts/app_zh_CN.ts @@ -56,235 +56,230 @@ CtrlAdvancedPanel - + Advanced 高级设置 - + Screen Width(pixel) 屏幕宽(像素) - + Width - - + + Height - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + Set 设置 - + Alias 别名 - + Web Server Address: Web服务器地址: - + MCU Uploading 正在上传单片机 - + Setting 正在设置 - + Traffic screen settings 交通屏设置 - + Setting protocol ... 正在设置协议 ... - + Set protocol 设置协议 - + Getting protocol ... 正在回读协议 ... - + Get protocol 回读协议 - - + + Port 端口 - - Realtimer Server Address: - Realtimer地址: + + Realtime Address: + Realtime 地址: - + Firmware Management 固件管理 - + update or uninstall 更新或卸载 - + Clear 清空 - + Check Apk 检查Apk - + Uninstall 卸载 - + Running check 运行状态监测 - + Restart 重启 - + Check Log 查看日志 - + Start LedSet4 使用 LedSet4.0 配置LED模组(Apk Display2.0以上版本) - + Open ADB 打开ADB调试功能 - + Post Custom JSON Post Custom JSON - - - - - - + + + + + + Clear Program 清除节目 - - www.ledokcloud.com/realtime - - - - + Config 配置 - + Refresh 刷新 - + Restore to default 恢复默认值 - + Taxi top screen configuration 车顶有无客电平配置 - - + + Service:High Out of service:Low 有客:高电平 无客:低电平 - - + + Service:Low Out of service:High 有客:低电平 无客:高电平 - + Binding *.ic account indentity voucher 绑定taxihub平台用户身份凭证 - + Rotate 旋转 - + Min brightness 最低亮度 - - - + + + Readback 回读 - + Send 发送 - + Max brightness 最高亮度 @@ -295,607 +290,587 @@ 设置屏幕像素尺寸 - - - - - + + + + + Success 成功 - + Compant ID: 公司ID: - + Compant ID 公司ID - - InputWebServerAddressTip - 请输入Web服务器地址 - - - - InputCompanyIdTip - 请输入公司ID - - - - + + SetOnlineAddr 设置web服务器地址 - - + + ClearRealtimeServer 清除 - - + + SetRealtimeServer 设置RealTimer地址 - - Tip Info - 提示 - - - - + + RestartAndroid 重启 - - + + running 正在运行 - - + + no running 没有运行 - + Check Apk Version 查询已安装apk版本 - - + + UninstallSoftware 卸载 - - + + Check apk running status 监测APK运行状态 - - + + OpenAdb 打开ADB调试功能 - + indentity voucher (*.ic) 身份凭证(*.ic) - - - - - + + + + + InvokeTaxiAppFunction 绑定证书 - - + + AliIotSetting - + Software Version Info 软件版本信息 - + Package 包名 - + Version 版本 - - + + Package name is null 包名为空 - + Clearing Program 正在清除节目 - - + + Timeout 超时 - - - - + + + + Failed 失败 - + Getting Log 正在获取日志 - - - - - - - - - - - - - + + + + + + + + + + + + + Error 错误 - + Setting Timing Reboot 正在设置定时重启 - + Set Timing Reboot 设置定时重启 - + Getting Timing Reboot 正在获取定时重启 - + Get Timing Reboot 获取定时重启 - + totalResolution 包括行场数的分辨率 - + strCurDisplayResolution 当前显示屏分辨率 - - + + File not exist 文件不存在 - + Getting Player State 正在获取播放器状态 - - - + + + Get Player State 获取播放器状态 - - + + Player State 播放器状态 - - This operation will clear current program. - 这个操作会清除当前节目。 - - - - Do you want to continue? - 是否继续? - - - - + + Cannot Open File 文件打开失败 - + Uploading 正在上传 - + Update 更新 - - + + Set Display Mode 设置显示模式 - - + + Get Display Mode 获取显示模式 - - + + Set Screen Offset 设置屏幕偏移 - - + + Get Screen Offset 获取屏幕偏移 - + Open file Failed 文件打开失败 - + Setting Wallpaper 正在设置系统桌面背景 - - + + Set Wallpaper 设置系统桌面背景 - + System Updating 系统升级中 - - + + System Update 系统升级 - + Getting MCU Version 正在获取单片机版本 - - + + MCU Version 单片机版本 - + Select File 选择文件 - + Setting player background 正在设置播放器背景 - - + + Set player background 设置播放器背景 - + Clearing player background 正在清除播放器背景 - - - - - - - - + + + + + + + + Clear player background 清除播放器背景 - - + + GetScreenRotation 获取屏幕旋转 - - - + + + Charging Station 充电桩 - + Setting Baud Rate 正在设置波特率 - + Set Baud Rate 设置波特率 - + Getting Baud Rate 正在获取波特率 - + Get Baud Rate 获取波特率 - - + + Text is empty 文本为空 - - + + Json Parse Error - - + + Json isn't an Object - + Info 信息 - + Setting card work mode ... 正在设置控制卡工作模式 ... - + Set card work mode 设置控制卡工作模式 - + Getting card work mode ... 正在回读控制卡工作模式 ... - + Get card work mode 回读控制卡工作模式 - + Input password 输入密码 - + Change Password 修改密码 - + + Get Receive Card Num + 获取接收卡数量 + + + Resolution Config 分辨率配置 - + Full screen 全屏 - + Part 局部 - + Display Mode 显示模式 - + Screen Position 屏幕位置 - + Offset 偏移 - + Hidden Settings 隐藏的设置 - + Click right button to hide 点击右键隐藏 - - + + Update MCU 更新单片机 - + Get MCU Version 获取单片机版本 - + Baud Config 波特率配置 - + Model 设备型号 - + Uart 串口节点 - + Baud 波特率 - - - - - - - - + + + + + + + + Get 获取 - + Timing Reboot 定时重启 - + Protocol 协议 - + Server 服务端 - + Client 客户端 - - + + SetScreenRotation 设置屏幕旋转 - - + + SetMinBrightness 设置最小的亮度值 - - + + SetMaxBrightness 设置亮度最大值 - - + + GetMinBrightness 获取亮度最小值 - - + + GetMaxBrightness 获取亮度最大值 - - + + Card work mode 控制卡工作模式 - - + + SetSpecialResolution 设置分辨率 - - + + GetSpecialResolution 读取分辨率 - - + + CleanDisplayScreenSize 恢复默认分辨率 - - + + SetHighForBusy 设置有无客电平 - - + + GetStateForBusy 获取有无客电平 @@ -911,76 +886,80 @@ - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tip 提示 @@ -988,50 +967,56 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + NoSelectedController 请先选择大屏幕 @@ -1046,7 +1031,7 @@ 请输入正确的高度像素值 - + Password is error 密码错误 @@ -2427,209 +2412,185 @@ CtrlTestPanel - + Test Screen 测试屏幕 - + Line test 线条测试 - - + + + - Red - - + + + - Green 绿 - - + + + - Blue - - + + + - White - + Vertical 竖线 - + Slash 斜线 - - + + Horizontal 横线 - - + + Speed 速度 - + ms(>10) 毫秒(>10) - + Line Distance 线距 + + - - Test 测试 - + Gradation test 灰度测试 - + Only the gray value is displayed 只显示颜色值 - + GrayValue 灰度值 - + Color test 颜色测试 - + Gradient 渐变 - + Clear 清空 - + Reset 循环 - - - - + + Success + 成功 + + + + + Anycast 点播 - + Stop 停止 - - - - - - - - + + + + + + + Tip 提示 - - - - - - + + + + + + NoSelectedController 请先选择大屏幕 - - - - - - + + + + + + StartTest 开始测试 - - + + StopTest 停止测试 - - loopback mode + + Loop Mode 循环模式 - - Connect timeout - 连接超时 - - - - - receive - 接收 - - - - Connect - 连接 - - - - timeout - 超时 - - - + Reset loop mode 设置循环 - - - - success - 成功 - CtrlVerifyClockPanel @@ -3097,29 +3058,29 @@ Def - - - - + + + - - - + + + + Device replied 设备回复 - + - + Success 成功 - - + + Fail 失败 @@ -3128,236 +3089,236 @@ DevicePanel - + All 总数 总数 - + Online 在线 在线 - - + + Refresh 刷新 刷新 - - - - - + + + + + Current Screen 当前屏幕 - - - + + + none - - - + + + Specify IP 指定IP 指定IP - + Current Brightness 当前亮度 - + Android Version 安卓版本 - + FPGA Version FPGA版本 - + Brightness Level 亮度等级 - + Android OS Resolution 安卓分辨率 - + Firmware Version 固件版本 - - + - + + Player Version 播放器固件版本 - + Detail Info 详细信息 - + Getting 正在获取 - + Specify IP list 指定IP列表 - + Search 搜索 - - + + Attention 注意 - - + + Please input IP address! 请输入IP地址! - + Cancel 取消 - + Screen ID 屏幕ID - + Screen Size 屏幕像素 - + Alias 别名 - + Screenshot 回读画面 - - + + On - - + + Off - + Brightness Adj. 亮度调节 - + Power Control 电源控制 - + Net Config 网络配置 - + Time Sync 对时管理 - + Video source 同异步配置 - + Password 设置密码 - + Advanced 高级设置 - + Volume Adj. 音量调节 - + Test 测试 - - + + Multi screen operation 多屏操作 - - + + selected num 选中数目 - - + + Clear 清空 - + More Info 更多信息 - + Screen Brightness 屏幕亮度 - + Power Status 屏幕开关状态 - + Security 加密 @@ -3396,549 +3357,643 @@ EAClock - + Basic Properties 基本属性 - + Time Zone 时区 - + Custom Dial 自定义表盘 - + Select 选择 - + Select Dail file 选择表盘图片 - + Hour Mark 时标 - - + + Circular 圆形 - - + + Rectangle 矩形 - + Number 数字 - + Min Mark 分标 - + Color 颜色 - + Length - + Width - + Hour Hand 时针 - + Min Hand 分针 - + Sec Hand 秒针 - + Show 显示 - + Text 文本 - - - Play Properties - 播放方式 - - - - Play Duration - 播放时长 - - - - s - - EBase - + Area 区域(px) - + X - + Y - + W - + H - + Border 边框 - - + + + + None - + + Effect 特效 - + Rotate 旋转 - + Blink 闪烁 - + Speed 速度 - + Slow - + Moderate - + Fast + + + Play Time + 播放时间 + + + + Start + 开始 + + + + + + + s + + + + + Duration + 时长 + + + + Entry + 入场 + + + + + Random + 随机 + + + + + Expand horizontal + 水平展开 + + + + + Expand vertical + 垂直展开 + + + + + Expand to left + 向左展开 + + + + + Expand to top + 向上展开 + + + + + Expand to right + 向右展开 + + + + + Expand to bottom + 向下展开 + + + + Zoom in + 放大 + + + + Zoom in from left-top + 从左上角放大 + + + + Zoom in from right-top + 从右上角放大 + + + + Zoom in from right-bottom + 从右下角放大 + + + + Zoom in from left-bottom + 从左下角放大 + + + + + Rotate zoom + 旋转放大 + + + + + Rotate zoom reverse + 反向旋转放大 + + + + Fade in + 淡入 + + + + + Move to left + 向左移动 + + + + + Move to top + 向上移动 + + + + + Move to right + 向右移动 + + + + + Move to bottom + 向下移动 + + + + + Dur + 时长 + + + + Exit + 出场 + + + + Zoom out + 缩小 + + + + Zoom out to left-top + 向左上角缩小 + + + + Zoom out to right-top + 向右上角缩小 + + + + Zoom out to right-bottom + 向右下角缩小 + + + + Zoom out to left-bottom + 向左下角缩小 + + + + Fade out + 淡出 + EDClock - + MON 星期一 - + TUE 星期二 - + WED 星期三 - + THU 星期四 - + FRI 星期五 - + SAT 星期六 - + SUN 星期日 - - + + AM 上午 - - + + PM 下午 - + Basic Properties 基本属性 - + Time Zone 时区 - + Year - + Month - + Day - + Hour - + Min. - + Sec. - + Weekly 星期 - + Full Year 四位年 - + 12-Hour 12小时制 - + Date Style 日期风格 - + Time Style 时间风格 - + Display Style 显示风格 - + Multiline 多行显示 - - - Play Properties - 播放方式 - - - - Play Duration - 播放时长 - - - - s - - EEnviron - - - - - - - - - - - - - - - north - - - - - - - - - - - - - - - - - - east - - - - - - - - - - - - - - - - - - south - - - - - - - - - - - - - - - - - - west - 西 - - - + Temperature 温度 - + Humidity 湿度 - + Noise 噪音 - + Wind Speed 风速 - + Wind Direction 风向 - + Pressure 气压 - + Rainfall 雨量 - + Radiation 辐射 - + Beam 光照强度 - + + + + N + + + + + + + NE + 东北 + + + + + + E + + + + + + + SE + 东南 + + + + + + S + + + + + + + SW + 西南 + + + + + + W + 西 + + + + + + NW + 西北 + + + Basic Properties 基本属性 - + Title 标题 - + Compensation 补偿 - + Left 靠左 - + Center 居中 - + Right 靠右 - + Single scroll 单行滚动 - + Speed 速度 - - ms/pixel - 毫秒/像素 - - - + Back Color 背景色 - - - Play Properties - 播放方式 - - - - Play Duration - 播放时长 - - - - s - - EGif - + Basic Properties 基本属性 - + File 文件 - + Select File 选择文件 - - - Play Properties - 播放方式 - - - - Play Duration - 播放时长 - - - - s - - - - - Play Times - 播放次数 - EMultiWin @@ -4017,118 +4072,27 @@ EPhoto - + Basic Properties 基本属性 - + File 文件 - + Select File 选择文件 - + Image Read Error 图片读取错误 - - Play Properties - 播放方式 - - - - Play Duration - 播放时长 - - - - - s - - - - - Enter Style - 入场特效 - - - - None - - - - - Alpha In - 淡入 - - - - Moving to left - 连续左移 - - - - Moving to right - 连续右移 - - - - Moving to top - 连续上移 - - - - Move to bottom - 连续下移 - - - - Zoom In - 放大 - - - - Zoom In to left_bottom - 左下角放大 - - - - Zoom In to left_top - 左上角放大 - - - - Zoom In to right_top - 右上角放大 - - - - Zoom In to right bottom - 右下角放大 - - - - Rotate to right - 向右旋转 - - - - Rotate to left - 向左旋转 - - - - Enter Duration - 特效时长 - - - + Images (*.png *.jpg *.jpeg *.bmp) 图片(*.png *.jpg *.jpeg *.bmp) @@ -4136,191 +4100,122 @@ EText - + Enter your text 请输入内容 - + Basic Properties 基本属性 - + Back Color 背景色 - + Kerning 字间距 - + Line Spacing 行距 - + PageCount: 总页数: - + page - + Import txt File 导入 txt 文件 - + Select File 选择文件 - + Fail 失败 - + Cannot Open File 文件打开失败 - + Play Properties 播放方式 - + Flip 翻页 - + Scroll 滚动 - + Static 静态 - - - - Play Duration - 播放时长 - - - - Duration/Page - 每页播放时长 - - - - Effect time - 特效时长 - - - - - Tip Info - 提示 - - - - - Effect time cannot be longer than duration time - 特效时长不能大于播放时长 - - - - s - - - - + Text Color 文字颜色 - + Colorful Text 炫彩文字 - - - Entrance Effect - 入场特效 - - no - - - - - random - 随机 - - - - right to left - 连续左移 - - - - bottom to top - 连续上移 - - - - left to right - 连续右移 - - - - top to bottom - 连续下移 - - - Head-Tail Spacing 首尾间隔 - + Scroll Style 滚动方向 - + Right -> Left 向左 - + Bottom -> Top 向上 - + Left -> Right 向右 - + Top -> Bottom 向下 - + Scroll Speed 滚动速度 @@ -4328,142 +4223,117 @@ ETimer - + day - + hour - + min - + sec - + Basic Properties 基本属性 - + Count Down 倒计时 - + Count Up 正计时 - + Time 目标时间 - + Day - + Hour - + Min - + Sec - + Multiline 多行显示 - + Text 文本 - - - Play Properties - 播放方式 - - - - Play Duration - 播放时长 - - - - s - - EVideo - + Basic Properties 基本属性 - + File 文件 - + Play Properties 播放方式 - - Play Duration - 播放时长 - - - + Select File 选择文件 - - s - - - - + Play Times 播放次数 - + Video Transcoding 视频转码 - - + + Video Transcoding Progress 视频转码进度 - - + + Error 错误 @@ -4481,40 +4351,30 @@ EWeb - + Basic Properties 基本属性 - - - Play Duration - 播放时长 - - - - s - - EleTimer - + day - + hour - + min - + sec @@ -4522,67 +4382,67 @@ GenTmpThread - + MON 星期一 - + TUE 星期二 - + WED 星期三 - + THU 星期四 - + FRI 星期五 - + SAT 星期六 - + SUN 星期日 - + AM 上午 - + PM 下午 - + day - + hour - + min - + sec @@ -4590,7 +4450,7 @@ ImgDlg - + Screenshot 屏幕截图 @@ -4641,177 +4501,182 @@ MainWindow - + Language 语言 - + Help 帮助 - - + + Check for updates 检查更新 - - + + firmware manager 固件管理 - - - + + + Preferences 偏好设置 - - + + Info 信息 - - - + + + About 关于 - - + + Setting 设置 - + Software Update 软件更新 - + CurVersion 当前版本 - + Latest Version 最新版本 - + Update Log 更新日志 - + The current version is already the latest version 已经是最新的版本 - + Video compress to 视频压缩成 - + Video transcoding to 视频转码成 - + Text antialiasing 文字反锯齿 - + TextAntilaTip (提示:该选项适合小间距大尺寸的屏幕,选中此项,文字边缘会有暗影已达到字体边缘光滑的效果;小尺寸屏幕和单双色屏幕不建议使用) - + Ultra-Long Screen Split 超长屏打折 - + Program Send Batch 同时发送节目数量 - + Hide Detect Button 隐藏一键找卡 - + + Show Alias in Terminal Control + 在终端控制显示别名 + + + Show Lora Screen 显示光影屏 - + Download 下载 - + Fail 失败 - + Cannot Save File 保存文件失败 - - - + + + Downloading updates 正在下载更新 - + Error 错误 - + Device 设备管理 - + Program 节目管理 - + Control 终端控制 - + Lora Screen 光影屏 - + Check card 一键找卡 - + Tip Info 提示 - + RestoreLedCardIpByUdpTip 该操作会把局域网内的所有与计算机IP不在同一网段的控制卡修复成固定IP,请谨慎操作! @@ -4825,6 +4690,7 @@ + Error 错误 @@ -4935,84 +4801,84 @@ PageListItem - + times - + Page name 节目名称 - + New 新建 - + Play times 播放次数 - + Sources Repeat 素材循环 - + Audios 音频 - + Total Dur 总时长 - - + + s - + Select File 选择文件 - + Duration 时长 - + Vol 音量 - + Valid Date 有效日期 - - + + Warning 警告 - + Start Time can't be later than End Time 开始时间不能晚于结束时间 - + End Time can't be earlier than Start Time 结束时间不能早于开始时间 - + Plan 时间计划表 @@ -5020,37 +4886,37 @@ PlanItemWgt - + M - + Tu - + W - + Th - + F - + Sa - + Su @@ -5058,17 +4924,17 @@ PlayWin - + Move to Top Left 移动到左上角 - + Set Position 设置位置 - + Close 关闭 @@ -5076,12 +4942,12 @@ PlayerBackSendThread - + Open file failed 文件读取失败 - + Read file failed 文件读取失败 @@ -5102,44 +4968,54 @@ ProgCreateDlg - + Resolution 分辨率 - + Solution Information 节目信息 - + Solution Name 节目名称 - + Width - + Height - + Remarks 备注 - + Ultra-Long Screen Split 超长屏打折 - - Part Width - 打折宽度 + + Horizontal + 水平 + + + + Vertical + 垂直 + + + + Lengths of Parts + 每段长度 @@ -5150,192 +5026,192 @@ 保存 - + Setting 设置 - + Text 文本 - + Photo 图片 - + Video 视频 - + Gif 动画 - + Clock 数字时钟 - + Analog Clock 模拟时钟 - + Environment 环境监测 - + Web 网页 - + MuliContentWindow 多素材窗口 - + In this window, a plurality of different program materials can be added and played according to the order of joining the list; 该窗口中可以加入多个不同是节目素材,并按照加入列表的先后顺序播放 - + Timer 计时器 - + Play 播放 - + Stop 停止 - + Publish 发布 - - - + + + Select File 选择文件 - + program 节目列表 - + Add page 添加页面 - + Copy page 复制页面 - + Delete page 删除页面 - - + + Tip Info 提示 - + Are you sure you want to delete this program page? 确定要删除该节目页吗? - + Move up 向上移动一个页面 - + Move down 向下移动一个页面 - + widget properties 组件属性 - + Page properties 节目属性 - + Do you want to save the modifications? 是否保存修改? - + Create Dir failed 创建目录失败 - + Saving... 正在保存... - + Success 成功 - + Convertering 整理数据中 - + Demos 测试素材 - + Open Demo 打开测试素材 - + Generate preview data 生成预览数据 - - - + + + Error 错误 - + Rename fail when saving 重命名文件夹失败 - + Remove Recursively fail when saving @@ -5343,124 +5219,124 @@ ProgPanel - - + + New 新建 - - + + Edit 编辑 - - + + Delete 删除 - - - + + + Import 导入 - - - + + + Export 导出 - - + + Send 发送 - + Publish 发布 - + Name 名称 - - + + Choose Directory 选择目录 - + Tip 提示 - + The imported directory is already in the working directory, so there is no need to import it again! 该导入的目录已经在工作目录下,无需再次导入! - + :solution(s) already exist.are you sure you want to overwrite the existing solution(s)? :节目已存在。是否确实要覆盖现有节目? - - + + Play 播放 - - + + Stop 停止 - + Resolution 分辨率 - + File Size 文件大小 - + Last Modify 最后修改时间 - + USB Update USB更新 - + Program name conflicted 节目名称重复 - + Warning 警告 - + You will delete the selected solution(s),are you sure? 是否确认删除选中的节目? - - + + Tip Info 提示 @@ -5468,17 +5344,17 @@ ProgPortDlg - + Solution Name 节目名称 - + Progress 进度 - + Done 完成 @@ -5494,12 +5370,12 @@ QObject - + Setting up the LedOK Express... 初始化LedOK Express... - + Input password 输入密码 @@ -5509,34 +5385,34 @@ 错误 - + USB Update Program USB更新节目 - + Password 密码 - - + + Convertering 整理数据中 - - + + Tip 提示 - + No checked USB device 未检查USB设备 - + please select usb device in list 请在列表中选择usb设备 @@ -5550,12 +5426,12 @@ 节目为空 - + Open file failed 文件打开失败 - + Read file failed 文件读取失败 @@ -5678,8 +5554,8 @@ - Installing - 正在安装 + Upgrading + 升级中 @@ -5807,7 +5683,7 @@ Don't power off during this process - 这个过程请勿断电 + 升级过程中请勿断电 diff --git a/LedOK/ts/app_zh_TW.ts b/LedOK/ts/app_zh_TW.ts index 32c4ec6..00f1572 100644 --- a/LedOK/ts/app_zh_TW.ts +++ b/LedOK/ts/app_zh_TW.ts @@ -56,235 +56,230 @@ CtrlAdvancedPanel - + Advanced 高級設定 - + Screen Width(pixel) 螢幕寬(點數) - + Width - - + + Height - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + Set 設定 - + Alias 別名 - + Web Server Address: Web伺服器地址: - + MCU Uploading 正在上傳單片機 - + Setting 正在設定 - + Traffic screen settings 交通屏設定 - + Setting protocol ... 正在設定協定 - + Set protocol 設定協定 - + Getting protocol ... 正在回讀協定 ... - + Get protocol 回讀協定 - - + + Port - - Realtimer Server Address: - Realtimer地址: + + Realtime Address: + Realtime 地址: - + Firmware Management 固件管理 - + update or uninstall 更新或卸載 - + Clear 清空 - + Check Apk 檢查Apk - + Uninstall 卸載 - + Running check 運行狀態監測 - + Restart 重啓 - + Check Log 查看日誌 - + Start LedSet4 - + Open ADB 打開ADB調試功能 - + Post Custom JSON Post Custom JSON - - - - - - + + + + + + Clear Program 清除節目 - - www.ledokcloud.com/realtime - - - - + Config 配寘 - + Refresh 檢測 - + Restore to default 恢復預設值 - + Taxi top screen configuration 車頂有無客電平配寘 - - + + Service:High Out of service:Low 有客:高電平無客:低電平 - - + + Service:Low Out of service:High 有客:低電平 無客:高電平 - + Binding *.ic account indentity voucher 綁定taxihub平臺用戶身份憑證 - + Rotate 旋轉 - + Min brightness 最低亮度 - - - + + + Readback 回讀 - + Send 發送 - + Max brightness 最高亮度 @@ -295,21 +290,21 @@ 設定螢幕點數尺寸 - - - - - + + + + + Success 成功 - + Compant ID: 公司ID: - + Compant ID 公司ID @@ -317,636 +312,622 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + NoSelectedController 請先選擇大螢幕 - - InputWebServerAddressTip - 請輸入Web伺服器地址 - - - - InputCompanyIdTip - 請輸入公司ID - - - - + + SetOnlineAddr 設定web伺服器地址 - - + + ClearRealtimeServer 清除 - - + + SetRealtimeServer 設定RealTimer地址 - - Tip Info - 提示 - - - - + + RestartAndroid 重啓 - - + + running 正在運行 - - + + no running 沒有運行 - + Check Apk Version 査詢已安裝apk版本 - - + + UninstallSoftware 卸載 - - + + Check apk running status 監測APK運行狀態 - - + + OpenAdb 打開ADB調試功能 - + indentity voucher (*.ic) 身份憑證(*.ic) - - - - - + + + + + InvokeTaxiAppFunction 綁定證書 - - + + AliIotSetting - + Software Version Info 軟體版本資訊 - + Package 包名 - + Version 版本 - - + + Package name is null 包名為空 - + Clearing Program 正在清除節目 - - + + Timeout 超時 - - - - + + + + Failed 失敗 - + Getting Log 讀取日誌 - - - - - - - - - - - - - + + + + + + + + + + + + + Error 錯誤 - + Setting Timing Reboot 正在設定定時重啓 - + Set Timing Reboot 設定定時重啓 - + Getting Timing Reboot 正在獲取定時重啓 - + Get Timing Reboot 獲取定時重啓 - + totalResolution 行数を含む解像度 - + strCurDisplayResolution 當前顯示分辯率 - - + + File not exist 檔案不存在 - + Getting Player State 正在獲取播放機狀態 - - - + + + Get Player State 獲取播放機狀態 - - + + Player State 播放機狀態 - - This operation will clear current program. - 這個操作會清除當前節目 - - - - Do you want to continue? - 是否繼續? - - - - + + Cannot Open File 檔案打開失敗 - + Uploading 正在上傳 - + Update 更新 - - + + Set Display Mode 設定顯示模式 - - + + Get Display Mode 獲取顯示模式 - - + + Set Screen Offset 設定螢幕偏移 - - + + Get Screen Offset 獲取螢幕偏移 - + Open file Failed 檔案打開失敗 - + Setting Wallpaper 正在設定系統桌面背景 - - + + Set Wallpaper 設定系統桌面背景 - + System Updating 系統升級中 - - + + System Update 系統升級 - + Getting MCU Version 正在獲取單片機版本 - - + + MCU Version 單片機版本 - + Select File 選擇檔案 - + Setting player background 正在設定播放機背景 - - + + Set player background 設定播放機背景 - + Clearing player background 正在清除播放機背景 - - - - - - - - + + + + + + + + Clear player background 清除播放機背景 - - + + GetScreenRotation 獲取荧幕旋轉 - - - + + + Charging Station 充電樁 - + Setting Baud Rate 正在設定串列傳輸速率 - + Set Baud Rate 設定串列傳輸速率 - + Getting Baud Rate 正在讀取串列傳輸速率 - + Get Baud Rate 讀取串列傳輸速率 - - + + Text is empty - - + + Json Parse Error - - + + Json isn't an Object - + Info 資訊 - + Setting card work mode ... 正在設定控制卡工作模式 ... - + Set card work mode 設定控制卡工作模式 - + Getting card work mode ... 正在回讀控制卡工作模式 ... - + Get card work mode 回讀控制卡工作模式 - + Input password 輸入密碼 - + Change Password 修改密碼 - + + Get Receive Card Num + 獲取接收卡數量 + + + Resolution Config 分辯率配寘 - + Full screen 全屏 - + Part 局部 - + Display Mode 顯示模式 - + Screen Position 螢幕位置 - + Offset 偏移 - + Hidden Settings 隱藏的設定 - + Click right button to hide 點擊右鍵隱藏 - - + + Update MCU 更新單片機 - + Get MCU Version 獲取單片機版本 - + Baud Config 串列傳輸速率配寘 - + Model 設備型號 - + Uart 串口節點 - + Baud 串列傳輸速率 - - - - - - - - + + + + + + + + Get 讀取 - + Timing Reboot 定時重啓 - + Protocol 協定 - + Server 服務端 - + Client 用戶端 - - + + SetScreenRotation 設定螢幕旋轉 - - + + SetMinBrightness 設定最小的亮度值 - - + + SetMaxBrightness 設定亮度最大值 - - + + GetMinBrightness 獲取亮度最小值 - - + + GetMaxBrightness 獲取亮度最大值 - - + + Card work mode 控制卡工作模式 - - + + SetSpecialResolution 設定分辯率 - - + + GetSpecialResolution 讀取分辯率 - - + + CleanDisplayScreenSize 恢復默認分辯率 - - + + SetHighForBusy 設定有無客電平 - - + + GetStateForBusy 獲取有無客電平 @@ -962,76 +943,80 @@ - - - - - - - - + + + + + + + - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tip 提示 @@ -1046,7 +1031,7 @@ 請輸入正確的高度點數值 - + Password is error 密碼錯誤 @@ -2432,209 +2417,185 @@ CtrlTestPanel - + Test Screen 測試螢幕 - + Line test 線條測試 - - + + + - Red - - + + + - Green - - + + + - Blue - - + + + - White - + Vertical 豎線 - + Slash 斜線 - - + + Horizontal 橫線 - - + + Speed 速度 - + ms(>10) 毫秒(>10) - + Line Distance 線距 + + - - Test 測試 - + Gradation test 灰度測試 - + Only the gray value is displayed 只顯示顏色值 - + GrayValue 灰度值 - + Color test 顏色測試 - + Gradient 漸變 - + Clear 清空 - + Reset 迴圈 - - - - + + Success + 成功 + + + + + Anycast 點播 - + Stop 停止 - - - - - - - - + + + + + + + Tip 提示 - - - - - - + + + + + + NoSelectedController 請先選擇大螢幕 - - - - - - + + + + + + StartTest 開始測試 - - + + StopTest 停止測試 - - loopback mode + + Loop Mode 迴圈模式 - - Connect timeout - 連接超時 - - - - - receive - 接收 - - - - Connect - 連接 - - - - timeout - 超時 - - - + Reset loop mode 設定迴圈 - - - - success - 成功 - CtrlVerifyClockPanel @@ -3102,29 +3063,29 @@ Def - - - - + + + - - - + + + + Device replied 設備回復 - + - + Success 成功 - - + + Fail 失敗 @@ -3133,234 +3094,234 @@ DevicePanel - + All 總數 - + Online 在线 線上 - - + + Refresh 檢測 - - - + + + Specify IP 指定IP 指定IP - - - - - + + + + + Current Screen 当前屏幕 - - - + + + none - + Current Brightness 當前亮度 - + Android Version 安卓版本 - + FPGA Version FPGA版本 - + Brightness Level 亮度等級 - + Android OS Resolution 安卓分辯率 - + Firmware Version 固件版本 - - + - + + Player Version 播放機固件版本 - + Detail Info 詳細資訊 - + Getting 正在獲取 - + Specify IP list 指定IP清單 - + Search 蒐索 - - + + Attention 注意 - - + + Please input IP address! 請輸入IP地址! - + Cancel 取消 - + Screen ID 螢幕ID - + Screen Size 螢幕點數 - + Alias 別名 - + Screenshot 回讀畫面 - - + + On - - + + Off - + Brightness Adj. 亮度調節 - + Power Control 電源控制 - + Net Config 網絡配寘 - + Time Sync 對時管理 - + Video source 同異步配寘 - + Password 設寘密碼 - + Advanced 高級設定 - + Volume Adj. 音量調節 - + Test 測試 - - + + Multi screen operation 多屏操作 - - + + selected num 選中數目 - - + + Clear 清空 - + More Info 更多資訊 - + Screen Brightness 螢幕亮度 - + Power Status 螢幕開關狀態 - + Security 加密 @@ -3399,549 +3360,643 @@ EAClock - + Basic Properties 基本屬性 - + Time Zone 時區 - + Custom Dial 自定義錶盤 - + Select 選擇 - + Select Dail file 選擇錶盤圖片 - + Hour Mark 時標 - - + + Circular 圓形 - - + + Rectangle 矩形 - + Number 數位 - + Min Mark 分標 - + Color 顏色 - + Length - + Width - + Hour Hand 時針 - + Min Hand 分針 - + Sec Hand 分針 - + Show 顯示 - + Text 文字 - - - Play Properties - 播放管道 - - - - Play Duration - 播放時長 - - - - s - - EBase - + Area 區域(px) - + X - + Y - + W - + H - + Border 邊框 - - + + + + None - + + Effect 特效 - + Rotate 旋轉 - + Blink 閃爍 - + Speed 速度 - + Slow - + Moderate - + Fast + + + Play Time + 播放時間 + + + + Start + 開始 + + + + + + + s + + + + + Duration + 時長 + + + + Entry + 入場 + + + + + Random + 隨機 + + + + + Expand horizontal + 水平展開 + + + + + Expand vertical + 垂直展開 + + + + + Expand to left + 向左展開 + + + + + Expand to top + 向上展開 + + + + + Expand to right + 向右展開 + + + + + Expand to bottom + 向下展開 + + + + Zoom in + 放大 + + + + Zoom in from left-top + 從左上角放大 + + + + Zoom in from right-top + 從右上角放大 + + + + Zoom in from right-bottom + 從右下角放大 + + + + Zoom in from left-bottom + 從左下角放大 + + + + + Rotate zoom + 旋轉放大 + + + + + Rotate zoom reverse + 反向旋轉放大 + + + + Fade in + 淡入 + + + + + Move to left + 向左移動 + + + + + Move to top + 向上移動 + + + + + Move to right + 向右移動 + + + + + Move to bottom + 向下移動 + + + + + Dur + 時長 + + + + Exit + 出場 + + + + Zoom out + 縮小 + + + + Zoom out to left-top + 向左上角縮小 + + + + Zoom out to right-top + 向右上角縮小 + + + + Zoom out to right-bottom + 向右下角縮小 + + + + Zoom out to left-bottom + 向左下角縮小 + + + + Fade out + 淡出 + EDClock - + MON 星期一 - + TUE 星期二 - + WED 星期三 - + THU 星期四 - + FRI 星期五 - + SAT 星期六 - + SUN 星期日 - - + + AM 上午 - - + + PM 下午 - + Basic Properties 基本屬性 - + Time Zone 時區 - + Year - + Month - + Day - + Hour - + Min. - + Sec. - + Weekly 星期 - + Full Year 四位年 - + 12-Hour 12小時制 - + Date Style 日期風格 - + Time Style 時間風格 - + Display Style 顯示風格 - + Multiline 多行顯示 - - - Play Properties - 播放管道 - - - - Play Duration - 播放時長 - - - - s - - EEnviron - - - - - - - - - - - - - - - north - - - - - - - - - - - - - - - - - - east - - - - - - - - - - - - - - - - - - south - - - - - - - - - - - - - - - - - - west - 西 - - - + Temperature 溫度 - + Humidity 濕度 - + Noise 譟音 - + Wind Speed 風速 - + Wind Direction 風向 - + Pressure 氣壓 - + Rainfall 雨量 - + Radiation 輻射 - + Beam 光照強度 - + + + + N + + + + + + + NE + 東北 + + + + + + E + + + + + + + SE + 東南 + + + + + + S + + + + + + + SW + 西南 + + + + + + W + 西 + + + + + + NW + 西北 + + + Basic Properties 基本屬性 - + Title 標題 - + Compensation 補償 - + Left 靠左 - + Center 居中 - + Right 靠右 - + Single scroll 單行滾動 - + Speed 速度 - - ms/pixel - 毫秒/點數 - - - + Back Color 背景色 - - - Play Properties - 播放管道 - - - - Play Duration - 播放時長 - - - - s - - EGif - + Basic Properties 基本屬性 - + File 檔案 - + Select File 選擇檔案 - - - Play Properties - 播放管道 - - - - Play Duration - 播放時長 - - - - s - - - - - Play Times - 播放次數 - EMultiWin @@ -4020,118 +4075,27 @@ EPhoto - + Basic Properties 基本屬性 - + File 檔案 - + Select File 選擇檔案 - + Image Read Error 圖片讀取錯誤 - - Play Properties - 播放管道 - - - - Play Duration - 播放時長 - - - - - s - - - - - Enter Style - 入場特效 - - - - None - - - - - Alpha In - 淡入 - - - - Moving to left - 連續左移 - - - - Moving to right - 連續右移 - - - - Moving to top - 連續上移 - - - - Move to bottom - 連續下移 - - - - Zoom In - 放大 - - - - Zoom In to left_bottom - 左下角放大 - - - - Zoom In to left_top - 左上角放大 - - - - Zoom In to right_top - 右上角放大 - - - - Zoom In to right bottom - 右下角放大 - - - - Rotate to right - 向右旋轉 - - - - Rotate to left - 向左旋轉 - - - - Enter Duration - 特效時長 - - - + Images (*.png *.jpg *.jpeg *.bmp) 圖片(*.png *.jpg *.jpeg *.bmp) @@ -4139,191 +4103,122 @@ EText - + Enter your text 請輸入內容 - + Basic Properties 基本屬性 - + Back Color 背景色 - + Kerning 字間距 - + Line Spacing 行距 - + PageCount: 總頁數: - + page - + Import txt File 導入 txt 檔案 - + Select File 選擇檔案 - + Fail 失敗 - + Cannot Open File 檔案打開失敗 - + Play Properties 播放管道 - + Flip 翻頁 - + Scroll 滾動 - + Static 靜態 - - - - Play Duration - 播放時長 - - - - Duration/Page - 每頁播放時長 - - - - Effect time - 特效時長 - - - - - Tip Info - 提示 - - - - - Effect time cannot be longer than duration time - 特效時長不能大於播放時長 - - - - s - - - - + Text Color 文字顏色 - + Colorful Text 炫彩文字 - - - Entrance Effect - 入場特效 - - no - - - - - random - 隨機 - - - - right to left - 連續左移 - - - - bottom to top - 連續上移 - - - - left to right - 連續右移 - - - - top to bottom - 連續下移 - - - Head-Tail Spacing 首尾間隔 - + Scroll Style 滾動方向 - + Right -> Left 向左 - + Bottom -> Top 向上 - + Left -> Right 向右 - + Top -> Bottom 向下 - + Scroll Speed 滾動速度 @@ -4331,142 +4226,117 @@ ETimer - + day - + hour - + min - + sec - + Basic Properties 基本屬性 - + Count Down 倒數計時 - + Count Up 正計時 - + Time 目標時間 - + Day - + Hour - + Min - + Sec - + Multiline 多行顯示 - + Text 文字 - - - Play Properties - 播放管道 - - - - Play Duration - 播放時長 - - - - s - - EVideo - + Basic Properties 基本屬性 - + File 檔案 - + Play Properties 播放管道 - - Play Duration - 播放時長 - - - + Select File 選擇檔案 - - s - - - - + Play Times 播放次數 - + Video Transcoding - - + + Video Transcoding Progress 視頻轉碼進度 - - + + Error 錯誤 @@ -4484,40 +4354,30 @@ EWeb - + Basic Properties 基本屬性 - - - Play Duration - 播放時長 - - - - s - - EleTimer - + day - + hour - + min - + sec @@ -4525,67 +4385,67 @@ GenTmpThread - + MON 星期一 - + TUE 星期二 - + WED 星期三 - + THU 星期四 - + FRI 星期五 - + SAT 星期六 - + SUN 星期日 - + AM 上午 - + PM 下午 - + day - + hour - + min - + sec @@ -4593,7 +4453,7 @@ ImgDlg - + Screenshot 螢幕截圖 @@ -4644,177 +4504,182 @@ MainWindow - + Language 語言 - + Help 幫助 - - + + Check for updates 檢查更新 - - + + firmware manager 固件管理 - - - + + + Preferences 偏好設定 - - + + Info 資訊 - - - + + + About 關於 - - + + Setting 設定 - + Software Update 軟體更新 - + CurVersion 當前版本 - + Latest Version 最新版本 - + Update Log 更新日誌 - + The current version is already the latest version 已經是最新的版本 - + Video compress to 視頻壓縮成 - + Video transcoding to 視頻轉碼成 - + Text antialiasing 文字反鋸齒 - + TextAntilaTip (提示:該選項適合小間距大尺寸的螢幕,選中此項,文字邊緣會有暗影已達到字體邊緣光滑的效果;小尺寸螢幕和單雙色螢幕不建議使用) - + Ultra-Long Screen Split 超長屏打折 - + Program Send Batch 同時發送節目數量 - + Hide Detect Button 隱藏一鍵找卡 - + + Show Alias in Terminal Control + 在終端控制顯示別名 + + + Show Lora Screen 顯示光影屏 - + Download 下載 - + Fail 失敗 - + Cannot Save File 保存檔案失敗 - - - + + + Downloading updates 下載更新 - + Error 錯誤 - + Device 設備管理 - + Program 節目管理 - + Control 終端控制 - + Lora Screen 光影屏 - + Check card 一鍵找卡 - + Tip Info 提示 - + RestoreLedCardIpByUdpTip 該操作會把局域網內的所有與電腦IP不在同一網段的控制卡修復成固定IP,請謹慎操作! @@ -4828,6 +4693,7 @@ + Error 錯誤 @@ -4938,84 +4804,84 @@ PageListItem - + times - + Page name 節目名稱 - + New 新建 - + Play times 播放次數 - + Sources Repeat 素材迴圈 - + Audios 音訊 - + Total Dur 總時長 - - + + s - + Select File 選擇檔案 - + Duration 時長 - + Vol 音量 - + Valid Date 有效日期 - - + + Warning 警告 - + Start Time can't be later than End Time 開始時間不能晚於結束時間 - + End Time can't be earlier than Start Time 結束時間不能早於開始時間 - + Plan 時間計畫表 @@ -5023,37 +4889,37 @@ PlanItemWgt - + M - + Tu - + W - + Th - + F - + Sa - + Su @@ -5061,17 +4927,17 @@ PlayWin - + Move to Top Left 移動到左上角 - + Set Position 設定位置 - + Close 關閉 @@ -5079,12 +4945,12 @@ PlayerBackSendThread - + Open file failed 檔案打開失敗 - + Read file failed 檔案讀取失敗 @@ -5105,44 +4971,54 @@ ProgCreateDlg - + Resolution 分辯率 - + Solution Information 節目資訊 - + Solution Name 節目名稱 - + Width - + Height - + Remarks 備註 - + Ultra-Long Screen Split 超長屏打折 - - Part Width - 打折寬度 + + Horizontal + 水平 + + + + Vertical + 垂直 + + + + Lengths of Parts + 每段長度 @@ -5153,192 +5029,192 @@ 保存 - + Setting 設定 - + Text 文字 - + Photo 圖片 - + Video 視頻 - + Gif 動畫 - + Clock 數位時鐘 - + Analog Clock 圓形時鐘 - + Environment 環境監測 - + Web 網頁 - + MuliContentWindow 多素材視窗 - + In this window, a plurality of different program materials can be added and played according to the order of joining the list; 該視窗中可以加入多個不同是節目素材,並按照加入列表的先後順序播放 - + Timer 計時器 - + Play 播放 - + Stop 停止 - + Publish 發佈 - - - + + + Select File 選擇檔案 - + program 節目清單 - + Add page 添加頁面 - + Copy page 複製頁面 - + Delete page 删除頁面 - - + + Tip Info 提示 - + Are you sure you want to delete this program page? 確定要删除該節目頁嗎? - + Move up 向上移動一個頁面 - + Move down 向下移動一個頁面 - + widget properties 組件内容 - + Page properties 節目内容 - + Do you want to save the modifications? 是否保存修改? - + Create Dir failed 創建目錄失敗 - + Saving... 正在保存… - + Success 成功 - + Convertering 整理數據中 - + Demos 測試素材 - + Open Demo 打開測試素材 - + Generate preview data 生成預覽數據 - - - + + + Error 錯誤 - + Rename fail when saving - + Remove Recursively fail when saving @@ -5346,124 +5222,124 @@ ProgPanel - - + + New 新建 - - + + Edit 編輯 - - + + Delete 删除 - - - + + + Import 導入 - - - + + + Export 匯出 - - + + Send 發送 - + Publish 發佈 - + Name 名稱 - - + + Choose Directory 選擇目錄 - + Tip 提示 - + The imported directory is already in the working directory, so there is no need to import it again! 該導入的目錄已經在工作目錄下,無需再次導入! - + :solution(s) already exist.are you sure you want to overwrite the existing solution(s)? :節目已存在。是否確實要覆蓋現有節目? - - + + Play 播放 - - + + Stop 停止 - + Resolution 分辯率 - + File Size 文件大小 - + Last Modify 最後修改時間 - + USB Update USB更新 - + Program name conflicted 節目名稱重複 - + Warning 警告 - + You will delete the selected solution(s),are you sure? 是否確認删除選中的節目? - - + + Tip Info 提示 @@ -5471,17 +5347,17 @@ ProgPortDlg - + Solution Name 節目名稱 - + Progress 進度 - + Done 完成 @@ -5497,12 +5373,12 @@ QObject - + Setting up the LedOK Express... 初始化LedOK Express… - + Input password 輸入密碼 @@ -5512,34 +5388,34 @@ 錯誤 - + USB Update Program USB更新節目 - + Password 密碼 - - + + Convertering 整理數據中 - - + + Tip 提示 - + No checked USB device 未檢查USB設備 - + please select usb device in list 請在清單中選擇usb設備 @@ -5553,12 +5429,12 @@ 節目為空 - + Open file failed 檔案打開失敗 - + Read file failed 檔案讀取失敗 @@ -5681,8 +5557,8 @@ - Installing - 正在安裝 + Upgrading + 陞級中 @@ -5810,7 +5686,7 @@ Don't power off during this process - 這個過程請勿斷電 + 陞級過程中請勿斷電