diff --git a/.gitignore b/.gitignore index ffa5ab4..2a86861 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,7 @@ moc_*.cpp qrc_*.cpp ui_*.h Makefile* +*/build/* build-* # QtCreator diff --git a/Compass/Compass.pro b/Compass/Compass.pro index 0bf981f..0cb6f68 100644 --- a/Compass/Compass.pro +++ b/Compass/Compass.pro @@ -10,7 +10,7 @@ RESOURCES += res.qrc win32 { EXE_SUFFIX = .exe - copy.files += $$files(ffmpeg/bin/*.dll) + # copy.files += $$files(ffmpeg/bin/*.dll) # copy.files += 7z/7z.dll # copy.files += 7z/7z.exe @@ -28,17 +28,17 @@ osx { QMAKE_BUNDLE_DATA += copy QMAKE_BUNDLE_DATA += copydir } -copy.files += ffmpeg$$DIR_SUFFIX/bin/ffmpeg$$EXE_SUFFIX +# copy.files += ffmpeg$$DIR_SUFFIX/bin/ffmpeg$$EXE_SUFFIX -INCLUDEPATH += $$PWD/ffmpeg$$DIR_SUFFIX/include -LIBS += -L$$PWD/ffmpeg$$DIR_SUFFIX/lib/\ - -lavcodec \ - -lavdevice \ - -lavfilter \ - -lavformat \ - -lavutil \ - -lswresample \ - -lswscale +# INCLUDEPATH += $$PWD/ffmpeg$$DIR_SUFFIX/include +# LIBS += -L$$PWD/ffmpeg$$DIR_SUFFIX/lib/\ +# -lavcodec \ +# -lavdevice \ +# -lavfilter \ +# -lavformat \ +# -lavutil \ +# -lswresample \ +# -lswscale # You can make your code fail to compile if it uses deprecated APIs. @@ -46,7 +46,6 @@ LIBS += -L$$PWD/ffmpeg$$DIR_SUFFIX/lib/\ #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 SOURCES += \ - ffutil.cpp \ gutil/cu.cpp \ gutil/qaesencryption.cpp \ gutil/qcore.cpp \ @@ -59,10 +58,11 @@ SOURCES += \ mainwindow.cpp \ mediapanel.cpp \ opendlg.cpp \ - planpanel.cpp + outputpanel.cpp \ + planpanel.cpp \ + progresspanel.cpp HEADERS += \ - ffutil.h \ gutil/cu.h \ gutil/qaesencryption.h \ gutil/qcore.h \ @@ -75,7 +75,9 @@ HEADERS += \ mainwindow.h \ mediapanel.h \ opendlg.h \ - planpanel.h + outputpanel.h \ + planpanel.h \ + progresspanel.h # Default rules for deployment. qnx: target.path = /tmp/$${TARGET}/bin diff --git a/Compass/ffutil.cpp b/Compass/ffutil.cpp deleted file mode 100644 index 624f5b5..0000000 --- a/Compass/ffutil.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include "ffutil.h" -#include -#include -extern "C"{ -#include -#include -} - -static void imgCleanupHandler(void *info) { - delete [] (uchar*)info; -} - -QString videoInfo(QByteArray url, QImage &img, int64_t *dur, AVCodecID *codec_id) { - AVFormatContext *fmt_ctx = avformat_alloc_context(); - QString err; - { - if(avformat_open_input(&fmt_ctx, url.constData(), 0, 0) != 0) { - err = "Couldn't open input stream"; - goto free; - } - if(avformat_find_stream_info(fmt_ctx, 0) < 0) { - err = "Couldn't find stream information"; - goto free; - } - if(dur) *dur = fmt_ctx->duration; - int vi_idx = -1; - for(uint ss=0; ssnb_streams; ss++) if(fmt_ctx->streams[ss]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {vi_idx = ss; break;} - if(vi_idx == -1) { - err = "Didn't find a Video Stream"; - goto free; - } - auto codecpar = fmt_ctx->streams[vi_idx]->codecpar; - if(codec_id) *codec_id = codecpar->codec_id; - qDebug()<<"codecpar w h"<width<<"x"<height<<"codec_id"<codec_id<codec_id); - if(av_seek_frame(fmt_ctx, -1, 1000000, AVSEEK_FLAG_BACKWARD) < 0) { - err = "av_seek_frame fail"; - goto free; - } - const AVCodec *decoder = avcodec_find_decoder(codecpar->codec_id); - if(decoder==0) { - err = "Could not found Video Decoder"; - goto free; - } - auto vcCtx = avcodec_alloc_context3(decoder); - avcodec_parameters_to_context(vcCtx, codecpar); - if(avcodec_open2(vcCtx, decoder, 0) < 0) { - err = "Could not open Video Codec Ctx"; - avcodec_free_context(&vcCtx); - goto free; - } - auto sws_ctx = sws_getContext(vcCtx->width, vcCtx->height, vcCtx->pix_fmt, vcCtx->width, vcCtx->height, AV_PIX_FMT_RGB32, SWS_FAST_BILINEAR, 0, 0, 0); - auto packet = av_packet_alloc(); - auto frm = av_frame_alloc(); - int dstStride[4]{(vcCtx->width*4+63)/64*64}; - dstStride[3] = dstStride[0] * vcCtx->height; - uint8_t *dst[4]{0}; - while(1) { - if(av_read_frame(fmt_ctx, packet) < 0) break; - if(packet->stream_index != vi_idx) continue; - int res = avcodec_send_packet(vcCtx, packet); - if(res < 0) break; - while((res = avcodec_receive_frame(vcCtx, frm)) != AVERROR(EAGAIN)) { - if(res < 0) goto free2; - dst[0] = new uchar[dstStride[3]]; - sws_scale(sws_ctx, frm->data, frm->linesize, 0, vcCtx->height, dst, dstStride); - img = QImage(dst[0], vcCtx->width, vcCtx->height, dstStride[0], QImage::Format_ARGB32, imgCleanupHandler, dst[0]); - goto free2; - } - } - free2: - av_frame_free(&frm); - av_packet_free(&packet); - avcodec_free_context(&vcCtx); - sws_freeContext(sws_ctx); - } - free: - avformat_close_input(&fmt_ctx); - return err; -} -QString audioInfo(QByteArray url, int64_t *dur) { - AVFormatContext *fmt_ctx = avformat_alloc_context(); - QString err; - { - if(avformat_open_input(&fmt_ctx, url.constData(), nullptr, nullptr) != 0) { - err = "Couldn't open input stream"; - goto free; - } - if(avformat_find_stream_info(fmt_ctx, nullptr) < 0) { - err = "Couldn't find stream information"; - goto free; - } - if(dur!=nullptr) *dur = fmt_ctx->duration; - } - free: - avformat_close_input(&fmt_ctx); - return err; -} diff --git a/Compass/ffutil.h b/Compass/ffutil.h deleted file mode 100644 index fff1b75..0000000 --- a/Compass/ffutil.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef FFUTIL_H -#define FFUTIL_H - -#include -extern "C"{ -#include -} - -QString videoInfo(QByteArray url, QImage &, int64_t *dur, AVCodecID *); -QString audioInfo(QByteArray url, int64_t *dur); - -#endif // FFUTIL_H diff --git a/Compass/layer.cpp b/Compass/layer.cpp index f50207e..0535cde 100644 --- a/Compass/layer.cpp +++ b/Compass/layer.cpp @@ -7,71 +7,54 @@ #include #include #include +#include +#include -Layer::Layer(int idx, const QString &name, QWidget *parent) : QWidget(parent), idx(idx), name(name) { - mSidePen.setCapStyle(Qt::FlatCap); - mSidePen.setDashPattern(QVector{1,3}); -} - -void Layer::paintEvent(QPaintEvent *event) { +void Layer::paintEvent(QPaintEvent *) { QPainter painter(this); - if(isSelected) { - mSidePen.setColor(Qt::green); - painter.setPen(mSidePen); + if(gEditView->selected == this) { + painter.setPen(item ? Qt::cyan : Qt::green); painter.drawRect(0, 0, width(), height()); - m_rLT = QRectF(-HandleSize/2, -HandleSize/2, HandleSize, HandleSize);//左上角 - m_rT = QRectF(width()/2 - HandleSize/2, -HandleSize/2, HandleSize, HandleSize);//上中 - m_rRT = QRectF(width() - HandleSize/2, - HandleSize/2, HandleSize, HandleSize);//右上角 - m_rL = QRectF(-HandleSize/2, height()/2 - HandleSize/2, HandleSize, HandleSize); - m_rR = QRectF(width() - HandleSize/2, height()/2 - HandleSize/2, HandleSize, HandleSize); - m_rLB = QRectF(-HandleSize/2, height() - HandleSize/2, HandleSize, HandleSize); - m_rB = QRectF(width()/2 - HandleSize/2, height() - HandleSize/2, HandleSize, HandleSize); - m_rRB = QRectF(width() - HandleSize/2, height() - HandleSize/2, HandleSize, HandleSize); - painter.setPen(Qt::green); - painter.drawRect(m_rLT); - painter.drawRect(m_rT); - painter.drawRect(m_rRT); - painter.drawRect(m_rL); - painter.drawRect(m_rR); - painter.drawRect(m_rLB); - painter.drawRect(m_rB); - painter.drawRect(m_rRB); + painter.drawRect(hdlLT); + painter.drawRect(hdlT); + painter.drawRect(hdlRT); + painter.drawRect(hdlL); + painter.drawRect(hdlR); + painter.drawRect(hdlLB); + painter.drawRect(hdlB); + painter.drawRect(hdlRB); } else { - mSidePen.setColor(Qt::darkGreen); - painter.setPen(mSidePen); + painter.setPen(item ? Qt::darkCyan : Qt::darkGreen); painter.drawRect(0, 0, width(), height()); } - //磁条吸附时两化吸附的边 - static QPen snapPen(Qt::green); - painter.setPen(snapPen); + QRectF rect(8, 8, width()-16, height()-16); + if(item) painter.drawText(rect, QString("%1\n%2×%3").arg(name).arg(sSize.width()).arg(sSize.height()), QTextOption(Qt::AlignCenter)); + else { + painter.drawText(rect, QString("%1 %2").arg(name).arg(idx), QTextOption(Qt::AlignLeft | Qt::AlignTop)); + painter.drawText(rect, QString("%1×%2").arg(sSize.width()).arg(sSize.height()), QTextOption(Qt::AlignRight | Qt::AlignBottom)); + } + + //吸附 high light + if(gEditView->selected != this)painter.setPen(item ? Qt::cyan : Qt::green); if(snapLR==1) painter.drawLine(0, 0, 0, height()); else if(snapLR==2) painter.drawLine(width(), 0, width(), height()); if(snapTB==1) painter.drawLine(0, 0, width(), 0); else if(snapTB==2) painter.drawLine(0, height(), width(), height()); - - QRectF rect(8, 8, width()-16, height()-16); - painter.drawText(rect, QString("%1 %2").arg(name).arg(idx), QTextOption(Qt::AlignLeft | Qt::AlignTop)); - painter.drawText(rect, QString("%1*%2").arg(sSize.width()).arg(sSize.height()), QTextOption(Qt::AlignRight | Qt::AlignBottom)); } void Layer::mousePressEvent(QMouseEvent *e) { QWidget::mousePressEvent(e); if(e->button() != Qt::LeftButton) return; - if(! isSelected) { - isSelected = true; - otherLayers.clear(); - auto parent = this->parentWidget(); - if(parent) { - auto children = parent->children(); - for(auto child : children) if(child!=this) { - auto layer = dynamic_cast(child); - if(layer==0) continue; - layer->isSelected = false; - otherLayers.emplace_back(layer); - } + if(item) { + if(! gOutPanel->isVisible()) return; + if(gEditView->selected!=this) { + gOutPanel->enCurChanged = false; + gOutPanel->tree->setCurrentItem(item); + gOutPanel->enCurChanged = true; } - } + } else if(gOutPanel->isVisible()) return; + gEditView->select(this); setFrmSec(e->pos()); auto mousePos = e->globalPosition(); auto elePos = pos(); @@ -91,8 +74,7 @@ void Layer::mouseReleaseEvent(QMouseEvent *event) { QWidget::mouseReleaseEvent(event); if(Qt::LeftButton == event->button()) { mPressRel.setX(FLT_MAX); - clearSnap(); - for(auto ele : otherLayers) ele->clearSnap(); + for(auto layer : gEditView->layers) layer->clearSnap(); } } #define SnapSpace 6 @@ -101,163 +83,167 @@ void Layer::mouseMoveEvent(QMouseEvent *e) { setFrmSec(e->pos()); return; } - if(! isSelected) return; + if(gEditView->selected != this) return; if(mFrmSec==Qt::NoSection || mPressRel.x()>=FLT_MAX) return; auto mousePos = e->globalPosition(); auto dstHor = mPressRel.x() + mousePos.x(); auto dstVer = mPressRel.y() + mousePos.y(); - snapLR = snapTB = 0; - for(auto ele : otherLayers) ele->clearSnap(); + bool posChanged = false, sizeChanged = false; + for(auto layer : gEditView->layers) layer->clearSnap(); if(mFrmSec==Qt::TitleBarArea) { - if(snapLR==0) for(auto ele : otherLayers) {//左右 - if(fabs(dstHor - ele->x()) < SnapSpace) { - dstHor = ele->x(); + if(snapLR==0) for(auto layer : gEditView->layers) if(layer!=this) {//左右 + if(fabs(dstHor - layer->x()) < SnapSpace) { + dstHor = layer->x(); snapLR = 1; - ele->snapLR = 1; - ele->update(); + layer->snapLR = 1; + layer->update(); break; } - auto eleRight = ele->x() + ele->width(); + auto eleRight = layer->x() + layer->width(); if(fabs(dstHor - eleRight) < SnapSpace) { dstHor = eleRight; snapLR = 1; - ele->snapLR = 2; - ele->update(); + layer->snapLR = 2; + layer->update(); break; } auto right = dstHor + width(); - if(fabs(right - ele->x()) < SnapSpace && ele->x() - width() >= 0) { - dstHor = ele->x() - width(); + if(fabs(right - layer->x()) < SnapSpace && layer->x() - width() >= 0) { + dstHor = layer->x() - width(); snapLR = 2; - ele->snapLR = 1; - ele->update(); + layer->snapLR = 1; + layer->update(); break; } if(fabs(right - eleRight) < SnapSpace && eleRight - width() >= 0) { dstHor = eleRight - width(); snapLR = 2; - ele->snapLR = 2; - ele->update(); + layer->snapLR = 2; + layer->update(); break; } } - if(snapTB==0) for(auto ele : otherLayers) {//上下 - if(fabs(dstVer-ele->y()) < SnapSpace) { - dstVer = ele->y(); + if(snapTB==0) for(auto layer : gEditView->layers) if(layer!=this) {//上下 + if(fabs(dstVer-layer->y()) < SnapSpace) { + dstVer = layer->y(); snapTB = 1; - ele->snapTB = 1; - ele->update(); + layer->snapTB = 1; + layer->update(); break; } - auto eleBtm = ele->y() + ele->height(); + auto eleBtm = layer->y() + layer->height(); if(fabs(dstVer - eleBtm) < SnapSpace) { dstVer = eleBtm; snapTB = 1; - ele->snapTB = 2; - ele->update(); + layer->snapTB = 2; + layer->update(); break; } auto btm = dstVer + height(); - if(fabs(btm - ele->y()) < SnapSpace && ele->y() - height() >= 0) { - dstVer = ele->y() - height(); + if(fabs(btm - layer->y()) < SnapSpace && layer->y() - height() >= 0) { + dstVer = layer->y() - height(); snapTB = 2; - ele->snapTB = 1; - ele->update(); + layer->snapTB = 1; + layer->update(); break; } if(fabs(btm - eleBtm) < SnapSpace && eleBtm - height() >= 0) { dstVer = eleBtm - height(); snapTB = 2; - ele->snapTB = 2; - ele->update(); + layer->snapTB = 2; + layer->update(); break; } } move(dstHor, dstVer); + posChanged = true; } else if(mFrmSec==Qt::BottomRightSection) { if(dstHor < HandleSize) dstHor = HandleSize; if(dstVer < HandleSize) dstVer = HandleSize; resize(dstHor, dstVer); + sizeChanged = true; } else if(mFrmSec==Qt::RightSection) { if(dstHor < HandleSize) dstHor = HandleSize; auto right = x() + dstHor; - for(Layer *ele : otherLayers) {//左右 - if(fabs(right - ele->x()) < SnapSpace) { - dstHor = ele->x() - x(); + for(Layer *layer : gEditView->layers) if(layer!=this) {//左右 + if(fabs(right - layer->x()) < SnapSpace) { + dstHor = layer->x() - x(); snapLR = 2; - ele->snapLR = 1; - ele->update(); + layer->snapLR = 1; + layer->update(); break; } - auto eleRight = ele->x() + ele->width(); + auto eleRight = layer->x() + layer->width(); if(fabs(right - eleRight) < SnapSpace) { dstHor = eleRight - x(); snapLR = 2; - ele->snapLR = 2; - ele->update(); + layer->snapLR = 2; + layer->update(); break; } } resize(dstHor, mPressRel.y()); + sizeChanged = true; } else if(mFrmSec==Qt::BottomSection) { if(dstVer < HandleSize) dstVer = HandleSize; auto btm = y() + dstVer; - for(Layer *ele : otherLayers) {//上下 - auto eleBtm = ele->y() + ele->height(); - if(fabs(btm - ele->y()) < SnapSpace) { - dstVer = ele->y() - y(); + for(Layer *layer : gEditView->layers) if(layer!=this) {//上下 + auto eleBtm = layer->y() + layer->height(); + if(fabs(btm - layer->y()) < SnapSpace) { + dstVer = layer->y() - y(); snapTB = 2; - ele->snapTB = 1; - ele->update(); + layer->snapTB = 1; + layer->update(); break; } if(fabs(btm - eleBtm) < SnapSpace) { dstVer = eleBtm - y(); snapTB = 2; - ele->snapTB = 2; - ele->update(); + layer->snapTB = 2; + layer->update(); break; } } resize(mPressRel.rx(), dstVer); + sizeChanged = true; } else { QRectF geo(x(), y(), width(), height()); if(mFrmSec==Qt::LeftSection) { dstHor = qMin(dstHor, geo.right() - HandleSize); - if(dstHor > 8) for(auto ele : otherLayers) {//左右 - if(fabs(dstHor - ele->x()) < SnapSpace) { - dstHor = ele->x(); + if(dstHor > 8) for(auto layer : gEditView->layers) if(layer!=this) {//左右 + if(fabs(dstHor - layer->x()) < SnapSpace) { + dstHor = layer->x(); snapLR = 1; - ele->snapLR = 1; - ele->update(); + layer->snapLR = 1; + layer->update(); break; } - auto eleRight = ele->x() + ele->width(); + auto eleRight = layer->x() + layer->width(); if(fabs(dstHor - eleRight) < SnapSpace) { dstHor = eleRight; snapLR = 1; - ele->snapLR = 2; - ele->update(); + layer->snapLR = 2; + layer->update(); break; } } geo.setLeft(dstHor); } else if(mFrmSec==Qt::TopSection) { dstVer = qMin(dstVer, geo.bottom() - HandleSize); - if(dstVer > 8) for(Layer *ele : otherLayers) {//上下 - if(fabs(dstVer - ele->y()) < SnapSpace) { - dstVer = ele->y(); + if(dstVer > 8) for(Layer *layer : gEditView->layers) if(layer!=this) {//上下 + if(fabs(dstVer - layer->y()) < SnapSpace) { + dstVer = layer->y(); snapTB = 1; - ele->snapTB = 1; - ele->update(); + layer->snapTB = 1; + layer->update(); break; } - auto eleBtm = ele->y() + ele->height(); + auto eleBtm = layer->y() + layer->height(); if(fabs(dstVer - eleBtm) < SnapSpace) { dstVer = eleBtm; snapTB = 1; - ele->snapTB = 2; - ele->update(); + layer->snapTB = 2; + layer->update(); break; } } @@ -279,10 +265,44 @@ void Layer::mouseMoveEvent(QMouseEvent *e) { geo.setBottom(dstVer); } setGeometry(geo.toRect()); + posChanged = true; + sizeChanged = true; + } + if(posChanged) sPos = (pos()-gOrigin) / gScale; + if(sizeChanged) sSize = size() / gScale; + if(item) { + view->setSceneRect({sPos, sSize}); + if(posChanged) { + gOutPanel->edX->blockSignals(true); + gOutPanel->edY->blockSignals(true); + gOutPanel->edX->setValue(sPos.x()); + gOutPanel->edY->setValue(sPos.y()); + gOutPanel->edX->blockSignals(false); + gOutPanel->edY->blockSignals(false); + } + if(sizeChanged) { + view->resize(sSize); + gOutPanel->edW->blockSignals(true); + gOutPanel->edH->blockSignals(true); + gOutPanel->edW->setValue(sSize.width()); + gOutPanel->edH->setValue(sSize.height()); + gOutPanel->edW->blockSignals(false); + gOutPanel->edH->blockSignals(false); + item->setText("size"**gOutPanel->tree, QString("%1×%2").arg(sSize.width()).arg(sSize.height())); + } + } else { + auto cell = (Cell*) gTable->data(rowIdx, gPlayinC).toULongLong(); + if(cell) { + if(posChanged) cell->wgt->setPos(sPos); + if(sizeChanged) { + if(cell->type=='V') { + ((QGraphicsVideoItem*) cell->wgt)->setSize(sSize); + } else if(cell->type=='I') { + ((ImgItem*) cell->wgt)->size = sSize; + } + } + } } - sPos = (pos()-gOrigin) / gScale; - auto cell = (Cell*) gTable->data(rowIdx, gPlayinC).toULongLong(); - if(cell) cell->wgt->setPos(sPos); } void Layer::leaveEvent(QEvent *) { setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor); @@ -290,14 +310,14 @@ void Layer::leaveEvent(QEvent *) { } void Layer::setFrmSec(const QPointF &pos) { - if(m_rLT.contains(pos)) setFrmSecIfNeed(Qt::TopLeftSection, Qt::SizeFDiagCursor); - else if(m_rT.contains(pos)) setFrmSecIfNeed(Qt::TopSection, Qt::SizeVerCursor); - else if(m_rRT.contains(pos)) setFrmSecIfNeed(Qt::TopRightSection, Qt::SizeBDiagCursor); - else if(m_rL.contains(pos)) setFrmSecIfNeed(Qt::LeftSection, Qt::SizeHorCursor); - else if(m_rR.contains(pos)) setFrmSecIfNeed(Qt::RightSection, Qt::SizeHorCursor); - else if(m_rLB.contains(pos)) setFrmSecIfNeed(Qt::BottomLeftSection, Qt::SizeBDiagCursor); - else if(m_rB.contains(pos)) setFrmSecIfNeed(Qt::BottomSection, Qt::SizeVerCursor); - else if(m_rRB.contains(pos)) setFrmSecIfNeed(Qt::BottomRightSection, Qt::SizeFDiagCursor); + if(hdlLT.contains(pos)) setFrmSecIfNeed(Qt::TopLeftSection, Qt::SizeFDiagCursor); + else if(hdlT.contains(pos)) setFrmSecIfNeed(Qt::TopSection, Qt::SizeVerCursor); + else if(hdlRT.contains(pos)) setFrmSecIfNeed(Qt::TopRightSection, Qt::SizeBDiagCursor); + else if(hdlL.contains(pos)) setFrmSecIfNeed(Qt::LeftSection, Qt::SizeHorCursor); + else if(hdlR.contains(pos)) setFrmSecIfNeed(Qt::RightSection, Qt::SizeHorCursor); + else if(hdlLB.contains(pos)) setFrmSecIfNeed(Qt::BottomLeftSection, Qt::SizeBDiagCursor); + else if(hdlB.contains(pos)) setFrmSecIfNeed(Qt::BottomSection, Qt::SizeVerCursor); + else if(hdlRB.contains(pos)) setFrmSecIfNeed(Qt::BottomRightSection, Qt::SizeFDiagCursor); else if(pos.x()>=0 && pos.x()<=width() && pos.y()>=0 && pos.y()<=height()) setFrmSecIfNeed(Qt::TitleBarArea, Qt::SizeAllCursor); else setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor); } @@ -313,3 +333,114 @@ void Layer::clearSnap() { snapLR = snapTB = 0; update(); } + +OutputView::OutputView(QWidget *parent) : QGraphicsView(parent) { + auto format = QSurfaceFormat::defaultFormat(); + format.setSwapBehavior(QSurfaceFormat::SingleBuffer); + format.setRenderableType(QSurfaceFormat::OpenGL); + auto glWgt = new QOpenGLWidget; + glWgt->setFormat(format); + + setViewport(glWgt); + setWindowFlag(Qt::FramelessWindowHint); + setAttribute(Qt::WA_AlwaysStackOnTop); + setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + setBackgroundBrush(Qt::black); + setAlignment(Qt::AlignTop|Qt::AlignLeft); + setTransformationAnchor(QGraphicsView::NoAnchor); + setInteractive(false); + setScene(gScene); +} +void OutputView::mousePressEvent(QMouseEvent *e) { + QWidget::mousePressEvent(e); + if(e->button() != Qt::LeftButton) return; + auto mousePos = e->globalPosition(); + auto elePos = pos(); + mPressRel = elePos - mousePos; +} + +void OutputView::mouseReleaseEvent(QMouseEvent *event) { + QWidget::mouseReleaseEvent(event); + if(Qt::LeftButton == event->button()) { + mPressRel.setX(FLT_MAX); + } + setAttribute(Qt::WA_AlwaysStackOnTop); +} +#define SnapSpace 6 +void OutputView::mouseMoveEvent(QMouseEvent *e) { + if(! (e->buttons() & Qt::LeftButton)) return; + if(mPressRel.x()>=FLT_MAX) return; + auto mousePos = e->globalPosition(); + auto dstHor = mPressRel.x() + mousePos.x(); + auto dstVer = mPressRel.y() + mousePos.y(); + // if(snapLR==0) for(auto layer : gEditView->layers) if(layer!=this) {//左右 + // if(fabs(dstHor - layer->x()) < SnapSpace) { + // dstHor = layer->x(); + // snapLR = 1; + // layer->snapLR = 1; + // layer->update(); + // break; + // } + // auto eleRight = layer->x() + layer->width(); + // if(fabs(dstHor - eleRight) < SnapSpace) { + // dstHor = eleRight; + // snapLR = 1; + // layer->snapLR = 2; + // layer->update(); + // break; + // } + // auto right = dstHor + width(); + // if(fabs(right - layer->x()) < SnapSpace && layer->x() - width() >= 0) { + // dstHor = layer->x() - width(); + // snapLR = 2; + // layer->snapLR = 1; + // layer->update(); + // break; + // } + // if(fabs(right - eleRight) < SnapSpace && eleRight - width() >= 0) { + // dstHor = eleRight - width(); + // snapLR = 2; + // layer->snapLR = 2; + // layer->update(); + // break; + // } + // } + // if(snapTB==0) for(auto layer : gEditView->layers) if(layer!=this) {//上下 + // if(fabs(dstVer-layer->y()) < SnapSpace) { + // dstVer = layer->y(); + // snapTB = 1; + // layer->snapTB = 1; + // layer->update(); + // break; + // } + // auto eleBtm = layer->y() + layer->height(); + // if(fabs(dstVer - eleBtm) < SnapSpace) { + // dstVer = eleBtm; + // snapTB = 1; + // layer->snapTB = 2; + // layer->update(); + // break; + // } + // auto btm = dstVer + height(); + // if(fabs(btm - layer->y()) < SnapSpace && layer->y() - height() >= 0) { + // dstVer = layer->y() - height(); + // snapTB = 2; + // layer->snapTB = 1; + // layer->update(); + // break; + // } + // if(fabs(btm - eleBtm) < SnapSpace && eleBtm - height() >= 0) { + // dstVer = eleBtm - height(); + // snapTB = 2; + // layer->snapTB = 2; + // layer->update(); + // break; + // } + // } + move(dstHor, dstVer); +} +void OutputView::leaveEvent(QEvent *) { + //setFrmSecIfNeed(Qt::NoSection, Qt::ArrowCursor); + mPressRel.setX(FLT_MAX); +} diff --git a/Compass/layer.h b/Compass/layer.h index 449c83d..e0c9c90 100644 --- a/Compass/layer.h +++ b/Compass/layer.h @@ -2,25 +2,25 @@ #define LAYER_H #include "main.h" -#include -#include #define HandleSize 10 +class OutputView; class Layer : public QWidget { Q_OBJECT public: - explicit Layer(int idx, const QString &name, QWidget *parent = 0); - inline void setGeo() { + explicit Layer(int idx, const QString &name, QWidget *parent = 0) : QWidget(parent), idx(idx), name(name) {} + inline void updateGeo() { setGeometry(QRect(sPos*gScale+gOrigin, sSize*gScale)); } + void select(); QPoint sPos; QSize sSize{1920, 1080}; int idx = 1, rowIdx = 0; QString name; - char type = 'L'; - bool isSelected = false; + TreeWidgetItem *item = 0; + OutputView *view = 0; protected: void paintEvent(QPaintEvent *) override; @@ -28,18 +28,41 @@ protected: void mouseReleaseEvent(QMouseEvent *) override; void mouseMoveEvent(QMouseEvent *) override; void leaveEvent(QEvent *) override; + void resizeEvent(QResizeEvent *event) override { + hdlT = QRectF(width()/2 - HandleSize/2, -HandleSize/2, HandleSize, HandleSize); + hdlRT = QRectF(width() - HandleSize/2, - HandleSize/2, HandleSize, HandleSize); + hdlL = QRectF(-HandleSize/2, height()/2 - HandleSize/2, HandleSize, HandleSize); + hdlR = QRectF(width() - HandleSize/2, height()/2 - HandleSize/2, HandleSize, HandleSize); + hdlLB = QRectF(-HandleSize/2, height() - HandleSize/2, HandleSize, HandleSize); + hdlB = QRectF(width()/2 - HandleSize/2, height() - HandleSize/2, HandleSize, HandleSize); + hdlRB = QRectF(width() - HandleSize/2, height() - HandleSize/2, HandleSize, HandleSize); + } void setFrmSec(const QPointF &); void setFrmSecIfNeed(Qt::WindowFrameSection frmSec, Qt::CursorShape cursor); void clearSnap(); - QPen mSidePen; - - QRectF m_rL, m_rR, m_rT, m_rB, m_rLT, m_rRT, m_rRB, m_rLB; + QRectF hdlLT = QRectF(-HandleSize/2, -HandleSize/2, HandleSize, HandleSize), hdlT, hdlRT, hdlL, hdlR, hdlLB, hdlB, hdlRB; QPointF mPressRel{FLT_MAX, FLT_MAX}; Qt::WindowFrameSection mFrmSec = Qt::NoSection; char snapLR = 0, snapTB = 0; - std::vector otherLayers; +}; + + +class OutputView : public QGraphicsView { + Q_OBJECT +public: + explicit OutputView(QWidget *parent = 0); + +protected: + void mousePressEvent(QMouseEvent *) override; + void mouseReleaseEvent(QMouseEvent *) override; + void mouseMoveEvent(QMouseEvent *) override; + void leaveEvent(QEvent *) override; + void clearSnap(); + + QPointF mPressRel{FLT_MAX, FLT_MAX}; + char snapLR = 0, snapTB = 0; }; #endif // LAYER_H diff --git a/Compass/liveeditor.cpp b/Compass/liveeditor.cpp index 934a811..8f9986e 100644 --- a/Compass/liveeditor.cpp +++ b/Compass/liveeditor.cpp @@ -4,26 +4,31 @@ #include "layer.h" #include #include +#include #include +#include LiveEditor::LiveEditor(QWidget *parent) : QWidget(parent) { - gScene = new QGraphicsScene(this); - auto hBox = new HBox(this); hBox->setContentsMargins(0, 0, 0, 0); hBox->setSpacing(0); - gEditView = new GraphicsView; + auto format = QSurfaceFormat::defaultFormat(); + format.setSwapBehavior(QSurfaceFormat::SingleBuffer); + QSurfaceFormat::setDefaultFormat(format); + + gEditView = new EditView; + gEditView->setViewport(new QOpenGLWidget); gEditView->setBackgroundBrush(Qt::black); gEditView->setAlignment(Qt::AlignTop|Qt::AlignLeft); - gEditView->setTransformationAnchor(GraphicsView::NoAnchor); + gEditView->setTransformationAnchor(QGraphicsView::NoAnchor); gEditView->setInteractive(false); gEditView->setSceneRect({-gOrigin / gScale, QSizeF(1, 1)}); - gEditView->setScene(gScene); + gEditView->setScene(gScene = new QGraphicsScene(this)); gEditView->scale(gScale, gScale); - auto origin = ((GraphicsView*)gEditView)->originWgt = new OriginWgt(gEditView); - origin->setGeometry(gOrigin.x()-10, gOrigin.y()-10, 20, 20); + gEditView->originWgt = new OriginWgt(gEditView); + gEditView->originWgt->setGeometry(gOrigin.x()-10, gOrigin.y()-10, 20, 20); hBox->addWidget(gEditView); @@ -32,9 +37,9 @@ LiveEditor::LiveEditor(QWidget *parent) : QWidget(parent) { toolBar->setStyleSheet("QToolBar{spacing: 2px;}"); toolBar->setIconSize({18, 18}); - auto actScaleUp = new QAction(QIcon(":/res/program/ScaleUp.png"), tr("Zoom In")); - toolBar->addAction(actScaleUp); - connect(actScaleUp, &QAction::triggered, this, [this] { + auto actScaleAdd = new QAction(QIcon(":/res/program/ScaleUp.png"), tr("Zoom In")); + toolBar->addAction(actScaleAdd); + connect(actScaleAdd, &QAction::triggered, this, [this] { if(gScale >= 8) return; gScale *= 1.1; scaleChanged(); @@ -45,9 +50,9 @@ LiveEditor::LiveEditor(QWidget *parent) : QWidget(parent) { edScale->setAlignment(Qt::AlignCenter); toolBar->addWidget(edScale); - auto actScaleDown = new QAction(QIcon(":/res/program/ScaleDown.png"), tr("Zoom Out")); - toolBar->addAction(actScaleDown); - connect(actScaleDown, &QAction::triggered, this, [this] { + auto actScaleMinus = new QAction(QIcon(":/res/program/ScaleDown.png"), tr("Zoom Out")); + toolBar->addAction(actScaleMinus); + connect(actScaleMinus, &QAction::triggered, this, [this] { if(gScale <= 0.01) return; gScale *= 0.909090909090; scaleChanged(); @@ -65,15 +70,13 @@ LiveEditor::LiveEditor(QWidget *parent) : QWidget(parent) { toolBar->addAction(actFull); hBox->addWidget(toolBar); } + void LiveEditor::scaleChanged() { gEditView->setSceneRect({-gOrigin / gScale, QSizeF(1, 1)}); QTransform tran; tran.scale(gScale, gScale); gEditView->setTransform(tran); - for(auto child : gEditView->children()) { - auto layer = dynamic_cast(child); - if(layer) layer->setGeo(); - } + for(auto layer : gEditView->layers) layer->updateGeo(); edScale->setText(QString::number(gScale)); } @@ -83,20 +86,40 @@ void LiveEditor::onTileFull() { // element->setPos(0,0); } - -void GraphicsView::mousePressEvent(QMouseEvent *e) { +void EditView::select(Layer *layer) { + if(selected==layer) return; + if(selected) selected->update(); + selected = layer; + if(selected==0) return; + selected->update(); + if(selected->item) { + gOutPanel->edName->setText(selected->item->text("name"**gOutPanel->tree)); + gOutPanel->edX->blockSignals(true); + gOutPanel->edY->blockSignals(true); + gOutPanel->edW->blockSignals(true); + gOutPanel->edH->blockSignals(true); + gOutPanel->edX->setValue(selected->sPos.x()); + gOutPanel->edY->setValue(selected->sPos.y()); + gOutPanel->edW->setValue(selected->sSize.width()); + gOutPanel->edH->setValue(selected->sSize.height()); + gOutPanel->edX->blockSignals(false); + gOutPanel->edY->blockSignals(false); + gOutPanel->edW->blockSignals(false); + gOutPanel->edH->blockSignals(false); + } +} +void EditView::mousePressEvent(QMouseEvent *e) { QWidget::mousePressEvent(e); if(e->button() != Qt::LeftButton) return; pressRel = gOrigin - e->globalPosition().toPoint(); } - -void GraphicsView::mouseReleaseEvent(QMouseEvent *event) { +void EditView::mouseReleaseEvent(QMouseEvent *event) { QWidget::mouseReleaseEvent(event); if(Qt::LeftButton == event->button()) { pressRel.setX(INT_MAX); } } -void GraphicsView::mouseMoveEvent(QMouseEvent *e) { +void EditView::mouseMoveEvent(QMouseEvent *e) { if(! (e->buttons() & Qt::LeftButton)) return; if(pressRel.x()==INT_MAX) return; auto mousePos = e->globalPosition().toPoint(); diff --git a/Compass/liveeditor.h b/Compass/liveeditor.h index 7b84ca8..3ea4f67 100644 --- a/Compass/liveeditor.h +++ b/Compass/liveeditor.h @@ -4,6 +4,17 @@ #include #include +class Layer; +class LiveEditor : public QWidget { + Q_OBJECT +public: + explicit LiveEditor(QWidget *parent = 0); + void scaleChanged(); + void onTileFull(); + + QLabel *edScale; +}; + class OriginWgt : public QWidget { public: using QWidget::QWidget; @@ -14,23 +25,14 @@ public: } }; -class Layer; -class LiveEditor : public QWidget { - Q_OBJECT -public: - explicit LiveEditor(QWidget *parent = 0); - - Layer* selected(); - void scaleChanged(); - void onTileFull(); - - QLabel *edScale; -}; - -class GraphicsView : public QGraphicsView { +class EditView : public QGraphicsView { Q_OBJECT public: using QGraphicsView::QGraphicsView; + void select(Layer *layer); + + Layer* selected = 0; + std::vector layers; OriginWgt *originWgt; protected: void mousePressEvent(QMouseEvent *) override; diff --git a/Compass/main.cpp b/Compass/main.cpp index 75f74ce..f5d6cce 100644 --- a/Compass/main.cpp +++ b/Compass/main.cpp @@ -10,9 +10,10 @@ QString gProgFile; JObj gProg; const QString UpdVerUrl; QGraphicsScene *gScene; -QGraphicsView *gEditView; +EditView *gEditView; double gScale = 0.1; QPoint gOrigin{20, 20}; +OutputPanel *gOutPanel; TableWidget *gTable, *gTableH, *gTableV; int gPlayinC = 0; //Tick *gTick; @@ -107,6 +108,5 @@ int main(int argc, char *argv[]) { //if(dlg.exec()!=QDialog::Accepted) return 0; } MainWindow w; - w.show(); return a.exec(); } diff --git a/Compass/main.h b/Compass/main.h index dcb96c2..9602d04 100644 --- a/Compass/main.h +++ b/Compass/main.h @@ -3,6 +3,8 @@ #include "gutil/qgui.h" #include "gutil/qjson.h" +#include "liveeditor.h" +#include "outputpanel.h" #include #include "QImageReader" #include @@ -15,9 +17,10 @@ extern QString gProgFile; extern JObj gProg; extern const QString UpdVerUrl; extern QGraphicsScene *gScene; -extern QGraphicsView *gEditView; +extern EditView *gEditView; extern double gScale; extern QPoint gOrigin; +extern OutputPanel *gOutPanel; extern TableWidget *gTable, *gTableH, *gTableV; extern int gPlayinC; //extern Tick *gTick; diff --git a/Compass/mainwindow.cpp b/Compass/mainwindow.cpp index 5bc4753..1bd1227 100644 --- a/Compass/mainwindow.cpp +++ b/Compass/mainwindow.cpp @@ -1,6 +1,8 @@ #include "mainwindow.h" #include "mediapanel.h" +#include "outputpanel.h" #include "planpanel.h" +#include "progresspanel.h" #include #include #include @@ -14,32 +16,37 @@ #include #include #include +#include MainWindow::MainWindow() { - resize(1280, 800); + resize(1400, 840); setWindowTitle("Compass"); setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea); setCentralWidget(liveEditor = new LiveEditor); - tabPorper = new QTabWidget; - tabPorper->setMinimumWidth(360); - tabPorper->setStyleSheet("QTabWidget::pane{border:none;}"); + tab = new QTabWidget; + tab->setMinimumWidth(360); + tab->setStyleSheet("QTabWidget::pane{border:none;}"); auto scroll = new QScrollArea; scroll->setFrameShape(QFrame::NoFrame); scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scroll->setWidgetResizable(true); - tabPorper->addTab(scroll, tr("Properties")); + tab->addTab(scroll, tr("Layer Properties")); - auto mediapanel = new MediaPanel; - tabPorper->addTab(mediapanel, tr("Library")); - tabPorper->setCurrentIndex(1); + auto mediaPanel = new MediaPanel; + tab->addTab(mediaPanel, tr("Media Library")); + + auto outputPanel = new OutputPanel; + tab->addTab(outputPanel, tr("Output")); + + tab->setCurrentIndex(1); auto dockProperties = new QDockWidget; dockProperties->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); dockProperties->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); - dockProperties->setWidget(tabPorper); + dockProperties->setWidget(tab); addDockWidget(Qt::RightDockWidgetArea, dockProperties); auto dockPlan = new QDockWidget(tr("Plan")); @@ -51,7 +58,7 @@ MainWindow::MainWindow() { auto dockProgress = new QDockWidget(tr("Progress")); dockProgress->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable); dockProgress->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea); - //dockProgress->setWidget(dockWidgetContents); + dockProgress->setWidget(new ProgressPanel); addDockWidget(Qt::BottomDockWidgetArea, dockProgress); splitDockWidget(dockPlan, dockProgress, Qt::Vertical); @@ -65,4 +72,11 @@ MainWindow::MainWindow() { action = new QAction(QIcon(":/res/program/Setting.png"), tr("Setting")); toolBar->addAction(action); toolBar->addSeparator(); + + show(); + dockProgress->setMaximumHeight(80); + + QTimer::singleShot(68, [=] { + dockProgress->setMaximumHeight(200); + }); } diff --git a/Compass/mainwindow.h b/Compass/mainwindow.h index 6dcf382..e584c1f 100644 --- a/Compass/mainwindow.h +++ b/Compass/mainwindow.h @@ -12,7 +12,7 @@ class MainWindow : public QMainWindow { public: MainWindow(); LiveEditor *liveEditor; - QTabWidget *tabPorper; + QTabWidget *tab; }; #endif // MAINWINDOW_H diff --git a/Compass/mediapanel.cpp b/Compass/mediapanel.cpp index 4b5a5f2..67179dc 100644 --- a/Compass/mediapanel.cpp +++ b/Compass/mediapanel.cpp @@ -14,19 +14,18 @@ #include #include +MediaTree *gMediaTree; + MediaPanel::MediaPanel(QWidget *parent) : QWidget(parent) { auto vBox = new VBox(this); vBox->setContentsMargins(0, 0, 0, 0); vBox->setSpacing(0); auto hBox = new HBox(vBox); - hBox->setContentsMargins(6,6,6,6); - hBox->setSpacing(6); - bnNew = new QPushButton(translate("","New")); - bnNew->setMinimumSize(75, 30); - bnNew->setProperty("ssType", "progManageTool"); - hBox->addWidget(bnNew); - connect(bnNew, &QPushButton::clicked, this, [this] { + auto bnAdd = new QPushButton("🞥"); + bnAdd->setMaximumWidth(50); + hBox->addWidget(bnAdd); + connect(bnAdd, &QPushButton::clicked, this, [this] { auto file = QFileDialog::getOpenFileName(this, 0, gFileHome); if(file.isEmpty()) return; QFileInfo info(file); @@ -38,7 +37,7 @@ MediaPanel::MediaPanel(QWidget *parent) : QWidget(parent) { if(suffix.startsWith("mp")) { auto player = new QMediaPlayer; player->setSource(QUrl::fromLocalFile(file)); - item = new MediaItem(file, tree); + item = new MediaItem(file, gMediaTree); item->setText("type", "Video"); auto videoWgt = new QVideoWidget; player->setVideoOutput(videoWgt); @@ -48,7 +47,8 @@ MediaPanel::MediaPanel(QWidget *parent) : QWidget(parent) { player->stop(); player->deleteLater(); videoWgt->deleteLater(); - item->setText("size", QString("%1*%2").arg(frame.width()).arg(frame.height())); + qDebug()<<"pixelFormat"<setText("size", QString("%1×%2").arg(frame.width()).arg(frame.height())); item->setText("dur", QTime::fromMSecsSinceStartOfDay(player->duration()).toString("hh:mm:ss.zzz")); item->profile = frame.toImage().scaledToHeight(60, Qt::SmoothTransformation); auto edProfile = new QLabel; @@ -66,10 +66,10 @@ MediaPanel::MediaPanel(QWidget *parent) : QWidget(parent) { QMessageBox::critical(this, "Image Read Error", QString::number(reader.error())+" "+reader.errorString()); return; } - item = new MediaItem(file, tree); + item = new MediaItem(file, gMediaTree); item->setText("type", "Image"); item->setText("dur", "00:10:00.000"); - item->setText("size", QString("%1*%2").arg(img.width()).arg(img.height())); + item->setText("size", QString("%1×%2").arg(img.width()).arg(img.height())); item->profile = img.scaledToHeight(60, Qt::SmoothTransformation); auto edProfile = new QLabel; edProfile->setPixmap(QPixmap::fromImage(item->profile)); @@ -82,11 +82,10 @@ MediaPanel::MediaPanel(QWidget *parent) : QWidget(parent) { } }); - bnDelete = new QPushButton(tr("Delete")); - bnDelete->setMinimumSize(75, 30); - bnDelete->setProperty("ssType", "progManageTool"); - hBox->addWidget(bnDelete); - connect(bnDelete, &QPushButton::clicked, this, [=] { + auto bnDelet = new QPushButton("🗑"); + bnDelet->setMaximumWidth(50); + hBox->addWidget(bnDelet); + connect(bnDelet, &QPushButton::clicked, this, [=] { // for(int i=0; itopLevelItemCount(); i++) if(tree->item(i)->checkState("check") == Qt::Checked) { // auto item = (MediaItem*) tree->topLevelItem(i--); // item->del(); @@ -94,31 +93,6 @@ MediaPanel::MediaPanel(QWidget *parent) : QWidget(parent) { // } }); - bnRename = new QPushButton(tr("Rename")); - bnRename->setMinimumSize(60, 30); - bnRename->setProperty("ssType", "progManageTool"); - hBox->addWidget(bnRename); - connect(bnRename, &QPushButton::clicked, this, [=] { - // int cnt = tree->topLevelItemCount(); - // QString progName; - // for(int i=0; iitem(i)->checkState("check") == Qt::Checked) { - // progName = ((MediaItem*) tree->topLevelItem(i))->mName; - // break; - // } - // if(progName.isEmpty()) return; - // bool ok = false; - // auto newName = QInputDialog::getText(this, "Rename '"+progName+"'", "New Name", QLineEdit::Normal, "", &ok); - // if(! ok) return; - // if(newName.isEmpty()) { - // QMessageBox::warning(this, "Warning", "New Name is Empty"); - // return; - // } - // auto progsDir = programsDir(); - // auto res = QDir(progsDir).rename(progName, newName); - // if(res) addProFiles(); - // else QMessageBox::warning(this, "Error", "Rename Failed"); - }); - hBox->addStretch(); auto fdSearch = new QLineEdit; @@ -128,33 +102,33 @@ MediaPanel::MediaPanel(QWidget *parent) : QWidget(parent) { fdSearch->addAction(search, QLineEdit::LeadingPosition); fdSearch->setClearButtonEnabled(true); //fdSearch->setStyleSheet("border: 1px solid #888;"); - connect(fdSearch, &QLineEdit::textChanged, this, [this](const QString &text) { - auto cnt = tree->topLevelItemCount(); + connect(fdSearch, &QLineEdit::textChanged, this, [](const QString &text) { + auto cnt = gMediaTree->topLevelItemCount(); for(int i=0; iitem(i); + auto item = gMediaTree->item(i); item->setHidden(! (text.isEmpty() || item->text("name").contains(text) || item->text("resolution").contains(text))); } }); hBox->addWidget(fdSearch); - tree = new MediaTree; - tree->addCol("#", "", 20); - tree->addCol("profile", "", 42); - tree->addCol("name", "", 140); - tree->addCol("type", "", 45); - tree->addCol("size", "", 60); - tree->addCol("dur", "", 80); - tree->setDefs()->setHeaderAlignC(); - tree->minRowHeight = 26; - tree->setSortingEnabled(true); - tree->setDragEnabled(true); - tree->setAcceptDrops(true); - tree->setDropIndicatorShown(true); - vBox->addWidget(tree); + gMediaTree = new MediaTree; + gMediaTree->addCol("#", "", 20); + gMediaTree->addCol("profile", "", 42); + gMediaTree->addCol("name", "", 140); + gMediaTree->addCol("type", "", 45); + gMediaTree->addCol("size", "", 60); + gMediaTree->addCol("dur", "", 80); + gMediaTree->setDefs()->setHeaderAlignC(); + gMediaTree->minRowHeight = 26; + gMediaTree->setSortingEnabled(true); + gMediaTree->setDragEnabled(true); + gMediaTree->setAcceptDrops(true); + gMediaTree->setDropIndicatorShown(true); + vBox->addWidget(gMediaTree); auto dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); if(mProgsDir.isEmpty()) return; - tree->clear(); + gMediaTree->clear(); // for(auto &progName : progNames) { // auto file = mProgsDir + "/" + progName + "/pro.json"; // QFile qFile(file); @@ -172,7 +146,7 @@ MediaPanel::MediaPanel(QWidget *parent) : QWidget(parent) { // } QSettings settings; - tree->sortByColumn(settings.value("MediaSortColumn").toInt(), (Qt::SortOrder)settings.value("MediaSortOrder").toInt()); + gMediaTree->sortByColumn(settings.value("MediaSortColumn").toInt(), (Qt::SortOrder)settings.value("MediaSortOrder").toInt()); transUi(); } @@ -182,17 +156,10 @@ void MediaPanel::changeEvent(QEvent *event) { if(event->type() == QEvent::LanguageChange) transUi(); } void MediaPanel::transUi() { - tree->headerItem()->setText("name"**tree, tr("Name")); - tree->headerItem()->setText("type"**tree, tr("Type")); - tree->headerItem()->setText("size"**tree, tr("Size")); - tree->headerItem()->setText("dur"**tree, tr("Duration")); - bnNew->setText(tr("New")); - bnDelete->setText(tr("Delete")); - bnRename->setText(tr("Rename")); -} - -MediaItem::MediaItem(const QString &file, TreeWidget *tree) : TreeWidgetItem(tree), file(file) { - + gMediaTree->headerItem()->setText("name"**gMediaTree, tr("Name")); + gMediaTree->headerItem()->setText("type"**gMediaTree, tr("Type")); + gMediaTree->headerItem()->setText("size"**gMediaTree, tr("Size")); + gMediaTree->headerItem()->setText("dur"**gMediaTree, tr("Duration")); } void MediaTree::dropEvent(QDropEvent *event) { @@ -201,7 +168,4 @@ void MediaTree::dropEvent(QDropEvent *event) { return; } TreeWidget::dropEvent(event); - qDebug()<<" event"<source(); - qDebug()<<" mimeData"<mimeData(); } diff --git a/Compass/mediapanel.h b/Compass/mediapanel.h index 8b21425..5edfcae 100644 --- a/Compass/mediapanel.h +++ b/Compass/mediapanel.h @@ -16,26 +16,24 @@ protected: void dropEvent(QDropEvent *event) override; }; +extern MediaTree *gMediaTree; + class MediaPanel : public QWidget { Q_OBJECT public: explicit MediaPanel(QWidget *parent = 0); - MediaTree *tree; protected: void changeEvent(QEvent *) override; void transUi(); private: QString mProgsDir; - QPushButton *bnNew; - QPushButton *bnDelete; - QPushButton *bnRename; }; class MediaItem : public TreeWidgetItem { public: - explicit MediaItem(const QString &dir, TreeWidget *parent); + explicit MediaItem(const QString &file, TreeWidget *parent) : TreeWidgetItem(parent), file(file) {} QString file; QImage profile; diff --git a/Compass/outputpanel.cpp b/Compass/outputpanel.cpp new file mode 100644 index 0000000..ae66bbf --- /dev/null +++ b/Compass/outputpanel.cpp @@ -0,0 +1,181 @@ +#include "outputpanel.h" +#include "main.h" +#include "layer.h" +#include +#include +#include +#include +#include + +OutputPanel::OutputPanel(QWidget *parent) : QWidget(parent) { + gOutPanel = this; + auto vBox = new VBox(this); + vBox->setContentsMargins(0, 0, 0, 0); + vBox->setSpacing(0); + auto hBox = new HBox(vBox); + + auto bnAdd = new QPushButton("🞥"); + bnAdd->setMaximumWidth(50); + hBox->addWidget(bnAdd); + connect(bnAdd, &QPushButton::clicked, this, [=] { + QString name; + auto cnt = tree->topLevelItemCount(); + for(int i=1;;i++) { + name = QString("Output %1").arg(i); + for(int r=0; rtopLevelItem(r)->text("name"**tree)==name) goto conti; + break; + conti:; + } + auto out = new Layer(0, name, gEditView); + gEditView->layers.push_back(out); + out->updateGeo(); + out->show(); + out->item = new OutputItem(tree); + out->item->setText("name", out->name); + out->item->setText("size", QString("%1×%2").arg(out->sSize.width()).arg(out->sSize.height())); + out->item->setData(0, (quint64) out); + tree->setCurrentItem(out->item); + out->view = new OutputView; + out->view->setGeometry({QPoint(), out->sSize}); + out->view->setSceneRect({out->sPos, out->sSize}); + }); + + auto bnDelet = new QPushButton("🗑"); + bnDelet->setMaximumWidth(50); + hBox->addWidget(bnDelet); + connect(bnDelet, &QPushButton::clicked, this, [=] { + // for(int i=0; itopLevelItemCount(); i++) if(tree->item(i)->checkState("check") == Qt::Checked) { + // auto item = (MediaItem*) tree->topLevelItem(i--); + // item->del(); + // delete item; + // } + }); + + hBox->addStretch(); + + tree = new TreeWidget; + tree->addCol("#", "", 20); + tree->addCol("name", "", 140); + tree->addCol("size", "", 120); + tree->setDefs()->setHeaderAlignC(); + tree->minRowHeight = 26; + connect(tree, &TreeWidget::currentItemChanged, this, [=](QTreeWidgetItem *current, QTreeWidgetItem *) { + if(enCurChanged) gEditView->select((Layer*) current->data(0, Qt::UserRole).toULongLong()); + }); + vBox->addWidget(tree); + + vBox->addSpacing(8); + vBox->addLabel("Output Area Properties"); + vBox->addSpacing(6); + + auto grid = new Grid(vBox); + grid->setHorizontalSpacing(6); + int r = 0; + grid->addLabel("Name", r, 0); + edName = new QLineEdit; + grid->addWidget(edName, r, 1); + r++; + + grid->addLabel("Position", r, 0); + + hBox = new HBox; + hBox->addLabel("X:")->setMinimumWidth(20); + + edX = new QSpinBox; + edX->setRange(-99999, 999999); + connect(edX, &QSpinBox::valueChanged, this, [=](int value) { + auto layer = gEditView->selected; + if(! layer) return; + layer->sPos.rx() = value; + layer->view->move(layer->sPos); + layer->updateGeo(); + layer->update(); + }); + hBox->addWidget(edX); + + hBox->addSpacing(10); + + hBox->addLabel("Y:")->setMinimumWidth(20); + edY = new QSpinBox; + edY->setRange(-99999, 999999); + edY->setValue(y()); + connect(edY, &QSpinBox::valueChanged, this, [=](int value) { + auto layer = gEditView->selected; + if(! layer) return; + layer->sPos.ry() = value; + layer->view->move(layer->sPos); + layer->updateGeo(); + layer->update(); + }); + hBox->addWidget(edY); + hBox->addStretch(); + grid->addLayout(hBox, r, 1); + r++; + + grid->addLabel("Size", r, 0); + hBox = new HBox; + hBox->addLabel("W:")->setMinimumWidth(20); + + edW = new QSpinBox; + edW->setRange(10, 999999); + connect(edW, &QSpinBox::valueChanged, this, [=](int value) { + auto layer = gEditView->selected; + if(! layer || ! layer->item) return; + layer->sSize.rwidth() = value; + layer->view->resize(layer->sSize); + layer->updateGeo(); + layer->update(); + layer->item->setText("size"**tree, QString("%1×%2").arg(layer->sSize.rwidth()).arg(layer->sSize.rheight())); + }); + hBox->addWidget(edW); + + hBox->addSpacing(10); + hBox->addLabel("H:")->setMinimumWidth(20); + edH = new QSpinBox; + edH->setRange(10, 999999); + connect(edH, &QSpinBox::valueChanged, this, [=](int value) { + auto layer = gEditView->selected; + if(! layer || ! layer->item) return; + layer->sSize.rheight() = value; + layer->view->resize(layer->sSize); + layer->updateGeo(); + layer->update(); + layer->item->setText("size"**tree, QString("%1×%2").arg(layer->sSize.rwidth()).arg(layer->sSize.rheight())); + }); + hBox->addWidget(edH); + hBox->addStretch(); + grid->addLayout(hBox, r, 1); + r++; + + auto edShow = new QCheckBox("Open"); + connect(edShow, &QCheckBox::checkStateChanged, this, [=](Qt::CheckState checkState) { + auto area = gEditView->selected; + if(! area || ! area->view) return; + area->view->setVisible(checkState==Qt::Checked); + }); + grid->addWidget(edShow, r, 1); + r++; + + transUi(); +} + +void OutputPanel::showEvent(QShowEvent *event) { + QWidget::showEvent(event); + for(auto layer : gEditView->layers) if(layer->item) layer->raise(); + auto item = tree->curItem(); + if(item) gEditView->select((Layer*) item->data(0).toULongLong()); + qDebug()<<"showEvent"; +} +void OutputPanel::hideEvent(QHideEvent *event) { + QWidget::hideEvent(event); + for(auto layer : gEditView->layers) if(layer->item) layer->stackUnder(gEditView->originWgt); + qDebug()<<"hideEvent"; +} +void OutputPanel::changeEvent(QEvent *event) { + QWidget::changeEvent(event); + if(event->type() == QEvent::LanguageChange) transUi(); +} +void OutputPanel::transUi() { + tree->headerItem()->setText("name"**tree, tr("Name")); + tree->headerItem()->setText("size"**tree, tr("Size")); +} diff --git a/Compass/outputpanel.h b/Compass/outputpanel.h new file mode 100644 index 0000000..ad4b7f7 --- /dev/null +++ b/Compass/outputpanel.h @@ -0,0 +1,31 @@ +#ifndef OUTPUTPANEL_H +#define OUTPUTPANEL_H + +#include "gutil/qgui.h" +#include + +class OutputPanel : public QWidget { + Q_OBJECT +public: + explicit OutputPanel(QWidget *parent = 0); + + TreeWidget *tree; + QLineEdit *edName; + QSpinBox *edX, *edY, *edW, *edH; + bool enCurChanged = true; +protected: + void showEvent(QShowEvent *event) override; + void hideEvent(QHideEvent *event) override; + void changeEvent(QEvent *) override; + void transUi(); +}; + +class OutputItem : public TreeWidgetItem { +public: + using TreeWidgetItem::TreeWidgetItem; + + QPoint pos; + QSize size{1920, 1080}; +}; + +#endif // OUTPUTPANEL_H diff --git a/Compass/planpanel.cpp b/Compass/planpanel.cpp index 2a2f47a..5f6d4c7 100644 --- a/Compass/planpanel.cpp +++ b/Compass/planpanel.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -37,8 +38,8 @@ PlanPanel::PlanPanel(QWidget *parent) : QWidget{parent} { auto hBox = new HBox(wgt); hBox->setContentsMargins(0,0,0,0); hBox->setSpacing(0); - auto btn = new QPushButton(">"); - btn->setMaximumWidth(26); + auto btn = new QPushButton("⏵"); + btn->setMaximumWidth(24); grp->addButton(btn); hBox->addWidget(btn); hBox->addLabel(QString("P%1").arg(c+1)); @@ -47,8 +48,9 @@ PlanPanel::PlanPanel(QWidget *parent) : QWidget{parent} { connect(grp, &QButtonGroup::buttonClicked, this, &PlanPanel::play); grid->addWidget(gTableH, 0, 1); - gTableV = new PlanTableV(1, 1); - gTableV->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + gTableV = new PlanTableV(0, 1); + gTableV->horizontalScrollBar()->hide(); + gTableV->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); gTableV->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); gTableV->horizontalHeader()->hide(); gTableV->verticalHeader()->hide(); @@ -61,8 +63,10 @@ PlanPanel::PlanPanel(QWidget *parent) : QWidget{parent} { grid->addWidget(gTableV, 1, 0); gTable = new PlanTable(0, 50); - gTable->horizontalHeader()->setVisible(false); - gTable->verticalHeader()->setVisible(false); + gTable->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); + gTable->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + gTable->horizontalHeader()->hide(); + gTable->verticalHeader()->hide(); gTable->setColWidth(CellWidth)->setRowHeight(CellHeight)->setRowResize(QHeaderView::Fixed); gTable->setDragEnabled(true); gTable->setAcceptDrops(true); @@ -94,7 +98,8 @@ void PlanPanel::addRow() { gTableV->setCellWidget(r, 0, wgt); auto layer = new Layer(r+1, "Layer", gEditView); - layer->setGeo(); + gEditView->layers.push_back(layer); + layer->updateGeo(); layer->show(); gTableV->setData(r, 0, (quint64) layer); @@ -139,8 +144,10 @@ void ImgItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q painter->drawPixmap(boundingRect(), img, QRectF(0, 0, img.width(), img.height())); } +void PlanTable::dragEnterEvent(QDragEnterEvent *event) { + if(event->source()==this || event->source()==gMediaTree) QTableWidget::dragEnterEvent(event); +} void PlanTable::dropEvent(QDropEvent *event) { - MediaTree *tree; if(event->source()==this) { auto idxFrom = currentIndex(); auto cell = data(idxFrom.row(), idxFrom.column()); @@ -158,22 +165,25 @@ void PlanTable::dropEvent(QDropEvent *event) { if(cellOld.isValid() && cellOld!=cell) delete (Cell*) cellOld.toULongLong(); setData(idx.row(), idx.column(), cell); event->accept(); - } else if((tree = dynamic_cast(event->source()))) { + } else if(event->source()==gMediaTree) { auto idx = indexAt(event->position().toPoint()); auto wgt = cellWidget(idx.row(), idx.column()); - auto item = (MediaItem*) tree->currentItem(); + auto item = (MediaItem*) gMediaTree->currentItem(); auto lb = (QLabel*) wgt->children().at(2); - qDebug()<<" currentIndex"<setText(item->text("name"**tree)); + lb->setText(item->text("name"**gMediaTree)); lb = (QLabel*) wgt->children().at(1); lb->setPixmap(QPixmap::fromImage(item->profile)); - auto type = item->text("type"**tree); + auto type = item->text("type"**gMediaTree); if(type=="Video") { auto wgt = new QGraphicsVideoItem; wgt->setAspectRatioMode(Qt::IgnoreAspectRatio); auto player = new QMediaPlayer; player->setSource(QUrl::fromLocalFile(item->file)); player->setVideoOutput(wgt); + player->setAudioOutput(new QAudioOutput); + connect(wgt, &QGraphicsVideoItem::parentChanged, player, [=]() { + if(wgt->parent()!=gScene) player->stop(); + }); setData(idx.row(), idx.column(), (quint64) new Cell('V', wgt, player)); } else if(type=="Image") { QImageReader reader(item->file); diff --git a/Compass/planpanel.h b/Compass/planpanel.h index 0600d28..37eb0a8 100644 --- a/Compass/planpanel.h +++ b/Compass/planpanel.h @@ -47,6 +47,7 @@ public: using TableWidget::TableWidget; protected: + void dragEnterEvent(QDragEnterEvent *event) override; void dropEvent(QDropEvent *event) override; }; diff --git a/Compass/progresspanel.cpp b/Compass/progresspanel.cpp new file mode 100644 index 0000000..4746270 --- /dev/null +++ b/Compass/progresspanel.cpp @@ -0,0 +1,52 @@ +#include "progresspanel.h" +#include "mediapanel.h" +#include "main.h" +#include "layer.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +ProgressPanel::ProgressPanel(QWidget *parent) : QWidget{parent} { + auto hBox = new HBox(this); + hBox->setContentsMargins(0,0,0,0); + hBox->setSpacing(0); + auto btnPlay = new QPushButton("||>"); + btnPlay->setMaximumWidth(100); + btnPlay->setFixedHeight(60); + connect(btnPlay, &QPushButton::clicked, this, &ProgressPanel::play); + hBox->addWidget(btnPlay); + + auto scrollArea = new QScrollArea; + hBox->addWidget(scrollArea); + vBox = new VBox(scrollArea); + vBox->setContentsMargins(0,0,0,0); + vBox->setSpacing(0); + //connect(gTable->verticalScrollBar(), &QScrollBar::valueChanged, gTableV->verticalScrollBar(), &QScrollBar::setValue); +} + +void ProgressPanel::addRow() { + auto hBox = new HBox(vBox); + auto btnPlay = new QPushButton("||>"); + connect(btnPlay, &QPushButton::clicked, this, [=]{ + + }); + hBox->addWidget(btnPlay); + + auto slider = new QSlider(Qt::Horizontal); + slider->setRange(0, 100); + + auto lb = hBox->addLabel(); + connect(slider, &QSlider::valueChanged, lb, [lb](int value) { + lb->setText(QTime::fromMSecsSinceStartOfDay(value).toString("HH:mm:ss.zzz")); + }); + lb = hBox->addLabel(); +} +void ProgressPanel::play() { + +} diff --git a/Compass/progresspanel.h b/Compass/progresspanel.h new file mode 100644 index 0000000..d5ebd10 --- /dev/null +++ b/Compass/progresspanel.h @@ -0,0 +1,19 @@ +#ifndef PROGRESSPANEL_H +#define PROGRESSPANEL_H + +#include "gutil/qgui.h" +#include +#include + +class ProgressPanel : public QWidget { + Q_OBJECT +public: + explicit ProgressPanel(QWidget *parent = 0); + + void addRow(); + void play(); + + VBox *vBox; +}; + +#endif // PROGRESSPANEL_H diff --git a/LedOK/Demos/Demo Video 4K.mp4 b/LedOK/Demos/Demo Video 1080p.mp4 similarity index 51% rename from LedOK/Demos/Demo Video 4K.mp4 rename to LedOK/Demos/Demo Video 1080p.mp4 index 55c018d..57f07a2 100644 Binary files a/LedOK/Demos/Demo Video 4K.mp4 and b/LedOK/Demos/Demo Video 1080p.mp4 differ diff --git a/LedOK/Demos/Sysolution Control.png b/LedOK/Demos/Demo.png similarity index 100% rename from LedOK/Demos/Sysolution Control.png rename to LedOK/Demos/Demo.png diff --git a/LedOK/Demos/Sysolution Innovation.png b/LedOK/Demos/Sysolution Innovation.png deleted file mode 100644 index 1aec0cc..0000000 Binary files a/LedOK/Demos/Sysolution Innovation.png and /dev/null differ diff --git a/LedOK/LedOK Express.pro b/LedOK/LedOK Express.pro index ac2a81e..edbd73c 100644 --- a/LedOK/LedOK Express.pro +++ b/LedOK/LedOK Express.pro @@ -1,20 +1,19 @@ QT += core gui widgets QT += multimedia QT += network +QT += webenginewidgets QT += concurrent QT += serialport QT += opengl -QT += webenginewidgets greaterThan(QT_MAJOR_VERSION, 5) { QT += openglwidgets - CONFIG += c++20 } else { - CONFIG += c++17 QMAKE_CFLAGS += /utf-8 QMAKE_CXXFLAGS += /utf-8 } +CONFIG += c++17 CONFIG += lrelease CONFIG += embed_translations @@ -27,7 +26,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 = 2.0.1 +VERSION = 2.0.3 DEFINES += APP_VERSION=\\\"$$VERSION\\\" msvc { contains(QT_ARCH, i386) { @@ -112,12 +111,12 @@ else: unix:!android: target.path = /opt/$${TARGET}/bin RESOURCES += res.qrc SOURCES += \ + base/calendarbutton.cpp \ base/changepasswordform.cpp \ base/switchcontrol.cpp \ base/extendedgroupbox.cpp \ base/ffutil.cpp \ base/locolorselector.cpp \ - base/lodateselector.cpp \ base/loqtitlebar.cpp \ base/loqtreewidget.cpp \ device/progressesdlg.cpp \ @@ -181,11 +180,11 @@ SOURCES += \ program/videosplitthread.cpp HEADERS += \ + base/calendarbutton.h \ base/changepasswordform.h \ base/switchcontrol.h \ base/extendedgroupbox.h \ base/locolorselector.h \ - base/lodateselector.h \ base/loqtitlebar.h \ base/loqtreewidget.h \ device/progressesdlg.h \ diff --git a/LedOK/base/calendarbutton.cpp b/LedOK/base/calendarbutton.cpp new file mode 100644 index 0000000..4c03013 --- /dev/null +++ b/LedOK/base/calendarbutton.cpp @@ -0,0 +1,33 @@ +#include "calendarbutton.h" +#include +#include +#include + +CalendarButton::CalendarButton(QWidget *parent) : QPushButton(parent) { + setStyleSheet(R"rrr( +CalendarButton { + image: url(:/res/Calendar.png); + padding: 0; + max-width: 32px; + max-height: 32px; +} +CalendarButton:!enabled{ + image: url(:/res/Calendar-gray.png); +} +CalendarButton:pressed { + margin-top: 1px; + margin-left: 1px; + margin-bottom: -1px; + margin-right: -1px; +} +)rrr"); + auto dlg = new QDialog(this); + dlg->setWindowTitle(tr("Select a Date")); + dlg->setWindowFlag(Qt::WindowContextHelpButtonHint, false); + auto vBox = new QVBoxLayout(dlg); + vBox->setContentsMargins(0,0,0,0); + calendar = new QCalendarWidget; + connect(calendar, &QCalendarWidget::clicked, dlg, &QDialog::accept); + vBox->addWidget(calendar); + connect(this, &QPushButton::clicked, dlg, &QDialog::exec); +} diff --git a/LedOK/base/calendarbutton.h b/LedOK/base/calendarbutton.h new file mode 100644 index 0000000..07dfe7f --- /dev/null +++ b/LedOK/base/calendarbutton.h @@ -0,0 +1,15 @@ +#ifndef CALENDARBUTTON_H +#define CALENDARBUTTON_H + +#include +#include + +class CalendarButton : public QPushButton { + Q_OBJECT +public: + explicit CalendarButton(QWidget *parent = 0); + + QCalendarWidget *calendar = 0; +}; + +#endif // CALENDARBUTTON_H diff --git a/LedOK/base/changepasswordform.cpp b/LedOK/base/changepasswordform.cpp index c8137fe..37ad2e7 100644 --- a/LedOK/base/changepasswordform.cpp +++ b/LedOK/base/changepasswordform.cpp @@ -1,4 +1,5 @@ #include "changepasswordform.h" +#include "main.h" #include #include #include @@ -48,7 +49,7 @@ ChangePasswordForm::ChangePasswordForm(QWidget *parent) : QDialog(parent) { connect(btnBox, &QDialogButtonBox::accepted, this, [=] { QString pwdOld = fdOld->text(); if(pwdOld.isEmpty()) { - QMessageBox::warning(this, tr("Tip"), tr("Please input old password")); + QMessageBox::warning(this, translate("","Tip"), tr("Please input old password")); fdOld->setFocus(); return; } @@ -56,24 +57,24 @@ ChangePasswordForm::ChangePasswordForm(QWidget *parent) : QDialog(parent) { auto pwdRaw = settings.value("advUiPs"); QString pwd = pwdRaw.isNull() ? "888" : QString::fromUtf8(QByteArray::fromBase64(pwdRaw.toString().toLatin1())); if(pwd != pwdOld) { - QMessageBox::critical(this, tr("Tip"), tr("Old password is wrong")); + QMessageBox::critical(this, translate("","Tip"), tr("Old password is wrong")); fdOld->setFocus(); return; } QString pwdNew = fdNew->text(); if(pwdNew.length() < 3 && ! pwdNew.isEmpty()) { - QMessageBox::warning(this, tr("Tip"), tr("Please enter a password with more than 3 characters")); + QMessageBox::warning(this, translate("","Tip"), tr("Please enter a password with more than 3 characters")); fdNew->setFocus(); return; } QString pwdAgn = fdAgn->text(); if(pwdAgn != pwdNew) { - QMessageBox::warning(this, tr("Tip"), tr("The new password is not consistent in two times")); + QMessageBox::warning(this, translate("","Tip"), tr("The new password is not consistent in two times")); fdAgn->setFocus(); return; } settings.setValue("advUiPs", QString::fromLatin1(pwdNew.toUtf8().toBase64())); - QMessageBox::information(this, tr("Tip"), tr("Password changed successfully")); + QMessageBox::information(this, translate("","Tip"), tr("Password changed successfully")); accept(); }); vBox->addWidget(btnBox); diff --git a/LedOK/base/lodateselector.cpp b/LedOK/base/lodateselector.cpp deleted file mode 100644 index 66d4dbb..0000000 --- a/LedOK/base/lodateselector.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "lodateselector.h" -#include -#include -#include - -LoDateSelector::LoDateSelector(QWidget *parent) : QPushButton(parent) { - setStyleSheet(R"rrr( -LoDateSelector { - background-color: transparent; - image: url(:/res/program/DateSelect_enable.png); - padding: 0; - max-width: 32px; - max-height: 32px; -} -LoDateSelector:!enabled{ - image: url(:/res/program/DateSelect_e.png); -} -LoDateSelector:pressed { - margin-top: 1px; - margin-left: 1px; - margin-bottom: -1px; - margin-right: -1px; -} -)rrr"); - connect(this, &QPushButton::clicked, this, [this] { - QDialog dlg(this); - dlg.setWindowTitle(tr("Date selector")); - dlg.setWindowFlag(Qt::WindowContextHelpButtonHint, false); - auto vBox = new QVBoxLayout(&dlg); - vBox->setContentsMargins(0,0,0,0); - auto calendar = new QCalendarWidget(); - connect(calendar, &QCalendarWidget::clicked, &dlg, &QDialog::accept); - connect(calendar, &QCalendarWidget::clicked, this, &LoDateSelector::sDateSelected); - vBox->addWidget(calendar); - dlg.exec(); - }); -} diff --git a/LedOK/base/lodateselector.h b/LedOK/base/lodateselector.h deleted file mode 100644 index 15e06bc..0000000 --- a/LedOK/base/lodateselector.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef LODATESELECTOR_H -#define LODATESELECTOR_H - -#include - -class LoDateSelector : public QPushButton{ - Q_OBJECT -public: - explicit LoDateSelector(QWidget *parent = nullptr); -signals: - void sDateSelected(const QDate &); -}; - -#endif // LODATESELECTOR_H diff --git a/LedOK/base/loqtitlebar.cpp b/LedOK/base/loqtitlebar.cpp index 3378d1a..548789d 100644 --- a/LedOK/base/loqtitlebar.cpp +++ b/LedOK/base/loqtitlebar.cpp @@ -1,5 +1,5 @@ #include "loqtitlebar.h" -#include +#include "main.h" LoQTitleBar::LoQTitleBar(QWidget *parent) : QWidget(parent) { bn_Minimize = new QPushButton(this); @@ -11,7 +11,7 @@ LoQTitleBar::LoQTitleBar(QWidget *parent) : QWidget(parent) { bn_Minimize->setToolTip(tr("Minimize")); bn_Maximize->setToolTip(tr("Maximize")); - bn_Close->setToolTip(tr("Close")); + bn_Close->setToolTip(translate("","Close")); connect(bn_Minimize, &QPushButton::clicked, window(), &QWidget::showMinimized); connect(bn_Maximize, &QPushButton::clicked, this, [this](){ @@ -24,7 +24,7 @@ LoQTitleBar::LoQTitleBar(QWidget *parent) : QWidget(parent) { void LoQTitleBar::refreshLable() { bn_Minimize->setToolTip(tr("Minimize")); bn_Maximize->setToolTip(tr("Maximize")); - bn_Close->setToolTip(tr("Close")); + bn_Close->setToolTip(translate("","Close")); } bool LoQTitleBar::eventFilter(QObject *, QEvent *e) { if(e->type()==QEvent::WindowStateChange) bn_Maximize->setToolTip(window()->isMaximized() ? tr("Restore") : tr("Maximize")); diff --git a/LedOK/basedlg.cpp b/LedOK/basedlg.cpp index 574b256..17a4b10 100644 --- a/LedOK/basedlg.cpp +++ b/LedOK/basedlg.cpp @@ -6,7 +6,7 @@ BaseDlg::BaseDlg(QWidget *parent) : QDialog(parent) { setWindowFlag(Qt::FramelessWindowHint); - setAttribute(Qt::WA_TranslucentBackground); + if(QSysInfo::productVersion()!="7" || ! QSysInfo::productType().startsWith("win")) setAttribute(Qt::WA_TranslucentBackground); } void BaseDlg::paintEvent(QPaintEvent *e) { diff --git a/LedOK/basewin.cpp b/LedOK/basewin.cpp index c1b04d4..ef304c8 100644 --- a/LedOK/basewin.cpp +++ b/LedOK/basewin.cpp @@ -7,7 +7,7 @@ BaseWin::BaseWin(QWidget *parent) : QWidget(parent){ setWindowFlag(Qt::FramelessWindowHint); - setAttribute(Qt::WA_TranslucentBackground); + if(QSysInfo::productVersion()!="7" || ! QSysInfo::productType().startsWith("win")) setAttribute(Qt::WA_TranslucentBackground); setMouseTracking(true); auto layout = new QBoxLayout(QBoxLayout::TopToBottom, this); layout->setContentsMargins(8,8,8,8); @@ -40,7 +40,7 @@ void BaseWin::paintEvent(QPaintEvent *e) { void BaseWin::mousePressEvent(QMouseEvent *e) { if(e->button() != Qt::LeftButton) return; setFrmSec(e->pos()); - if(mFrmSec==Qt::TitleBarArea || mFrmSec==Qt::TopSection || mFrmSec==Qt::LeftSection || mFrmSec==Qt::TopLeftSection) mPressRel = -e->pos(); + if(mFrmSec==Qt::TitleBarArea || mFrmSec==Qt::TopSection || mFrmSec==Qt::LeftSection || mFrmSec==Qt::TopLeftSection) mPressRel = e->pos(); else if(mFrmSec==Qt::BottomRightSection) mPressRel = QPoint(width() - e->globalX(), height() - e->globalY()); else if(mFrmSec==Qt::RightSection ) mPressRel = QPoint(width() - e->globalX(), height() ); else if(mFrmSec==Qt::BottomSection ) mPressRel = QPoint(width() , height() - e->globalY()); @@ -55,15 +55,15 @@ void BaseWin::mouseMoveEvent(QMouseEvent *e) { if(e->buttons() & Qt::LeftButton) { if(mFrmSec==Qt::NoSection || mPressRel.x()==INT_MAX) return; if(isMaximized()) return; - if(mFrmSec==Qt::TitleBarArea) move(mPressRel + e->globalPos()); + if(mFrmSec==Qt::TitleBarArea) move(e->globalPos() - mPressRel); else if(mFrmSec==Qt::BottomRightSection) resize(mPressRel.rx() + e->globalX(), mPressRel.ry() + e->globalY()); else if(mFrmSec==Qt::RightSection ) resize(mPressRel.rx() + e->globalX(), mPressRel.ry() ); else if(mFrmSec==Qt::BottomSection ) resize(mPressRel.rx() , mPressRel.ry() + e->globalY()); else { auto geo = geometry(); - if(mFrmSec==Qt::LeftSection) geo.setLeft(mPressRel.rx() + e->globalX()); - else if(mFrmSec==Qt::TopSection) geo.setTop(mPressRel.ry() + e->globalY()); - else if(mFrmSec==Qt::TopLeftSection) geo.setTopLeft(mPressRel + e->globalPos()); + if(mFrmSec==Qt::LeftSection) geo.setLeft(e->globalX() - mPressRel.rx()); + else if(mFrmSec==Qt::TopSection) geo.setTop(e->globalY() - mPressRel.ry()); + else if(mFrmSec==Qt::TopLeftSection) geo.setTopLeft(e->globalPos() - mPressRel); else if(mFrmSec==Qt::TopRightSection) geo.setTopRight(mPressRel + e->globalPos()); else if(mFrmSec==Qt::BottomLeftSection) geo.setBottomLeft(mPressRel + e->globalPos()); setGeometry(geo); diff --git a/LedOK/device/ctrladvancedpanel.cpp b/LedOK/device/ctrladvancedpanel.cpp index b5ea0d7..7fa9608 100644 --- a/LedOK/device/ctrladvancedpanel.cpp +++ b/LedOK/device/ctrladvancedpanel.cpp @@ -1,17 +1,24 @@ #include "ctrladvancedpanel.h" -#include "device/progressesdlg.h" -#include "main.h" -#include "gutil/qwaitingdlg.h" #include "base/changepasswordform.h" -#include "tools.h" +#include "base/calendarbutton.h" +#include "device/progressesdlg.h" +#include "deviceitem.h" +#include "devicepanel.h" +#include "gutil/qcore.h" #include "gutil/qgui.h" -#include "gutil/qnetwork.h" #include "gutil/qjson.h" +#include "gutil/qnetwork.h" +#include "gutil/qwaitingdlg.h" +#include "main.h" #include "program/ephoto.h" #include "upgradeapkdialog.h" -#include "deviceitem.h" +#include +#include #include +#include #include +#include +#include #include #include #include @@ -20,15 +27,9 @@ #include #include #include -#include -#include -#include #include -#include -#include "devicepanel.h" -#include -#include #include +#include CtrlAdvancedPanel::CtrlAdvancedPanel() { setFocusPolicy(Qt::StrongFocus); @@ -64,18 +65,18 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn); connect(btn, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto width = fdScreenWidth->text(); if(width.isEmpty()) { - QMessageBox::information(this, tr("Tip"),tr("InputWidthTip")); + QMessageBox::information(this, translate("","Tip"),tr("InputWidthTip")); fdScreenWidth->setFocus(); return; } auto height = fdScreenHeight->text(); if(height.isEmpty()) { - QMessageBox::information(this, tr("Tip"),tr("InputHeightTip")); + QMessageBox::information(this, translate("","Tip"),tr("InputHeightTip")); fdScreenHeight->setFocus(); return; } @@ -85,7 +86,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { json.insert("width", width.toInt()); json.insert("height", height.toInt()); if(gSelCards.count() == 1) { - auto waitingDlg = new WaitingDlg(this, tr("SetScreenSize")); + auto waitingDlg = new WaitingDlg(this, translate("","Set ")+translate("","Screen Size")); Def_CtrlReqPre connect(reply, &QNetworkReply::finished, this, [=] { Def_CtrlSetReqAfter @@ -94,8 +95,8 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, gFdResInfo, [=] { - auto err = checkReplyForJson(reply); - gFdResInfo->append(card.id+" "+tr("SetScreenSize")+" "+(err.isEmpty() ? QCoreApplication::translate("Def","Success") : err)); + auto err = errStrWithJson(reply); + gFdResInfo->append(card.id+" "+translate("","Set ")+translate("","Screen Size")+" "+(err.isEmpty() ? translate("","Success") : err)); // if(! err.isEmpty()) return; // auto item = findItem(card.id); // if(item) { @@ -120,7 +121,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto alias = fdAlias->text(); @@ -143,8 +144,8 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, gFdResInfo, [=] { - auto err = checkReplyForJson(reply); - gFdResInfo->append(card.id+" "+tr("SetCardAlias")+" "+(err.isEmpty() ? QCoreApplication::translate("Def","Success") : err)); + auto err = errStrWithJson(reply); + gFdResInfo->append(card.id+" "+tr("SetCardAlias")+" "+(err.isEmpty() ? translate("","Success") : err)); if(! err.isEmpty()) return; auto item = findItem(card.id); if(item) { @@ -165,12 +166,15 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { hBox->addWidget(lbWebAddr); fdWebAddr = new QComboBox; +#ifndef leyide fdWebAddr->addItem("www.m2mled.net"); fdWebAddr->addItem("www.ledaips.com"); - fdWebAddr->addItem("https://www.taxihub.cn:2340"); + fdWebAddr->addItem("https://www.vehhub.top:2340"); fdWebAddr->addItem("https://www.ledaips.com:2340"); fdWebAddr->addItem("https://www.36taxi.com:2340"); fdWebAddr->addItem("www.tlzxled.com"); + fdWebAddr->addItem("192.168.2.201/api/websocket/2/{id}"); +#endif fdWebAddr->setMinimumWidth(260); fdWebAddr->setEditable(true); hBox->addWidget(fdWebAddr); @@ -185,26 +189,31 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto serverAddr = fdWebAddr->currentText(); auto companyId = fdCompanyId->text(); -// auto res = QMessageBox::question(this, tr("Tip Info"), tr("This operation will clear current program.")+"\n"+tr("Do you want to continue?")); +// auto res = QMessageBox::question(this, translate("","Tip"), 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"); - json.insert("server", serverAddr); json.insert("companyID", companyId); if(gSelCards.count() == 1) { auto waitingDlg = new WaitingDlg(this, tr("SetOnlineAddr")); - Def_CtrlReqPre + waitingDlg->show(); + auto card = gSelCards[0]; + json.insert("server", serverAddr.replace("{id}", card.id)); + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json); + connect(waitingDlg, &WaitingDlg::rejected, reply, &QNetworkReply::deleteLater); connect(reply, &QNetworkReply::finished, this, [=] { Def_CtrlSetReqAfter }); } else { for(auto &card :gSelCards) { + auto addr = serverAddr; + json.insert("server", addr.replace("{id}", card.id)); Def_CtrlSetMulti(tr("SetOnlineAddr")) } } @@ -217,8 +226,10 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { hBox->addWidget(lbRealtime = new QLabel); fdRealtimeServer = new QComboBox; +#ifndef leyide fdRealtimeServer->addItem("www.ledokcloud.com/realtime"); fdRealtimeServer->addItem("192.168.8.:10010"); +#endif fdRealtimeServer->setMinimumWidth(260); fdRealtimeServer->setEditable(true); hBox->addWidget(fdRealtimeServer); @@ -226,7 +237,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -251,7 +262,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnRealtimeClear->setProperty("ssType", "progManageTool"); connect(btnRealtimeClear, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } fdRealtimeServer->clearEditText(); @@ -296,7 +307,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnApkCheck->setProperty("ssType", "progManageTool"); connect(btnApkCheck, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -309,7 +320,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { Def_CtrlSingleGetReply waitingDlg->close(); fdPkg->clear(); - auto apps = json["apps"].toArray(); + auto apps = json["apps"]; auto infoDlg = new QDialog(this); infoDlg->setAttribute(Qt::WA_DeleteOnClose); #ifdef Q_OS_WIN @@ -328,9 +339,9 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { table->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); table->setRowCount(apps.size()); vBox->addWidget(table); - for(int i=0; isetItem(i, "apk", new QTableWidgetItem{app["appName"].toString()}); table->setItem(i, "ver", new QTableWidgetItem{app["versionName"].toString()}); table->setItem(i, "pkg", new QTableWidgetItem{packageName}); @@ -352,12 +363,12 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { fdUninstall->setProperty("ssType", "progManageTool"); connect(fdUninstall, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto pkg = fdPkg->currentText(); if(pkg.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("Package name is null")); + QMessageBox::information(this, translate("","Tip"), tr("Package name is null")); return; } QJsonObject json; @@ -382,12 +393,12 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnIsRunning->setProperty("ssType", "progManageTool"); connect(btnIsRunning, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto pkg = fdPkg->currentText(); if(pkg.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("Package name is null")); + QMessageBox::information(this, translate("","Tip"), tr("Package name is null")); return; } QJsonObject json; @@ -400,7 +411,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { connect(reply, &QNetworkReply::finished, this, [=] { Def_CtrlSingleGetReply waitingDlg->close(); - QMessageBox::information(this, tr("Tip"), json["running"].toBool() ? tr("running") : tr("no running")); + QMessageBox::information(this, translate("","Tip"), json["running"].toBool() ? tr("running") : tr("no running")); }); } else { for(auto &card : gSelCards) { @@ -423,7 +434,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnRestart->setProperty("ssType", "progManageTool"); connect(btnRestart, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -447,7 +458,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnClearProg->setProperty("ssType", "progManageTool"); connect(btnClearProg, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } JObj json{{"_type","DelPrograms"},{"_id","DelPrograms"},{"zVer","xixun1"}}; @@ -474,17 +485,17 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { auto json = JFrom(resp, &error); if(! error.isEmpty()) { waitingDlg->close(); - QMessageBox::critical(this, tr("Tip"), error); + QMessageBox::critical(this, translate("","Tip"), error); } else if(! json["success"].toBool()) { waitingDlg->close(); - QMessageBox::critical(this, tr("Tip"), tr("Clear Program")+" "+tr("Failed")); + QMessageBox::critical(this, translate("","Tip"), tr("Clear Program")+" "+tr("Failed")); } else 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()); + QMessageBox::critical(this, translate("","Tip"), QString(socketErrKey(err))+" ("+QString::number(err)+") "+tcp->errorString()); }); tcp->connectToHost(card.ip, 3333); tcp->startTimer(10000); @@ -506,7 +517,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { auto json = JFrom(resp, &error); if(! error.isEmpty()) gFdResInfo->append(cardId+" "+tr("Clear Program")+" "+error); else if(! json["success"].toBool()) gFdResInfo->append(cardId+" "+tr("Clear Program")+" "+tr("Failed")); - else gFdResInfo->append(cardId+" "+tr("Clear Program")+" "+tr("Success")); + else gFdResInfo->append(cardId+" "+tr("Clear Program")+" "+translate("","Success")); }); connect(tcp, &QTcpSocket::errorOccurred, tcp, [=](QAbstractSocket::SocketError err) { tcp->close(); @@ -524,7 +535,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGetPlayerState->setProperty("ssType", "progManageTool"); connect(btnGetPlayerState, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } JObj json{{"_type","getPlayerState"},{"_id","getPlayerState"},{"zVer","xixun1"}}; @@ -551,7 +562,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { QString error; auto json = JFrom(resp, &error); if(! error.isEmpty()) { - QMessageBox::critical(this, tr("Error"), error); + QMessageBox::critical(this, translate("","Error"), error); return; } QMessageBox::information(this, tr("Player State"), json["code"].toStr()+". "+json["des_en"].toStr()+"\n"+json["des"].toStr()); @@ -560,7 +571,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { tcp->close(); tcp->deleteLater(); waitingDlg->close(); - QMessageBox::critical(this, tr("Error"), QString(socketErrKey(err))+" ("+QString::number(err)+") "+tcp->errorString()); + QMessageBox::critical(this, translate("","Error"), QString(socketErrKey(err))+" ("+QString::number(err)+") "+tcp->errorString()); }); tcp->connectToHost(card.ip, 3333); tcp->startTimer(10000); @@ -602,7 +613,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGetLog->setProperty("ssType", "progManageTool"); connect(btnGetLog, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } if(gSelCards.count() == 1) { @@ -614,7 +625,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { waitingDlg->close(); QString err = checkReply(reply); if(! err.isEmpty()) { - QMessageBox::critical(this, tr("Error"), err); + QMessageBox::critical(this, translate("","Error"), err); return; } auto wgt = new QWidget(this, Qt::Window); @@ -637,7 +648,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnLogOn->setProperty("ssType", "progManageTool"); connect(btnLogOn, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } JObj json; @@ -662,7 +673,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnLogOff->setProperty("ssType", "progManageTool"); connect(btnLogOff, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } JObj json; @@ -694,7 +705,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnViewProg->setProperty("ssType", "progManageTool"); connect(btnViewProg, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } JObj json{{"_type", "GetJsonWithFileInfo"}}; @@ -750,7 +761,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGetPlayerInfo->setProperty("ssType", "progManageTool"); connect(btnGetPlayerInfo, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } JObj json{{"_type", "GetInfo"}}; @@ -805,7 +816,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { GetBuf->setProperty("ssType", "progManageTool"); connect(GetBuf, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } JObj json{{"_type", "GetLog"}}; @@ -860,7 +871,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnListFiles->setProperty("ssType", "progManageTool"); connect(btnListFiles, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } JObj json{{"_type", "ListProgFiles"}}; @@ -915,7 +926,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnDownFile->setProperty("ssType", "progManageTool"); connect(btnDownFile, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QInputDialog dlg(this); @@ -937,7 +948,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { if(! tcp.waitForConnected(10000)) { tcp.close(); if(! fdProgress.isVisible()) return; - QMessageBox::information(this, tr("Error"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitConnected"); + QMessageBox::information(this, translate("","Error"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitConnected"); continue; } QFile file(tar+" "+card.id); @@ -947,7 +958,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { if(resNum == -1 || ! tcp.waitForBytesWritten()) { tcp.close(); if(! fdProgress.isVisible()) return; - QMessageBox::information(this, tr("Error"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at write"); + QMessageBox::information(this, translate("","Error"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at write"); continue; } resNum = 0; @@ -958,17 +969,17 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { QString err; auto json = JFrom(&tcp, &err); if(! err.isEmpty()) { - QMessageBox::information(this, tr("Error"), err); + QMessageBox::information(this, translate("","Error"), err); goto end; } auto msg = json["msg"].toStr(); if(! msg.isEmpty()) { - QMessageBox::information(this, tr("Error"), msg); + QMessageBox::information(this, translate("","Error"), msg); goto end; } tarSize = json["len"].toLong(); if(tarSize==0) { - QMessageBox::information(this, tr("Error"), "tarSize==0"); + QMessageBox::information(this, translate("","Error"), "tarSize==0"); goto end; } fdProgress.setMaximum(tarSize); @@ -976,22 +987,184 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { auto res = tcp.readAll(); if(res.size()==0) continue; if(file.write(res) != res.size()) { - QMessageBox::information(this, tr("Error"), "write error"); + QMessageBox::information(this, translate("","Error"), "write error"); goto end; } resNum += res.size(); fdProgress.setValue(resNum); if(resNum>=tarSize) goto end; } - QMessageBox::information(this, tr("Error"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitRead2\n"); + QMessageBox::information(this, translate("","Error"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitRead2\n"); end: tcp.close(); } fdProgress.close(); - QMessageBox::information(this, tr("Error"), "OK"); + QMessageBox::information(this, translate("","Tip"), "OK"); }); hBox->addWidget(btnDownFile); + auto btnFinish = new QPushButton("Finish"); + connect(btnFinish, &QPushButton::clicked, this, [this] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); + return; + } + JObj json{{"_type", "finishActivity"}}; + auto fd = new QTextEdit; + LocalObj lll; + connect(fd, &QTextEdit::destroyed, &lll, &LocalObj::reset); + fd->setAttribute(Qt::WA_DeleteOnClose); + auto ft = fd->font(); + ft.setFamily("Consolas"); + fd->setFont(ft); + fd->setWindowTitle("Finish"); + fd->resize(400, 400); + fd->show(); + for(auto &card : gSelCards) { + fd->append(card.id+" Finish"); + TcpSocket tcp; + tcp.connectToHost(card.ip, 3333); + if(! tcp.waitForConnected(10000)) { + tcp.close(); + if(lll.cnt==0) return; + fd->append(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitConnected\n"); + continue; + } + auto resNum = tcp.write(JToBytes(json)); + tcp.flush(); + if(resNum == -1 || ! tcp.waitForBytesWritten()) { + tcp.close(); + if(lll.cnt==0) return; + fd->append(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at write\n"); + continue; + } + if(! tcp.waitForReadyRead()) { + tcp.close(); + if(lll.cnt==0) return; + fd->append(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitRead\n"); + continue; + } + fd->append(tcp.readAll()); + while(tcp.waitForReadyRead(1000)) { + if(lll.cnt==0) return; + fd->insertPlainText(tcp.readAll()); + } + tcp.close(); + if(lll.cnt==0) return; + if(tcp.error()!=QAbstractSocket::SocketTimeoutError) fd->append(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitRead2\n"); + fd->append("END"); + } + }); + hBox->addWidget(btnFinish); + + auto btnStart = new QPushButton("Start"); + connect(btnStart, &QPushButton::clicked, this, [this] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); + return; + } + JObj json{{"_type", "startActivity"}}; + auto fd = new QTextEdit; + LocalObj lll; + connect(fd, &QTextEdit::destroyed, &lll, &LocalObj::reset); + fd->setAttribute(Qt::WA_DeleteOnClose); + auto ft = fd->font(); + ft.setFamily("Consolas"); + fd->setFont(ft); + fd->setWindowTitle("Start"); + fd->resize(400, 400); + fd->show(); + for(auto &card : gSelCards) { + fd->append(card.id+" Start"); + TcpSocket tcp; + tcp.connectToHost(card.ip, 3333); + if(! tcp.waitForConnected(10000)) { + tcp.close(); + if(lll.cnt==0) return; + fd->append(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitConnected\n"); + continue; + } + auto resNum = tcp.write(JToBytes(json)); + tcp.flush(); + if(resNum == -1 || ! tcp.waitForBytesWritten()) { + tcp.close(); + if(lll.cnt==0) return; + fd->append(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at write\n"); + continue; + } + if(! tcp.waitForReadyRead()) { + tcp.close(); + if(lll.cnt==0) return; + fd->append(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitRead\n"); + continue; + } + fd->append(tcp.readAll()); + while(tcp.waitForReadyRead(1000)) { + if(lll.cnt==0) return; + fd->insertPlainText(tcp.readAll()); + } + tcp.close(); + if(lll.cnt==0) return; + if(tcp.error()!=QAbstractSocket::SocketTimeoutError) fd->append(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitRead2\n"); + fd->append("END"); + } + }); + hBox->addWidget(btnStart); + + auto btnGetProgFrom = new QPushButton("getProgFrom"); + connect(btnGetProgFrom, &QPushButton::clicked, this, [this] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); + return; + } + JObj json{{"_type", "getProgFrom"}}; + auto fd = new QTextEdit; + LocalObj lll; + connect(fd, &QTextEdit::destroyed, &lll, &LocalObj::reset); + fd->setAttribute(Qt::WA_DeleteOnClose); + auto ft = fd->font(); + ft.setFamily("Consolas"); + fd->setFont(ft); + fd->setWindowTitle("Finish"); + fd->resize(400, 400); + fd->show(); + for(auto &card : gSelCards) { + fd->append(card.id+" Finish"); + TcpSocket tcp; + tcp.connectToHost(card.ip, 3333); + if(! tcp.waitForConnected(10000)) { + tcp.close(); + if(lll.cnt==0) return; + fd->append(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitConnected\n"); + continue; + } + auto resNum = tcp.write(JToBytes(json)); + tcp.flush(); + if(resNum == -1 || ! tcp.waitForBytesWritten()) { + tcp.close(); + if(lll.cnt==0) return; + fd->append(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at write\n"); + continue; + } + if(! tcp.waitForReadyRead()) { + tcp.close(); + if(lll.cnt==0) return; + fd->append(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitRead\n"); + continue; + } + fd->append(tcp.readAll()); + while(tcp.waitForReadyRead(1000)) { + if(lll.cnt==0) return; + fd->insertPlainText(tcp.readAll()); + } + tcp.close(); + if(lll.cnt==0) return; + if(tcp.error()!=QAbstractSocket::SocketTimeoutError) fd->append(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitRead2\n"); + fd->append("END"); + } + }); + hBox->addWidget(btnGetProgFrom); + hBox->addStretch(); hBox = new HBox(vBox); hBox->addWidget(lbTimingReboot = new QLabel); @@ -1003,10 +1176,10 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "SetTimingReboot"); json.insert("_type", "SetTimingReboot"); json.insert("time", fdRebootTime->text()); @@ -1027,10 +1200,10 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "GetTimingReboot"); json.insert("_type", "GetTimingReboot"); if(gSelCards.count() == 1) { @@ -1063,7 +1236,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { auto hBox = new HBox(grpY50); auto fdY50Resolu = new QComboBox; - auto params = QDir(QApplication::applicationDirPath()+"/rk_lcd_parameters").entryList(QDir::Files); + auto params = QDir(QCoreApplication::applicationDirPath()+"/rk_lcd_parameters").entryList(QDir::Files); for(auto ¶m : params) fdY50Resolu->addItem(param); fdY50Resolu->setMinimumWidth(160); hBox->addWidget(fdY50Resolu); @@ -1072,17 +1245,17 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnY50Set->setProperty("ssType", "progManageTool"); connect(btnY50Set, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - auto file = QApplication::applicationDirPath()+"/rk_lcd_parameters/"+fdY50Resolu->currentText(); + auto file = QCoreApplication::applicationDirPath()+"/rk_lcd_parameters/"+fdY50Resolu->currentText(); QFile qFile(file); if(! qFile.exists()) { - QMessageBox::information(this, tr("Tip"), tr("File not exist")); + QMessageBox::information(this, translate("","Tip"), tr("File not exist")); return; } if(! qFile.open(QIODevice::ReadOnly)) { - QMessageBox::information(this, tr("Tip"), tr("Cannot Open File")+": "+qFile.errorString()+"\n"+file); + QMessageBox::information(this, translate("","Tip"), tr("Cannot Open File")+": "+qFile.errorString()+"\n"+file); return; } auto fileData = qFile.readAll(); @@ -1102,7 +1275,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { QString err = checkReply(reply); if(! err.isEmpty()) { waitingDlg->close(); - QMessageBox::critical(this, tr("Error"), err); + QMessageBox::critical(this, translate("","Error"), err); return; } waitingDlg->success(); @@ -1113,7 +1286,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { auto reply = req.timeout(120000).type("multipart/form-data; boundary="+Boundary).post(data); connect(reply, &QNetworkReply::finished, this, [=] { QString err = checkReply(reply); - gFdResInfo->append(card.id+" "+tr("Update")+" "+(err.isEmpty()?tr("Success"):err)); + gFdResInfo->append(card.id+" "+tr("Update")+" "+(err.isEmpty()?translate("","Success"):err)); }); } } @@ -1123,6 +1296,55 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { } vBox->addWidget(grpY50); + grpG12 = new QGroupBox; + { + auto hBox = new HBox(grpG12); + + auto edG12Reso = new QComboBox; + edG12Reso->setMinimumWidth(160); + edG12Reso->addItem("4096x2160P30", "4096x2160@30.00-4184-4272-4400-2168-2178-2250-5-297000"); + edG12Reso->addItem("4096x2160P25", "4096x2160@25.00-5064-5152-5280-2168-2178-2250-5-297000"); + edG12Reso->addItem("4096x2160P24", "4096x2160@24.00-5116-5204-5500-2168-2178-2250-5-297000"); + edG12Reso->addItem("3840x2160P30", "3840x2160@30.00-4016-4104-4400-2168-2178-2250-5-297000"); + edG12Reso->addItem("3840x2160P25", "3840x2160@25.00-4896-4984-5280-2168-2178-2250-5-297000"); + edG12Reso->addItem("3840x2160P24", "3840x2160@24.00-5116-5204-5500-2168-2178-2250-5-297000"); + edG12Reso->addItem("1920x1080P60", "1920x1080@60.00-2008-2052-2200-1084-1089-1125-5-148500"); + edG12Reso->addItem("1920x1080I60", "1920x1080@60.00-2008-2052-2200-1084-1094-1125-15-74250"); + edG12Reso->addItem("1920x1080P50", "1920x1080@50.00-2448-2492-2640-1084-1089-1125-5-148500"); + edG12Reso->addItem("1920x1080I50", "1920x1080@50.00-2448-2492-2640-1084-1094-1125-15-74250"); + edG12Reso->addItem("1280x720P60", "1280x720@60.00-1390-1430-1650-725-730-750-5-74250"); + edG12Reso->addItem("1280x720P50", "1280x720@50.00-1720-1760-1980-725-730-750-5-74250"); + edG12Reso->addItem("720x576P50", "720x576@50.00-732-796-864-581-586-625-a-27000"); + edG12Reso->addItem("720x480P60", "720x480@59.94-736-798-858-489-495-525-a-27000"); + hBox->addWidget(edG12Reso); + + btnSets.push_back(btn = new QPushButton); + connect(btn, &QPushButton::clicked, this, [=] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); + return; + } + JObj json; + json.insert("_id", "SetScreenSizeTo3568"); + json.insert("_type", "SetScreenSizeTo3568"); + json.insert("screenSize", edG12Reso->currentData().toString()); + if(gSelCards.count() == 1) { + auto waitingDlg = new WaitingDlg(this, translate("","Setting ")+translate("","Screen Size")+" 3568 ..."); + Def_CtrlReqPre + connect(reply, &QNetworkReply::finished, this, [=] { + Def_CtrlSetReqAfter + }); + } else { + for(auto &card : gSelCards) { + Def_CtrlSetMulti(translate("","Set ")+translate("","Screen Size")+" 3568") + } + } + }); + hBox->addWidget(btn); + hBox->addStretch(); + } + vBox->addWidget(grpG12); + hBox = new HBox(vBox); @@ -1138,7 +1360,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")+" ..."); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")+" ..."); return; } QJsonObject json; @@ -1162,7 +1384,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -1214,7 +1436,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -1223,14 +1445,14 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { json.insert("index", fdScreenPos->value()); json.insert("x", fdScreenOff->value()); if(gSelCards.count() == 1) { - auto waitingDlg = new WaitingDlg(this, tr("Set Screen Offset")+" ..."); + auto waitingDlg = new WaitingDlg(this, translate("","Setting ")+tr("Screen Offset")+" ..."); Def_CtrlReqPre connect(reply, &QNetworkReply::finished, this, [=] { Def_CtrlSetReqAfter }); } else { for(auto &card : gSelCards) { - Def_CtrlSetMulti(tr("Set Screen Offset")) + Def_CtrlSetMulti(translate("","Set ")+tr("Screen Offset")) } } }); @@ -1239,14 +1461,14 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; json.insert("_id", "GetConfigScreen"); json.insert("_type", "GetConfigScreen"); if(gSelCards.count() == 1) { - auto waitingDlg = new WaitingDlg(this, tr("Get Screen Offset")+" ..."); + auto waitingDlg = new WaitingDlg(this, translate("","Getting ")+tr("Screen Offset")+" ..."); Def_CtrlReqPre connect(reply, &QNetworkReply::finished, this, [=] { Def_CtrlSingleGetReply @@ -1264,7 +1486,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { if(err.isEmpty()) { err = lbScreenPos->text()+" "+QString::number(json["offsetNum"].toInt())+". "+lbScreenOff->text()+" "+QString::number(json["offsetValue"].toInt()); } - gFdResInfo->append(cardId+" "+tr("Get Screen Offset")+" "+err); + gFdResInfo->append(cardId+" "+translate("","Get ")+tr("Screen Offset")+" "+err); }); } } @@ -1291,7 +1513,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } JObj json; @@ -1301,37 +1523,45 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { json.insert("max", edCameraDisMax->value()); json.insert("zVer", "xixun1"); if(gSelCards.count() == 1) { - WaitingDlg waitingDlg(this, tr("Setting Camera Range")+" ..."); - waitingDlg.showLater(); + LoadingDlg loading(this, translate("","Setting ")+tr("Camera Distance")+" ..."); auto card = gSelCards[0]; TcpSocket tcp; tcp.connectToHost(card.ip, 3333); - if(! tcp.waitForConnected(10000)) { + if(! tcp.waitForConnected(5000)) { tcp.close(); - if(! waitingDlg.isVisible()) return; - waitingDlg.close(); - QMessageBox::critical(this, tr("Error"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitConnected"); + if(loading.result()==LoadingDlg::Rejected) return; + loading.rejected(); + QMessageBox::critical(this, translate("","Error"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitConnected"); return; } + if(loading.result()==LoadingDlg::Rejected) {tcp.close(); return;} auto resNum = tcp.write(JToBytes(json)); tcp.flush(); if(resNum == -1 || ! tcp.waitForBytesWritten(10000)) { tcp.close(); - if(! waitingDlg.isVisible()) return; - waitingDlg.close(); - QMessageBox::critical(this, tr("Error"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at write"); + if(loading.result()==LoadingDlg::Rejected) return; + loading.rejected(); + QMessageBox::critical(this, translate("","Error"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at write"); return; } + if(loading.result()==LoadingDlg::Rejected) {tcp.close(); return;} if(! tcp.waitForReadyRead(10000)) { tcp.close(); - if(! waitingDlg.isVisible()) return; - waitingDlg.close(); - QMessageBox::critical(this, tr("Error"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitForReadyRead"); + if(loading.result()==LoadingDlg::Rejected) return; + loading.rejected(); + QMessageBox::critical(this, translate("","Error"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitForReadyRead"); return; } - tcp.readAll(); + auto res = tcp.readAll(); tcp.close(); - waitingDlg.success(); + if(loading.result()==LoadingDlg::Rejected) return; + auto json = JFrom(res); + if(json["result"]!="Success") { + loading.rejected(); + QMessageBox::critical(this, translate("","Error"), res); + } + loading.success(); + loading.exec(); } else { for(auto &card : gSelCards) { auto tcp = new TcpSocket; @@ -1349,15 +1579,15 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { QString error; auto json = JFrom(resp, &error); if(! error.isEmpty()) { - gFdResInfo->append(cardId+" "+tr("Set Camera Range")+" "+error); + gFdResInfo->append(cardId+" "+translate("","Set ")+tr("Camera Distance")+" "+error); return; } - gFdResInfo->append(cardId+" "+tr("Set Camera Range")+" "+tr("Success")); + gFdResInfo->append(cardId+" "+translate("","Set ")+tr("Camera Distance")+" "+translate("","Success")); }); connect(tcp, &QTcpSocket::errorOccurred, tcp, [=](QAbstractSocket::SocketError err) { tcp->close(); tcp->deleteLater(); - gFdResInfo->append(cardId+" "+tr("Set Camera Range")+" "+socketErrKey(err)+" ("+QString::number(err)+") "+tcp->errorString()); + gFdResInfo->append(cardId+" "+translate("","Set ")+tr("Camera Distance")+" "+socketErrKey(err)+" ("+QString::number(err)+") "+tcp->errorString()); }); tcp->connectToHost(card.ip, 3333); tcp->startTimer(10000); @@ -1368,6 +1598,85 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { hBox->addStretch(); } + { + hBox = new HBox(vBox); + + hBox->addWidget(lbLockCard = new QLabel); + + auto edLockDate = new QDateEdit; + edLockDate->setDisplayFormat("yyyy-MM-dd"); + auto cur = QDate::currentDate(); + edLockDate->setDate(cur); + edLockDate->setMinimumDate(cur); + hBox->addWidget(edLockDate); + + auto btnLockDate = new CalendarButton; + btnLockDate->calendar->setMinimumDate(cur); + connect(btnLockDate->calendar, &QCalendarWidget::clicked, edLockDate, &QDateEdit::setDate); + hBox->addWidget(btnLockDate); + hBox->addSpacing(10); + + hBox->addWidget(lbLockPswd = new QLabel); + auto edLockPswd = new QLineEdit; + edLockPswd->setMaximumWidth(150); + hBox->addWidget(edLockPswd); + + btnLock = new QPushButton; + btnLock->setProperty("ssType", "progManageTool"); + connect(btnLock, &QPushButton::clicked, this, [=] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); + return; + } + JObj json; + json.insert("_id", "SetLockCard"); + json.insert("_type", "SetLockCard"); + json.insert("lockDate", edLockDate->date().toString("yyyy-MM-dd")); + json.insert("lockPassword", edLockPswd->text()); + if(gSelCards.count() == 1) { + auto waitingDlg = new WaitingDlg(this, translate("","Setting ")+tr("Lock Card")+" ..."); + Def_CtrlReqPre + connect(reply, &QNetworkReply::finished, this, [=] { + Def_CtrlSetReqAfter + }); + } else { + for(auto &card : gSelCards) { + Def_CtrlSetMulti(translate("","Set ")+tr("Lock Card")) + } + } + }); + hBox->addWidget(btnLock); + + btnUnlock = new QPushButton; + btnUnlock->setProperty("ssType", "progManageTool"); + connect(btnUnlock, &QPushButton::clicked, this, [=] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); + return; + } + JObj json; + json.insert("_id", "UnLockCard"); + json.insert("_type", "UnLockCard"); + json.insert("lockPassword", edLockPswd->text()); + if(gSelCards.count() == 1) { + auto waitingDlg = new WaitingDlg(this, translate("","Setting ")+translate("","Unlock")+" ..."); + Def_CtrlReqPre + connect(reply, &QNetworkReply::finished, this, [=] { + Def_CtrlSetReqAfter + }); + } else { + for(auto &card : gSelCards) { + Def_CtrlSetMulti(translate("","Set ")+translate("","Unlock")) + } + } + }); + hBox->addWidget(btnUnlock); + + hBox->addStretch(); + } + + +#if !defined leyide && !defined Q_OS_MAC hBox = new HBox(vBox); btnLedSet = new QPushButton; @@ -1379,6 +1688,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { }); hBox->addWidget(btnLedSet); hBox->addStretch(); +#endif hBox = new HBox(vBox); @@ -1386,7 +1696,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnReceCardsGet->setProperty("ssType", "progManageTool"); connect(btnReceCardsGet, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -1437,10 +1747,6 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { // hBox->addStretch(); -#ifndef Q_OS_WIN - btnLedSet->setVisible(false); -#endif - auto line = new QFrame; line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); @@ -1451,82 +1757,176 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnBindTaxiIc->setProperty("ssType", "progManageTool"); connect(btnBindTaxiIc, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QString icFile = QFileDialog::getOpenFileName(this, "open file dialog", "", tr("indentity voucher (*.ic)")); - if(icFile.isEmpty()) return; - QFile file(icFile); + auto filename = QFileDialog::getOpenFileName(this, "Open File Dialog", "", tr("Identity Certificate")+" (*.ic)"); + if(filename.isEmpty()) return; + QFile file(filename); if(! file.open(QIODevice::ReadOnly)) { - QMessageBox::information(this, tr("Tip"), tr("Open file Failed")); + QMessageBox::critical(this, translate("","Error"), tr("Open file Failed")); return; } - auto data = file.readAll(); + QString error; + auto jsonIC = JFrom(&file, &error); file.close(); - QJsonParseError jsonErr; - QJsonDocument icJson = QJsonDocument::fromJson(data, &jsonErr); - if(jsonErr.error != QJsonParseError::NoError) { - QMessageBox::information(this, tr("Tip"), "JsonError "+jsonErr.errorString()+"\n"+data); + if(! error.isEmpty()) { + QMessageBox::critical(this, translate("","Error"), error); return; } - QJsonObject jsonCommand; - jsonCommand.insert("action", "BindAccount"); - jsonCommand.insert("accountIdToken", icJson["account_id_token"]); - jsonCommand.insert("server", icJson["taxiServerURL"]); - jsonCommand.insert("tlsServer", icJson["taxiServerTLSURL"]); - QJsonObject json; - json.insert("action", "InvokeTaxiAppFunction"); - json.insert("jsonCommand", jsonCommand); + JObj InvokeTaxi; + InvokeTaxi["action"] = "InvokeTaxiAppFunction"; + InvokeTaxi["jsonCommand"] = JObj{ + {"action", "BindAccount"}, + {"accountIdToken", jsonIC["account_id_token"]}, + {"server", jsonIC["taxiServerURL"]}, + {"tlsServer", jsonIC["taxiServerTLSURL"]} + }; + WaitingDlg *waitingDlg = 0; if(gSelCards.count() == 1) { - auto waitingDlg = new WaitingDlg(this, tr("InvokeTaxiAppFunction")); + waitingDlg = new WaitingDlg(this, tr("Check Apk Version")); waitingDlg->show(); - auto reply = NetReq("http://"+gSelCards[0].ip+":3000").timeout(120000).post(json); - ConnReply(reply, waitingDlg) [=] { - QString err = checkReply(reply); + } + for(auto &card : gSelCards) { + auto cardId = card.id; + JObj json; + json["_id"] = "CheckSoftVersions"; + json["_type"] = "CheckSoftVersions"; + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json); + if(waitingDlg) connect(waitingDlg, &QObject::destroyed, reply, &QNetworkReply::deleteLater); + connect(reply, &QNetworkReply::finished, waitingDlg ? (QObject*)waitingDlg : (QObject*)this, [=] { + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) { - waitingDlg->close(); - QMessageBox::critical(this, tr("Error"), err); + if(waitingDlg) { + waitingDlg->close(); + QMessageBox::critical(this, translate("","Error"), err); + } else gFdResInfo->append(cardId+" "+tr("Binding certificate")+" "+translate("","Error")+" "+err); + return; + } + QString playerVer, taxiVer; + auto apps = json["apps"]; + for(auto &app : apps) { + auto packageName = app["packageName"].toStr(); + if(packageName=="com.xixun.xixunplayer") playerVer = app["versionName"].toStr(); + else if(packageName=="net.sysolution.taxiapp") taxiVer = app["versionName"].toStr(); + } + if(taxiVer.isEmpty()) { + if(! playerVer.isEmpty()) { + JObj json; + json.insert("_id", "UninstallSoftware"); + json.insert("_type", "UninstallSoftware"); + json.insert("packageName", "com.xixun.xixunplayer"); + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json); + if(waitingDlg) waitingDlg->fdText->setText(translate("","Uninstall")+" XixunPlayer ..."); + else gFdResInfo->append(cardId+" "+translate("","Uninstall")+" XixunPlayer ..."); + if(waitFinished(reply, waitingDlg)) return; + auto err = errStrWithJson(reply, "error"); + if(! err.isEmpty()) { + if(waitingDlg) { + waitingDlg->close(); + QMessageBox::critical(this, translate("","Uninstall")+" "+translate("","Error"), err); + } else gFdResInfo->append(cardId+" "+translate("","Uninstall")+" "+translate("","Error")+": "+err); + return; + } + } + auto files = QDir(QCoreApplication::applicationDirPath()+"/files").entryList(QDir::Files); + QString fileName; + for(auto file : files) if(file.startsWith("VehPlay")) { + fileName = file; + break; + } + if(fileName.isEmpty()) { + if(waitingDlg) { + waitingDlg->close(); + QMessageBox::critical(this, translate("","Error"), tr("No VehPlayer File")); + } else gFdResInfo->append(cardId+" "+tr("No VehPlayer File")); + return; + } + QByteArray fileData; + QFile file(QCoreApplication::applicationDirPath()+"/files/"+fileName); + if(! file.open(QIODevice::ReadOnly)) return; + fileData = file.readAll(); + file.close(); + if(fileData.size() != file.size()) { + if(waitingDlg) { + waitingDlg->close(); + QMessageBox::critical(this, translate("","Error"), tr("Failed to Read File")); + } else gFdResInfo->append(cardId+" "+tr("Failed to Read File")); + return; + } + auto nameBytes = fileName.toUtf8(); + auto Boundary = "----QtLedOK_.oOo._"+QUuid::createUuid().toByteArray(QUuid::WithoutBraces); + QByteArray data; + data.append("--").append(Boundary).append("\r\nContent-Disposition: form-data; name=\"username\"\r\n\r\n10005\r\n"); + data.append("--").append(Boundary).append("\r\nContent-Disposition: form-data; name=\"").append(nameBytes).append("\"; filename=\"").append(nameBytes).append("\"\r\n\r\n").append(fileData).append("\r\n"); + data.append("--").append(Boundary).append("--\r\n"); + NetReq req("http://"+card.ip+":2016/upload?type=software"); + auto reply = req.type("multipart/form-data; boundary="+Boundary).post(data); + if(waitingDlg) waitingDlg->fdText->setText(translate("","Upload")+" VehPlayer ..."); + else gFdResInfo->append(cardId+" "+translate("","Upload")+" VehPlayer ..."); + if(waitFinished(reply, waitingDlg)) return; + auto err = errStrWithData(reply); + if(! err.isEmpty()) { + if(waitingDlg) { + waitingDlg->close(); + QMessageBox::critical(this, translate("","Upload")+" "+translate("","Error"), err); + } else gFdResInfo->append(cardId+" "+translate("","Upload")+" "+translate("","Error")+": "+err); + return; + } + JObj json; + json.insert("_id", "UpgradeSoftware"); + json.insert("_type", "UpgradeSoftware"); + json.insert("fileName", fileName); + json.insert("isCustom", true); + reply = NetReq("http://"+card.ip+":2016/settings").post(json); + if(waitingDlg) waitingDlg->fdText->setText(translate("","Install")+" VehPlayer ..."); + else gFdResInfo->append(cardId+" "+translate("","Install")+" VehPlayer ..."); + if(waitFinished(reply, waitingDlg)) return; + err = errStrWithJson(reply); + if(! err.isEmpty()) { + if(waitingDlg) { + waitingDlg->close(); + QMessageBox::critical(this, translate("","Install")+" "+translate("","Error"), err); + } else gFdResInfo->append(cardId+" "+translate("","Install")+" "+translate("","Error")+": "+err); + return; + } + if(waitingDlg) waitingDlg->fdText->setText(translate("","Wait for")+" 6s ..."); + else gFdResInfo->append(cardId+" "+translate("","Wait for")+" 6s ..."); + if(wait(6000, waitingDlg)) return; + } + auto reply = NetReq("http://"+card.ip+":3000").post(InvokeTaxi); + if(waitingDlg) waitingDlg->fdText->setText(tr("Binding certificate")+" ..."); + else gFdResInfo->append(cardId+" "+tr("Binding certificate")+" ..."); + if(waitFinished(reply, waitingDlg)) return; + err = checkReply(reply); + if(! err.isEmpty()) { + if(waitingDlg) { + waitingDlg->close(); + QMessageBox::critical(this, translate("","Error"), err); + } else gFdResInfo->append(cardId+" "+tr("Binding certificate")+" "+translate("","Error")+" "+err); return; } auto data = reply->readAll(); - QJsonParseError jsonErr; - QJsonDocument json = QJsonDocument::fromJson(data, &jsonErr); - if(jsonErr.error != QJsonParseError::NoError) { - waitingDlg->close(); - QMessageBox::critical(this, tr("Error"), "JsonError "+jsonErr.errorString()+"\n"+data); + QString error; + json = JFrom(data, &error); + if(! error.isEmpty()) { + if(waitingDlg) { + waitingDlg->close(); + QMessageBox::critical(this, translate("","Error"), "JsonError "+error+"\n"+data); + } else gFdResInfo->append(cardId+" "+tr("Binding certificate")+" "+translate("","Error")+" JsonError "+error+"\n"+data); return; } if(json["result"].toString() != "true") { - waitingDlg->close(); - QMessageBox::critical(this, tr("Error"), data); + if(waitingDlg) { + waitingDlg->close(); + QMessageBox::critical(this, translate("","Error"), data); + } else gFdResInfo->append(cardId+" "+tr("Binding certificate")+" "+translate("","Error")+" "+data); return; } - waitingDlg->success(); + if(waitingDlg) waitingDlg->success(); + else gFdResInfo->append(cardId+" "+tr("Binding certificate")+" "+translate("","Success")); }); - } else { - for(auto &card : gSelCards) { - auto reply = NetReq("http://"+card.ip+":3000").timeout(120000).post(json); - auto cardId = card.id; - connect(reply, &QNetworkReply::finished, this, [reply, cardId] { - QString err = checkReply(reply); - if(! err.isEmpty()) { - gFdResInfo->append(cardId+" "+tr("InvokeTaxiAppFunction")+" "+tr("Error")+" "+err); - return; - } - auto data = reply->readAll(); - QJsonParseError jsonErr; - QJsonDocument json = QJsonDocument::fromJson(data, &jsonErr); - if(jsonErr.error != QJsonParseError::NoError) { - gFdResInfo->append(cardId+" "+tr("InvokeTaxiAppFunction")+" "+tr("Error")+" JsonError "+jsonErr.errorString()+"\n"+data); - return; - } - if(json["result"].toString() != "true") { - gFdResInfo->append(cardId+" "+tr("InvokeTaxiAppFunction")+" "+tr("Error")+" "+data); - return; - } - gFdResInfo->append(cardId+" "+tr("InvokeTaxiAppFunction")+" "+QCoreApplication::translate("Def","Success")); - }); - } } }); hBox->addWidget(btnBindTaxiIc); @@ -1547,7 +1947,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -1572,7 +1972,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGetTopLevel->setProperty("ssType", "progManageTool"); connect(btnGetTopLevel, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -1622,7 +2022,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -1646,7 +2046,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -1697,7 +2097,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -1721,7 +2121,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -1775,7 +2175,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSetBack->setProperty("ssType", "progManageTool"); connect(btnSetBack, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QColorDialog colorDlg(this); @@ -1806,7 +2206,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSysUpd->setProperty("ssType", "progManageTool"); connect(btnSysUpd, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -1832,18 +2232,18 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnMcuUpd->setProperty("ssType", "progManageTool"); connect(btnMcuUpd, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto filePath = QFileDialog::getOpenFileName(this, "Open File", QString(), ".bin file (*.bin)"); if(filePath.isEmpty()) return; QFile qFile(filePath); if(! qFile.exists()) { - QMessageBox::information(this, tr("Tip"), tr("File not exist")); + QMessageBox::information(this, translate("","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, translate("","Tip"), tr("Cannot Open File")+": "+qFile.errorString()+"\n"+filePath); return; } auto fileData = qFile.readAll(); @@ -1893,7 +2293,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnMcuGet->setProperty("ssType", "progManageTool"); connect(btnMcuGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -1905,7 +2305,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { connect(reply, &QNetworkReply::finished, this, [=] { Def_CtrlSingleGetReply waitingDlg->close(); - QMessageBox::information(this, tr("Tip"), tr("MCU Version")+": "+json["mcuVersion"].toString()); + QMessageBox::information(this, translate("","Tip"), tr("MCU Version")+": "+json["mcuVersion"].toString()); }); } else { for(auto &card : gSelCards) { @@ -1928,10 +2328,10 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnPlayerBackSet->setProperty("ssType", "progManageTool"); connect(btnPlayerBackSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - auto file = QFileDialog::getOpenFileName(this, tr("Select File"), gFileHome, EPhoto::filters()); + auto file = QFileDialog::getOpenFileName(this, translate("","Select File"), gFileHome, EPhoto::filters()); if(file.isEmpty()) return; QFileInfo info(file); if(! info.isFile()) return; @@ -1944,7 +2344,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { if(err.isEmpty()) waitingDlg->success(); else { waitingDlg->close(); - QMessageBox::critical(this, tr("Error"), err); + QMessageBox::critical(this, translate("","Error"), err); } }); thread->start(); @@ -1953,7 +2353,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { auto thread = new PlayerBackSendThread(file, card.ip); auto cardId = card.id; connect(thread, &PlayerBackSendThread::emErr, this, [cardId](QString err) { - gFdResInfo->append(cardId+" "+tr("Set player background")+" "+(err.isEmpty() ? tr("Success") : err)); + gFdResInfo->append(cardId+" "+tr("Set player background")+" "+(err.isEmpty() ? translate("","Success") : err)); }); thread->start(); } @@ -1965,7 +2365,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnPlayerBackClear->setProperty("ssType", "progManageTool"); connect(btnPlayerBackClear, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } if(gSelCards.count() == 1) { @@ -1979,7 +2379,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { waitingDlg->close(); tcp->abort(); tcp->deleteLater(); - QMessageBox::critical(this, tr("Tip"), tr("Clear player background")+" "+tr("Timeout")); + QMessageBox::critical(this, translate("","Tip"), tr("Clear player background")+" "+tr("Timeout")); }); connect(waitingDlg, &WaitingDlg::rejected, tcp, [=] { timer->stop(); @@ -2000,10 +2400,10 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { QJsonDocument json = QJsonDocument::fromJson(resp, &parseErr); if(parseErr.error != QJsonParseError::NoError) { waitingDlg->close(); - QMessageBox::critical(this, tr("Tip"), parseErr.errorString()); + QMessageBox::critical(this, translate("","Tip"), parseErr.errorString()); } else if(! json["success"].toBool()) { waitingDlg->close(); - QMessageBox::critical(this, tr("Tip"), tr("Clear player background")+" "+tr("Failed")); + QMessageBox::critical(this, translate("","Tip"), tr("Clear player background")+" "+tr("Failed")); } else waitingDlg->success(); }); connect(tcp, &QTcpSocket::errorOccurred, tcp, [=](QAbstractSocket::SocketError err) { @@ -2011,7 +2411,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { tcp->close(); tcp->deleteLater(); waitingDlg->close(); - QMessageBox::critical(this, tr("Tip"), QString(socketErrKey(err))+" ("+QString::number(err)+") "+tcp->errorString()); + QMessageBox::critical(this, translate("","Tip"), QString(socketErrKey(err))+" ("+QString::number(err)+") "+tcp->errorString()); }); tcp->connectToHost(card.ip, 3333); timer->start(10000); @@ -2040,7 +2440,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { QJsonDocument json = QJsonDocument::fromJson(resp, &parseErr); if(parseErr.error != QJsonParseError::NoError) gFdResInfo->append(cardId+" "+tr("Clear player background")+" "+parseErr.errorString()); else if(! json["success"].toBool()) gFdResInfo->append(cardId+" "+tr("Clear player background")+" "+tr("Failed")); - else gFdResInfo->append(cardId+" "+tr("Clear player background")+" "+tr("Success")); + else gFdResInfo->append(cardId+" "+tr("Clear player background")+" "+translate("","Success")); }); connect(tcp, &QTcpSocket::errorOccurred, tcp, [tcp, timer, cardId](QAbstractSocket::SocketError err) { timer->stop(); @@ -2087,7 +2487,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnM80Set->setProperty("ssType", "progManageTool"); connect(btnM80Set, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -2113,7 +2513,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnM80Refresh->setProperty("ssType", "progManageTool"); connect(btnM80Refresh, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -2146,21 +2546,21 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnM80Restore->setProperty("ssType", "progManageTool"); connect(btnM80Restore, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; json.insert("_id", "CleanDisplayScreenSize"); json.insert("_type", "CleanDisplayScreenSize"); if(gSelCards.count() == 1) { - auto waitingDlg = new WaitingDlg(this, tr("CleanDisplayScreenSize")); + auto waitingDlg = new WaitingDlg(this, tr("Restore to default relolution")); Def_CtrlReqPre connect(reply, &QNetworkReply::finished, this, [=] { Def_CtrlSetReqAfter }); } else { for(auto &card : gSelCards) { - Def_CtrlSetMulti(tr("CleanDisplayScreenSize")) + Def_CtrlSetMulti(tr("Restore to default relolution")) } } }); @@ -2193,7 +2593,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto id = btnGrp->checkedId(); @@ -2218,7 +2618,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -2268,7 +2668,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } JObj json; @@ -2277,14 +2677,14 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { json.insert("x", edOffX->value()); json.insert("y", edOffY->value()); if(gSelCards.count() == 1) { - auto waitingDlg = new WaitingDlg(this, tr("SetScreenOffset")); + auto waitingDlg = new WaitingDlg(this, translate("","Setting ")+tr("Screen Offset")); Def_CtrlReqPre connect(reply, &QNetworkReply::finished, this, [=] { Def_CtrlSetReqAfter }); } else { for(auto &card : gSelCards) { - Def_CtrlSetMulti(tr("SetScreenOffset")) + Def_CtrlSetMulti(translate("","Set ")+tr("Screen Offset")) } } }); @@ -2292,14 +2692,14 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; json.insert("_id", "GetScreenOffset"); json.insert("_type", "GetScreenOffset"); if(gSelCards.count() == 1) { - auto waitingDlg = new WaitingDlg(this, tr("GetScreenOffset")+" ..."); + auto waitingDlg = new WaitingDlg(this, translate("","Getting ")+tr("Screen Offset")+" ..."); Def_CtrlReqPre connect(reply, &QNetworkReply::finished, this, [=] { Def_CtrlSingleGetReply @@ -2314,7 +2714,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { QJsonDocument json; auto err = checkReplyForJson(reply, &json); if(err.isEmpty()) err = "x: "+ QString::number(json["x"].toInt())+" y: "+ QString::number(json["y"].toInt()); - gFdResInfo->append(card.id+" "+tr("GetScreenOffset")+" "+err); + gFdResInfo->append(card.id+" "+translate("","Get ")+tr("Screen Offset")+" "+err); }); } } @@ -2335,7 +2735,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -2343,14 +2743,14 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { json.insert("_type", "SetChargingStationID"); json.insert("number", fdChargingStation->text()); if(gSelCards.count() == 1) { - auto waitingDlg = new WaitingDlg(this, tr("Setting ")+tr("Charging Station")+" ID ..."); + auto waitingDlg = new WaitingDlg(this, translate("","Setting ")+tr("Charging Station")+" ID ..."); Def_CtrlReqPre connect(reply, &QNetworkReply::finished, this, [=] { Def_CtrlSetReqAfter }); } else { for(auto &card : gSelCards) { - Def_CtrlSetMulti(tr("Set")+" "+tr("Charging Station")+" ID") + Def_CtrlSetMulti(translate("","Set")+" "+tr("Charging Station")+" ID") } } }); @@ -2429,7 +2829,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [this, fdUart, fdBaud] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -2454,7 +2854,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [this, fdUart, fdBaud] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -2489,7 +2889,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { fdIsOpenADB = new QCheckBox; connect(fdIsOpenADB, &QCheckBox::toggled, this, [this](bool checked) { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -2512,7 +2912,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { hBox = new HBox(vBox); - lbCustomJson = new QLabel; + lbCustomJson = new QLabel("Post Custom JSON"); hBox->addWidget(lbCustomJson); hBox->addSpacing(40); @@ -2521,22 +2921,22 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSendCustomJson->setProperty("ssType", "progManageTool"); connect(btnSendCustomJson, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto text = fdCustomJson->toPlainText().toUtf8(); if(text.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("Text is empty")); + QMessageBox::information(this, translate("","Tip"), tr("Text is empty")); return; } QJsonParseError jsonErr; QJsonDocument json = QJsonDocument::fromJson(text, &jsonErr); if(jsonErr.error != QJsonParseError::NoError) { - QMessageBox::information(this, tr("Tip"), tr("Json Parse Error")+jsonErr.errorString()); + QMessageBox::information(this, translate("","Tip"), tr("Json Parse Error")+jsonErr.errorString()); return; } if(! json.isObject()) { - QMessageBox::information(this, tr("Tip"), tr("Json isn't an Object")); + QMessageBox::information(this, translate("","Tip"), tr("Json isn't an Object")); return; } if(gSelCards.count() == 1) { @@ -2557,22 +2957,22 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnCustomJsonGet->setProperty("ssType", "progManageTool"); connect(btnCustomJsonGet, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto text = fdCustomJson->toPlainText().toUtf8(); if(text.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("Text is empty")); + QMessageBox::information(this, translate("","Tip"), tr("Text is empty")); return; } QString jsonErr; auto json = JFrom(text, &jsonErr); if(! jsonErr.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("Json Parse Error")+" "+jsonErr); + QMessageBox::information(this, translate("","Tip"), tr("Json Parse Error")+" "+jsonErr); return; } if(! json.isObj()) { - QMessageBox::information(this, tr("Tip"), tr("Json isn't an Object")); + QMessageBox::information(this, translate("","Tip"), tr("Json isn't an Object")); return; } if(gSelCards.count() == 1) { @@ -2581,7 +2981,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { connect(reply, &QNetworkReply::finished, this, [=] { waitingDlg->close(); auto err = errStrWithData(reply); - if(! err.isEmpty()) QMessageBox::critical(this, tr("Error"), err); + if(! err.isEmpty()) QMessageBox::critical(this, translate("","Error"), err); else QMessageBox::information(this, tr("Info"), reply->readAll()); }); } else { @@ -2619,7 +3019,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [this, fdTraficProtocol] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -2643,7 +3043,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [this, fdTraficProtocol] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -2703,7 +3103,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnSets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -2728,7 +3128,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btnGets.push_back(btn = new QPushButton); connect(btn, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -2773,7 +3173,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() { btn->setProperty("ssType", "progManageTool"); connect(btn, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto fd = new QTextEdit; @@ -2817,7 +3217,7 @@ void CtrlAdvancedPanel::init() { auto vBox = new VBox(&dlg); vBox->addStretch(); auto hBox = new HBox(vBox); - hBox->addWidget(new QLabel(tr("Input password"))); + hBox->addWidget(new QLabel(translate("","Input Password"))); auto fdPassword = new QLineEdit; fdPassword->setEchoMode(QLineEdit::Password); @@ -2840,7 +3240,7 @@ void CtrlAdvancedPanel::init() { auto pwdVar = QSettings().value("advUiPs"); auto password = pwdVar.isNull() ? "888" : QString::fromUtf8(QByteArray::fromBase64(pwdVar.toString().toLatin1())); if(fdPassword->text() == password) dlg.accept(); - else QMessageBox::critical(&dlg, tr("Tip"),tr("Password is error")); + else QMessageBox::critical(&dlg, translate("","Tip"),tr("Password is error")); }); if(dlg.exec()==QDialog::Accepted) { isPassed = true; @@ -2881,9 +3281,8 @@ void CtrlAdvancedPanel::init() { // } auto isY50 = card.id.startsWith("st5", Qt::CaseInsensitive) - || card.id.startsWith("m5h", Qt::CaseInsensitive) - || card.id.startsWith("m5s", Qt::CaseInsensitive) - || card.id.startsWith("m6s", Qt::CaseInsensitive) + || card.id.startsWith("m5", Qt::CaseInsensitive) + || card.id.startsWith("m6", Qt::CaseInsensitive) || card.id.startsWith("m7", Qt::CaseInsensitive) || card.id.startsWith("y0", Qt::CaseInsensitive) || card.id.startsWith("y1", Qt::CaseInsensitive) @@ -2920,24 +3319,25 @@ void CtrlAdvancedPanel::changeEvent(QEvent *event) { if(event->type() == QEvent::LanguageChange) transUi(); } void CtrlAdvancedPanel::transUi() { - for(auto btn : btnSets) btn->setText(tr("Set")); - for(auto btn : btnGets) btn->setText(tr("Get")); + for(auto btn : btnSets) btn->setText(translate("","Set")); + for(auto btn : btnGets) btn->setText(translate("","Get")); - btnBindTaxiIc->setText(tr("Binding *.ic account indentity voucher")); - btnGetTopLevel->setText(tr("Readback")); - btnLedSet->setText(tr("Start LedSet4")); + btnBindTaxiIc->setText(tr("Bind Taxihub identity certificate")); + btnGetTopLevel->setText(translate("","Readback")); + if(btnLedSet) btnLedSet->setText(tr("Start LedSet4.0")); btnReceCardsGet->setText(tr("Get Receive Card Num")); grpPlayer->setTitle(tr("Player Debug")); grpM80->setTitle("M80 "+tr("Config")); - btnM80Refresh->setText(tr("Refresh")); + btnM80Refresh->setText(translate("","Refresh")); btnM80Restore->setText(tr("Restore to default")); - btnM80Set->setText(tr("Set")); + btnM80Set->setText(translate("","Set")); - grpY50->setTitle("M50S / M60S / M70S / M5H / M7L / ST50 / Y1G / Y1C / Y4A / Y5A / Y08 / Y35 / Y37 "+tr("Resolution Config")); + grpY50->setTitle("M50S / M60S / M70S / M5H / M6L / M7L / ST50 / Y1G / Y1C / Y4A / Y5A / Y08 / Y35 / Y37 "+tr("Resolution Config")); + grpG12->setTitle("G12 "+tr("Resolution Config")); fdDisMode->setItemText(0, tr("Full screen")); fdDisMode->setItemText(1, tr("Part")); - btnY50Set->setText(tr("Set")); + btnY50Set->setText(translate("","Set")); lbDisMode->setText(tr("Display Mode")+":"); @@ -2945,6 +3345,10 @@ void CtrlAdvancedPanel::transUi() { lbScreenOff->setText(tr("Offset")+":"); lbCameraDis->setText(tr("Camera Distance")+":"); + lbLockCard->setText(tr("Lock Card")+": "+translate("","Date")); + lbLockPswd->setText(translate("","Password")); + btnLock->setText(translate("","Lock")); + btnUnlock->setText(translate("","Unlock")); fdScreenHeight->setPlaceholderText(tr("Height")); fdScreenWidth->setPlaceholderText(tr("Width")); @@ -2961,9 +3365,8 @@ void CtrlAdvancedPanel::transUi() { lbUart->setText(tr("Uart")); lbBaud->setText(tr("Baud")); fdIsOpenADB->setText(tr("Open ADB")); - lbCustomJson->setText(tr("Post Custom JSON")); - btnSendCustomJson->setText(tr("Send")); - btnCustomJsonGet->setText(tr("Get")); + btnSendCustomJson->setText(translate("","Send")); + btnCustomJsonGet->setText(translate("","Get")); grpHighForBusy->setTitle(tr("Taxi top screen configuration")); lbTitle->setText(tr("Advanced")); @@ -2988,7 +3391,7 @@ void CtrlAdvancedPanel::transUi() { btnPlayerBackSet->setText(tr("Set player background")); btnPlayerBackClear->setText(tr("Clear player background")); - btnRealtimeClear->setText(tr("Clear")); + btnRealtimeClear->setText(translate("","Clear")); btnRestart->setText(tr("Restart")); btnIsRunning->setText(tr("Running check")); fdUninstall->setText(tr("Uninstall")); diff --git a/LedOK/device/ctrladvancedpanel.h b/LedOK/device/ctrladvancedpanel.h index d7049a3..562cba7 100644 --- a/LedOK/device/ctrladvancedpanel.h +++ b/LedOK/device/ctrladvancedpanel.h @@ -55,21 +55,20 @@ private: QLabel *lbTimingReboot; - QGroupBox *grpPlayer, *grpM80, *grpY50; + QGroupBox *grpPlayer, *grpY50, *grpG12, *grpM80; QComboBox *fdM80Resolu, *fdDisMode; - QPushButton *btnM80Set, *btnY50Set; - QPushButton *btnM80Refresh; - QPushButton *btnM80Restore; + QPushButton *btnY50Set, *btnM80Set, *btnM80Refresh, *btnM80Restore; QLabel *lbDisMode; QLabel *lbScreenPos, *lbScreenOff; - QLabel *lbOffset, *lbCameraDis; + QLabel *lbOffset, *lbCameraDis, *lbLockCard, *lbLockPswd; + QPushButton *btnLock, *btnUnlock; QGroupBox *grpHighForBusy; QRadioButton *fdHighForBusy; QRadioButton *fdTopLevelLH; QPushButton *btnGetTopLevel; - QPushButton *btnLedSet; + QPushButton *btnLedSet = 0; QPushButton *btnReceCardsGet, *btnBindTaxiIc; QGroupBox *grpMinMaxBrightness; diff --git a/LedOK/device/ctrlbrightpanel.cpp b/LedOK/device/ctrlbrightpanel.cpp index 873c51a..65fa6b9 100644 --- a/LedOK/device/ctrlbrightpanel.cpp +++ b/LedOK/device/ctrlbrightpanel.cpp @@ -87,7 +87,7 @@ CtrlBrightPanel::CtrlBrightPanel() { btnSensiSet->setProperty("ssType", "progManageTool"); connect(btnSensiSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -113,7 +113,7 @@ CtrlBrightPanel::CtrlBrightPanel() { btnSensiGet->setProperty("ssType", "progManageTool"); connect(btnSensiGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -128,12 +128,12 @@ CtrlBrightPanel::CtrlBrightPanel() { fdSensi->setValue(json["sensitivity"].toInt()); }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); auto cardId = card.id; connect(reply, &QNetworkReply::finished, this, [reply, cardId] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) err = QString::number(json["sensitivity"].toInt()); gFdResInfo->append(cardId+" "+tr("GetBrightnessSensitivity")+" "+err); }); @@ -170,7 +170,7 @@ CtrlBrightPanel::CtrlBrightPanel() { btnMinBrightSet->setProperty("ssType", "progManageTool"); connect(btnMinBrightSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto isAdaptToOld = fdAdaptToOld->isChecked(); @@ -200,7 +200,7 @@ CtrlBrightPanel::CtrlBrightPanel() { btnMinBrightGet->setProperty("ssType", "progManageTool"); connect(btnMinBrightGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -218,13 +218,13 @@ CtrlBrightPanel::CtrlBrightPanel() { fdMinBright->setValue(value); }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); auto cardId = card.id; auto brightLevel = card.BrightnessLevel; connect(reply, &QNetworkReply::finished, this, [=] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) { auto value = json["minBrightnessPercentage"].toInt(-1); if(value==-1) value = qRound(json["brightness"].toInt() * 100.0 / brightLevel); @@ -267,14 +267,14 @@ CtrlBrightPanel::CtrlBrightPanel() { btnUpload->setProperty("ssType", "progManageTool"); connect(btnUpload, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QString sensorName; if(fdRL2->isChecked()) sensorName = fdRL2->text(); else if(fdR68->isChecked()) sensorName = fdR68->text(); else { - QMessageBox::information(this, tr("Tip"), tr("NeedSelectSensorTypeTip")); + QMessageBox::information(this, translate("","Tip"), tr("NeedSelectSensorTypeTip")); return; } QString xlsxFile = QFileDialog::getOpenFileName(this, tr("Open file dialog"), "/", "brightness files(*.xlsx)"); @@ -285,7 +285,7 @@ CtrlBrightPanel::CtrlBrightPanel() { if(workbook->sheetCount() < 2) { sheet = xlsx.currentWorksheet(); if(sheet==0) { - QMessageBox::information(this, tr("Tip"), tr("Not found current worksheet")); + QMessageBox::information(this, translate("","Tip"), tr("Not found current worksheet")); return; } } else { @@ -299,7 +299,7 @@ CtrlBrightPanel::CtrlBrightPanel() { } } if(sheet==0) { - QMessageBox::information(this, tr("Tip"), "Not found sheet "+sensorName); + QMessageBox::information(this, translate("","Tip"), "Not found sheet "+sensorName); return; } } @@ -307,7 +307,7 @@ CtrlBrightPanel::CtrlBrightPanel() { for(int j=0; j<255; j++) { auto val = sheet->read(3, j+3).toString(); if(val.isEmpty()) { - QMessageBox::information(this, tr("Tip"), "Cell is empty at 3, "+QString::number(j+3)); + QMessageBox::information(this, translate("","Tip"), "Cell is empty at 3, "+QString::number(j+3)); return; } values.append(val); @@ -335,14 +335,14 @@ CtrlBrightPanel::CtrlBrightPanel() { btnTableGet->setProperty("ssType", "progManageTool"); connect(btnTableGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QString strSensorType; if(fdRL2->isChecked()) strSensorType = fdRL2->text(); else if(fdR68->isChecked()) strSensorType = fdR68->text(); else { - QMessageBox::information(this, tr("Tip"), tr("NeedSelectSensorTypeTip")); + QMessageBox::information(this, translate("","Tip"), tr("NeedSelectSensorTypeTip")); return; } QJsonObject json; @@ -354,24 +354,24 @@ CtrlBrightPanel::CtrlBrightPanel() { connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg, card, strSensorType] { Def_CtrlSingleGetReply waitingDlg->close(); - QStringList values = json["values"].toVariant().value(); - if(values.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("no sensorBrightnessTable")); + auto values = json["values"]; + if(values.empty()) { + QMessageBox::information(this, translate("","Tip"), tr("no sensorBrightnessTable")); return; } - QString tempFile = QCoreApplication::applicationDirPath()+"/files/bright-template.xlsx"; + auto tempFile = QCoreApplication::applicationDirPath()+"/files/bright-template.xlsx"; QFile tempQFile(tempFile); if(! tempQFile.exists()) { - QMessageBox::information(this, tr("Tip"), tempFile+" is not exist"); + QMessageBox::information(this, translate("","Tip"), tempFile+" is not exist"); return; } QString selectFilter = "*.xlsx"; - QString savingFile = QFileDialog::getSaveFileName(this, tr("Save file"), card.id + "BrightnessTable.xlsx", "brightness(*.xlsx );", &selectFilter, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + auto savingFile = QFileDialog::getSaveFileName(this, tr("Save file"), card.id + "BrightnessTable.xlsx", "brightness(*.xlsx );", &selectFilter, QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if(savingFile.isEmpty()) return; tempQFile.copy(savingFile); QXlsx::Document xlsx(savingFile); xlsx.selectSheet(strSensorType); - for(int m=0; msetProperty("ssType", "progManageTool"); connect(btnCurBrightGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -406,12 +406,12 @@ CtrlBrightPanel::CtrlBrightPanel() { auto waitingDlg = new WaitingDlg(this, tr("GetCurrentSensorBrightness")); Def_CtrlReqPre connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg, card] { - QJsonDocument json; + JValue json; QByteArray data; - QString err = checkReplyForJson(reply, &json, &data); + auto err = errStrWithJson(reply, &json, &data); if(! err.isEmpty()) { waitingDlg->close(); - QMessageBox::critical(this, tr("Error"), err); + QMessageBox::critical(this, translate("","Error"), err); return; } waitingDlg->success(); @@ -420,11 +420,11 @@ CtrlBrightPanel::CtrlBrightPanel() { fdCurBright->setText(QString::number(qRound(json["value"].toInt() * 100.0 / card.BrightnessLevel))+"%"); }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, this, [reply, card] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) err = (json["is485"].toBool() ? "R60 " : "RL1 ") + QString::number(qRound(json["value"].toInt() * 100.0 / card.BrightnessLevel))+"%"; gFdResInfo->append(card.id+" "+tr("GetCurrentSensorBrightness")+" "+err); }); @@ -471,7 +471,7 @@ CtrlBrightPanel::CtrlBrightPanel() { btnFixedSet->setProperty("ssType", "progManageTool"); connect(btnFixedSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto isAdaptToOld = fdAdaptToOld->isChecked(); @@ -488,7 +488,7 @@ CtrlBrightPanel::CtrlBrightPanel() { Def_CtrlSetReqAfter }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { if(isAdaptToOld) json.insert("brightness", (percent * card.BrightnessLevel + 50) / 100); Def_CtrlSetMulti(tr("SetBrightness")) } @@ -502,7 +502,7 @@ CtrlBrightPanel::CtrlBrightPanel() { btnFixedGet->setProperty("ssType", "progManageTool"); connect(btnFixedGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -512,12 +512,12 @@ CtrlBrightPanel::CtrlBrightPanel() { auto waitingDlg = new WaitingDlg(this, tr("GetBrightness")); Def_CtrlReqPre connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg, card] { - QJsonDocument json; + JValue json; QByteArray data; - QString err = checkReplyForJson(reply, &json, &data); + auto err = errStrWithJson(reply, &json, &data); if(! err.isEmpty()) { waitingDlg->close(); - QMessageBox::critical(this, tr("Error"), err); + QMessageBox::critical(this, translate("", "Error"), err); return; } waitingDlg->success(); @@ -531,11 +531,11 @@ CtrlBrightPanel::CtrlBrightPanel() { } }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, this, [reply, card] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) { auto bright = json["brightnessPercentage"].toInt(-1); if(bright==-1) bright = qRound(json["brightness"].toInt() * 100.0 / card.BrightnessLevel); @@ -736,7 +736,7 @@ CtrlBrightPanel::CtrlBrightPanel() { btnScheSet->setProperty("ssType", "progManageTool"); connect(btnScheSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto isAdaptToOld = fdAdaptToOld->isChecked(); @@ -767,7 +767,7 @@ CtrlBrightPanel::CtrlBrightPanel() { btnScheGet->setProperty("ssType", "progManageTool"); connect(btnScheGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -818,13 +818,13 @@ void CtrlBrightPanel::init() { mSensi = -1; mTask = -1; - QJsonObject json; + JObj json; json.insert("_id", "GetAutoBrightnessTask"); json.insert("_type", "GetAutoBrightnessTask"); auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, this, [this, reply, card] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; mTask = restoreScheduleJson(json, card.BrightnessLevel); if(mTask) radioSchedule->setChecked(true); @@ -832,13 +832,13 @@ void CtrlBrightPanel::init() { else if(mSensi == 0) radioManual->setChecked(true); }); - json = QJsonObject(); + json = JObj(); json.insert("_id", "GetBrightnessSensitivity"); json.insert("_type", "GetBrightnessSensitivity"); 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); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; mSensi = json["sensitivity"].toInt(); fdSensi->setValue(mSensi); @@ -847,13 +847,13 @@ void CtrlBrightPanel::init() { else radioManual->setChecked(true); }); - json = QJsonObject(); + json = JObj(); json.insert("_id", "GetMinBrightness"); json.insert("_type", "GetMinBrightness"); reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, this, [this, reply, card] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; auto value = json["minBrightnessPercentage"].toInt(-1); if(value==-1) value = qRound(json["brightness"].toInt() * 100.0 / card.BrightnessLevel); @@ -876,22 +876,22 @@ void CtrlBrightPanel::transUi() { fdSensiTypeTip->setText(tr("BrightTip2")); lbSensi->setText(tr("Sensitivity")); lbMinBright->setText(tr("Minbrightness")); - btnMinBrightSet->setText(tr("Set")); - btnSensiSet->setText(tr("Set")); - btnUpload->setText(tr("Upload")); - btnMinBrightGet->setText(tr("Readback")); - btnSensiGet->setText(tr("Readback")); - btnTableGet->setText(tr("ReadbackTable")); - btnCurBrightGet->setText(tr("Refresh")); + btnMinBrightSet->setText(translate("","Set")); + btnSensiSet->setText(translate("","Set")); + btnUpload->setText(tr("Upload File")); + btnMinBrightGet->setText(translate("","Readback")); + btnSensiGet->setText(translate("","Readback")); + btnTableGet->setText(translate("","Readback")); + btnCurBrightGet->setText(translate("","Refresh")); lbCurBright->setText(tr("Cur Brigntness")+": "); lbFixedBright->setText(tr("Brightness value")); - btnFixedSet->setText(tr("Set")); - btnFixedGet->setText(tr("Readback")); + btnFixedSet->setText(translate("","Set")); + btnFixedGet->setText(translate("","Readback")); lbDefBright->setText(tr("Default brightness")); btnScheAdd->setText(tr("Add")); - btnScheClear->setText(tr("Clear")); + btnScheClear->setText(translate("","Clear")); btnScheDel->setText(tr("Delete")); btnScheImport->setText(tr("Import")); btnScheExport->setText(tr("Export")); @@ -901,11 +901,11 @@ void CtrlBrightPanel::transUi() { tableSche->setHeaderText("end", tr("End Time")); btnScheSet->setText(tr("Apply")); - btnScheGet->setText(tr("Readback")); + btnScheGet->setText(translate("","Readback")); fdScheTip->setText(tr("Default brightness tip")); } -bool CtrlBrightPanel::restoreScheduleJson(QJsonDocument &json, int max) { +bool CtrlBrightPanel::restoreScheduleJson(JValue &json, int max) { tableSche->setRowCount(0); auto taskBrightness = json["taskBrightness"]; auto brightness = json["defaultBrightnessPercentage"].toInt(-1); @@ -914,7 +914,7 @@ bool CtrlBrightPanel::restoreScheduleJson(QJsonDocument &json, int max) { auto jsitems = taskBrightness["items"].toArray(); auto brightnesses = json["brightnessPercentageList"].toArray(); for(int i=0; irowCount(); tableSche->insertRow(row); @@ -924,7 +924,7 @@ bool CtrlBrightPanel::restoreScheduleJson(QJsonDocument &json, int max) { auto slider = new QSlider(Qt::Horizontal); slider->setRange(1, 100); if(brightnesses.size() > i) slider->setValue(brightnesses[i].toInt()); - else slider->setValue(qRound(jsitems.at(i)["brightness"].toInt() * 100.0 / max)); + else slider->setValue(qRound(jsitems[i]["brightness"].toInt() * 100.0 / max)); hBox->addWidget(slider); auto lb = new QLabel(QString::number(slider->value())+"%"); @@ -944,7 +944,7 @@ bool CtrlBrightPanel::restoreScheduleJson(QJsonDocument &json, int max) { timeEdit->setAlignment(Qt::AlignCenter); tableSche->setCellWidget(row, "end", timeEdit); } - return jsitems.count() > 0; + return jsitems.size() > 0; } void CtrlBrightPanel::getScheduleJson(QJsonObject &json, int max) { QJsonArray items, brightnesses; diff --git a/LedOK/device/ctrlbrightpanel.h b/LedOK/device/ctrlbrightpanel.h index 032005a..22ab62c 100644 --- a/LedOK/device/ctrlbrightpanel.h +++ b/LedOK/device/ctrlbrightpanel.h @@ -2,10 +2,12 @@ #define CTRLBRIGHTPANEL_H #include "gutil/qgui.h" +#include "gutil/qjson.h" #include #include #include #include +#include class CtrlBrightPanel : public QWidget { Q_OBJECT @@ -18,7 +20,7 @@ protected: void transUi(); private: - bool restoreScheduleJson(QJsonDocument &, int); + bool restoreScheduleJson(JValue &, int); void getScheduleJson(QJsonObject &, int); QLabel *lbTitle; QRadioButton *radioAuto; diff --git a/LedOK/device/ctrlhdmipanel.cpp b/LedOK/device/ctrlhdmipanel.cpp index 655316a..0affda6 100644 --- a/LedOK/device/ctrlhdmipanel.cpp +++ b/LedOK/device/ctrlhdmipanel.cpp @@ -51,12 +51,19 @@ CtrlHdmiPanel::CtrlHdmiPanel() { hBox->addSpacing(20); fdHdmi2 = new QRadioButton("HDMI 2"); hBox->addWidget(fdHdmi2); - hBox->addStretch(); auto btnGroup = new QButtonGroup(this); btnGroup->addButton(fdAsync, 0); btnGroup->addButton(fdHdmi, 1); btnGroup->addButton(fdHdmi2, 2); + + hBox->addSpacing(20); + + edAutoSwitch = new QCheckBox; + edAutoSwitch->setChecked(true); + hBox->addWidget(edAutoSwitch); + hBox->addStretch(); + vBox->addSpacing(20); hBox = new HBox(vBox); @@ -67,11 +74,11 @@ CtrlHdmiPanel::CtrlHdmiPanel() { btnSyncSet->setProperty("ssType", "progManageTool"); connect(btnSyncSet, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } auto id = btnGroup->checkedId(); - QJsonObject json; + JObj json; json.insert("_id", "SyncSwitch"); json.insert("_type", "SyncSwitch"); json.insert("switchOn", (bool)id); @@ -83,7 +90,7 @@ CtrlHdmiPanel::CtrlHdmiPanel() { Def_CtrlSetReqAfter }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { if(id) { Def_CtrlSetMulti(tr("SyncSwitch")) } else { @@ -91,6 +98,25 @@ CtrlHdmiPanel::CtrlHdmiPanel() { } } } + if(id) { + json = JObj(); + json.insert("_id", "AutoSyncSwitch"); + json.insert("_type", "AutoSyncSwitch"); + json.insert("isAuto", edAutoSwitch->isChecked()); + if(gSelCards.count() == 1) { + if(gSelCards[0].id.startsWith("g", Qt::CaseInsensitive)) { + auto waitingDlg = new WaitingDlg(this, tr("SyncSwitch")); + Def_CtrlReqPre + connect(reply, &QNetworkReply::finished, this, [=] { + Def_CtrlSetReqAfter + }); + } + } else { + for(auto &card : gSelCards) if(card.id.startsWith("g", Qt::CaseInsensitive)) { + Def_CtrlSetMulti(tr("SyncSwitch")) + } + } + } }); hBox->addWidget(btnSyncSet); hBox->addSpacing(20); @@ -100,10 +126,10 @@ CtrlHdmiPanel::CtrlHdmiPanel() { btnSyncGet->setProperty("ssType", "progManageTool"); connect(btnSyncGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "IsSync"); json.insert("_type", "IsSync"); if(gSelCards.count() == 1) { @@ -113,21 +139,21 @@ CtrlHdmiPanel::CtrlHdmiPanel() { Def_CtrlSingleGetReply waitingDlg->success(); auto switchOn = json["switchOn"]; - if(switchOn.isUndefined()) switchOn = json["result"]; + if(switchOn.isNull()) switchOn = json["result"]; if(! switchOn.toBool()) fdAsync->setChecked(true); else if(json["number"].toInt()==2) fdHdmi2->setChecked(true); else fdHdmi->setChecked(true); }); } else { - foreach(auto card, gSelCards) { - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + for(auto &card : gSelCards) { + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json); auto cardId = card.id; connect(reply, &QNetworkReply::finished, this, [reply, cardId] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) { auto switchOn = json["switchOn"]; - if(switchOn.isUndefined()) switchOn = json["result"]; + if(switchOn.isNull()) switchOn = json["result"]; if(! switchOn.toBool()) err = tr("Async"); else { err = "HDMI"; @@ -214,7 +240,7 @@ CtrlHdmiPanel::CtrlHdmiPanel() { if(! scheQFile.open(QIODevice::ReadOnly)) return; auto data = scheQFile.readAll(); scheQFile.close(); - restoreScheduleJson(QJsonDocument::fromJson(data).object()); + restoreScheduleJson(JFrom(data).toObj()); }); hBox->addWidget(btnScheImport); @@ -249,7 +275,7 @@ CtrlHdmiPanel::CtrlHdmiPanel() { btnScheSet->setMinimumSize(QSize(60, 30)); connect(btnScheSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -277,7 +303,7 @@ CtrlHdmiPanel::CtrlHdmiPanel() { btnScheGet->setProperty("ssType", "progManageTool"); connect(btnScheGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -289,7 +315,7 @@ CtrlHdmiPanel::CtrlHdmiPanel() { connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg] { Def_CtrlSingleGetReply waitingDlg->success(); - restoreScheduleJson(json["creenTask"].toObject()); + restoreScheduleJson(json["creenTask"].toObj()); }); } }); @@ -317,21 +343,24 @@ void CtrlHdmiPanel::init() { btnScheGet->setEnabled(isSingle); if(! isSingle) { fdHdmi2->setVisible(true); + edAutoSwitch->setVisible(true); return; } auto card = gSelCards[0]; - fdHdmi2->setVisible(card.id.startsWith("m8s", Qt::CaseInsensitive)); + auto needShow = card.id.startsWith("g", Qt::CaseInsensitive) || card.id.startsWith("m8s", Qt::CaseInsensitive); + fdHdmi2->setVisible(needShow); + edAutoSwitch->setVisible(needShow); - QJsonObject json; + JObj json; json.insert("_id", "IsSync"); json.insert("_type", "IsSync"); - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json); connect(reply, &QNetworkReply::finished, this, [this, reply] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; auto switchOn = json["switchOn"]; - if(switchOn.isUndefined()) switchOn = json["result"]; + if(switchOn.isNull()) switchOn = json["result"]; if(! switchOn.toBool()) fdAsync->setChecked(true); else if(json["number"].toInt()==2) fdHdmi2->setChecked(true); else fdHdmi->setChecked(true); @@ -346,9 +375,11 @@ void CtrlHdmiPanel::transUi() { fdManual->setText(tr("Manual")); fdSchedule->setText(tr("Schedule")); + edAutoSwitch->setText(tr("Auto Switch")); + fdAsync->setText(tr("Async")); - btnSyncSet->setText(tr("Set")); - btnSyncGet->setText(tr("Readback")); + btnSyncSet->setText(translate("","Set")); + btnSyncGet->setText(translate("","Readback")); tableSche->setHeaderText("start", tr("Start Time")); tableSche->setHeaderText("end", tr("End Time")); @@ -362,19 +393,19 @@ void CtrlHdmiPanel::transUi() { btnScheAdd->setText(tr("Add")); btnScheSet->setText(tr("Apply")); - btnScheClear->setText(tr("Clear")); + btnScheClear->setText(translate("","Clear")); btnScheDel->setText(tr("Delete")); btnScheImport->setText(tr("Import")); btnScheExport->setText(tr("Export")); labelSyncScheduleTip->setText(tr("By default, the asynchronous content is played, and the synchronous signal content is played in the fixed time period")); btnScheSet->setText(tr("Apply")); - btnScheGet->setText(tr("Readback")); + btnScheGet->setText(translate("","Readback")); } -void CtrlHdmiPanel::restoreScheduleJson(QJsonObject oTaskSync) { +void CtrlHdmiPanel::restoreScheduleJson(JObj oTaskSync) { tableSche->setRowCount(0); auto oSchedules = oTaskSync["schedules"].toArray(); - foreach(QJsonValue oSchedule, oSchedules) { + for(auto &oSchedule : oSchedules) { int row = tableSche->rowCount(); tableSche->insertRow(row); diff --git a/LedOK/device/ctrlhdmipanel.h b/LedOK/device/ctrlhdmipanel.h index 7be99a4..c08c541 100644 --- a/LedOK/device/ctrlhdmipanel.h +++ b/LedOK/device/ctrlhdmipanel.h @@ -2,7 +2,8 @@ #define CTRLHDMIPANEL_H #include "gutil/qgui.h" -#include +#include "gutil/qjson.h" +#include #include #include @@ -10,7 +11,7 @@ class CtrlHdmiPanel : public QWidget { Q_OBJECT public: CtrlHdmiPanel(); - void restoreScheduleJson(QJsonObject oTaskSync); + void restoreScheduleJson(JObj oTaskSync); QJsonObject getScheduleJson(); protected: void showEvent(QShowEvent *event) override; @@ -21,6 +22,7 @@ protected: private: QLabel *lbHdmiCfg; QRadioButton *fdManual, *fdSchedule, *fdAsync, *fdHdmi, *fdHdmi2; + QCheckBox *edAutoSwitch; QPushButton *btnSyncSet, *btnSyncGet; TableWidget *tableSche; diff --git a/LedOK/device/ctrlnetworkpanel.cpp b/LedOK/device/ctrlnetworkpanel.cpp index 6a31fc5..48925e7 100644 --- a/LedOK/device/ctrlnetworkpanel.cpp +++ b/LedOK/device/ctrlnetworkpanel.cpp @@ -23,7 +23,7 @@ CtrlNetworkPanel::CtrlNetworkPanel() { auto hBox = new HBox(vBox); hBox->addStretch(); - fdDhcp = new QRadioButton; + fdDhcp = new QRadioButton("DHCP"); fdDhcp->setChecked(true); hBox->addWidget(fdDhcp, 0, Qt::AlignTop); @@ -103,7 +103,7 @@ CtrlNetworkPanel::CtrlNetworkPanel() { btnLanSet->setProperty("ssType", "progManageTool"); connect(btnLanSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QString ip = fdIP->text(); @@ -137,7 +137,7 @@ CtrlNetworkPanel::CtrlNetworkPanel() { return; } } - QJsonObject json; + JObj json; json.insert("_id", "SetEthernet"); json.insert("_type", "SetEthernet"); json.insert("dhcp", fdDhcp->isChecked()); @@ -152,7 +152,7 @@ CtrlNetworkPanel::CtrlNetworkPanel() { Def_CtrlSetReqAfter }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { Def_CtrlSetMulti(tr("SetEthernet")) } } @@ -166,10 +166,10 @@ CtrlNetworkPanel::CtrlNetworkPanel() { btnLanGet->setProperty("ssType", "progManageTool"); connect(btnLanGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "GetEthernet"); json.insert("_type", "GetEthernet"); if(gSelCards.count() == 1) { @@ -191,12 +191,12 @@ CtrlNetworkPanel::CtrlNetworkPanel() { fdDns->setText(json["dnsAddr"].toString()); }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); auto cardId = card.id; connect(reply, &QNetworkReply::finished, this, [reply, cardId] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) err = json["dhcp"].toBool() ? tr("DHCP IP") : tr("STATIC IP"); gFdResInfo->append(cardId+" "+tr("GetEthernet")+" "+err); gFdResInfo->append(" IP: "+json["ipAddr"].toString()); @@ -216,33 +216,20 @@ CtrlNetworkPanel::CtrlNetworkPanel() { line->setFrameShadow(QFrame::Sunken); vBox->addWidget(line); - label_5 = new QLabel; - label_5->setFont(ftTitle); - label_5->setAlignment(Qt::AlignCenter); - vBox->addWidget(label_5); + lbWifiCfg = new QLabel; + lbWifiCfg->setFont(ftTitle); + lbWifiCfg->setAlignment(Qt::AlignCenter); + vBox->addWidget(lbWifiCfg); hBox = new HBox(vBox); hBox->addStretch(); - - auto stackedWifi = new QStackedLayout; - fdIsWifi = new QRadioButton; - connect(fdIsWifi, &QRadioButton::toggled, this, [stackedWifi](bool checked) { - stackedWifi->setCurrentIndex(checked ? 0 : 1); - }); - hBox->addWidget(fdIsWifi); - hBox->addSpacing(50); - - fdIsHotspot = new QRadioButton; - hBox->addWidget(fdIsHotspot); - hBox->addStretch(); - - auto aaaQButtonGroup = new QButtonGroup(fdIsWifi); - aaaQButtonGroup->addButton(fdIsWifi); - aaaQButtonGroup->addButton(fdIsHotspot); - - vBox->addLayout(stackedWifi); { - auto vvv = new VBox(stackedWifi); + auto vvv = new VBox(hBox); + auto hBox = new HBox(vvv); + hBox->addStretch(); + hBox->addWidget(fdIsWifi = new QCheckBox); + hBox->addStretch(); + hBox = new HBox(vvv); lbWifiName = new QLabel; @@ -250,18 +237,18 @@ CtrlNetworkPanel::CtrlNetworkPanel() { lbWifiName->setAlignment(Qt::AlignRight|Qt::AlignVCenter); hBox->addWidget(lbWifiName); - fdWifiName = new QComboBox; - fdWifiName->setEditable(true); - fdWifiName->setMinimumWidth(200); - fdWifiName->setSizeAdjustPolicy(QComboBox::AdjustToContents); - hBox->addWidget(fdWifiName); + edWifiName = new QComboBox; + edWifiName->setEditable(true); + edWifiName->setMinimumWidth(180); + edWifiName->setSizeAdjustPolicy(QComboBox::AdjustToContents); + hBox->addWidget(edWifiName); btnScan = new QPushButton; btnScan->setMinimumWidth(60); btnScan->setProperty("ssType", "progManageTool"); connect(btnScan, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -274,10 +261,10 @@ CtrlNetworkPanel::CtrlNetworkPanel() { Def_CtrlSingleGetReply waitingDlg->success(); auto wifis = json["wifiList"].toArray(); - auto cur = fdWifiName->currentText(); - fdWifiName->clear(); - foreach(QJsonValue wifi, wifis) fdWifiName->addItem(QIcon(":/res/signal-"+QString::number((wifi["signal"].toInt()+19)/20)+".png"), wifi["ssid"].toString()); - if(! cur.isEmpty()) fdWifiName->setCurrentText(cur); + auto cur = edWifiName->currentText(); + edWifiName->clear(); + for(auto &wifi : wifis) edWifiName->addItem(QIcon(":/res/signal-"+QString::number((wifi["signal"].toInt()+19)/20)+".png"), wifi["ssid"].toString()); + if(! cur.isEmpty()) edWifiName->setCurrentText(cur); }); } }); @@ -286,20 +273,107 @@ CtrlNetworkPanel::CtrlNetworkPanel() { hBox = new HBox(vvv); - lbWifiPassword = new QLabel; - lbWifiPassword->setMinimumWidth(80); - lbWifiPassword->setAlignment(Qt::AlignRight|Qt::AlignVCenter); - hBox->addWidget(lbWifiPassword); + lbWifiPswd = new QLabel; + lbWifiPswd->setMinimumWidth(80); + lbWifiPswd->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + hBox->addWidget(lbWifiPswd); - fdWifiPassword = new QLineEdit; - fdWifiPassword->setFixedWidth(200); - fdWifiPassword->setEchoMode(QLineEdit::PasswordEchoOnEdit); - hBox->addWidget(fdWifiPassword); + edWifiPswd = new QLineEdit; + edWifiPswd->setFixedWidth(180); + edWifiPswd->setEchoMode(QLineEdit::PasswordEchoOnEdit); + hBox->addWidget(edWifiPswd); hBox->addStretch(); + hBox = new HBox(vvv); + hBox->addStretch(); + btnWiFiSet = new QPushButton; + btnWiFiSet->setMinimumSize(QSize(60, 30)); + btnWiFiSet->setProperty("ssType", "progManageTool"); + connect(btnWiFiSet, &QPushButton::clicked, this, [this] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); + return; + } + auto isWifi = fdIsWifi->isChecked(); + JObj json; + json.insert("_id", "SetSwitchWiFi"); + json.insert("_type", "SetSwitchWiFi"); + json.insert("enable", true); + JObj jsonG; + jsonG.insert("_id", "ControllerWifiSwitch"); + jsonG.insert("_type", "ControllerWifiSwitch"); + jsonG.insert("isWifi", true); + jsonG.insert("isOpen", isWifi); + JObj json2; + json2.insert("_id", "ConfigurationWiFi"); + json2.insert("_type", "ConfigurationWiFi"); + json2.insert("ssid", edWifiName->currentText()); + json2.insert("password", edWifiPswd->text()); + if(gSelCards.count() == 1) { + auto waitingDlg = new WaitingDlg(this, tr("ConfigurationWiFi")+" ..."); + waitingDlg->show(); + auto card = gSelCards[0]; + auto isG = card.id.startsWith("g", Qt::CaseInsensitive); + if(isWifi) { + auto reply = NetReq("http://"+card.ip+":2016/settings").post(isG ? jsonG : json); + ConnReply(reply, waitingDlg) [=] { + auto err = errStrWithJson(reply); + if(! err.isEmpty()) { + waitingDlg->close(); + QMessageBox::critical(this, translate("","Error"), err); + return; + } + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json2); + ConnReply(reply, waitingDlg) [=] { + Def_CtrlSetReqAfter + }); + }); + } else if(isG) { + auto reply = NetReq("http://"+card.ip+":2016/settings").post(jsonG); + ConnReply(reply, waitingDlg) [=] { + Def_CtrlSetReqAfter + }); + } + else waitingDlg->success(); + } else { + for(auto &card : gSelCards) { + auto isG = card.id.startsWith("g", Qt::CaseInsensitive); + if(isWifi) { + auto reply = NetReq("http://"+card.ip+":2016/settings").post(isG ? jsonG : json); + connect(reply, &QNetworkReply::finished, gFdResInfo, [=] { + auto err = errStrWithJson(reply); + if(! err.isEmpty()) { + gFdResInfo->append(card.id+" "+tr("ConfigurationWiFi")+" "+err); + return; + } + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json2); + connect(reply, &QNetworkReply::finished, gFdResInfo, [=] { + auto err = errStrWithJson(reply); + gFdResInfo->append(card.id+" "+tr("ConfigurationWiFi")+" "+(err.isEmpty()?translate("","Success"):err)); + }); + }); + } else if(isG) { + auto reply = NetReq("http://"+card.ip+":2016/settings").post(jsonG); + connect(reply, &QNetworkReply::finished, gFdResInfo, [=] { + auto err = errStrWithJson(reply); + gFdResInfo->append(card.id+" "+tr("ConfigurationWiFi")+" "+(err.isEmpty()?translate("","Success"):err)); + }); + } + else gFdResInfo->append(card.id+" "+tr("ConfigurationWiFi")+" "+translate("","Success")); + } + } + }); + hBox->addWidget(btnWiFiSet); + hBox->addStretch(); vvv->addStretch(); + } + { + auto vvv = new VBox(hBox); + auto hBox = new HBox(vvv); + hBox->addStretch(); + hBox->addWidget(fdIsAP = new QCheckBox); + hBox->addStretch(); - vvv = new VBox(stackedWifi); hBox = new HBox(vvv); lbHotspotName = new QLabel; @@ -307,22 +381,22 @@ CtrlNetworkPanel::CtrlNetworkPanel() { lbHotspotName->setAlignment(Qt::AlignRight|Qt::AlignVCenter); hBox->addWidget(lbHotspotName); - fdHotspotName = new QLineEdit; - fdHotspotName->setFixedWidth(200); - hBox->addWidget(fdHotspotName); + edHotspotName = new QLineEdit; + edHotspotName->setFixedWidth(180); + hBox->addWidget(edHotspotName); hBox->addStretch(); hBox = new HBox(vvv); - lbHotspotPassword = new QLabel; - lbHotspotPassword->setMinimumWidth(80); - lbHotspotPassword->setAlignment(Qt::AlignRight|Qt::AlignVCenter); - hBox->addWidget(lbHotspotPassword); + lbHotspotPswd = new QLabel; + lbHotspotPswd->setMinimumWidth(80); + lbHotspotPswd->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + hBox->addWidget(lbHotspotPswd); - fdHotspotPassword = new QLineEdit; - fdHotspotPassword->setEchoMode(QLineEdit::PasswordEchoOnEdit); - fdHotspotPassword->setFixedWidth(200); - hBox->addWidget(fdHotspotPassword); + edHotspotPswd = new QLineEdit; + edHotspotPswd->setEchoMode(QLineEdit::PasswordEchoOnEdit); + edHotspotPswd->setFixedWidth(180); + hBox->addWidget(edHotspotPswd); hBox->addStretch(); hBox = new HBox(vvv); @@ -331,133 +405,157 @@ CtrlNetworkPanel::CtrlNetworkPanel() { lll->setMinimumWidth(80); hBox->addWidget(lll); - fdIs2_4G = new QRadioButton("2.4G"); - fdIs2_4G->setChecked(true); - hBox->addWidget(fdIs2_4G); + auto edIs2_4G = new QRadioButton("2.4G"); + edIs2_4G->setChecked(true); + hBox->addWidget(edIs2_4G); - auto fdIs5G = new QRadioButton("5G"); - hBox->addWidget(fdIs5G); + edIs5G = new QRadioButton("5G"); + hBox->addWidget(edIs5G); hBox->addStretch(); + hBox = new HBox(vvv); + hBox->addStretch(); + + btnHotspotSet = new QPushButton; + btnHotspotSet->setMinimumSize(60, 30); + btnHotspotSet->setProperty("ssType", "progManageTool"); + connect(btnHotspotSet, &QPushButton::clicked, this, [this] { + if(gSelCards.isEmpty()) { + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); + return; + } + auto isAp = fdIsAP->isChecked(); + JObj jsonG; + jsonG.insert("_id", "ControllerWifiSwitch"); + jsonG.insert("_type", "ControllerWifiSwitch"); + jsonG.insert("isWifi", false); + jsonG.insert("isOpen", isAp); + JObj json; + json.insert("_id", "ConfigurationHotSpot"); + json.insert("_type", "ConfigurationHotSpot"); + json.insert("apName", edHotspotName->text()); + json.insert("apBand", edIs5G->isChecked() ? 1 : 0); + json.insert("password", edHotspotPswd->text()); + if(gSelCards.count() == 1) { + auto waitingDlg = new WaitingDlg(this, tr("Config Hotspot")+" ..."); + waitingDlg->show(); + auto card = gSelCards[0]; + auto isG = card.id.startsWith("g", Qt::CaseInsensitive); + if(isG) { + auto reply = NetReq("http://"+card.ip+":2016/settings").post(jsonG); + connect(waitingDlg, &WaitingDlg::rejected, reply, &QNetworkReply::deleteLater); + connect(reply, &QNetworkReply::finished, waitingDlg, [=] { + auto err = errStrWithJson(reply); + if(! err.isEmpty()) { + waitingDlg->close(); + QMessageBox::critical(this, translate("","Error"), err); + return; + } + if(isAp) { + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json); + ConnReply(reply, waitingDlg) [=] { + Def_CtrlSetReqAfter + }); + } else waitingDlg->success(); + }); + } else if(isAp) { + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json); + ConnReply(reply, waitingDlg) [=] { + Def_CtrlSetReqAfter + }); + } else waitingDlg->success(); + } else { + for(auto &card : gSelCards) { + auto isG = card.id.startsWith("g", Qt::CaseInsensitive); + if(isG) { + auto reply = NetReq("http://"+card.ip+":2016/settings").post(jsonG); + connect(reply, &QNetworkReply::finished, gFdResInfo, [=] { + auto err = errStrWithJson(reply); + if(! err.isEmpty()) { + gFdResInfo->append(card.id+" "+tr("Config Hotspot")+" "+err); + return; + } + if(isAp) { + Def_CtrlSetMulti(tr("Config Hotspot")); + } else gFdResInfo->append(card.id+" "+tr("Config Hotspot")+" "+translate("","Success")); + }); + } else if(isAp) { + Def_CtrlSetMulti(tr("Config Hotspot")); + } else gFdResInfo->append(card.id+" "+tr("Config Hotspot")+" "+translate("","Success")); + } + } + }); + hBox->addWidget(btnHotspotSet); + + hBox->addStretch(); vvv->addStretch(); } + hBox->addStretch(); fdIsWifi->setChecked(true); hBox = new HBox(vBox); hBox->addStretch(); - btnWiFiSet = new QPushButton; - btnWiFiSet->setMinimumSize(QSize(60, 30)); - btnWiFiSet->setProperty("ssType", "progManageTool"); - connect(btnWiFiSet, &QPushButton::clicked, this, [this] { - if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); - return; - } - auto isWifi = fdIsWifi->isChecked(); - if(isWifi) { - QJsonObject json; - json.insert("_id", "SetSwitchWiFi"); - json.insert("_type", "SetSwitchWiFi"); - json.insert("enable", true); - QJsonObject json2; - json2.insert("_id", "ConfigurationWiFi"); - json2.insert("_type", "ConfigurationWiFi"); - json2.insert("ssid", fdWifiName->currentText()); - json2.insert("password", fdWifiPassword->text()); - if(gSelCards.count() == 1) { - auto waitingDlg = new WaitingDlg(this, tr("ConfigurationWiFi")+" ..."); - Def_CtrlReqPre - connect(reply, &QNetworkReply::finished, waitingDlg, [=] { - QString err = checkReplyForJson(reply); - if(! err.isEmpty()) { - waitingDlg->close(); - QMessageBox::critical(this, tr("Error"), err); - return; - } - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json2); - ConnReply(reply, waitingDlg) [=] { - Def_CtrlSetReqAfter - }); - }); - } else { - foreach(auto card, gSelCards) { - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); - connect(reply, &QNetworkReply::finished, this, [=] { - QString err = checkReplyForJson(reply); - if(! err.isEmpty()) { - gFdResInfo->append(card.id+" "+tr("ConfigurationWiFi")+" "+err); - return; - } - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json2); - connect(reply, &QNetworkReply::finished, this, [=] { - QString err = checkReplyForJson(reply); - gFdResInfo->append(card.id+" "+tr("ConfigurationWiFi")+" "+(err.isEmpty()?QCoreApplication::translate("Def","Success"):err)); - }); - }); - } - } - } else { - QJsonObject json; - json.insert("_id", "ConfigurationHotSpot"); - json.insert("_type", "ConfigurationHotSpot"); - json.insert("apName", fdHotspotName->text()); - json.insert("apBand", fdIs2_4G->isChecked() ? 0 : 1); - json.insert("password", fdHotspotPassword->text()); - if(gSelCards.count() == 1) { - auto waitingDlg = new WaitingDlg(this, tr("ConfigurationHotSpot")+" ..."); - Def_CtrlReqPre - connect(reply, &QNetworkReply::finished, this, [=] { - Def_CtrlSetReqAfter - }); - } else { - foreach(auto card, gSelCards) { - Def_CtrlSetMulti(tr("ConfigurationHotSpot")); - } - } - } - }); - hBox->addWidget(btnWiFiSet); - hBox->addSpacing(50); - btnWiFiGet = new QPushButton; - btnWiFiGet->setMinimumSize(QSize(60, 30)); + btnWiFiGet->setMinimumSize(60, 30); btnWiFiGet->setProperty("ssType", "progManageTool"); connect(btnWiFiGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "IsPortableHotSpot"); json.insert("_type", "IsPortableHotSpot"); + JObj jsonG; + jsonG.insert("_id", "GetWifiSwitchState"); + jsonG.insert("_type", "GetWifiSwitchState"); if(gSelCards.count() == 1) { - auto waitingDlg = new WaitingDlg(this, tr("IsPortableHotSpot")+" ..."); - Def_CtrlReqPre - connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg] { + auto waitingDlg = new WaitingDlg(this, tr("Get AP or WiFi")+" ..."); + waitingDlg->show(); + auto card = gSelCards[0]; + auto isG = card.id.startsWith("g", Qt::CaseInsensitive); + auto reply = NetReq("http://"+card.ip+":2016/settings").post(isG ? jsonG : json); + connect(waitingDlg, &WaitingDlg::rejected, reply, &QNetworkReply::deleteLater); + connect(reply, &QNetworkReply::finished, this, [=] { Def_CtrlSingleGetReply waitingDlg->success(); - fdWifiName->setCurrentText(json["wifi"].toString()); - auto hotSpots = json["hotSpots"].toString(); - fdHotspotName->setText(hotSpots); - if(hotSpots.isEmpty()) fdIsWifi->setChecked(true); - else fdIsHotspot->setChecked(true); + if(isG) { + fdIsWifi->setChecked(json["wifiEnable"].toBool()); + fdIsAP->setChecked(json["apEnable"].toBool()); + edWifiName->setCurrentText(json["wifiName"].toString()); + edHotspotName->setText(json["hotSpotName"].toString()); + edIs5G->setChecked(json["apBand"].toBool()); + } else { + edWifiName->setCurrentText(json["wifi"].toString()); + auto hotSpots = json["hotSpots"].toString(); + edHotspotName->setText(hotSpots); + fdIsWifi->setChecked(hotSpots.isEmpty()); + fdIsAP->setChecked(! hotSpots.isEmpty()); + } }); } else { - foreach(auto card, gSelCards) { - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + for(auto &card : gSelCards) { + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json); auto cardId = card.id; - connect(reply, &QNetworkReply::finished, this, [reply, cardId] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + auto isG = card.id.startsWith("g", Qt::CaseInsensitive); + connect(reply, &QNetworkReply::finished, this, [=] { + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) { - err = tr("success"); - auto wifi = json["wifi"].toString(); - if(! wifi.isEmpty()) err += " "+tr("WifiName")+":"+wifi; - auto hotSpots = json["hotSpots"].toString(); - if(! hotSpots.isEmpty()) err += " "+tr("ApName")+":"+hotSpots; + err = translate("","Success"); + if(isG) { + err = err+"\nWifi: "+(json["wifiEnable"].toBool()?"On":"Off")+" "+json["wifiName"].toString(); + err = err+"\nAP: "+(json["apEnable"].toBool()?"On":"Off")+" "+json["hotSpotName"].toString() + +(json["apBand"].toBool() ? " 5G" : " 2.4G"); + } else { + auto wifi = json["wifi"].toString(); + if(! wifi.isEmpty()) err += " "+tr("WifiName")+":"+wifi; + auto hotSpots = json["hotSpots"].toString(); + if(! hotSpots.isEmpty()) err += " "+tr("ApName")+":"+hotSpots; + } } - gFdResInfo->append(cardId+" "+tr("IsPortableHotSpot")+" "+err); + gFdResInfo->append(cardId+" "+tr("Get AP or WiFi")+" "+err); }); } } @@ -488,7 +586,7 @@ CtrlNetworkPanel::CtrlNetworkPanel() { fdCarrierName->setEnabled(checked); if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -514,7 +612,7 @@ CtrlNetworkPanel::CtrlNetworkPanel() { btnSIMStatusGet->setProperty("ssType", "progManageTool"); connect(btnSIMStatusGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -526,7 +624,7 @@ CtrlNetworkPanel::CtrlNetworkPanel() { connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg] { Def_CtrlSingleGetReply waitingDlg->close(); - QString str4GStatus = tr("状态:"); + QString str4GStatus = tr("Status")+":"; auto state = json["state"].toInt(); if(state<2) str4GStatus += tr("未知"); else if(state==2) str4GStatus += tr("锁定状态,需要用户的PIN码解锁"); @@ -580,7 +678,7 @@ CtrlNetworkPanel::CtrlNetworkPanel() { } str4GStatus += tr("信号强度:") + QString::number(json["signalStrength"].toInt())+"\n"; } - QMessageBox::information(this, tr("Tip"), str4GStatus); + QMessageBox::information(this, translate("","Tip"), str4GStatus); }); } }); @@ -608,7 +706,7 @@ CtrlNetworkPanel::CtrlNetworkPanel() { fdCarrierName->clear(); fdCarrierName->addItem(""); auto apnInfos = fdMcc->itemData(index).toJsonArray(); - foreach(QJsonValue apnInfo, apnInfos) fdCarrierName->addItem(apnInfo["carrier"].toString(), apnInfo); + for(QJsonValue apnInfo : apnInfos) fdCarrierName->addItem(apnInfo["carrier"].toString(), apnInfo); }); hBox->addWidget(fdMcc); @@ -702,7 +800,7 @@ CtrlNetworkPanel::CtrlNetworkPanel() { btnAPNCusSet->setProperty("ssType", "progManageTool"); connect(btnAPNCusSet, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -740,10 +838,10 @@ CtrlNetworkPanel::CtrlNetworkPanel() { btnAPNCusGet->setProperty("ssType", "progManageTool"); connect(btnAPNCusGet, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "GetCurrentAPN"); json.insert("_type", "GetCurrentAPN"); if(gSelCards.count() == 1) { @@ -765,12 +863,12 @@ CtrlNetworkPanel::CtrlNetworkPanel() { fdCus_mmsPort->setText(json["mmsport"].toString()); }); } else { - foreach(auto card, gSelCards) { - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + for(auto &card : gSelCards) { + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json); auto cardId = card.id; connect(reply, &QNetworkReply::finished, this, [reply, cardId] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) { err = json["apn"].toString(); auto user = json["user"].toString(); @@ -804,10 +902,10 @@ CtrlNetworkPanel::CtrlNetworkPanel() { fdFightModel->setText(tr("OFF"), tr("ON")); connect(fdFightModel, &SwitchControl::checkedChanged, this, [=](bool checked) { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "ContrFlightMode"); json.insert("_type", "ContrFlightMode"); json.insert("state", checked); @@ -818,7 +916,7 @@ CtrlNetworkPanel::CtrlNetworkPanel() { Def_CtrlSetReqAfter }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { Def_CtrlSetMulti(tr("ContrFlightMode")) } } @@ -830,10 +928,10 @@ CtrlNetworkPanel::CtrlNetworkPanel() { btnFlightModelGet->setProperty("ssType", "progManageTool"); connect(btnFlightModelGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "GetFlightModeState"); json.insert("_type", "GetFlightModeState"); if(gSelCards.count() == 1) { @@ -846,12 +944,12 @@ CtrlNetworkPanel::CtrlNetworkPanel() { fdFightModel->update(); }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); auto cardId = card.id; connect(reply, &QNetworkReply::finished, this, [reply, cardId] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) err = json["result"].toBool() ? "true" : "false"; gFdResInfo->append(cardId+" "+tr("GetFlightModeState")+" "+err); }); @@ -880,13 +978,13 @@ void CtrlNetworkPanel::init() { if(! isSingle) return; auto card = gSelCards[0]; - QJsonObject json; + JObj json; json.insert("_id", "GetEthernet"); json.insert("_type", "GetEthernet"); 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); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; if(json["dhcp"].toBool()) { @@ -902,63 +1000,76 @@ void CtrlNetworkPanel::init() { fdDns->setText(json["dnsAddr"].toString()); }); - json = QJsonObject(); + json = JObj(); json.insert("_id", "GetWifiList"); json.insert("_type", "GetWifiList"); - reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + reply = NetReq("http://"+card.ip+":2016/settings").post(json); connect(reply, &QNetworkReply::finished, this, [=] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; auto wifis = json["wifiList"].toArray(); - fdWifiName->clear(); - foreach(QJsonValue wifi, wifis) fdWifiName->addItem(QIcon(":/res/signal-"+QString::number((wifi["signal"].toInt()+19)/20)+".png"), wifi["ssid"].toString()); + edWifiName->clear(); + for(JValue &wifi : wifis) edWifiName->addItem(QIcon(":/res/signal-"+QString::number((wifi["signal"].toInt()+19)/20)+".png"), wifi["ssid"].toString()); { - QJsonObject json; - json.insert("_id", "IsPortableHotSpot"); - json.insert("_type", "IsPortableHotSpot"); - 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); + JObj json; + auto isG = card.id.startsWith("g", Qt::CaseInsensitive); + if(isG) { + json.insert("_id", "GetWifiSwitchState"); + json.insert("_type", "GetWifiSwitchState"); + } else { + json.insert("_id", "IsPortableHotSpot"); + json.insert("_type", "IsPortableHotSpot"); + } + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json); + connect(reply, &QNetworkReply::finished, this, [=] { + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; - auto wifi = json["wifi"].toString(); - fdWifiName->setCurrentText(wifi); - auto hotSpots = json["hotSpots"].toString(); - fdHotspotName->setText(hotSpots); - if(hotSpots.isEmpty()) fdIsWifi->setChecked(true); - else fdIsHotspot->setChecked(true); + if(isG) { + fdIsWifi->setChecked(json["wifiEnable"].toBool()); + fdIsAP->setChecked(json["apEnable"].toBool()); + edWifiName->setCurrentText(json["wifiName"].toString()); + edHotspotName->setText(json["hotSpotName"].toString()); + edIs5G->setChecked(json["apBand"].toBool()); + } else { + edWifiName->setCurrentText(json["wifi"].toString()); + auto hotspots = json["hotSpots"].toString(); + edHotspotName->setText(hotspots); + fdIsWifi->setChecked(hotspots.isEmpty()); + fdIsAP->setChecked(! hotspots.isEmpty()); + } }); } }); - json = QJsonObject(); + json = JObj(); json.insert("_id", "GetSwitchSimData"); json.insert("_type", "GetSwitchSimData"); reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, this, [=] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; - bool b = json["enable"].toBool(); - fdEnableCellular->setChecked(b); - fdMcc->setEnabled(b); - fdCarrierName->setEnabled(b); + auto enable = json["enable"].toBool(); + fdEnableCellular->setChecked(enable); + fdMcc->setEnabled(enable); + fdCarrierName->setEnabled(enable); }); - json = QJsonObject(); + json = JObj(); json.insert("_id", "GetAPNList"); json.insert("_type", "GetAPNList"); reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, this, [=] { QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + auto err = checkReplyForJson(reply, &json); if(! err.isEmpty()) return; fdMcc->clear(); fdMcc->addItem(""); auto apns = json["apns"].toArray(); - foreach(QJsonValue apn, apns) { - QString mcc = apn["mcc"].toString(); + for(QJsonValue apn : apns) { + auto mcc = apn["mcc"].toString(); for(int i=0; icount(); i++) if(mcc==fdMcc->itemText(i)) { auto var = fdMcc->itemData(i); fdMcc->setItemData(i, QVariant()); @@ -973,13 +1084,13 @@ void CtrlNetworkPanel::init() { getCurrentAPN(card.ip); - json = QJsonObject(); + json = JObj(); json.insert("_id", "GetFlightModeState"); json.insert("_type", "GetFlightModeState"); - reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + reply = NetReq("http://"+card.ip+":2016/settings").post(json); connect(reply, &QNetworkReply::finished, this, [=] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; fdFightModel->setCheckedStatus(json["result"].toBool()); fdFightModel->update(); @@ -992,27 +1103,27 @@ void CtrlNetworkPanel::changeEvent(QEvent *event) { } void CtrlNetworkPanel::transUi() { lbLanCfg->setText(tr("Wire Enther(RJ45) Configuration")); - fdDhcp->setText(tr("DHCP")); fdSpecifyIp->setText(tr("Specify IP")); lbHotspotName->setText(tr("AP name")); labelGateway->setText(tr("Gateway")); lbWifiName->setText(tr("WiFi name")); labelIpAddress->setText(tr("IP Address")); - lbHotspotPassword->setText(tr("Password")); + lbHotspotPswd->setText(tr("Password")); labelDnsAddress->setText(tr("DNS Address")); labelMaskAddress->setText(tr("Subnet mask")); - lbWifiPassword->setText(tr("Password")); + lbWifiPswd->setText(tr("Password")); btnScan->setText(tr("Scan")); - btnWiFiSet->setText(tr("Set")); - btnLanSet->setText(tr("Set")); - btnWiFiGet->setText(tr("Readback")); - btnLanGet->setText(tr("Readback")); - fdIsWifi->setText(tr("WiFi Mode")); - fdIsHotspot->setText(tr("Ap Mode")); - label_5->setText(tr("WIFI Configuration")); - fdHotspotPassword->setPlaceholderText(tr("Input password")); - fdWifiPassword->setPlaceholderText(tr("Input password")); - fdHotspotName->setPlaceholderText(tr("Input ap name")); + btnWiFiSet->setText(translate("","Set")); + btnHotspotSet->setText(translate("","Set")); + btnLanSet->setText(translate("","Set")); + btnWiFiGet->setText(translate("","Readback")); + btnLanGet->setText(translate("","Readback")); + fdIsWifi->setText(tr("Enable WiFi")); + fdIsAP->setText(tr("Enable AP")); + lbWifiCfg->setText(tr("WiFi Config")); + edHotspotPswd->setPlaceholderText(translate("","Input Password")); + edWifiPswd->setPlaceholderText(translate("","Input Password")); + edHotspotName->setPlaceholderText(tr("Input ap name")); lbCellularConfig->setText(tr("Cellular Config")); lbCheckStatusTip->setText(tr("Through the check status button")); fdEnableCellular->setText(tr("Enable Cellular Data")); @@ -1021,7 +1132,7 @@ void CtrlNetworkPanel::transUi() { label_2->setText(tr("Country ID(mcc):")); label_3->setText(tr("Carrier Name")); fdCus_apn->setPlaceholderText(tr("APN(Required)")); - btnFlightModelGet->setText(tr("Readback")); + btnFlightModelGet->setText(translate("","Readback")); btnSIMStatusGet->setText(tr("Get cellular network status information")); label_10->setText(tr("Flight Mode")); @@ -1034,18 +1145,18 @@ void CtrlNetworkPanel::transUi() { lbCus_proxy->setText(tr("Proxy")); lbCus_mmsPort->setText(tr("MMS Port")); lbCus_mmsProxy->setText(tr("MMS Proxy")); - btnAPNCusSet->setText(tr("Set")); - btnAPNCusGet->setText(tr("Readback")); + btnAPNCusSet->setText(translate("","Set")); + btnAPNCusGet->setText(translate("","Readback")); } void CtrlNetworkPanel::getCurrentAPN(QString &ip) { - QJsonObject json; + JObj json; json.insert("_id", "GetCurrentAPN"); json.insert("_type", "GetCurrentAPN"); auto reply = NetReq("http://"+ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, this, [=] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; fdCus_Name->setText(json["carrier"].toString()); fdCus_apn->setText(json["apn"].toString()); diff --git a/LedOK/device/ctrlnetworkpanel.h b/LedOK/device/ctrlnetworkpanel.h index f2475e3..52b43e6 100644 --- a/LedOK/device/ctrlnetworkpanel.h +++ b/LedOK/device/ctrlnetworkpanel.h @@ -45,21 +45,17 @@ private: QLabel *labelIpAddress, *labelMaskAddress, *labelGateway, *labelDnsAddress; QLineEdit *fdIP, *fdMask, *fdGateWay, *fdDns; QPushButton *btnLanSet, *btnLanGet; - QLabel *label_5; - QLabel *lbWifiName; - QComboBox *fdWifiName; - QRadioButton *fdIs2_4G; - QLabel *lbWifiPassword; + QLabel *lbWifiCfg, *lbWifiName; + QComboBox *edWifiName; + QRadioButton *edIs5G; + QLabel *lbWifiPswd; - QRadioButton *fdIsWifi, *fdIsHotspot; - QLineEdit *fdWifiPassword; + QCheckBox *fdIsWifi, *fdIsAP; + QLineEdit *edWifiPswd; QPushButton *btnScan; - QPushButton *btnWiFiSet; - QPushButton *btnWiFiGet; - QLabel *lbHotspotName; - QLabel *lbHotspotPassword; - QLineEdit *fdHotspotName; - QLineEdit *fdHotspotPassword; + QPushButton *btnWiFiSet, *btnHotspotSet, *btnWiFiGet; + QLabel *lbHotspotName, *lbHotspotPswd; + QLineEdit *edHotspotName, *edHotspotPswd; QFrame *line_3; QLabel *lbCellularConfig; QCheckBox *fdEnableCellular; diff --git a/LedOK/device/ctrlpowerpanel.cpp b/LedOK/device/ctrlpowerpanel.cpp index d726c01..7497ac6 100644 --- a/LedOK/device/ctrlpowerpanel.cpp +++ b/LedOK/device/ctrlpowerpanel.cpp @@ -52,7 +52,7 @@ CtrlPowerPanel::CtrlPowerPanel() { fdScreen->setTextColor(QColor(100,100,100), QColor(0, 160, 230)); connect(fdScreen, &SwitchControl::checkedChanged, this, [this](bool checked) { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -82,7 +82,7 @@ CtrlPowerPanel::CtrlPowerPanel() { btnScreenGet->setProperty("ssType", "progManageTool"); connect(btnScreenGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -106,8 +106,8 @@ CtrlPowerPanel::CtrlPowerPanel() { foreach(auto card, gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, this, [=] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) { err = json["on"].toBool() ? tr("On") : tr("Off"); auto item = findItem(card.id); @@ -194,7 +194,7 @@ CtrlPowerPanel::CtrlPowerPanel() { if(! scheQFile.open(QIODevice::ReadOnly)) return; auto data = scheQFile.readAll(); scheQFile.close(); - restoreScheduleJson(QJsonDocument::fromJson(data).object()); + restoreScheduleJson(JFrom(data)); }); hBox->addWidget(pushButtonImport); @@ -229,7 +229,7 @@ CtrlPowerPanel::CtrlPowerPanel() { pushButtonApply->setMinimumSize(QSize(60, 30)); connect(pushButtonApply, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } if(tableSche->rowCount()==0) clearSche(); @@ -259,7 +259,7 @@ CtrlPowerPanel::CtrlPowerPanel() { pushButtonClearSchedule->setProperty("ssType", "progManageTool"); connect(pushButtonClearSchedule, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } clearSche(); @@ -272,7 +272,7 @@ CtrlPowerPanel::CtrlPowerPanel() { pushButtonReadback->setProperty("ssType", "progManageTool"); connect(pushButtonReadback, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -284,7 +284,7 @@ CtrlPowerPanel::CtrlPowerPanel() { connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg] { Def_CtrlSingleGetReply waitingDlg->success(); - restoreScheduleJson(json["screenTask"].toObject()); + restoreScheduleJson(json["screenTask"].toObj()); }); } }); @@ -318,10 +318,10 @@ void CtrlPowerPanel::init() { json.insert("_type", "GetTimingScreenTask"); auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, this, [this, reply, card] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; - if(restoreScheduleJson(json["screenTask"].toObject())) fdSchedule->setChecked(true); + if(restoreScheduleJson(json["screenTask"].toObj())) fdSchedule->setChecked(true); else fdManual->setChecked(true); }); } @@ -337,7 +337,7 @@ void CtrlPowerPanel::transUi() { lbScreen->setText(tr("Power")); fdScreen->setText(tr("Off"), tr("On")); - btnScreenGet->setText(tr("Readback")); + btnScreenGet->setText(translate("","Readback")); tableSche->setHeaderText("start", tr("Start Time")); tableSche->setHeaderText("end", tr("End Time")); @@ -351,18 +351,18 @@ void CtrlPowerPanel::transUi() { pushButtonAdd->setText(tr("Add")); pushButtonApply->setText(tr("Apply")); - pushButtonClear->setText(tr("Clear")); + pushButtonClear->setText(translate("","Clear")); pushButtonDelete->setText(tr("Delete")); pushButtonImport->setText(tr("Import")); pushButtonExport->setText(tr("Export")); labelPowerScheduleTip->setText(tr("It is power off state outside the schedule time period")); pushButtonClearSchedule->setText(tr("Clear Schedule")); - pushButtonReadback->setText(tr("Readback")); + pushButtonReadback->setText(translate("","Readback")); } -bool CtrlPowerPanel::restoreScheduleJson(QJsonObject oTaskSync) { +bool CtrlPowerPanel::restoreScheduleJson(JValue oTaskSync) { tableSche->setRowCount(0); auto schedules = oTaskSync["schedules"].toArray(); - foreach(QJsonValue schedule, schedules) { + for(auto &schedule : schedules) { int row = tableSche->rowCount(); tableSche->insertRow(row); @@ -389,7 +389,7 @@ bool CtrlPowerPanel::restoreScheduleJson(QJsonObject oTaskSync) { } } } - return schedules.count() > 0; + return schedules.size() > 0; } QJsonObject CtrlPowerPanel::getScheduleJson() { QJsonArray schedules; @@ -416,7 +416,7 @@ QJsonObject CtrlPowerPanel::getScheduleJson() { }; } void CtrlPowerPanel::clearSche() { - auto btn = QMessageBox::question(this, tr("Tip Info"), tr("Clear schedule task?")); + auto btn = QMessageBox::question(this, translate("","Tip"), tr("Clear schedule task?")); if(btn != QMessageBox::Yes) return; QJsonObject json; json.insert("_id", "CleanTimingScreenTask"); diff --git a/LedOK/device/ctrlpowerpanel.h b/LedOK/device/ctrlpowerpanel.h index 044dd18..7297a5f 100644 --- a/LedOK/device/ctrlpowerpanel.h +++ b/LedOK/device/ctrlpowerpanel.h @@ -2,6 +2,7 @@ #define CTRLPOWERPANEL_H #include "gutil/qgui.h" +#include "gutil/qjson.h" #include #include #include @@ -11,7 +12,7 @@ class CtrlPowerPanel : public QWidget { Q_OBJECT public: CtrlPowerPanel(); - bool restoreScheduleJson(QJsonObject oTaskSync); + bool restoreScheduleJson(JValue oTaskSync); QJsonObject getScheduleJson(); void clearSche(); protected: diff --git a/LedOK/device/ctrlpwdpanel.cpp b/LedOK/device/ctrlpwdpanel.cpp index 14ba538..2ede8ce 100644 --- a/LedOK/device/ctrlpwdpanel.cpp +++ b/LedOK/device/ctrlpwdpanel.cpp @@ -61,26 +61,26 @@ CtrlPwdPanel::CtrlPwdPanel() { btnPwdSet->setProperty("ssType", "progManageTool"); connect(btnPwdSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } if(fdOldPwd->isVisible() && fdOldPwd->text().isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("InputOriginalPasswordTip")); + QMessageBox::information(this, translate("","Tip"), tr("InputOriginalPasswordTip")); return; } if(fdNewPwd->text().isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("InputNewPasswordTip")); + QMessageBox::information(this, translate("","Tip"), tr("InputNewPasswordTip")); return; } if(fdPwdAgain->text().isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("InputRepeatPasswordTip")); + QMessageBox::information(this, translate("","Tip"), tr("InputRepeatPasswordTip")); return; } if(fdNewPwd->text() != fdPwdAgain->text()) { - QMessageBox::information(this, tr("Tip"), tr("InputRepeatPasswordNotSameTip")); + QMessageBox::information(this, translate("","Tip"), tr("InputRepeatPasswordNotSameTip")); return; } - auto res = QMessageBox::information(this, tr("Tip Info"), tr("After setting the password, please remember the password and record it. If you forget the password, the device will be unable to operate. Are you sure you want to continue with this operation?"), QMessageBox::Ok, QMessageBox::Cancel); + auto res = QMessageBox::information(this, translate("","Tip"), tr("After setting the password, please remember the password and record it. If you forget the password, the device will be unable to operate. Are you sure you want to continue with this operation?"), QMessageBox::Ok, QMessageBox::Cancel); if(res != QMessageBox::Ok) return; QJsonObject json; json.insert("_id", "SetControllerPassword"); @@ -91,16 +91,16 @@ CtrlPwdPanel::CtrlPwdPanel() { auto waitingDlg = new WaitingDlg(this, tr("SetControllerPassword")+" ..."); Def_CtrlReqPre connect(reply, &QNetworkReply::finished, this, [=] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + QString err = errStrWithJson(reply, &json); if(! err.isEmpty()) { waitingDlg->close(); - QMessageBox::critical(this, tr("Error"), err); + QMessageBox::critical(this, translate("","Error"), err); return; } if(json["result"].toInt()) { waitingDlg->close(); - QMessageBox::critical(this, tr("Tip"), tr("OriginalPasswordErrorTip")); + QMessageBox::critical(this, translate("","Tip"), tr("OriginalPasswordErrorTip")); return; } waitingDlg->success(); @@ -121,12 +121,12 @@ CtrlPwdPanel::CtrlPwdPanel() { foreach(auto card, gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, this, [=] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) { if(json["result"].toInt()) err = tr("OriginalPasswordErrorTip"); else { - err = tr("Success"); + err = translate("","Success"); lbOldPwd->show(); fdOldPwd->show(); btnPwdClear->show(); @@ -150,11 +150,11 @@ CtrlPwdPanel::CtrlPwdPanel() { btnPwdClear->setProperty("ssType", "progManageTool"); connect(btnPwdClear, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } if(fdOldPwd->isVisible() && fdOldPwd->text().isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("InputOriginalPasswordTip")); + QMessageBox::information(this, translate("","Tip"), tr("InputOriginalPasswordTip")); return; } QJsonObject json; @@ -166,16 +166,16 @@ CtrlPwdPanel::CtrlPwdPanel() { auto waitingDlg = new WaitingDlg(this, tr("SetControllerPassword")+" ..."); Def_CtrlReqPre connect(reply, &QNetworkReply::finished, this, [=] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) { waitingDlg->close(); - QMessageBox::critical(this, tr("Error"), err); + QMessageBox::critical(this, translate("","Error"), err); return; } if(json["result"].toInt()) { waitingDlg->close(); - QMessageBox::critical(this, tr("Tip"), tr("OriginalPasswordErrorTip")); + QMessageBox::critical(this, translate("","Tip"), tr("OriginalPasswordErrorTip")); return; } waitingDlg->success(); @@ -196,12 +196,12 @@ CtrlPwdPanel::CtrlPwdPanel() { foreach(auto card, gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, this, [=] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) { if(json["result"].toInt()) err = tr("OriginalPasswordErrorTip"); else { - err = tr("Success"); + err = translate("","Success"); lbOldPwd->hide(); fdOldPwd->hide(); btnPwdClear->hide(); diff --git a/LedOK/device/ctrltestpanel.cpp b/LedOK/device/ctrltestpanel.cpp index 62f3bfc..8e2920f 100644 --- a/LedOK/device/ctrltestpanel.cpp +++ b/LedOK/device/ctrltestpanel.cpp @@ -238,7 +238,7 @@ CtrlTestPanel::CtrlTestPanel() { btnAnycastReset->setProperty("ssType", "progManageTool"); connect(btnAnycastReset, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } SendAnycastCmd(0); @@ -253,7 +253,7 @@ CtrlTestPanel::CtrlTestPanel() { btnAnycast->setProperty("ssType", "progManageTool"); connect(btnAnycast, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } SendAnycastCmd(fdAnycast->text().toInt()); @@ -287,7 +287,7 @@ CtrlTestPanel::CtrlTestPanel() { connect(pushButtonStartLine, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -323,7 +323,7 @@ CtrlTestPanel::CtrlTestPanel() { }); connect(pushButtonStartGray, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -359,7 +359,7 @@ CtrlTestPanel::CtrlTestPanel() { }); connect(pushButtonStartColor, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -395,7 +395,7 @@ CtrlTestPanel::CtrlTestPanel() { }); connect(btnStopTest, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -458,7 +458,7 @@ void CtrlTestPanel::transUi() { radioButton_Blue->setText(tr("Blue")); radioButton_White->setText(tr("White")); btnStopTest->setText(tr("Stop")); - btnAnycastClear->setText(tr("Clear")); + btnAnycastClear->setText(translate("","Clear")); btnAnycastReset->setText(tr("Reset")); btnAnycast->setText(tr("Anycast")); } @@ -499,7 +499,7 @@ void CtrlTestPanel::SendAnycastCmd(int progIdx) { tcp->close(); tcp->deleteLater(); waitingDlg->close(); - QMessageBox::critical(this, tr("Tip"), QString(socketErrKey(err))+" ("+QString::number(err)+") "+tcp->errorString()); + QMessageBox::critical(this, translate("","Tip"), QString(socketErrKey(err))+" ("+QString::number(err)+") "+tcp->errorString()); }); tcp->connectToHost(card.ip, 31299); tcp->startTimer(10000); @@ -516,7 +516,7 @@ void CtrlTestPanel::SendAnycastCmd(int progIdx) { tcp->stopTimer(); tcp->close(); tcp->deleteLater(); - gFdResInfo->append(cardId+" "+action+" "+tr("Success")); + gFdResInfo->append(cardId+" "+action+" "+translate("","Success")); }); connect(tcp, &QTcpSocket::errorOccurred, tcp, [=](QAbstractSocket::SocketError err) { tcp->close(); diff --git a/LedOK/device/ctrlverifyclockpanel.cpp b/LedOK/device/ctrlverifyclockpanel.cpp index f79c328..d8745ff 100644 --- a/LedOK/device/ctrlverifyclockpanel.cpp +++ b/LedOK/device/ctrlverifyclockpanel.cpp @@ -25,7 +25,7 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { fdTimeZoneSet = new QPushButton; connect(fdTimeZoneSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -59,7 +59,7 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { btnLangSet = new QPushButton; connect(btnLangSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -83,10 +83,10 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { btnLangGet = new QPushButton; connect(btnLangGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "GetLanguage"); json.insert("_type", "GetLanguage"); if(gSelCards.count() == 1) { @@ -99,12 +99,12 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { else fdIsEn->setChecked(true); }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); auto cardId = card.id; connect(reply, &QNetworkReply::finished, this, [reply, cardId] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) err = json["language"].toInt()==1 ? "中文" : "英文"; gFdResInfo->append(cardId+" 获取语言 "+err); }); @@ -131,7 +131,7 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { btnSyncTime->setMinimumSize(QSize(60, 30)); connect(btnSyncTime, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -162,10 +162,10 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { btnDateGet->setMinimumSize(QSize(0, 30)); connect(btnDateGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "GetControllerDate"); json.insert("_type", "GetControllerDate"); if(gSelCards.count() == 1) { @@ -177,12 +177,12 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { labelCurTime->setText(json["date"].toString()); }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); auto cardId = card.id; connect(reply, &QNetworkReply::finished, this, [reply, cardId] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) err = json["date"].toString(); gFdResInfo->append(cardId+" "+tr("GetControllerDate")+" "+err); }); @@ -284,7 +284,7 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { btnSyncSet->setMinimumSize(QSize(60, 30)); connect(btnSyncSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -320,10 +320,10 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { fdSyncGet->setMinimumSize(QSize(60, 30)); connect(fdSyncGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "GetingSyncMethod"); json.insert("_type", "GetingSyncMethod"); if(gSelCards.count() == 1) { @@ -335,13 +335,13 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { dealGetSync(json); }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); auto cardId = card.id; connect(reply, &QNetworkReply::finished, this, [reply, cardId] { - QJsonDocument json; + JValue json; QByteArray data; - QString err = checkReplyForJson(reply, &json, &data); + auto err = errStrWithJson(reply, &json, &data); if(err.isEmpty()) { QString strOtherSyncItem = tr("screenSwitch") + ":" + (json["screenSwitch"].toBool() ? tr("YES") : tr("NO")) + " " + tr("volume") + ":" + (json["volume"].toBool() ? tr("YES") : tr("NO")) @@ -406,7 +406,7 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { btnLoraMasterSet->setMinimumSize(QSize(0, 30)); connect(btnLoraMasterSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -424,8 +424,8 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { foreach(auto card, gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); connect(reply, &QNetworkReply::finished, this, [reply, card, isMaster] { - QString err = checkReplyForJson(reply); - gFdResInfo->append(card.id+" "+(isMaster ? tr("MasterSwitch ") : tr("SlaveSwitch "))+" "+(err.isEmpty()?QCoreApplication::translate("Def","Success"):err)); + QString err = errStrWithJson(reply); + gFdResInfo->append(card.id+" "+(isMaster ? tr("MasterSwitch ") : tr("SlaveSwitch "))+" "+(err.isEmpty()?translate("","Success"):err)); }); } } @@ -436,10 +436,10 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { btnLoraMasterGet->setMinimumSize(QSize(0, 30)); connect(btnLoraMasterGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "IsMasterSlave"); json.insert("_type", "IsMasterSlave"); if(gSelCards.count() == 1) { @@ -453,12 +453,12 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { fdSlave->setChecked(! isMaster); }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); auto cardId = card.id; connect(reply, &QNetworkReply::finished, this, [reply, cardId] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) err = json["result"].toBool() ? tr("Master") : tr("Slave"); gFdResInfo->append(cardId+" "+tr("Lora identity")+" "+err); }); @@ -494,10 +494,10 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { btnNtpSet->setMinimumSize(QSize(60, 30)); connect(btnNtpSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "SetNtpServer"); json.insert("_type", "SetNtpServer"); json.insert("ntpServer", fdNtpServer->text()); @@ -508,7 +508,7 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { Def_CtrlSetReqAfter }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { Def_CtrlSetMulti(tr("SetNtpServer")) } } @@ -519,10 +519,10 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { btnNtpGet->setMinimumSize(QSize(60, 30)); connect(btnNtpGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } - QJsonObject json; + JObj json; json.insert("_id", "GetNtpServer"); json.insert("_type", "GetNtpServer"); if(gSelCards.count() == 1) { @@ -534,12 +534,12 @@ CtrlVerifyClockPanel::CtrlVerifyClockPanel() { fdNtpServer->setText(json["ntpServer"].toString()); }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); auto cardId = card.id; connect(reply, &QNetworkReply::finished, this, [reply, cardId] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) err = json["ntpServer"].toString(); gFdResInfo->append(cardId+" "+tr("GetNtpServer")+" "+err); }); @@ -598,35 +598,35 @@ void CtrlVerifyClockPanel::init() { if(! isSingle) return; auto card = gSelCards[0]; - QJsonObject json; + JObj json; json.insert("_id", "GetingSyncMethod"); json.insert("_type", "GetingSyncMethod"); - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json); connect(reply, &QNetworkReply::finished, this, [this, reply] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; dealGetSync(json); }); - json = QJsonObject(); + json = JObj(); json.insert("_id", "GetTimezone"); json.insert("_type", "GetTimezone"); - reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + reply = NetReq("http://"+card.ip+":2016/settings").post(json); connect(reply, &QNetworkReply::finished, this, [this, reply] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; fdTimezone->setCurrentText(json["timezone"].toString()); }); - json = QJsonObject(); + json = JObj(); json.insert("_id", "GetLanguage"); json.insert("_type", "GetLanguage"); - reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + reply = NetReq("http://"+card.ip+":2016/settings").post(json); connect(reply, &QNetworkReply::finished, this, [this, reply] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; if(json["language"].toInt()==1) fdIsCn->setChecked(true); else fdIsEn->setChecked(true); @@ -637,21 +637,21 @@ void CtrlVerifyClockPanel::changeEvent(QEvent *event) { if(event->type() == QEvent::LanguageChange) transUi(); } void CtrlVerifyClockPanel::transUi() { - btnDateGet->setText(tr("Readback")); - btnLangGet->setText(tr("Readback")); - btnLangSet->setText(tr("Set")); - btnLoraMasterGet->setText(tr("Readback")); - btnLoraMasterSet->setText(tr("Set")); - btnNtpGet->setText(tr("Readback")); - btnNtpSet->setText(tr("Set")); + btnDateGet->setText(translate("","Readback")); + btnLangGet->setText(translate("","Readback")); + btnLangSet->setText(translate("","Set")); + btnLoraMasterGet->setText(translate("","Readback")); + btnLoraMasterSet->setText(translate("","Set")); + btnNtpGet->setText(translate("","Readback")); + btnNtpSet->setText(translate("","Set")); btnSyncTime->setText(tr("Verify to Computer time")); checkBoxBrightness->setText(tr("Brightness")); checkBoxScreenSwitch->setText(tr("Screen on/off")); checkBoxVolume->setText(tr("Volume")); fdIsLan->setText(tr("LAN")); fdNtpServer->setPlaceholderText(tr("NTP Server address")); - fdSyncGet->setText(tr("Readback")); - fdTimeZoneSet->setText(tr("Set")); + fdSyncGet->setText(translate("","Readback")); + fdTimeZoneSet->setText(translate("","Set")); groupBox->setTitle(tr("Enable Synchronous playing")); groupBox_5->setTitle(tr("Cur time of controller")); groupNTP->setTitle(tr("NTP Server")); @@ -665,11 +665,11 @@ void CtrlVerifyClockPanel::transUi() { lbLang->setText(tr("Language:")); lineEditIdCode->setPlaceholderText(tr("identification code")); lineEdit_3->setPlaceholderText(tr("Sync time interval")); - btnSyncSet->setText(tr("Set")); + btnSyncSet->setText(translate("","Set")); fdMaster->setText(tr("Master")); fdSlave->setText(tr("Slave")); } -void CtrlVerifyClockPanel::dealGetSync(QJsonDocument &json) { +void CtrlVerifyClockPanel::dealGetSync(JValue &json) { QString strType = json["time"].toString().toLower(); if(strType=="serial" || strType=="lan") { if(strType=="serial") fdIsLora->setChecked(true); diff --git a/LedOK/device/ctrlverifyclockpanel.h b/LedOK/device/ctrlverifyclockpanel.h index 1c6f581..85be683 100644 --- a/LedOK/device/ctrlverifyclockpanel.h +++ b/LedOK/device/ctrlverifyclockpanel.h @@ -1,6 +1,7 @@ #ifndef CTRLVERIFYCLOCKPANEL_H #define CTRLVERIFYCLOCKPANEL_H +#include "gutil/qjson.h" #include #include #include @@ -18,7 +19,7 @@ protected: void init(); void changeEvent(QEvent *) override; void transUi(); - void dealGetSync(QJsonDocument &json); + void dealGetSync(JValue &json); protected slots: void OnRadioButton(); void OnRadioButton2(); diff --git a/LedOK/device/ctrlvolumepanel.cpp b/LedOK/device/ctrlvolumepanel.cpp index 7f86e68..5a6100b 100644 --- a/LedOK/device/ctrlvolumepanel.cpp +++ b/LedOK/device/ctrlvolumepanel.cpp @@ -66,7 +66,7 @@ CtrlVolumePanel::CtrlVolumePanel() { fdVolumeSet->setProperty("ssType", "progManageTool"); connect(fdVolumeSet, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -93,7 +93,7 @@ CtrlVolumePanel::CtrlVolumePanel() { fdVolumeGet->setProperty("ssType", "progManageTool"); connect(fdVolumeGet, &QPushButton::clicked, this, [=] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -108,12 +108,12 @@ CtrlVolumePanel::CtrlVolumePanel() { fdVolume->setValue(json["volume"].toInt()); }); } else { - foreach(auto card, gSelCards) { + for(auto &card : gSelCards) { auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); auto cardId = card.id; connect(reply, &QNetworkReply::finished, this, [reply, cardId] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(err.isEmpty()) err = QString::number(json["volume"].toInt()); gFdResInfo->append(cardId+" "+tr("GetVolume")+" "+err); }); @@ -218,7 +218,7 @@ CtrlVolumePanel::CtrlVolumePanel() { if(! scheQFile.open(QIODevice::ReadOnly)) return; auto data = scheQFile.readAll(); scheQFile.close(); - restoreScheduleJson(QJsonDocument::fromJson(data).object()); + restoreScheduleJson(JFrom(data)); }); hBox->addWidget(btnScheImport); @@ -263,7 +263,7 @@ CtrlVolumePanel::CtrlVolumePanel() { btnScheSet->setProperty("ssType", "progManageTool"); connect(btnScheSet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -291,7 +291,7 @@ CtrlVolumePanel::CtrlVolumePanel() { btnScheGet->setProperty("ssType", "progManageTool"); connect(btnScheGet, &QPushButton::clicked, this, [this] { if(gSelCards.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QJsonObject json; @@ -303,7 +303,7 @@ CtrlVolumePanel::CtrlVolumePanel() { connect(reply, &QNetworkReply::finished, this, [this, reply, waitingDlg, card] { Def_CtrlSingleGetReply waitingDlg->success(); - restoreScheduleJson(json["taskVolume"].toObject()); + restoreScheduleJson(json["taskVolume"]); }); } }); @@ -334,10 +334,10 @@ void CtrlVolumePanel::init() { QJsonObject json; json.insert("_id", "GetVolume"); json.insert("_type", "GetVolume"); - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json); connect(reply, &QNetworkReply::finished, this, [this, reply] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; fdVolume->setValue(json["volume"].toInt()); }); @@ -345,12 +345,12 @@ void CtrlVolumePanel::init() { json = QJsonObject(); json.insert("_id", "GetAutoVolumeTask"); json.insert("_type", "GetAutoVolumeTask"); - reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); + reply = NetReq("http://"+card.ip+":2016/settings").post(json); connect(reply, &QNetworkReply::finished, this, [this, reply, card] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) return; - if(restoreScheduleJson(json["taskVolume"].toObject())) fdSchedule->setChecked(true); + if(restoreScheduleJson(json["taskVolume"].toObj())) fdSchedule->setChecked(true); else fdManual->setChecked(true); }); } @@ -365,12 +365,12 @@ void CtrlVolumePanel::transUi() { fdSchedule->setText(tr("Schedule")); lbVolume->setText(tr("Volume")); - fdVolumeSet->setText(tr("Set")); - fdVolumeGet->setText(tr("Readback")); + fdVolumeSet->setText(translate("","Set")); + fdVolumeGet->setText(translate("","Readback")); lbDefBright->setText(tr("Default volume")); btnScheAdd->setText(tr("Add")); - btnScheClear->setText(tr("Clear")); + btnScheClear->setText(translate("","Clear")); btnScheDel->setText(tr("Delete")); btnScheImport->setText(tr("Import")); btnScheExport->setText(tr("Export")); @@ -387,16 +387,16 @@ void CtrlVolumePanel::transUi() { tableSche->setHeaderText("6", tr("SAT")); btnScheSet->setText(tr("Apply")); - btnScheGet->setText(tr("Readback")); + btnScheGet->setText(translate("","Readback")); fdScheTip->setText(tr("Default volume tip")); } -bool CtrlVolumePanel::restoreScheduleJson(QJsonObject json) { +bool CtrlVolumePanel::restoreScheduleJson(JValue json) { tableSche->setRowCount(0); auto items = json["items"].toArray(); fdDefBright->setValue(items.size()==0 ? 10 : json["defaultVolume"].toInt()); - for(int i=0; irowCount(); tableSche->insertRow(row); @@ -405,7 +405,7 @@ bool CtrlVolumePanel::restoreScheduleJson(QJsonObject json) { auto slider = new QSlider(Qt::Horizontal); slider->setRange(0, 15); - slider->setValue(items.at(i)["volume"].toInt()); + slider->setValue(items[i]["volume"].toInt()); hBox->addWidget(slider); auto lb = new QLabel; @@ -437,7 +437,7 @@ bool CtrlVolumePanel::restoreScheduleJson(QJsonObject json) { } } } - return items.count() > 0; + return items.size() > 0; } QJsonObject CtrlVolumePanel::getScheduleJson() { QJsonArray items; diff --git a/LedOK/device/ctrlvolumepanel.h b/LedOK/device/ctrlvolumepanel.h index 824e81d..7593ef9 100644 --- a/LedOK/device/ctrlvolumepanel.h +++ b/LedOK/device/ctrlvolumepanel.h @@ -2,6 +2,7 @@ #define CTRLVOLUMEPANEL_H #include "gutil/qgui.h" +#include "gutil/qjson.h" #include #include #include @@ -17,7 +18,7 @@ protected: void transUi(); private: - bool restoreScheduleJson(QJsonObject); + bool restoreScheduleJson(JValue); QJsonObject getScheduleJson(); QLabel *lbVolumeControl; diff --git a/LedOK/device/progressesdlg.cpp b/LedOK/device/progressesdlg.cpp index ce3f717..21f2fd5 100644 --- a/LedOK/device/progressesdlg.cpp +++ b/LedOK/device/progressesdlg.cpp @@ -35,22 +35,22 @@ ProgressesDlg::ProgressesDlg(QWidget *parent) : QDialog(parent) { } void ProgressesItem::sendProgress(const QString &id) { - QJsonObject json; + JObj json; json.insert("_id", id); json.insert("_type", id); - auto reply = NetReq("http://"+text("ip")+":2016/settings").timeout(30000).post(json); + auto reply = NetReq("http://"+text("ip")+":2016/settings").post(json); ConnReply(reply, this) [=] { if(treeWidget()==0) return; JValue json; auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) { - setRes(id+" "+tr("Error")+": "+err, Qt::red); + setRes(id+" "+translate("","Error")+": "+err, Qt::red); return; } auto progre = json["progress"].toInt(); if(progre >= 100) { fdProgress->setValue(100); - setRes("FPGA "+tr("Install Success"), Qt::darkGreen); + setRes("MCU "+tr("Install Success"), Qt::darkGreen); } else if(progre == -1) { fdProgress->setValue(100); setRes(tr("Same version, needn't update"), Qt::darkGreen); diff --git a/LedOK/device/upgradeapkdialog.cpp b/LedOK/device/upgradeapkdialog.cpp index 26aa97d..4d86ed2 100644 --- a/LedOK/device/upgradeapkdialog.cpp +++ b/LedOK/device/upgradeapkdialog.cpp @@ -142,7 +142,7 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { else items.append(item); } if(items.isEmpty()) { - QMessageBox::information(this, tr("Tip"), tr("NoSelectedController")); + QMessageBox::information(this, translate("","Tip"), translate("","Please select screen first")); return; } QByteArray fileData; @@ -153,7 +153,7 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { fileData = file.readAll(); file.close(); if(fileData.size() != file.size()) { - QMessageBox::information(this, tr("Tip"), tr("File Read Fail")); + QMessageBox::information(this, translate("","Tip"), tr("Failed to Read File")); return; } } else if(! fileId.isEmpty()) { @@ -170,15 +170,15 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { fileData = reply->readAll(); if(! err.isEmpty()) { if(! fileData.isEmpty()) err += "\n"+fileData; - QMessageBox::critical(this, tr("Error"), err); + QMessageBox::critical(this, translate("","Error"), err); return; } if(fileData.isEmpty()) { - QMessageBox::critical(this, tr("Error"), tr("Online file is empty")); + QMessageBox::critical(this, translate("","Error"), tr("Online file is empty")); return; } } else { - QMessageBox::critical(this, tr("Error"), tr("File is empty")); + QMessageBox::critical(this, translate("","Error"), tr("File is empty")); return; } auto nameBytes = fileName.toUtf8(); @@ -193,7 +193,7 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { item->setResult(tr("Uploading")+" ..."); 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); + auto reply = req.timeout(120000).type("multipart/form-data; boundary="+Boundary).post(data); connect(reply, &QNetworkReply::uploadProgress, item, [item](qint64 bytesSent, qint64 bytesTotal) { if(bytesTotal==0) return; item->fdProgress->setValue(bytesSent*100/bytesTotal); @@ -219,14 +219,14 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { json.insert("_type", "SynchronousHardwareVersion"); } item->setResult(info); - auto reply = NetReq("http://"+item->text("ip")+":2016/settings").timeout(60000).post(json); + auto reply = NetReq("http://"+item->text("ip")+":2016/settings").timeout(120000).post(json); ConnReply(reply, item) [=] { if(item->treeWidget()==0) return; - QJsonDocument json; - auto err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) { item->isUpdating = false; - item->setResult(tr("Install error")+": "+err, Qt::red); + item->setResult(translate("","Install")+" "+translate("","Error")+": "+err, Qt::red); return; } if(isApk || ! json["hasProgress"].toBool()) { @@ -264,7 +264,7 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { connect(btnUninstall, &QPushButton::clicked, this, [this, fdApk] { auto strApkName = fdApk->currentText(); if(strApkName.isEmpty()) { - QMessageBox::information(this, tr("Tip"), "APK is Empty"); + QMessageBox::information(this, translate("","Tip"), "APK is Empty"); return; } if(! strApkName.endsWith(".xixunplayer") && ! strApkName.endsWith(".taxiapp") && QMessageBox::warning(this, tr("Reminder"), tr("Reminder: Uninstalling this program may cause the device to offline, cannot be found, lost configs and have a black screen. Please uninstall with caution!")+"\n"+tr("Do you want to continue?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) != QMessageBox::Yes) return; @@ -272,18 +272,18 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { for(int i=0; iitem(i)->checkState("id") == Qt::Checked) { auto item = (UpdateApkItem *) table->topLevelItem(i); item->setResult(tr("Uninstalling")+" ..."); - QJsonObject json; + JObj json; json.insert("_id", "UninstallSoftware"); json.insert("_type", "UninstallSoftware"); json.insert("packageName", strApkName); - auto reply = NetReq("http://"+item->text("ip")+":2016/settings").timeout(60000).post(json); - ConnReply(reply, item) [reply, item, strApkName] { - QString err = checkReplyForJson(reply, "error"); + auto reply = NetReq("http://"+item->text("ip")+":2016/settings").post(json); + ConnReply(reply, item) [=] { + auto err = errStrWithJson(reply, "error"); if(! err.isEmpty()) { - item->setResult(tr("Uninstall error")+": "+err, Qt::red); + item->setResult(translate("","Uninstall")+" "+translate("","Error")+": "+err, Qt::red); return; } - item->setResult(tr("Uninstall success"), Qt::darkGreen); + item->setResult(translate("","Uninstall")+" "+translate("","Success"), Qt::darkGreen); }); } }); @@ -291,7 +291,7 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { auto btnCheck = new QPushButton(tr("check running state")); connect(btnCheck, &QPushButton::clicked, this, [this, fdApk] { - QString strApkName = fdApk->currentText(); + auto strApkName = fdApk->currentText(); int cnt = table->topLevelItemCount(); for(int i=0; iitem(i)->checkState("id") == Qt::Checked) { auto item = (UpdateApkItem *) table->topLevelItem(i); @@ -322,7 +322,7 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { hBox->addStretch(); - auto btnRefresh = new QPushButton(tr("Refresh")); + auto btnRefresh = new QPushButton(translate("","Refresh")); connect(btnRefresh, &QPushButton::clicked, this, [=] { table->clear(); table->fdCheckAll->setCheckState(Qt::Unchecked); @@ -369,26 +369,26 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) { 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); + auto pwd = QInputDialog::getText(this, translate("","Input Password"), translate("","Input Password"), QLineEdit::Password, QString(), &ok); if(! ok) return; QJsonObject json; json.insert("_id", "VerifyPassword"); json.insert("_type", "VerifyPassword"); json.insert("pwd", pwd); - auto waitingDlg = new WaitingDlg(item->btnUnlock, tr("VerifyPassword")+" ..."); + auto waitingDlg = new WaitingDlg(item->btnUnlock, tr("Verify Password")+" ..."); waitingDlg->show(); auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json); ConnReply(reply, waitingDlg) [=] { - QJsonDocument json; - auto err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) { waitingDlg->close(); - QMessageBox::critical(this, tr("Error"), err); + QMessageBox::critical(this, translate("","Error"), err); return; } if(! json["result"].toBool()) { waitingDlg->close(); - QMessageBox::warning(this, tr("Tip Info"), tr("password is wrong")); + QMessageBox::warning(this, translate("","Tip"), tr("password is wrong")); return; } waitingDlg->success(); @@ -495,11 +495,11 @@ void UpgradeApkDialog::sendProgress(UpdateApkItem *item) { auto reply = NetReq("http://"+item->text("ip")+":2016/settings").timeout(30000).post(json); ConnReply(reply, item) [=] { if(item->treeWidget()==0) return; - QJsonDocument json; - auto err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) { item->isUpdating = false; - item->setResult("GetFpgaUpdateProgress "+tr("Error")+": "+err, Qt::red); + item->setResult("GetFpgaUpdateProgress "+translate("","Error")+": "+err, Qt::red); return; } auto progre = json["progress"].toInt(); @@ -532,9 +532,9 @@ void UpgradeApkDialog::keyPressEvent(QKeyEvent *event) { void UpdateApkItem::OnCheckFpgaVersions() { - QJsonObject json; - json.insert("_id", "CheckHardwareVersions"); - json.insert("_type", "CheckHardwareVersions"); + JObj json; + json["_id"] = "CheckHardwareVersions"; + json["_type"] = "CheckHardwareVersions"; auto reply = NetReq("http://"+text("ip")+":2016/settings").timeout(60000).post(json); ConnReply(reply, fdProgress) [=] { if(treeWidget()==0) return; @@ -553,9 +553,9 @@ void UpdateApkItem::OnCheckFpgaVersions() { }); } void UpdateApkItem::OnCheckSoftVersions(int repeat) { - QJsonObject json; - json.insert("_id", "CheckSoftVersions"); - json.insert("_type", "CheckSoftVersions"); + JObj json; + json["_id"] = "CheckSoftVersions"; + json["_type"] = "CheckSoftVersions"; auto reply = NetReq("http://"+text("ip")+":2016/settings").timeout(60000).post(json); ConnReply(reply, fdProgress) [=] { if(treeWidget()==0) return; diff --git a/LedOK/deviceitem.cpp b/LedOK/deviceitem.cpp index 6501223..6d51b5c 100644 --- a/LedOK/deviceitem.cpp +++ b/LedOK/deviceitem.cpp @@ -23,15 +23,15 @@ DeviceItem::DeviceItem(LoQTreeWidget *parent) : TreeWidgetItem(parent) { JObj json; json.insert("_id", "GetScreenshotFull"); json.insert("_type", "GetScreenshotFull"); - auto waitingDlg = new WaitingDlg(btnGetCapture, DevicePanel::tr("Getting ")+DevicePanel::tr("Screenshot")+" ..."); + auto waitingDlg = new WaitingDlg(btnGetCapture, translate("","Getting ")+DevicePanel::tr("Screenshot")+" ..."); waitingDlg->show(); auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json); ConnReply(reply, waitingDlg) [=] { waitingDlg->close(); - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) { - QMessageBox::critical(treeWidget(), DevicePanel::tr("Error"), err); + QMessageBox::critical(treeWidget(), translate("","Error"), err); return; } ImgDlg dlg(QByteArray::fromBase64(json["data"].toString().toLatin1()), treeWidget()); @@ -55,26 +55,26 @@ DeviceItem::DeviceItem(LoQTreeWidget *parent) : TreeWidgetItem(parent) { QObject::connect(btnUnlock, &QPushButton::clicked, btnUnlock, [this] { if(! mCard.isLocked) return; bool ok; - auto pwd = QInputDialog::getText(treeWidget(), DevicePanel::tr("Input password"), DevicePanel::tr("Input password"), QLineEdit::Password, QString(), &ok); + auto pwd = QInputDialog::getText(treeWidget(), translate("","Input Password"), translate("","Input Password"), QLineEdit::Password, QString(), &ok); if(! ok) return; JObj json; json.insert("_id", "VerifyPassword"); json.insert("_type", "VerifyPassword"); json.insert("pwd", pwd); - auto waitingDlg = new WaitingDlg(btnUnlock, DevicePanel::tr("VerifyPassword")+" ..."); + auto waitingDlg = new WaitingDlg(btnUnlock, DevicePanel::tr("Verify Password")+" ..."); waitingDlg->show(); auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(60000).post(json); ConnReply(reply, waitingDlg) [=] { - QJsonDocument json; - QString err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) { waitingDlg->close(); - QMessageBox::critical(treeWidget(), DevicePanel::tr("Error"), err); + QMessageBox::critical(treeWidget(), translate("","Error"), err); return; } if(! json["result"].toBool()) { waitingDlg->close(); - QMessageBox::critical(treeWidget(), DevicePanel::tr("Tip Info"), DevicePanel::tr("password is wrong")); + QMessageBox::critical(treeWidget(), translate("","Tip"), DevicePanel::tr("password is wrong")); return; } waitingDlg->success(); diff --git a/LedOK/devicepanel.cpp b/LedOK/devicepanel.cpp index 7734036..13a4ac2 100644 --- a/LedOK/devicepanel.cpp +++ b/LedOK/devicepanel.cpp @@ -120,7 +120,7 @@ QComboBox QAbstractItemView::item { QComboBox QAbstractItemView::item:selected {background-color: #09c;} )rrr"); - btnRefresh = new QPushButton(tr("Refresh"), areaFlash); + btnRefresh = new QPushButton(translate("","Refresh"), areaFlash); btnRefresh->setGeometry(0, 0, 75, areaFlash->height()); connect(btnRefresh, &QPushButton::clicked, this, [this] { mDeviceTable->clear(); @@ -230,7 +230,7 @@ QPushButton:hover {background-color: #08b;} msgpre.append(tr("FPGA Version")).append(": ").append(item->mCard.HardVersion).append("\n"); msgpre.append(tr("Firmware Version")).append(": ").append(item->mCard.firmwareVer).append("\n"); msgpre.append("IMEI: ").append(item->mCard.IMEI).append("\n"); - QMessageBox msgBox(QMessageBox::Information, item->mCard.id+" "+tr("Detail Info"), msgpre + tr("Player Version")+": "+tr("Getting")+" ..."); + QMessageBox msgBox(QMessageBox::Information, item->mCard.id+" "+tr("Detail Info"), msgpre + tr("Player Version")+": "+translate("","Getting")+" ..."); QJsonObject json; json.insert("_id", "CheckSoftVersions"); json.insert("_type", "CheckSoftVersions"); @@ -289,7 +289,7 @@ QPushButton:hover {background-color: #08b;} auto bnSearch = new QPushButton(tr("Search")); connect(bnSearch, &QPushButton::clicked, fdIP, [this] { - QString ipsStr = fdIP->toPlainText(); + auto ipsStr = fdIP->toPlainText(); if(ipsStr.isEmpty()) { QMessageBox::warning(this, tr("Attention"), tr("Please input IP address!")); return; @@ -299,8 +299,11 @@ QPushButton:hover {background-color: #08b;} QMessageBox::warning(this, tr("Attention"), tr("Please input IP address!")); return; } - QByteArray data = QJsonDocument(QJsonObject{{"action", "getInfo"}}).toJson(QJsonDocument::Compact); - for(auto &ip : ips) if(mUdpSocket.writeDatagram(data, QHostAddress(ip), 22222) != data.length()) qDebug() << "Specify IP write Failed." << ip; + auto data = QJsonDocument(QJsonObject{{"action", "getInfo"}}).toJson(QJsonDocument::Compact); + for(auto &ip : ips) { + if(mUdpSocket.writeDatagram(data, QHostAddress(ip), 22222) != data.length()) qDebug() << "Specify IP write Failed." << ip; + QCoreApplication::processEvents(); + } specifyIPDlg->accept(); }); hBox->addWidget(bnSearch); @@ -312,8 +315,8 @@ QPushButton:hover {background-color: #08b;} transUi(); - sendGetInfo(); - mUdpTimer.start(30000); + auto cnt = sendGetInfo(); + if(cnt<=100) mUdpTimer.start(30000); } DevicePanel::~DevicePanel() { @@ -321,7 +324,7 @@ DevicePanel::~DevicePanel() { mUdpTimer.stop(); } -void DevicePanel::sendGetInfo() { +int DevicePanel::sendGetInfo() { auto data = QJsonDocument(QJsonObject{{"action", "getInfo"}}).toJson(QJsonDocument::Compact); uchar ccc[]{0x7E, 0x7E, 0x7E, 0x90, 0x42, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x9F}; @@ -333,7 +336,7 @@ void DevicePanel::sendGetInfo() { bool can = (flags & QNetworkInterface::IsRunning) && (flags & QNetworkInterface::CanBroadcast) && ! (flags & QNetworkInterface::IsLoopBack); if(! can) continue; auto addrEntries = face.addressEntries(); - for(QNetworkAddressEntry &addrEntry : addrEntries) { + for(auto &addrEntry : addrEntries) { auto ip = addrEntry.ip(); if(ip.protocol()!=QAbstractSocket::IPv4Protocol) continue; auto broadcast = addrEntry.broadcast(); @@ -341,10 +344,18 @@ void DevicePanel::sendGetInfo() { } } auto ipstr = fdIP->toPlainText(); + int cnt = 0; if(! ipstr.isEmpty()) { auto ips = ipstr.split("\n", Qt::SkipEmptyParts); - for(auto &ip : ips) if(mUdpSocket.writeDatagram(data, QHostAddress(ip), 22222) != data.length()) qDebug() << "getInfo specify IP write failed." << ip; + cnt = ips.size(); + QTimer::singleShot(100, [=] { + for(auto &ip : ips) { + if(mUdpSocket.writeDatagram(data, QHostAddress(ip), 22222) != data.length()) qDebug() << "getInfo specify IP write failed." << ip; + QCoreApplication::processEvents(); + } + }); } + return cnt; } void DevicePanel::changeEvent(QEvent *event) { @@ -352,13 +363,13 @@ void DevicePanel::changeEvent(QEvent *event) { if(event->type() == QEvent::LanguageChange) transUi(); } void DevicePanel::transUi() { - btnRefresh->setText(tr("Refresh")); + btnRefresh->setText(translate("","Refresh")); bnSpecifyIP->setItemText(0,tr("Specify IP")); label_3->setText(tr("All")); mDeviceTable->setHeaderText("online", tr("Online")); mDeviceTable->setHeaderText("id", tr("Screen ID")); - mDeviceTable->setHeaderText("screenSize", tr("Screen Size")); + mDeviceTable->setHeaderText("screenSize", translate("","Screen Size")); mDeviceTable->setHeaderText("alias", tr("Alias")); mDeviceTable->setHeaderText("brightness", tr("Screen Brightness")); mDeviceTable->setHeaderText("power", tr("Power Status")); @@ -388,7 +399,7 @@ void DevicePanel::transCtrl() { if(gSelCards.count() < 1) fdCardNumInfo->setText(tr("Current Screen")+": "+tr("none")); else if(gSelCards.count()==1) fdCardNumInfo->setText(tr("Current Screen")+": "+gSelCards[0].id); else fdCardNumInfo->setText(tr("Multi screen operation")+". "+tr("selected num")+": "+QString::number(gSelCards.count())); - btnClear->setText(tr("Clear")); + btnClear->setText(translate("","Clear")); } } void DevicePanel::newCtrl() { @@ -465,7 +476,7 @@ void DevicePanel::newCtrl() { fdInfo->setMaximumWidth(360); vBox2->addWidget(fdInfo); - btnClear = new QPushButton(tr("Clear")); + btnClear = new QPushButton(translate("","Clear")); btnClear->setMinimumHeight(30); btnClear->setProperty("ssType", "progManageTool"); connect(btnClear, &QPushButton::clicked, fdInfo, &QTextEdit::clear); diff --git a/LedOK/devicepanel.h b/LedOK/devicepanel.h index cd8225f..a329e98 100644 --- a/LedOK/devicepanel.h +++ b/LedOK/devicepanel.h @@ -19,7 +19,7 @@ public: explicit DevicePanel(QSettings &, QWidget *parent = nullptr); ~DevicePanel(); - void sendGetInfo(); + int sendGetInfo(); void newCtrl(); void init(DeviceItem *item); diff --git a/LedOK/Demos/Demo Video 720p.mp4 b/LedOK/files/VehPlayer_v3.3.3-beta26.4.1.9-release{259}.apk similarity index 71% rename from LedOK/Demos/Demo Video 720p.mp4 rename to LedOK/files/VehPlayer_v3.3.3-beta26.4.1.9-release{259}.apk index 9c7344a..68fb017 100644 Binary files a/LedOK/Demos/Demo Video 720p.mp4 and b/LedOK/files/VehPlayer_v3.3.3-beta26.4.1.9-release{259}.apk differ diff --git a/LedOK/gutil/cpp.h b/LedOK/gutil/cpp.h index 2562ef2..0b72795 100644 --- a/LedOK/gutil/cpp.h +++ b/LedOK/gutil/cpp.h @@ -121,6 +121,9 @@ public: iterator end() const noexcept { return this->ptr ? this->ptr->data.end() : iterator(); } + bool contains(const V &val) const noexcept { + return this->ptr ? std::find(this->ptr->data.begin(), this->ptr->data.end(), val)!=this->ptr->data.end() : false; + } }; diff --git a/LedOK/gutil/qcore.h b/LedOK/gutil/qcore.h index 385c6c5..86dc3a2 100644 --- a/LedOK/gutil/qcore.h +++ b/LedOK/gutil/qcore.h @@ -33,13 +33,13 @@ inline QString byteSizeStr(double size) { return (size > 99 ? QString::number(size, 'f', 0) : QString::number(size, 'g', 3))+" "+units[i]; } -inline void wait(int msec, QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents) { - QTimer timer; - timer.setSingleShot(true); +inline int wait(int msec, QObject *context = 0, QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents) { QEventLoop loop; - QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); - timer.start(msec); - loop.exec(flags); + QTimer::singleShot(msec, &loop, &QEventLoop::quit); + if(context) QObject::connect(context, &QObject::destroyed, &loop, [&] { + loop.exit(1); + }); + return loop.exec(flags); } template diff --git a/LedOK/gutil/qnetwork.cpp b/LedOK/gutil/qnetwork.cpp index fc2b5c0..4f0d4d9 100644 --- a/LedOK/gutil/qnetwork.cpp +++ b/LedOK/gutil/qnetwork.cpp @@ -33,7 +33,7 @@ QString errStrWithData(QNetworkReply *reply, JValue *outJson) { auto data = reply->readAll(); QString error; *outJson = JFrom(data, &error); - if(! error.isEmpty()) return "JSON "+QCoreApplication::translate("Net","Error")+": "+error+"\n"+data; + if(! error.isEmpty()) return "JSON "+QCoreApplication::translate("","Error")+": "+error+"\n"+data; } return ""; } @@ -49,7 +49,7 @@ QString errStrWithData(QNetworkReply *reply, QJsonDocument *outJson) { auto data = reply->readAll(); QJsonParseError jsonErr; *outJson = QJsonDocument::fromJson(data, &jsonErr); - if(jsonErr.error != QJsonParseError::NoError) return "JSON "+QCoreApplication::translate("Net","Error")+": "+jsonErr.errorString()+"\n"+data; + if(jsonErr.error != QJsonParseError::NoError) return "JSON "+QCoreApplication::translate("","Error")+": "+jsonErr.errorString()+"\n"+data; } return ""; } diff --git a/LedOK/gutil/qnetwork.h b/LedOK/gutil/qnetwork.h index 423951a..7b6f083 100644 --- a/LedOK/gutil/qnetwork.h +++ b/LedOK/gutil/qnetwork.h @@ -96,7 +96,7 @@ QString errStr(QNetworkReply *); QString errStrWithData(QNetworkReply *, JValue * = 0); QString errStrWithData(QNetworkReply *, QJsonDocument *); -inline int waitFinished(QNetworkReply *reply, QObject *context, bool excludeUser = false) { +inline int waitFinished(QNetworkReply *reply, QObject *context = 0, bool excludeUser = false) { if(reply->isFinished()) return 0; QEventLoop loop; QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); diff --git a/LedOK/gutil/qwaitingdlg.cpp b/LedOK/gutil/qwaitingdlg.cpp index c1c9189..36f3e85 100644 --- a/LedOK/gutil/qwaitingdlg.cpp +++ b/LedOK/gutil/qwaitingdlg.cpp @@ -3,6 +3,49 @@ #include #include #include +#include + +LoadingDlg::LoadingDlg(QWidget *parent, QString text, QString sucText) : QDialog{parent, Qt::Tool}, sucText(sucText) { + setModal(true); + setResult(-1); + auto vBox = new VBox(this); + + mIndicator = new WaitingIndicator(this); + mIndicator->setFixedSize(100, 100); + vBox->addWidget(mIndicator, 0, Qt::AlignCenter); + + fdText = new QLabel(text); + fdText->setAlignment(Qt::AlignCenter); + gFont(fdText, 18, true); + vBox->addWidget(fdText); + + show(); + raise(); + activateWindow(); +} + +void LoadingDlg::closeEvent(QCloseEvent *event) { + if(closeTimerId) { + killTimer(closeTimerId); + closeTimerId = 0; + } + QDialog::closeEvent(event); +} +void LoadingDlg::timerEvent(QTimerEvent *event) { + if(closeTimerId==event->timerId()) { + killTimer(closeTimerId); + closeTimerId = 0; + accept(); + close(); + } else QDialog::timerEvent(event); +} +void LoadingDlg::success() { + fdText->setText(sucText.isEmpty() ? QCoreApplication::translate("","Success") : sucText); + mIndicator->success(); + if(! isVisible()) show(); + if(closeTimerId) killTimer(closeTimerId); + closeTimerId = startTimer(keepTime); +} WaitingDlg::WaitingDlg(QWidget *parent, QString text, QString sucText) : QDialog{parent, Qt::Tool}, sucText(sucText) { setAttribute(Qt::WA_DeleteOnClose); @@ -39,6 +82,7 @@ void WaitingDlg::timerEvent(QTimerEvent *event) { } else if(closeTimerId==event->timerId()) { killTimer(closeTimerId); closeTimerId = 0; + accept(); close(); } else QDialog::timerEvent(event); } @@ -53,7 +97,7 @@ void WaitingDlg::showLater() { showTimerId = startTimer(200); } void WaitingDlg::success() { - fdText->setText(sucText.isEmpty() ? tr("Success") : sucText); + fdText->setText(sucText.isEmpty() ? QCoreApplication::translate("","Success") : sucText); mIndicator->success(); if(showTimerId) { killTimer(showTimerId); diff --git a/LedOK/gutil/qwaitingdlg.h b/LedOK/gutil/qwaitingdlg.h index efc5651..0e13e96 100644 --- a/LedOK/gutil/qwaitingdlg.h +++ b/LedOK/gutil/qwaitingdlg.h @@ -9,15 +9,33 @@ class WaitingIndicator : public QWidget { Q_OBJECT public: using QWidget::QWidget; - QColor mColor{0x0088ff}; + QColor mColor = 0x0088ff; public slots: void success(); protected: void timerEvent(QTimerEvent * event) override; void paintEvent(QPaintEvent * event) override; - int angle{0}; - int timerId{0}; + int angle = 0; + int timerId = 0; +}; + +class LoadingDlg : public QDialog { + Q_OBJECT +public: + explicit LoadingDlg(QWidget *parent = nullptr, QString text = 0, QString sucText = 0); + + QLabel *fdText; + QString sucText; + WaitingIndicator *mIndicator; + int keepTime = 750; +public slots: + void success(); +protected: + void timerEvent(QTimerEvent *) override; + void closeEvent(QCloseEvent *) override; +private: + int closeTimerId = 0; }; class WaitingDlg : public QDialog { diff --git a/LedOK/main.cpp b/LedOK/main.cpp index 3c2ab07..395448f 100644 --- a/LedOK/main.cpp +++ b/LedOK/main.cpp @@ -51,6 +51,12 @@ int main(int argc, char *argv[]) { QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough); #endif + auto config = QSslConfiguration::defaultConfiguration(); + config.setProtocol(QSsl::AnyProtocol); + config.setPeerVerifyMode(QSslSocket::VerifyNone); + config.setPeerVerifyDepth(1); + QSslConfiguration::setDefaultConfiguration(config); + QApplication::setOrganizationName("Sysolution"); QApplication::setOrganizationDomain("ledok.cn"); QApplication::setApplicationName("LedOK Express"); @@ -108,14 +114,14 @@ QString checkReply(QNetworkReply *reply, QJsonDocument *outJson) { auto err = errStr(reply); if(! err.isEmpty()) { auto data = reply->readAll(); - if(! data.isEmpty()) err = err+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; + if(! data.isEmpty()) err = err+"\n"+translate("","Device replied")+": "+data; return err; } if(outJson) { auto data = reply->readAll(); QJsonParseError jsonErr; *outJson = QJsonDocument::fromJson(data, &jsonErr); - if(jsonErr.error != QJsonParseError::NoError) return "Json error: "+jsonErr.errorString()+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; + if(jsonErr.error != QJsonParseError::NoError) return "Json error: "+jsonErr.errorString()+"\n"+translate("","Device replied")+": "+data; } return ""; } @@ -124,47 +130,47 @@ QString errStrWithJson(QNetworkReply *reply, JValue *outJson, QByteArray *outDat auto data = reply->readAll(); if(outData) *outData = data; if(! err.isEmpty()) { - if(! data.isEmpty()) err = err+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; + if(! data.isEmpty()) err = err+"\n"+translate("","Device replied")+": "+data; return err; } QString error; auto json = JFrom(data, &error); - if(! error.isEmpty()) return "JSON Error: "+error+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; - if(! json["success"].toBool()) return QCoreApplication::translate("Def","Fail")+". "+QCoreApplication::translate("Def","Device replied")+": "+data; + if(! error.isEmpty()) return "JSON Error: "+error+"\n"+translate("","Device replied")+": "+data; + if(! json["success"].toBool()) return translate("","Fail")+". "+translate("","Device replied")+": "+data; if(outJson) *outJson = json; return ""; } +QString errStrWithJson(QNetworkReply *reply, QString errField) { + auto err = errStr(reply); + auto data = reply->readAll(); + if(! err.isEmpty()) { + if(! data.isEmpty()) err = err+"\n"+translate("","Device replied")+": "+data; + return err; + } + QString error; + auto json = JFrom(data, &error); + if(! error.isEmpty()) return "JSON Error: "+error+"\n"+translate("","Device replied")+": "+data; + if(! json["success"].toBool()) { + auto errStr = json[errField].toString(); + return translate("","Fail")+". "+translate("","Device replied")+": "+(errStr.isEmpty() ? data : errStr); + } + return ""; +} QString checkReplyForJson(QNetworkReply *reply, QJsonDocument *outJson, QByteArray *outData) { auto err = errStr(reply); auto data = reply->readAll(); if(outData) *outData = data; if(! err.isEmpty()) { - if(! data.isEmpty()) err = err+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; + if(! data.isEmpty()) err = err+"\n"+translate("","Device replied")+": "+data; return err; } QJsonParseError jsonErr; QJsonDocument json = QJsonDocument::fromJson(data, &jsonErr); - if(jsonErr.error != QJsonParseError::NoError) return "Json error: "+jsonErr.errorString()+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; - if(! json["success"].toBool()) return QCoreApplication::translate("Def","Fail")+". "+QCoreApplication::translate("Def","Device replied")+": "+data; + if(jsonErr.error != QJsonParseError::NoError) return "Json error: "+jsonErr.errorString()+"\n"+translate("","Device replied")+": "+data; + if(! json["success"].toBool()) return translate("","Fail")+". "+translate("","Device replied")+": "+data; if(outJson) outJson->swap(json); return ""; } -QString checkReplyForJson(QNetworkReply *reply, QString errField) { - auto err = errStr(reply); - auto data = reply->readAll(); - if(! err.isEmpty()) { - if(! data.isEmpty()) err = err+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; - return err; - } - QJsonParseError jsonErr; - QJsonDocument json = QJsonDocument::fromJson(data, &jsonErr); - if(jsonErr.error != QJsonParseError::NoError) return "Json error: "+jsonErr.errorString()+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; - if(! json["success"].toBool()) { - auto errStr = json[errField].toString(); - return QCoreApplication::translate("Def","Fail")+". "+QCoreApplication::translate("Def","Device replied")+": "+(errStr.isEmpty() ? data : errStr); - } - return ""; -} quint64 dirFileSize(const QString &path) { QDir dir(path); @@ -214,7 +220,7 @@ bool copyDir(const QString &source, const QString &destination, bool override) { } unsigned char GetCheckCodeIn8(unsigned char *str, unsigned int size) { unsigned char checkCode = 0; - for(int i=0; i #include #include #include #include -#define PAGEDEL_SUFFIX "@D$E$L&20111005&" +#define PAGEDEL_SUFFIX "~temp~temp~temp" #define RECTF_INVALID QRectF(-9999, -9999, 0, 0) struct LedCard { @@ -63,6 +65,7 @@ QString programsDir(); extern Tick *gTick; extern QString gFileHome; extern QString gApkHome; +extern int gProgWidth, gProgHeight; class DevicePanel; extern DevicePanel *gDevicePanel; extern QList gSelCards; @@ -76,6 +79,10 @@ extern bool gShowIP; extern bool gShowAlias; extern bool gShowLora; + +extern QTextEdit *gFdResInfo; +extern ProgItem *gProgItem; + extern quint64 dirFileSize(const QString &path); extern bool copyDir(const QString &source, const QString &destination, bool override); extern unsigned char GetCheckCodeIn8(unsigned char * pBuffer,unsigned int uiSize); @@ -95,6 +102,9 @@ enum _ENUM_CONTRL_WIDGET { class DeviceItem; extern DeviceItem *findItem(QString id); +inline QString translate(const char *ctx, const char *key) { + return QCoreApplication::translate(ctx, key); +} inline int verCompare(const QString& a, const QString& b) { auto aparts = a.split("."); auto bparts = b.split("."); @@ -110,40 +120,40 @@ inline int verCompare(const QString& a, const QString& b) { QString checkReply(QNetworkReply *, QJsonDocument * = 0); QString errStrWithJson(QNetworkReply *, JValue * = 0, QByteArray * = 0); +QString errStrWithJson(QNetworkReply *, QString errField); QString checkReplyForJson(QNetworkReply *, QJsonDocument * = 0, QByteArray * = 0); -QString checkReplyForJson(QNetworkReply *, QString errField); void MergeFmt(QTextEdit *textEdit, const QTextCharFormat &fmt); #define Def_CtrlReqPre \ waitingDlg->show();\ auto card = gSelCards[0];\ - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);\ + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json);\ connect(waitingDlg, &WaitingDlg::rejected, reply, &QNetworkReply::deleteLater); #define Def_CtrlSetReqAfter \ - QString err = checkReplyForJson(reply);\ + auto err = errStrWithJson(reply);\ if(! err.isEmpty()) {\ waitingDlg->close();\ - QMessageBox::critical(this, tr("Error"), err);\ + QMessageBox::critical(this, translate("","Error"), err);\ return;\ }\ waitingDlg->success(); #define Def_CtrlSingleGetReply \ - QJsonDocument json;\ - QString err = checkReplyForJson(reply, &json);\ + JValue json;\ + auto err = errStrWithJson(reply, &json);\ if(! err.isEmpty()) {\ waitingDlg->close();\ - QMessageBox::critical(this, tr("Error"), err);\ + QMessageBox::critical(this, translate("","Error"), err);\ return;\ } #define Def_CtrlSetMulti(tip) \ - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);\ + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json);\ connect(reply, &QNetworkReply::finished, gFdResInfo, [=] {\ - QString err = checkReplyForJson(reply);\ - gFdResInfo->append(card.id+" "+tip+" "+(err.isEmpty()?QCoreApplication::translate("Def","Success"):err));\ + auto err = errStrWithJson(reply);\ + gFdResInfo->append(card.id+" "+tip+" "+(err.isEmpty()?translate("","Success"):err));\ }); class LocalObj : public QObject { diff --git a/LedOK/mainwindow.cpp b/LedOK/mainwindow.cpp index b4657b8..ed66525 100644 --- a/LedOK/mainwindow.cpp +++ b/LedOK/mainwindow.cpp @@ -22,6 +22,7 @@ extern QPoint gPlayPos; QString gApkHome; +int gProgWidth = 512, gProgHeight = 256; bool gVideoCompress = false; bool gVideoTranscoding = false; bool gTextAntialiasing = false; @@ -350,7 +351,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { fdUpdLog->setReadOnly(true); vBox->addWidget(fdUpdLog); - auto reply = NetReq(updates["changelog_zh_CN"].toString()).timeout(60000).get(); + auto reply = NetReq(updates["changelog_zh_CN"].toString()).get(); ConnReply(reply, fdUpdLog) [=] { auto err = errStr(reply); if(! err.isEmpty()) { @@ -391,7 +392,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { auto err = errStr(reply); if(! err.isEmpty()) { msgBox.setIcon(QMessageBox::Critical); - msgBox.setText(tr("Error")+": "+err); + msgBox.setText(translate("","Error")+": "+err); return; } msgBox.accept(); @@ -409,7 +410,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { }); menu_setting->addAction(act_upd); - auto reply = NetReq(UpdVerUrl).timeout(60000).get(); + auto reply = NetReq(UpdVerUrl).get(); ConnReply(reply, this) [=] { auto err = errStr(reply); if(! err.isEmpty()) { @@ -567,11 +568,11 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { fdDetectCard->setCursor(Qt::PointingHandCursor); fdDetectCard->setProperty("ssType", "progManageTool"); connect(fdDetectCard, &QPushButton::clicked, this, [this] { - auto res = QMessageBox::warning(this, tr("Tip Info"), tr("RestoreLedCardIpByUdpTip"), QMessageBox::Ok, QMessageBox::Cancel); + auto res = QMessageBox::warning(this, translate("","Tip"), tr("RestoreLedCardIpByUdpTip"), QMessageBox::Ok, QMessageBox::Cancel); if(res != QMessageBox::Ok) return; QList networkinterfaces = QNetworkInterface::allInterfaces(); - foreach(QNetworkInterface interfaces, networkinterfaces) {//networkinterfaces负责提供主机的IP地址和网络接口的列表 - foreach(QNetworkAddressEntry entry, interfaces.addressEntries()) {//QNetworkAddressEntry存储了一个IP地址,子网掩码和广播地址 + for(QNetworkInterface &interfaces : networkinterfaces) {//networkinterfaces负责提供主机的IP地址和网络接口的列表 + for(QNetworkAddressEntry &entry : interfaces.addressEntries()) {//QNetworkAddressEntry存储了一个IP地址,子网掩码和广播地址 entry.setBroadcast(QHostAddress::Broadcast); QHostAddress broadcastAddress("255.255.255.255"); entry.setBroadcast(QHostAddress::Broadcast); @@ -617,6 +618,8 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) { hBox->addLabel("V" APP_VERSION" - " __DATE__); gApkHome = settings.value("ApkHome").toString(); + gProgWidth = settings.value("ProgWidth", 512).toInt(); + gProgHeight = settings.value("ProgHeight", 256).toInt(); gVideoCompress = settings.value("VideoCompress").toBool(); gVideoTranscoding = settings.value("VideoTranscoding").toBool(); gTextAntialiasing = settings.value("TextAntialiasing").toBool(); @@ -680,6 +683,8 @@ MainWindow::~MainWindow() { settings.setValue("MainIsMax", isMaximized()); settings.setValue("PlayPos", gPlayPos); if(! gApkHome.isEmpty()) settings.setValue("ApkHome", gApkHome); + settings.setValue("ProgWidth", gProgWidth); + settings.setValue("ProgHeight", gProgHeight); if(mDevicePanel->fdIP) { auto ipstr = mDevicePanel->fdIP->toPlainText(); if(! ipstr.isEmpty()) settings.setValue("SpecifyIP", ipstr); diff --git a/LedOK/mguangyingpinwidget.cpp b/LedOK/mguangyingpinwidget.cpp index 141fe98..47c5a3e 100644 --- a/LedOK/mguangyingpinwidget.cpp +++ b/LedOK/mguangyingpinwidget.cpp @@ -383,8 +383,8 @@ mGuangYingPinWidget::mGuangYingPinWidget(QWidget *parent) : QWidget(parent) { } connect(grp, &QButtonGroup::idClicked, this, [=](int id) { if(groupBox_com->isChecked()) { - if(pushButtonMainOpen->text()==tr("Close")) Set_program_buf_and_send(comboBox_SPortName->currentIndex(), id); - if(pushButtonAuxOpen->text()==tr("Close")) Set_program_buf_and_send(comboBox_SPortNameAux->currentIndex(), id); + if(pushButtonMainOpen->text()==translate("","Close")) Set_program_buf_and_send(comboBox_SPortName->currentIndex(), id); + if(pushButtonAuxOpen->text()==translate("","Close")) Set_program_buf_and_send(comboBox_SPortNameAux->currentIndex(), id); } if(groupBox_Network->isChecked()) Set_program_buf_and_send_by_udp(id); }); @@ -609,13 +609,13 @@ void mGuangYingPinWidget::changeEvent(QEvent *event) { if(event->type() == QEvent::LanguageChange) transUi(); } void mGuangYingPinWidget::transUi() { - pushButtonSend->setText(tr("Send")); + pushButtonSend->setText(translate("","Send")); pushButtonMainOpen->setText(tr("Open")); pushButtonAuxOpen->setText(tr("Open")); - pushButtonBrightnessSet->setText(tr("Set")); + pushButtonBrightnessSet->setText(translate("","Set")); pushButtonScreenOn->setText(tr("Screen On")); pushButtonScreenOff->setText(tr("Screen Off")); - pushButtonRefresh->setText(tr("Refresh")); + pushButtonRefresh->setText(translate("","Refresh")); groupBoxMain->setTitle(tr("Main")); groupBoxAux->setTitle(tr("Auxiliary")); groupBoxParam->setTitle(tr("Param configuration")); @@ -636,7 +636,7 @@ void mGuangYingPinWidget::transUi() { label_BrightNess->setText(tr("Brightness")); label_ComStatus->setText(tr("State:Off")); label_ComStatusAux->setText(tr("State:Off")); - pushButtonClearLog->setText(tr("Clear")); + pushButtonClearLog->setText(translate("","Clear")); checkBoxDebug->setText(tr("Debug")); groupBox_Network->setTitle(tr("Network")); groupBox_com->setTitle(tr("Com")); @@ -650,24 +650,24 @@ void mGuangYingPinWidget::OnAnsyProgramCustom(void) { int id = spinBox_ProgramIndex->value(); if(groupBox_com->isChecked()) { - if(pushButtonMainOpen->text()==tr("Close")) Set_program_buf_and_send(comboBox_SPortName->currentIndex(), id); - if(pushButtonAuxOpen->text()==tr("Close")) Set_program_buf_and_send(comboBox_SPortNameAux->currentIndex(), id); + if(pushButtonMainOpen->text()==translate("","Close")) Set_program_buf_and_send(comboBox_SPortName->currentIndex(), id); + if(pushButtonAuxOpen->text()==translate("","Close")) Set_program_buf_and_send(comboBox_SPortNameAux->currentIndex(), id); } if(groupBox_Network->isChecked()) Set_program_buf_and_send_by_udp(id); if(checkBoxDebug->isChecked()) textEditReadBuf->append("OnAnsyProgramCustom"); } void mGuangYingPinWidget::OnAnsyProgramCustomByChanged(int id) { if(groupBox_com->isChecked()) { - if(pushButtonMainOpen->text()==tr("Close")) Set_program_buf_and_send(comboBox_SPortName->currentIndex(), id); - if(pushButtonAuxOpen->text()==tr("Close")) Set_program_buf_and_send(comboBox_SPortNameAux->currentIndex(), id); + if(pushButtonMainOpen->text()==translate("","Close")) Set_program_buf_and_send(comboBox_SPortName->currentIndex(), id); + if(pushButtonAuxOpen->text()==translate("","Close")) Set_program_buf_and_send(comboBox_SPortNameAux->currentIndex(), id); } if(groupBox_Network->isChecked()) Set_program_buf_and_send_by_udp(id); } void mGuangYingPinWidget::OnBrightnessSetByChanged(int icurValue) { - if(pushButtonMainOpen->text()==tr("Close")) + if(pushButtonMainOpen->text()==translate("","Close")) Set_Brightness_buf_and_send(comboBox_SPortName->currentIndex(),icurValue); - if(pushButtonAuxOpen->text()==tr("Close")) + if(pushButtonAuxOpen->text()==translate("","Close")) Set_Brightness_buf_and_send(comboBox_SPortNameAux->currentIndex(),icurValue); } @@ -686,9 +686,9 @@ void mGuangYingPinWidget::OnBrightnessSet(void) { if(groupBox_com->isChecked()) { - if(pushButtonMainOpen->text()==tr("Close")) + if(pushButtonMainOpen->text()==translate("","Close")) Set_Brightness_buf_and_send(comboBox_SPortName->currentIndex(),spinBox_BrightnessValue->value()); - if(pushButtonAuxOpen->text()==tr("Close")) + if(pushButtonAuxOpen->text()==translate("","Close")) Set_Brightness_buf_and_send(comboBox_SPortNameAux->currentIndex(),spinBox_BrightnessValue->value()); } @@ -701,9 +701,9 @@ void mGuangYingPinWidget::OnScreenOn(void) { if(groupBox_com->isChecked()) { - if(pushButtonMainOpen->text()==tr("Close")) + if(pushButtonMainOpen->text()==translate("","Close")) Screen_OnOff_buf_and_send(comboBox_SPortName->currentIndex(),0x11); - if(pushButtonAuxOpen->text()==tr("Close")) + if(pushButtonAuxOpen->text()==translate("","Close")) Screen_OnOff_buf_and_send(comboBox_SPortNameAux->currentIndex(),0x11); } if(groupBox_Network->isChecked()) @@ -715,9 +715,9 @@ void mGuangYingPinWidget::OnScreenOff(void) { if(groupBox_com->isChecked()) { - if(pushButtonMainOpen->text()==tr("Close")) + if(pushButtonMainOpen->text()==translate("","Close")) Screen_OnOff_buf_and_send(comboBox_SPortName->currentIndex(),0x10); - if(pushButtonAuxOpen->text()==tr("Close")) + if(pushButtonAuxOpen->text()==translate("","Close")) Screen_OnOff_buf_and_send(comboBox_SPortNameAux->currentIndex(),0x10); } if(groupBox_Network->isChecked()) @@ -854,13 +854,13 @@ void mGuangYingPinWidget::MWOnoffPort(void) comboBox_SPortDataBit->setEnabled(false); comboBox_SPortOEBit->setEnabled(false); comboBox_SPortStopBit->setEnabled(false); - pushButtonMainOpen->setText(tr("Close")); + pushButtonMainOpen->setText(translate("","Close")); //发送设置使能 graphicsView_ComStatus->setStyleSheet("background-color: rgb(0, 255, 0);"); label_ComStatus->setText(tr("State:On")); } else { - QMessageBox::information(this, tr("Tip"), tr("OpenPort COM failed")); + QMessageBox::information(this, translate("","Tip"), tr("OpenPort COM failed")); } @@ -926,14 +926,14 @@ void mGuangYingPinWidget::MWOnoffPortAux(void) comboBox_SPortDataBitAux->setEnabled(false); comboBox_SPortOEBitAux->setEnabled(false); comboBox_SPortStopBitAux->setEnabled(false); - pushButtonAuxOpen->setText(tr("Close")); + pushButtonAuxOpen->setText(translate("","Close")); //发送设置使能 graphicsView_ComStatusAux->setStyleSheet("background-color: rgb(0, 255, 0);"); label_ComStatusAux->setText(tr("State:On")); } else { - QMessageBox::information(this, tr("Tip"), tr("OpenPort COM failed")); + QMessageBox::information(this, translate("","Tip"), tr("OpenPort COM failed")); } } diff --git a/LedOK/player/playwin.cpp b/LedOK/player/playwin.cpp index 4789d90..419a7af 100644 --- a/LedOK/player/playwin.cpp +++ b/LedOK/player/playwin.cpp @@ -1,4 +1,5 @@ #include "playwin.h" +#include "main.h" #include "eledigiclock.h" #include "eleanaclock.h" #include "eleborder.h" @@ -198,7 +199,7 @@ PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const JValue PosDlg dlg(this); dlg.exec(); }); - act = menu->addAction(tr("Close")); + act = menu->addAction(translate("","Close")); connect(act, &QAction::triggered, this, [this] { if(self==this) self = nullptr; close(); diff --git a/LedOK/progpanel.cpp b/LedOK/progpanel.cpp index 5fa2a30..201eadb 100644 --- a/LedOK/progpanel.cpp +++ b/LedOK/progpanel.cpp @@ -12,6 +12,7 @@ #include #include #include +#include ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { setAttribute(Qt::WA_DeleteOnClose); @@ -29,11 +30,11 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { vBox->addLayout(hBox); bnNew = new QPushButton(tr("New")); - bnNew->setFixedSize(88, 38); + bnNew->setMinimumSize(75, 30); bnNew->setProperty("ssType", "progManageTool"); hBox->addWidget(bnNew); connect(bnNew, &QPushButton::clicked, this, [this] { - ProgCreateDlg dlg("", 512, 256, "", "", false, this); + ProgCreateDlg dlg("", gProgWidth, gProgHeight, "", "", false, this); if(dlg.exec() != QDialog::Accepted) return; if(checkIfNameRepeated(dlg.fdName->text())) return; std::vector widths; @@ -58,7 +59,7 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { if(ttl > width) widths.back() -= ttl - width; } } - auto item = new ProgItem(mProgsDir, dlg.fdName->text(), dlg.fdWidth->value(), dlg.fdHeight->value(), dlg.fdRemark->toPlainText(), widths, max, dlg.fdVer->isChecked(), mProgTree); + auto item = new ProgItem(mProgsDir, dlg.fdName->text(), gProgWidth = dlg.fdWidth->value(), gProgHeight = dlg.fdHeight->value(), dlg.fdRemark->toPlainText(), widths, max, dlg.fdVer->isChecked(), mProgTree); item->isInsert = dlg.edIsInsert->isChecked(); item->save();//保存pro.json if(mProgTree->fdCheckAll->checkState()==Qt::Checked) { @@ -71,70 +72,67 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { }); bnEdit = new QPushButton(tr("Edit")); - bnEdit->setFixedSize(QSize(88, 38)); + bnEdit->setMinimumSize(75, 30); bnEdit->setProperty("ssType", "progManageTool"); bnEdit->setEnabled(false); hBox->addWidget(bnEdit); connect(bnEdit, SIGNAL(clicked(bool)), this, SLOT(onEditClicked(bool))); bnDelete = new QPushButton(tr("Delete")); - bnDelete->setFixedSize(QSize(88, 38)); + bnDelete->setMinimumSize(75, 30); bnDelete->setProperty("ssType", "progManageTool"); bnDelete->setEnabled(false); hBox->addWidget(bnDelete); connect(bnDelete, SIGNAL(clicked(bool)), this, SLOT(onDeleteClicked(bool))); bnImport = new QPushButton(tr("Import")); - bnImport->setFixedSize(88, 38); + bnImport->setMinimumSize(75, 30); bnImport->setProperty("ssType", "progManageTool"); hBox->addWidget(bnImport); connect(bnImport, &QPushButton::clicked, this, [this] { auto dir = QFileDialog::getExistingDirectory(this, tr("Choose Directory"), "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if(dir.isEmpty()) return; - QString progsDir = programsDir(); + auto progsDir = programsDir(); if(dir.contains(progsDir, Qt::CaseInsensitive)) { - QMessageBox::warning(this, tr("Tip"), tr("The imported directory is already in the working directory, so there is no need to import it again!")); + QMessageBox::warning(this, translate("","Tip"), tr("The imported directory is already in the working directory, so there is no need to import it again!")); return; } - QStringList progDirs; - if(QFileInfo::exists(dir + "/pro.json")) progDirs.append(dir); + PathPairList pathPairs; + if(QFileInfo::exists(dir + "/pro.json")) pathPairs.append({dir, progsDir+"/"+QFileInfo(dir).fileName()}); else { QStringList subdirNames = QDir(dir).entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); for(QString &subdirName : subdirNames) { auto subdir = dir + "/" + subdirName; if(! QFileInfo::exists(subdir + "/pro.json")) continue; if(QFileInfo::exists(progsDir + "/" + subdirName)) { - auto res = QMessageBox::information(this, tr("Tip Info"), subdirName + tr(":solution(s) already exist.are you sure you want to overwrite the existing solution(s)?"), QMessageBox::Yes, QMessageBox::No); + auto res = QMessageBox::information(this, translate("","Tip"), subdirName + tr(":solution(s) already exist.are you sure you want to overwrite the existing solution(s)?"), QMessageBox::Yes, QMessageBox::No); if(res == QMessageBox::No) continue; } - progDirs.append(subdir); + pathPairs.append({subdir, progsDir+"/"+subdirName}); } - if(progDirs.isEmpty()) return; + if(pathPairs.isEmpty()) return; } ProgPortDlg dlg(this, tr("Import")); - dlg.table->setRowCount(progDirs.count()); - for(int i=0; isetItem(i, 0, new QTableWidgetItem(QFileInfo(progDirs[i]).fileName())); + dlg.table->setRowCount(pathPairs.count()); + for(int i=0; isetItem(i, 0, new QTableWidgetItem(QFileInfo(pathPairs[i].first).fileName())); dlg.table->setCellWidget(i, 1, new QProgressBar); } connect(dlg.bnOK, &QPushButton::clicked, this, [=, &dlg] { - for(int i=0; icellWidget(i, 1))->setMaximum(dirFileSize(progDirs[i])); - auto thread = new CopyDirThread(); - thread->dirSrcs = progDirs; - thread->dirDst = progsDir; + for(int i=0; icellWidget(i, 1))->setMaximum(dirFileSize(pathPairs[i].first)); + auto thread = new CopyDirThread; + thread->paths = pathPairs; connect(thread, &CopyDirThread::sigProgress, &dlg, [&dlg](int i, int value) { ((QProgressBar*)dlg.table->cellWidget(i, 1))->setValue(value); }); thread->start(); }); dlg.exec(); - - mProgTree->clear(); addProFiles(); }); bnExport = new QPushButton(tr("Export")); - bnExport->setFixedSize(QSize(88, 38)); + bnExport->setMinimumSize(75, 30); bnExport->setEnabled(false); bnExport->setProperty("ssType", "progManageTool"); hBox->addWidget(bnExport); @@ -151,16 +149,15 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { dlg.table->setCellWidget(i, 1, new QProgressBar); } connect(dlg.bnOK, &QPushButton::clicked, this, [=, &dlg] { - QString dirDst = QFileDialog::getExistingDirectory(this, tr("Choose Directory"), "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + auto dirDst = QFileDialog::getExistingDirectory(this, tr("Choose Directory"), "/home", QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); if(dirDst.isEmpty()) return; auto progsDir = programsDir(); - auto thread = new CopyDirThread(); + auto thread = new CopyDirThread; for(int i=0; icellWidget(i, 1))->setMaximum(dirFileSize(dir)); - thread->dirSrcs.append(dir); + thread->paths.append({dir, dirDst+"/"}); } - thread->dirDst = dirDst; connect(thread, &CopyDirThread::sigProgress, &dlg, [&dlg](int i, int value) { ((QProgressBar*)dlg.table->cellWidget(i, 1))->setValue(value); }); @@ -169,15 +166,75 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { dlg.exec(); }); - bnSend = new QPushButton(tr("Send")); - bnSend->setFixedSize(QSize(88, 38)); + bnRename = new QPushButton(tr("Rename")); + bnRename->setMinimumSize(60, 30); + bnRename->setProperty("ssType", "progManageTool"); + hBox->addWidget(bnRename); + connect(bnRename, &QPushButton::clicked, this, [=] { + int cnt = mProgTree->topLevelItemCount(); + QString progName; + for(int i=0; iitem(i)->checkState("check") == Qt::Checked) { + progName = ((ProgItem*) mProgTree->topLevelItem(i))->mName; + break; + } + if(progName.isEmpty()) return; + bool ok = false; + auto newName = QInputDialog::getText(this, "Rename '"+progName+"'", "New Name", QLineEdit::Normal, "", &ok); + if(! ok) return; + if(newName.isEmpty()) { + QMessageBox::warning(this, "Warning", "New Name is Empty"); + return; + } + auto progsDir = programsDir(); + auto res = QDir(progsDir).rename(progName, newName); + if(res) addProFiles(); + else QMessageBox::warning(this, "Error", "Rename Failed"); + }); + // bnCopy = new QPushButton(tr("Copy")); + // bnCopy->setMinimumSize(60, 30); + // bnCopy->setProperty("ssType", "progManageTool"); + // hBox->addWidget(bnCopy); + // connect(bnCopy, &QPushButton::clicked, this, [=] { + // int cnt = mProgTree->topLevelItemCount(); + // QString progName; + // for(int i=0; iitem(i)->checkState("check") == Qt::Checked) { + // progName = ((ProgItem*) mProgTree->topLevelItem(i))->mName; + // break; + // } + // if(progName.isEmpty()) return; + // bool ok = false; + // auto newName = QInputDialog::getText(this, "Copy '"+progName+"'", "New Name", QLineEdit::Normal, "", &ok); + // if(! ok) return; + // if(newName.isEmpty()) { + // QMessageBox::warning(this, "Warning", "New Name is Empty"); + // return; + // } + // auto progsDir = programsDir(); + // auto dir = progsDir+"/"+progName; + // QDialog dlg(this); + // auto vBox = new VBox(&dlg); + // auto edProgress = new QProgressBar; + // edProgress->setMaximum(dirFileSize(dir)); + // vBox->addWidget(edProgress); + // auto thread = new CopyDirThread; + // thread->paths.append({dir, progsDir+"/"+newName}); + // connect(thread, &CopyDirThread::sigProgress, edProgress, [=](int value) { + // edProgress->setValue(value); + // if(value>=edProgress->maximum()) addProFiles(); + // }); + // progress->show(); + // thread->start(); + // }); + + bnSend = new QPushButton(translate("","Send")); + bnSend->setMinimumSize(75, 30); bnSend->setProperty("ssType", "progManageTool"); bnSend->setEnabled(false); bnSend->hide(); hBox->addWidget(bnSend); btnPlay = new QPushButton(tr("Play")+"/"+tr("Stop")); - btnPlay->setFixedSize(QSize(88, 38)); + btnPlay->setMinimumSize(75, 30); btnPlay->setProperty("ssType", "progManageTool"); hBox->addWidget(btnPlay); connect(btnPlay, &QPushButton::clicked, this, [this] { @@ -251,7 +308,7 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { auto str = ((ProgItem*)item)->mProgDir; QProcess::execute("explorer", {str.replace('/','\\')}); #endif -#ifdef Q_OS_MACOS +#ifdef Q_OS_MAC QProcess::execute("open", {"-R", ((ProgItem*)item)->mProgDir}); #endif }); @@ -269,16 +326,14 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) { QDir oldProgsQDir(oldProgsDir); if(oldProgsQDir.exists()) { CopyDirThread thread; - thread.dirDst = mProgsDir; auto names = oldProgsQDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); - for(auto &name : names) if(! name.endsWith("_tmp")) thread.dirSrcs.append(oldProgsDir + "/" + name); - if(! thread.dirSrcs.isEmpty()) thread.move(); + for(auto &name : names) if(! name.endsWith("_tmp")) thread.paths.append({oldProgsDir+"/"+name, mProgsDir+"/"+name}); + if(! thread.paths.isEmpty()) thread.move(); oldProgsQDir.removeRecursively(); } } } - //查找根路径下的项目文件夹,查找文件夹下的节目pro.json信息,包括节目名称,大小,像素,备注等信息 - if(! mProgsDir.isEmpty()) addProFiles(); + addProFiles(); QSettings settings; if(settings.value("ProgramListSortOrder").toInt()==0) mProgTree->sortByColumn(settings.value("ProgramListSortColumn").toInt(),Qt::SortOrder::AscendingOrder); else mProgTree->sortByColumn(settings.value("ProgramListSortColumn").toInt(),Qt::SortOrder::DescendingOrder); @@ -302,12 +357,15 @@ void ProgPanel::transUi() { bnDelete->setText(tr("Delete")); bnImport->setText(tr("Import")); bnExport->setText(tr("Export")); - bnSend->setText(tr("Send")); + bnRename->setText(tr("Rename")); + bnSend->setText(translate("","Send")); btnPlay->setText(tr("Play")+"/"+tr("Stop")); } void ProgPanel::addProFiles() { + if(mProgsDir.isEmpty()) return; auto progNames = QDir(mProgsDir).entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); + mProgTree->clear(); for(auto &progName : progNames) { auto file = mProgsDir + "/" + progName + "/pro.json"; QFile qFile(file); @@ -365,7 +423,7 @@ bool ProgPanel::checkIfNameRepeated(const QString &name, QTreeWidgetItem *skip){ return false; } void ProgPanel::onDeleteClicked(bool){ - auto res = QMessageBox::information(this, tr("Tip Info"), tr("You will delete the selected solution(s),are you sure?"), QMessageBox::Ok, QMessageBox::Cancel); + auto res = QMessageBox::information(this, translate("","Tip"), tr("You will delete the selected solution(s),are you sure?"), QMessageBox::Ok, QMessageBox::Cancel); if(res == QMessageBox::Ok) { for(int i=0; itopLevelItemCount(); i++) if(mProgTree->item(i)->checkState("check") == Qt::Checked) { auto item = (ProgItem*) mProgTree->topLevelItem(i--); diff --git a/LedOK/progpanel.h b/LedOK/progpanel.h index 3ad6b88..b5c5e46 100644 --- a/LedOK/progpanel.h +++ b/LedOK/progpanel.h @@ -28,7 +28,7 @@ private: QPushButton *bnNew; QPushButton *bnEdit; QPushButton *bnDelete; - QPushButton *bnImport, *bnExport; + QPushButton *bnImport, *bnExport, *bnRename, *bnCopy; QPushButton *bnSend, *btnPlay; }; diff --git a/LedOK/program/copydirthread.cpp b/LedOK/program/copydirthread.cpp index 4d34047..45707ff 100644 --- a/LedOK/program/copydirthread.cpp +++ b/LedOK/program/copydirthread.cpp @@ -6,9 +6,9 @@ CopyDirThread::CopyDirThread() { } void CopyDirThread::run() { - for(; i +using PathPairList = QList>; + class CopyDirThread : public QThread { Q_OBJECT public: CopyDirThread(); - QStringList dirSrcs; - QString dirDst; + PathPairList paths; void run(); void move(); protected: bool copyDir(const QString &fromDir, const QString &toDir, bool coverFileIfExist); bool moveDir(const QString &fromDir, const QString &toDir); - int i{0}; + int i = 0; int copiedSize = 0; signals: void sigProgress(int, int); diff --git a/LedOK/program/eaclock.cpp b/LedOK/program/eaclock.cpp index bcbe799..783bf99 100644 --- a/LedOK/program/eaclock.cpp +++ b/LedOK/program/eaclock.cpp @@ -201,7 +201,7 @@ QWidget* EAClock::attrWgt() { addBaseAttrWgt(vBox); auto hBox = new HBox(vBox); - hBox->addWidget(new QLabel(tr("Basic Properties"))); + hBox->addWidget(new QLabel(translate("","Basic Properties"))); auto line = new QFrame; line->setFrameShape(QFrame::HLine); diff --git a/LedOK/program/ebase.cpp b/LedOK/program/ebase.cpp index f36c668..37649ea 100644 --- a/LedOK/program/ebase.cpp +++ b/LedOK/program/ebase.cpp @@ -1,6 +1,6 @@ #include "ebase.h" #include "gutil/qgui.h" -#include "tools.h" +#include "main.h" #include #include #include @@ -20,11 +20,11 @@ int borderImgMaxWidth = 0; int borderImgMaxHeight = 0; struct Initer { Initer() { - auto names = QDir(QApplication::applicationDirPath()+"/borders").entryList(QDir::Files); + auto names = QDir(QCoreApplication::applicationDirPath()+"/borders").entryList(QDir::Files); for(auto &name : names) { BorderImg bdImg; bdImg.name = name; - bdImg.img = QPixmap(QApplication::applicationDirPath()+"/borders/"+bdImg.name); + bdImg.img = QPixmap(QCoreApplication::applicationDirPath()+"/borders/"+bdImg.name); borderImgs.append(bdImg); if(bdImg.img.width() > borderImgMaxWidth) borderImgMaxWidth = bdImg.img.width(); if(bdImg.img.height() > borderImgMaxHeight) borderImgMaxHeight = bdImg.img.height(); diff --git a/LedOK/program/edclock.cpp b/LedOK/program/edclock.cpp index 483151e..c8ec688 100644 --- a/LedOK/program/edclock.cpp +++ b/LedOK/program/edclock.cpp @@ -1,8 +1,8 @@ #include "edclock.h" #include "base/locolorselector.h" #include "main.h" -#include "tools.h" #include "gutil/qgui.h" +#include "tools.h" #include #include #include @@ -11,22 +11,7 @@ EDClock::EDClock(EBase *multiWin) : EBase(multiWin) { mType = EBase::DClock; - m_attr.timeZoneId = QTimeZone::systemTimeZoneId(); - m_attr.font = qfont("Arial", 12); - m_attr.year = true; - m_attr.month = true; - m_attr.day = true; - m_attr.hour = true; - m_attr.min = true; - m_attr.sec = true; - m_attr.weekly = true; - m_attr.fullYear = true; - m_attr.hour12 = true; - m_attr.AmPm = true; - m_attr.dateStyle = 0; - m_attr.timeStyle = 0; - m_attr.multiline = true; - m_attr.textColor = Qt::red; + timeZone = QTimeZone::systemTimeZone(); init(); } @@ -34,31 +19,49 @@ EDClock::EDClock(const JObj &json, EBase *multiWin) : EBase(multiWin) { mType = EBase::DClock; setBaseAttr(json); auto widget = json["widget"]; - auto font = widget["font"]; - m_attr.font = qfont(font["family"].toString(), font["size"].toInt(), font["bold"].toBool(), font["italics"].toBool()); - m_attr.font.setUnderline(font["underline"].toBool()); - m_attr.textColor = Tools::int2Color(font["color"].toInt()); - m_attr.timeZoneId = widget["timeZone"].toString().toUtf8(); - m_attr.year = widget["year"].toBool(); - m_attr.month = widget["month"].toBool(); - m_attr.day = widget["day"].toBool(); - m_attr.hour = widget["hour"].toBool(); - m_attr.min = widget["min"].toBool(); - m_attr.sec = widget["sec"].toBool(); - m_attr.weekly = widget["weekly"].toBool(); - m_attr.fullYear = widget["fullYear"].toBool(); - m_attr.hour12 = widget["12Hour"].toBool(); - m_attr.AmPm = widget["AmPm"].toBool(); - m_attr.dateStyle = widget["dateStyle"].toInt(); - m_attr.timeStyle = widget["timeStyle"].toInt(); - m_attr.multiline = widget["multiline"].toBool(); - 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; + if(widget.isNull()) { + widget = json; + font = qfont(json["font"].toString(), json["fontSize"].toInt(), json["fontBold"].toBool(), json["fontItalic"].toBool()); + font.setUnderline(json["fontUnderline"].toBool()); + color = json["color"].toStr("#ffff0000"); + hasYear = widget["hasYear"].toBool(); + hasMonth = widget["hasMonth"].toBool(); + hasDay = widget["hasDay"].toBool(); + hasHour = widget["hasHour"].toBool(); + hasMin = widget["hasMin"].toBool(); + hasSec = widget["hasSec"].toBool(); + hasWeek = widget["hasWeek"].toBool(); + hasAmPm = widget["hasAmPm"].toBool(); + is12Hour = widget["is12Hour"].toBool(); + isFullYear = widget["isFullYear"].toBool(); + isMultiline = json["isMultiline"].toBool(); + } else { + auto font = widget["font"]; + this->font = qfont(font["family"].toString(), font["size"].toInt(), font["bold"].toBool(), font["italics"].toBool()); + this->font.setUnderline(font["underline"].toBool()); + color = Tools::int2Color(font["color"].toInt()); + hasYear = widget["year"].toBool(); + hasMonth = widget["month"].toBool(); + hasDay = widget["day"].toBool(); + hasHour = widget["hour"].toBool(); + hasMin = widget["min"].toBool(); + hasSec = widget["sec"].toBool(); + hasWeek = widget["weekly"].toBool(); + hasAmPm = widget["AmPm"].toBool(); + is12Hour = widget["12Hour"].toBool(); + isFullYear = widget["fullYear"].toBool(); + isMultiline = widget["multiline"].toBool(); + } + timeZone = QTimeZone(widget["timeZone"].toString().toUtf8()); + dateStyle = widget["dateStyle"].toInt(); + isSingleHour = widget["timeStyle"].toInt(); + isSingleMD = dateStyle==1||dateStyle==2||dateStyle==4||dateStyle==6||dateStyle==8||dateStyle==10||dateStyle==12; init(); } void EDClock::init() { connect(gTick, &Tick::secChanged, this, [this](const QDateTime &cur) { - datetime = cur.toTimeZone(QTimeZone(m_attr.timeZoneId)); + datetime = cur.toTimeZone(timeZone); update(); }); } @@ -67,35 +70,35 @@ void EDClock::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q QString text; QDate date = datetime.date(); QTime time = datetime.time(); - QString spacer = m_attr.multiline ? "\n" : " "; - QString yearFmt = m_attr.fullYear ? "yyyy" : "yy"; + QString spacer = isMultiline ? "\n" : " "; + QString yearFmt = isFullYear ? "yyyy" : "yy"; QString monthFmt = isSingleMD ? "M" : "MM"; QString dateFmt = isSingleMD ? "d" : "dd"; QString sep; - if(m_attr.dateStyle > 7) sep = "-"; - else if(m_attr.dateStyle > 1) sep = "/"; - switch(m_attr.dateStyle) { + if(dateStyle > 7) sep = "-"; + else if(dateStyle > 1) sep = "/"; + switch(dateStyle) { case 0: case 1: - if(m_attr.year) text += date.toString(yearFmt) + "年"; - if(m_attr.month) text += date.toString(monthFmt) + "月"; - if(m_attr.day) text += date.toString(dateFmt) + "日"; + if(hasYear) text += date.toString(yearFmt) + "年"; + if(hasMonth) text += date.toString(monthFmt) + "月"; + if(hasDay) text += date.toString(dateFmt) + "日"; break; case 2: case 3: case 8: case 9: - if(m_attr.month) text += date.toString(monthFmt) + sep; - if(m_attr.day) text += date.toString(dateFmt) + sep; - if(m_attr.year) text += date.toString(yearFmt); + if(hasMonth) text += date.toString(monthFmt) + sep; + if(hasDay) text += date.toString(dateFmt) + sep; + if(hasYear) text += date.toString(yearFmt); if(text.endsWith(sep)) text.chop(1); break; case 4: case 5: case 10: case 11: - if(m_attr.day) text += date.toString(dateFmt) + sep; - if(m_attr.month) text += date.toString(monthFmt) + sep; - if(m_attr.year) text += date.toString(yearFmt); + if(hasDay) text += date.toString(dateFmt) + sep; + if(hasMonth) text += date.toString(monthFmt) + sep; + if(hasYear) text += date.toString(yearFmt); if(text.endsWith(sep)) text.chop(1); break; case 6: case 7: case 12: case 13: - if(m_attr.year) text += date.toString(yearFmt) + sep; - if(m_attr.month) text += date.toString(monthFmt) + sep; - if(m_attr.day) text += date.toString(dateFmt); + if(hasYear) text += date.toString(yearFmt) + sep; + if(hasMonth) text += date.toString(monthFmt) + sep; + if(hasDay) text += date.toString(dateFmt); if(text.endsWith(sep)) text.chop(1); break; default: @@ -103,7 +106,7 @@ void EDClock::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q } if(! text.isEmpty()) text += spacer; - if(m_attr.weekly) { + if(hasWeek) { auto dayOfWeek = date.dayOfWeek(); if(dayOfWeek==1) text += tr("MON"); else if(dayOfWeek==2) text += tr("TUE"); @@ -115,18 +118,24 @@ void EDClock::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, Q text += spacer; } QString timeFmt; - if(m_attr.hour12 && m_attr.AmPm) timeFmt += (time.hour()<12 ? tr("AM") : tr("PM")) + " "; - if(m_attr.hour) timeFmt += (m_attr.timeStyle!=1 ? "hh:" : "h:"); - if(m_attr.min) timeFmt += "mm:"; - if(m_attr.sec) timeFmt += "ss"; + if(is12Hour && hasAmPm) timeFmt += (time.hour()<12 ? tr("AM") : tr("PM")) + " "; + if(hasHour) timeFmt += (isSingleHour ? "h:" : "hh:"); + if(hasMin) timeFmt += "mm:"; + if(hasSec) timeFmt += "ss"; if(timeFmt.endsWith(":")) timeFmt.chop(1); if(! timeFmt.isEmpty()) text += time.toString(timeFmt); text = text.trimmed(); + auto lines = text.split("\n"); + auto rect = innerRect(); + if(lines.size() > 1) rect.setHeight(lineHeight = rect.height() / lines.size()); painter->save(); - painter->setPen(m_attr.textColor); - m_attr.font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias); - painter->setFont(m_attr.font); - painter->drawText(innerRect(), text, QTextOption(Qt::AlignCenter)); + painter->setPen(color); + font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias); + painter->setFont(font); + for(auto &line : lines) { + painter->drawText(rect, line, QTextOption(Qt::AlignCenter)); + rect.translate(0, rect.height()); + } painter->restore(); EBase::paint(painter, option, widget); } @@ -135,12 +144,12 @@ QWidget* EDClock::attrWgt() { auto wgtAttr = new QWidget(); auto vBox = new QVBoxLayout(wgtAttr); vBox->setContentsMargins(6, 0, 6, 0); - if(mMultiWin!=nullptr) vBox->setSpacing(3); + if(mMultiWin) vBox->setSpacing(3); addBaseAttrWgt(vBox); auto hBox = new QHBoxLayout(); - hBox->addWidget(new QLabel(tr("Basic Properties"))); + hBox->addWidget(new QLabel(translate("","Basic Properties"))); auto line = new QFrame(); line->setFrameShape(QFrame::HLine); @@ -156,9 +165,9 @@ QWidget* EDClock::attrWgt() { auto edTimeZone = new QComboBox; auto zoneIds = QTimeZone::availableTimeZoneIds(); for(auto &zoneId : zoneIds) edTimeZone->addItem(zoneId); - edTimeZone->setCurrentText(m_attr.timeZoneId); + edTimeZone->setCurrentText(timeZone.id()); connect(edTimeZone, &QComboBox::currentTextChanged, this, [this](const QString &text) { - m_attr.timeZoneId = text.toUtf8(); + timeZone = QTimeZone(text.toUtf8()); update(); }); hBox->addWidget(edTimeZone); @@ -176,25 +185,25 @@ QWidget* EDClock::attrWgt() { hBox->addSpacing(6); auto fdYear = new QCheckBox(tr("Year")); - fdYear->setChecked(m_attr.year); + fdYear->setChecked(hasYear); connect(fdYear, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.year = checked; + hasYear = checked; update(); }); hBox->addWidget(fdYear); auto fdMonth = new QCheckBox(tr("Month")); - fdMonth->setChecked(m_attr.month); + fdMonth->setChecked(hasMonth); connect(fdMonth, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.month = checked; + hasMonth = checked; update(); }); hBox->addWidget(fdMonth); auto fdDay = new QCheckBox(tr("Day")); - fdDay->setChecked(m_attr.day); + fdDay->setChecked(hasDay); connect(fdDay, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.day = checked; + hasDay = checked; update(); }); hBox->addWidget(fdDay); @@ -205,25 +214,25 @@ QWidget* EDClock::attrWgt() { hBox->addSpacing(6); auto fdHour = new QCheckBox(tr("Hour")); - fdHour->setChecked(m_attr.hour); + fdHour->setChecked(hasHour); connect(fdHour, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.hour = checked; + hasHour = checked; update(); }); hBox->addWidget(fdHour); auto fdMin = new QCheckBox(tr("Min.")); - fdMin->setChecked(m_attr.min); + fdMin->setChecked(hasMin); connect(fdMin, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.min = checked; + hasMin = checked; update(); }); hBox->addWidget(fdMin); auto fdSec = new QCheckBox(tr("Sec.")); - fdSec->setChecked(m_attr.sec); + fdSec->setChecked(hasSec); connect(fdSec, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.sec = checked; + hasSec = checked; update(); }); hBox->addWidget(fdSec); @@ -233,17 +242,17 @@ QWidget* EDClock::attrWgt() { hBox = new QHBoxLayout(); hBox->addSpacing(6); auto fdHasWeek = new QCheckBox(tr("Weekly")); - fdHasWeek->setChecked(m_attr.weekly); + fdHasWeek->setChecked(hasWeek); connect(fdHasWeek, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.weekly = checked; + hasWeek = checked; update(); }); hBox->addWidget(fdHasWeek); auto fdFullYear = new QCheckBox(tr("Full Year")); - fdFullYear->setChecked(m_attr.fullYear); + fdFullYear->setChecked(isFullYear); connect(fdFullYear, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.fullYear = checked; + isFullYear = checked; update(); }); hBox->addWidget(fdFullYear); @@ -254,19 +263,19 @@ QWidget* EDClock::attrWgt() { hBox->addSpacing(6); auto fdIs12Hour = new QCheckBox(tr("12-Hour")); - fdIs12Hour->setChecked(m_attr.hour12); + fdIs12Hour->setChecked(is12Hour); hBox->addWidget(fdIs12Hour); auto fdAmPm = new QCheckBox(tr("AM")+"/"+tr("PM")); - fdAmPm->setChecked(m_attr.AmPm); + fdAmPm->setChecked(hasAmPm); connect(fdIs12Hour, &QCheckBox::toggled, this, [this, fdAmPm](bool checked) { - m_attr.hour12 = checked; + is12Hour = checked; fdAmPm->setVisible(checked); if(! checked) fdAmPm->setChecked(false); update(); }); connect(fdAmPm, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.AmPm = checked; + hasAmPm = checked; update(); }); hBox->addWidget(fdAmPm); @@ -282,24 +291,24 @@ QWidget* EDClock::attrWgt() { hBox->addSpacing(6); hBox->addWidget(new QLabel(tr("Date Style"))); - auto fdDateFmt = new QComboBox(); - fdDateFmt->addItem("1955年02月04日"); - fdDateFmt->addItem("1955年2月4日"); - fdDateFmt->addItem("2/24/1955"); - fdDateFmt->addItem("02/24/1955"); - fdDateFmt->addItem("24/2/1955"); - fdDateFmt->addItem("24/02/1955"); - fdDateFmt->addItem("1955/2/24"); - fdDateFmt->addItem("1955/02/24"); - fdDateFmt->addItem("2-24-1955"); - fdDateFmt->addItem("02-24-1955"); - fdDateFmt->addItem("24-2-1955"); - fdDateFmt->addItem("24-02-1955"); - fdDateFmt->addItem("1955-2-24"); - fdDateFmt->addItem("1955-02-24"); - fdDateFmt->setCurrentIndex(m_attr.dateStyle); - connect(fdDateFmt, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int index) { - m_attr.dateStyle = index; + auto fdDateFmt = new QComboBox; + fdDateFmt->addItem("1970-02-24", 13); + fdDateFmt->addItem("1970-2-24", 12); + fdDateFmt->addItem("1970年02月04日", 0); + fdDateFmt->addItem("1970年2月4日", 1); + fdDateFmt->addItem("1970/02/24", 7); + fdDateFmt->addItem("1970/2/24", 6); + fdDateFmt->addItem("02-24-1970", 9); + fdDateFmt->addItem("2-24-1970", 8); + fdDateFmt->addItem("02/24/1970", 3); + fdDateFmt->addItem("2/24/1970", 2); + fdDateFmt->addItem("24-02-1970", 11); + fdDateFmt->addItem("24-2-1970", 10); + fdDateFmt->addItem("24/02/1970", 5); + fdDateFmt->addItem("24/2/1970", 4); + SetCurData(fdDateFmt, dateStyle); + connect(fdDateFmt, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=](int index) { + dateStyle = fdDateFmt->itemData(index).toInt(); isSingleMD = index==1||index==2||index==4||index==6||index==8||index==10||index==12; update(); }); @@ -312,12 +321,12 @@ QWidget* EDClock::attrWgt() { hBox->addSpacing(6); hBox->addWidget(new QLabel(tr("Time Style"))); - auto fdTimeFmt = new QComboBox(); + auto fdTimeFmt = new QComboBox; fdTimeFmt->addItem("HH:MM:SS"); fdTimeFmt->addItem("H:MM:SS"); - fdTimeFmt->setCurrentIndex(m_attr.timeStyle); + fdTimeFmt->setCurrentIndex(isSingleHour); connect(fdTimeFmt, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int index) { - m_attr.timeStyle = index; + isSingleHour = index; update(); }); hBox->addWidget(fdTimeFmt); @@ -330,9 +339,9 @@ QWidget* EDClock::attrWgt() { hBox->addWidget(new QLabel(tr("Display Style"))); auto fdIsMultiline = new QCheckBox(tr("Multiline")); - fdIsMultiline->setChecked(m_attr.multiline); + fdIsMultiline->setChecked(isMultiline); connect(fdIsMultiline, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.multiline = checked; + isMultiline = checked; update(); }); hBox->addWidget(fdIsMultiline); @@ -340,7 +349,7 @@ QWidget* EDClock::attrWgt() { vBox->addLayout(hBox); - line = new QFrame(); + line = new QFrame; line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); vBox->addWidget(line); @@ -350,23 +359,23 @@ QWidget* EDClock::attrWgt() { auto fdFontFamily = new QFontComboBox(); fdFontFamily->setEditable(false); - fdFontFamily->setCurrentText(m_attr.font.family()); + fdFontFamily->setCurrentText(font.family()); connect(fdFontFamily, &QFontComboBox::currentFontChanged, this, [this](const QFont &f) { - QFont font(f.family()); - font.setPixelSize(m_attr.font.pixelSize()); - font.setBold(m_attr.font.bold()); - font.setItalic(m_attr.font.italic()); - font.setUnderline(m_attr.font.underline()); - m_attr.font = font; + QFont ft(f.family()); + ft.setPixelSize(font.pixelSize()); + ft.setBold(font.bold()); + ft.setItalic(font.italic()); + ft.setUnderline(font.underline()); + font = ft; update(); }); hBox->addWidget(fdFontFamily); auto fdFontSize = new QSpinBox(); fdFontSize->setRange(4, 9999); - fdFontSize->setValue(m_attr.font.pixelSize()); + fdFontSize->setValue(font.pixelSize()); connect(fdFontSize, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { - m_attr.font.setPixelSize(value); + font.setPixelSize(value); update(); }); hBox->addWidget(fdFontSize); @@ -381,9 +390,9 @@ QWidget* EDClock::attrWgt() { fdBold->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; font-weight: bold;} QPushButton:checked{background: #29c; color: #fff;}"); fdBold->setFixedSize(30, 30); fdBold->setCheckable(true); - fdBold->setChecked(m_attr.font.bold()); + fdBold->setChecked(font.bold()); connect(fdBold, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.font.setBold(checked); + font.setBold(checked); update(); }); hBox->addWidget(fdBold); @@ -392,9 +401,9 @@ QWidget* EDClock::attrWgt() { fdItalic->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; font-style: italic;} QPushButton:checked{background: #29c; color: #fff;}"); fdItalic->setFixedSize(30, 30); fdItalic->setCheckable(true); - fdItalic->setChecked(m_attr.font.italic()); + fdItalic->setChecked(font.italic()); connect(fdItalic, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.font.setItalic(checked); + font.setItalic(checked); update(); }); hBox->addWidget(fdItalic); @@ -403,17 +412,17 @@ QWidget* EDClock::attrWgt() { fdFontUnderline->setStyleSheet("QPushButton{background: #bbb; color: #888; font-size: 20px; text-decoration: underline;} QPushButton:checked{background: #29c; color: #fff;}"); fdFontUnderline->setFixedSize(30, 30); fdFontUnderline->setCheckable(true); - fdFontUnderline->setChecked(m_attr.font.underline()); + fdFontUnderline->setChecked(font.underline()); connect(fdFontUnderline, &QCheckBox::toggled, this, [this](bool checked) { - m_attr.font.setUnderline(checked); + font.setUnderline(checked); update(); }); hBox->addWidget(fdFontUnderline); - auto fdColor = new LoColorSelector("T", m_attr.textColor); + auto fdColor = new LoColorSelector("T", color); fdColor->setFixedWidth(30); connect(fdColor, &LoColorSelector::sColorChanged, this, [this](const QColor &color) { - m_attr.textColor = color; + this->color = color; update(); }); hBox->addWidget(fdColor); @@ -424,33 +433,30 @@ QWidget* EDClock::attrWgt() { return wgtAttr; } -JObj EDClock::attrJson() const{ - JObj oWidget; - oWidget["timeZone"] = QString::fromUtf8(m_attr.timeZoneId); - oWidget["year"] = m_attr.year; - oWidget["month"] = m_attr.month; - oWidget["day"] = m_attr.day; - oWidget["hour"] = m_attr.hour; - oWidget["min"] = m_attr.min; - oWidget["sec"] = m_attr.sec; - oWidget["weekly"] = m_attr.weekly; - oWidget["fullYear"] = m_attr.fullYear; - oWidget["12Hour"] = m_attr.hour12; - oWidget["AmPm"] = m_attr.AmPm; - oWidget["dateStyle"] = m_attr.dateStyle; - oWidget["timeStyle"] = m_attr.timeStyle; - oWidget["multiline"] = m_attr.multiline; - oWidget["font"] = JObj{ - {"family", m_attr.font.family()}, - {"size", m_attr.font.pixelSize()}, - {"bold", m_attr.font.bold()}, - {"italics", m_attr.font.italic()}, - {"underline", m_attr.font.underline()}, - {"color", Tools::color2Int(m_attr.textColor)} - }; - JObj oRoot; - addBaseAttr(oRoot); - oRoot["elementType"] = "DClock"; - oRoot["widget"] = oWidget; - return oRoot; +JObj EDClock::attrJson() const { + JObj json; + addBaseAttr(json); + json["elementType"] = "DClock"; + json["timeZone"] = QString::fromUtf8(timeZone.id()); + json["hasYear"] = hasYear; + json["hasMonth"] = hasMonth; + json["hasDay"] = hasDay; + json["hasHour"] = hasHour; + json["hasMin"] = hasMin; + json["hasSec"] = hasSec; + json["hasWeek"] = hasWeek; + json["isFullYear"] = isFullYear; + json["is12Hour"] = is12Hour; + json["hasAmPm"] = hasAmPm; + json["dateStyle"] = dateStyle; + json["timeStyle"] = isSingleHour; + json["isMultiline"] = isMultiline; + json["color"] = color.name(QColor::HexArgb); + json["font"] = font.family(); + json["fontSize"] = font.pixelSize(); + json["fontBold"] = font.bold(); + json["fontItalic"] = font.italic(); + json["fontUnderline"] = font.underline(); + json["lineHeight"] = lineHeight; + return json; } diff --git a/LedOK/program/edclock.h b/LedOK/program/edclock.h index 0e9275f..0bfb697 100644 --- a/LedOK/program/edclock.h +++ b/LedOK/program/edclock.h @@ -1,36 +1,18 @@ #ifndef EDCLOCK_H #define EDCLOCK_H +#include "ebase.h" +#include "gutil/qgui.h" #include #include #include #include #include #include -#include "ebase.h" class EDClock : public EBase { Q_OBJECT public: - struct Data { - QByteArray timeZoneId; - QFont font; - QColor textColor; - bool year; - bool month; - bool day; - bool hour; - bool min; - bool sec; - bool weekly; - bool fullYear; - bool hour12; - bool AmPm; - bool multiline; - int dateStyle; - int timeStyle; - }; - explicit EDClock(EBase *multiWin = nullptr); explicit EDClock(const JObj &json, EBase *multiWin = nullptr); @@ -39,10 +21,26 @@ public: QWidget* attrWgt() override; JObj attrJson() const override; + QTimeZone timeZone; + QFont font = qfont("Arial", 12); + QColor color{Qt::red}; + int dateStyle = 0; + int isSingleHour = 0; + int lineHeight = 0; + bool hasYear = true; + bool hasMonth = true; + bool hasDay = true; + bool hasHour = true; + bool hasMin = true; + bool hasSec = true; + bool hasWeek = true; + bool hasAmPm = true; + bool isFullYear = true; + bool is12Hour = true; + bool isMultiline = true; private: void init(); - Data m_attr; QString img_dir; QDateTime datetime; bool isSingleMD = false; diff --git a/LedOK/program/eenviron.cpp b/LedOK/program/eenviron.cpp index 73226f1..5b60bd6 100644 --- a/LedOK/program/eenviron.cpp +++ b/LedOK/program/eenviron.cpp @@ -238,7 +238,7 @@ QWidget* EEnviron::attrWgt() { addBaseAttrWgt(vBox); auto hBox = new HBox(vBox); - hBox->addWidget(new QLabel(tr("Basic Properties"))); + hBox->addLabel(translate("","Basic Properties")); auto line = new QFrame; line->setFrameShape(QFrame::HLine); diff --git a/LedOK/program/egif.cpp b/LedOK/program/egif.cpp index 4ea6586..ff4ee5c 100644 --- a/LedOK/program/egif.cpp +++ b/LedOK/program/egif.cpp @@ -97,7 +97,7 @@ QWidget* EGif::attrWgt() { addBaseAttrWgt(vBox); auto hBox = new QHBoxLayout(); - hBox->addWidget(new QLabel(tr("Basic Properties"))); + hBox->addWidget(new QLabel(translate("","Basic Properties"))); auto line = new QFrame(); line->setFrameShape(QFrame::HLine); @@ -118,7 +118,7 @@ QWidget* EGif::attrWgt() { bnSelectFile->setFixedWidth(30); bnSelectFile->setObjectName("bnSelectFile"); connect(bnSelectFile, &QPushButton::clicked, wgtAttr, [=] { - auto file = QFileDialog::getOpenFileName(wgtAttr, tr("Select File"), gFileHome, EGif::filters()); + auto file = QFileDialog::getOpenFileName(wgtAttr, translate("","Select File"), gFileHome, EGif::filters()); if(file.isEmpty()) return; auto movie = new QMovie(file); if(! movie->isValid()) { diff --git a/LedOK/program/emultiwin.cpp b/LedOK/program/emultiwin.cpp index 5061da5..3b9a75c 100644 --- a/LedOK/program/emultiwin.cpp +++ b/LedOK/program/emultiwin.cpp @@ -139,7 +139,7 @@ QWidget* EMultiWin::attrWgt() { EBase *ele = 0; QListWidgetItem *item = 0; if(type==EBase::Image) { - auto files = QFileDialog::getOpenFileNames(wgtAttr, tr("Select File"), gFileHome, EPhoto::filters()); + auto files = QFileDialog::getOpenFileNames(wgtAttr, translate("","Select File"), gFileHome, EPhoto::filters()); for(int i=0; isetBaseAttr(json); 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) { +EPhoto::EPhoto(const QImage &img, const QString &dir, const QString &name, const JObj &json, PageListItem *pageItem, EBase *multiWin) : EBase(multiWin), img(img), mDir(dir), mName(name), mPageItem(pageItem) { mType = EBase::Image; + direct = json["direct"].toString(); + speed = json["speed"].toInt(); + tailSpacing = json["tailSpacing"].toInt(); scaleImgIfNeed(); } JObj EPhoto::attrJson() const { @@ -53,6 +56,9 @@ JObj EPhoto::attrJson() const { json["elementType"] = "Image"; json["dir"] = mDir; json["name"] = mName; + json["direct"] = direct; + json["speed"] = speed; + json["tailSpacing"] = tailSpacing; return json; } void EPhoto::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { @@ -93,7 +99,7 @@ QWidget* EPhoto::attrWgt() { addBaseAttrWgt(vBox); auto hBox = new HBox(vBox); - hBox->addWidget(new QLabel(tr("Basic Properties"))); + hBox->addWidget(new QLabel(translate("","Basic Properties"))); auto line = new QFrame(); line->setFrameShape(QFrame::HLine); @@ -113,7 +119,7 @@ QWidget* EPhoto::attrWgt() { bnSelectFile->setObjectName("bnSelectFile"); connect(bnSelectFile, &QPushButton::clicked, wgtAttr, [=] { QString home = mDir.startsWith(gProgItem->mProgDir) ? gFileHome : mDir; - QString file = QFileDialog::getOpenFileName(wgtAttr, tr("Select File"), home, EPhoto::filters()); + QString file = QFileDialog::getOpenFileName(wgtAttr, translate("","Select File"), home, EPhoto::filters()); if(file.isEmpty()) return; QImageReader reader(file); reader.setAutoTransform(true); @@ -132,6 +138,71 @@ QWidget* EPhoto::attrWgt() { }); hBox->addWidget(bnSelectFile); + + hBox = new HBox(vBox); + auto label = hBox->addLabel(tr("Scroll")+": "+tr("Direction")); + label->setMinimumWidth(80); + label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + + auto edDirect = new QComboBox; + edDirect->addItem(tr("No"), ""); + edDirect->addItem(tr("Right -> Left"), "left"); + edDirect->addItem(tr("Bottom -> Top"), "top"); + edDirect->addItem(tr("Left -> Right"), "right"); + edDirect->addItem(tr("Top -> Bottom"), "bottom"); + SetCurData(edDirect, direct); + connect(edDirect, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] { + direct = edDirect->currentData().toString(); + }); + hBox->addWidget(edDirect); + + label = hBox->addLabel(tr("Speed")); + label->setMinimumWidth(80); + label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + + 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(fd); + hBox->addLabel("px/s"); + hBox->addStretch(); + + // hBox = new HBox(vBox); + // label = hBox->addLabel(tr("Tail Spacing")); + // label->setMinimumWidth(80); + // label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + + // auto edTailSpacing = new QSpinBox; + // edTailSpacing->setRange(0, 9999); + // edTailSpacing->setValue(tailSpacing); + // connect(edTailSpacing, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { + // tailSpacing = value; + // }); + // hBox->addWidget(edTailSpacing); + // hBox->addStretch(); + // hBox = new HBox(vBox); // hBox->addWidget(new QLabel(tr("Play Properties"))); diff --git a/LedOK/program/ephoto.h b/LedOK/program/ephoto.h index 35da816..0efbe63 100644 --- a/LedOK/program/ephoto.h +++ b/LedOK/program/ephoto.h @@ -11,7 +11,7 @@ public: static EPhoto *create(const QString &file, PageListItem *pageItem, EBase *multiWin = nullptr); static EPhoto *create(const JObj &, PageListItem *pageItem, EBase *multiWin = nullptr); - explicit EPhoto(const QImage&, const QString &dir, const QString &name, PageListItem *pageItem, EBase *multiWin = nullptr); + explicit EPhoto(const QImage&, const QString &dir, const QString &name, const JObj &json, PageListItem *pageItem, EBase *multiWin = nullptr); void scaleImgIfNeed(); @@ -24,7 +24,8 @@ public: QWidget* attrWgt() override; QImage img; - QString mDir, mName; + QString mDir, mName, direct; + int speed = 0, tailSpacing = 0; protected: PageListItem *mPageItem; }; diff --git a/LedOK/program/etext.cpp b/LedOK/program/etext.cpp index 2e80cb4..785cb09 100644 --- a/LedOK/program/etext.cpp +++ b/LedOK/program/etext.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #if(QT_VERSION_MAJOR > 5) #include #else @@ -36,13 +37,15 @@ EText::EText(const JObj &json, EBase *multiWin) : EBase(multiWin) { text = widget["text"].toString(); align = (Qt::Alignment) widget["align"].toInt(); backColor = widget["backColor"].toString("#00000000"); + lastFont = widget["lastFont"].toString("黑体"); 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(); + tailSpacing = json["headTailSpacing"].toInt(); + useNewFmt = json["useNewFmt"].toBool(); } } else { playMode = playModes[play["style"].toInt()]; @@ -50,7 +53,7 @@ EText::EText(const JObj &json, EBase *multiWin) : EBase(multiWin) { QString ds[]{"left", "top", "right", "bottom"}; direction = ds[rolling["rollingStyle"].toInt()]; speed = 1000/rolling["rollingSpeed"].toInt(33); - headTailSpacing = rolling["headTailSpacing"].toInt(); + tailSpacing = rolling["headTailSpacing"].toInt(); } connect(this, &EText::sizeChanged, this, &EText::updImg); updImg(); @@ -79,7 +82,7 @@ QWidget* EText::attrWgt() { addBaseAttrWgt(vBox); auto hBox = new HBox(vBox); - hBox->addLabel(tr("Basic Properties")); + hBox->addLabel(translate("","Basic Properties")); auto line = new QFrame; line->setFrameShape(QFrame::HLine); @@ -92,13 +95,14 @@ QWidget* EText::attrWgt() { auto fdFontFamily = new QFontComboBox; fdFontFamily->setEditable(false); - fdFontFamily->setCurrentFont(QFont("黑体")); - connect(fdFontFamily, &QFontComboBox::currentFontChanged, fdText, [fdText](const QFont &f) { + fdFontFamily->setCurrentFont(QFont(lastFont)); + connect(fdFontFamily, &QFontComboBox::currentFontChanged, fdText, [=](const QFont &f) { QTextCharFormat fmt; fmt.setFontFamilies({f.family()}); QTextCursor cursor = fdText->textCursor(); if(! cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor); cursor.mergeCharFormat(fmt); + lastFont = f.family(); }); hBox->addWidget(fdFontFamily); @@ -107,7 +111,7 @@ QWidget* EText::attrWgt() { auto fdFontSize = new QSpinBox; fdFontSize->setRange(4, 9999); fdFontSize->setValue(16); - connect(fdFontSize, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, fdText, [fdText](int value) { + connect(fdFontSize, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, fdText, [=](int value) { if(value <= 0) return; QTextCharFormat fmt; fmt.setProperty(QTextFormat::FontPixelSize, value); @@ -329,8 +333,16 @@ QWidget* EText::attrWgt() { updImg(); }); connect(fdText, &QTextEdit::currentCharFormatChanged, this, [=](const QTextCharFormat &format) { + auto ft = format.font(); + auto families = ft.families(); + if(! families.isEmpty()) { + fdFontFamily->blockSignals(true); + fdFontFamily->setCurrentFont(families[0]); + fdFontFamily->blockSignals(false); + lastFont = families[0]; + } fdFontSize->blockSignals(true); - fdFontSize->setValue(format.font().pixelSize()); + fdFontSize->setValue(ft.pixelSize()); fdFontSize->blockSignals(false); auto foreground = format.foreground(); fdTextColor->blockSignals(true); @@ -382,7 +394,7 @@ QWidget* EText::attrWgt() { auto btnImport = new QPushButton(tr("Import txt File")); btnImport->setProperty("ssType", "progManageTool"); connect(btnImport, &QPushButton::clicked, fdText, [=] { - auto filePath = QFileDialog::getOpenFileName(wgtAttr, tr("Select File"), gFileHome, "Txt(*.txt)"); + auto filePath = QFileDialog::getOpenFileName(wgtAttr, translate("","Select File"), gFileHome, "Txt(*.txt)"); if(filePath.isEmpty()) return; QFile qFile(filePath); if(! qFile.open(QFile::ReadOnly)) { @@ -446,25 +458,9 @@ QWidget* EText::attrWgt() { vBox->setSpacing(3); auto hBox = new HBox(vBox); - auto label = new QLabel(tr("Head-Tail Spacing")); - label->setMinimumWidth(100); - hBox->addWidget(label); - - 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(fdHeadTailSpacing); - hBox->addStretch(); - - hBox = new HBox(vBox); - - label = new QLabel(tr("Scroll Style")); - label->setMinimumWidth(100); - hBox->addWidget(label); + auto label = hBox->addLabel(tr("Direction")); + label->setMinimumWidth(80); + label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); auto fdDirection = new QComboBox; fdDirection->addItem(tr("Right -> Left"), "left"); @@ -477,13 +473,10 @@ QWidget* EText::attrWgt() { updImg(); }); hBox->addWidget(fdDirection); - hBox->addStretch(); - hBox = new HBox(vBox); - - label = new QLabel(tr("Scroll Speed")); - label->setMinimumWidth(100); - hBox->addWidget(label); + label = hBox->addLabel(tr("Speed")); + label->setMinimumWidth(80); + label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); auto fd = new QComboBox; fd->setEditable(true); @@ -514,6 +507,29 @@ QWidget* EText::attrWgt() { hBox->addLabel("px/s"); hBox->addStretch(); + hBox = new HBox(vBox); + label = hBox->addLabel(tr("Tail Spacing")); + label->setMinimumWidth(80); + label->setAlignment(Qt::AlignRight|Qt::AlignVCenter); + + auto edTailSpacing = new QSpinBox; + edTailSpacing->setRange(0, 9999); + edTailSpacing->setValue(tailSpacing); + connect(edTailSpacing, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { + tailSpacing = value; + updImg(); + }); + hBox->addWidget(edTailSpacing); + hBox->addStretch(); + + auto edNewFmt = new QCheckBox(tr("New Format")+" (Player 2.1.18)"); + edNewFmt->setChecked(useNewFmt); + connect(edNewFmt, &QCheckBox::stateChanged, this, [this](int value) { + useNewFmt = value==Qt::Checked; + updImg(); + }); + hBox->addWidget(edNewFmt); + vBox->addStretch(); } auto stackBox = new QStackedLayout; @@ -554,6 +570,7 @@ JObj EText::attrJson() const { {"text", text}, {"align", (int) align}, {"backColor", backColor.name(QColor::HexArgb)}, + {"lastFont", lastFont}, {"files", files}, {"idDir", QString("%1-%2-%3-%4-%5").arg(zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight)} }; @@ -561,7 +578,8 @@ JObj EText::attrJson() const { if(playMode=="Scroll") { obj["direction"] = direction; obj["speed"] = speed; - obj["headTailSpacing"] = headTailSpacing; + obj["headTailSpacing"] = tailSpacing; + obj["useNewFmt"] = useNewFmt; } return obj; } @@ -633,13 +651,14 @@ void EText::updImg() { } emit updPageCnt(); } else if(playMode=="Scroll") {//生成一张大图 - if(direction=="left" || direction=="right") { + auto isHor = direction=="left" || direction=="right"; + if(isHor) { doc.setHtml(text.replace("

", "").replace("
", " ")); - width = ceil(doc.idealWidth()) + headTailSpacing; + width = ceil(doc.idealWidth()) + tailSpacing; } else { doc.setTextWidth(width); doc.setHtml(text); - height = doc.size().height() + headTailSpacing; + height = doc.size().height() + tailSpacing; } QImage img(width, height, QImage::Format_ARGB32); img.fill(backColor); @@ -647,7 +666,7 @@ void EText::updImg() { QPainter painter(&img); doc.drawContents(&painter); } - if(direction=="left" || direction=="right") { + if(isHor) { alignV(img); if(width < innerRect.width()) { auto newWidth = width*2; @@ -662,19 +681,26 @@ void EText::updImg() { } } mImgs.clear(); - mImgs.append(img); -// if(img.width()<=8192) mImgs.append(img); -// else { -// for(int i=0; i0); + } + } else { + if(img.height()<=4096) mImgs.append(img); + else { + auto rem = img.height(); + do { + mImgs.append(img.copy(0, img.height()-rem, img.width(), qMin(4096, rem))); + rem -= 4096; + } while (rem>0); + } + } } else if(playMode=="Static") {//生成一张图 doc.setHtml(text); doc.setTextWidth(width); diff --git a/LedOK/program/etext.h b/LedOK/program/etext.h index eef14f5..4e8e373 100644 --- a/LedOK/program/etext.h +++ b/LedOK/program/etext.h @@ -18,10 +18,12 @@ public: QString text; Qt::Alignment align; QColor backColor = Qt::transparent; + QString lastFont = "黑体"; QString playMode = "Flip"; QString direction = "left"; int speed = 60; - int headTailSpacing = 10; + int tailSpacing = 10; + bool useNewFmt = false; public slots: void updImg(); diff --git a/LedOK/program/etimer.cpp b/LedOK/program/etimer.cpp index 63250f1..4f7f5af 100644 --- a/LedOK/program/etimer.cpp +++ b/LedOK/program/etimer.cpp @@ -1,7 +1,6 @@ #include "etimer.h" -#include "tools.h" #include "main.h" -#include "base/lodateselector.h" +#include "base/calendarbutton.h" #include "base/locolorselector.h" #include "gutil/qgui.h" #include @@ -44,8 +43,7 @@ ETimer::ETimer(const JObj &json, EBase *multiWin) : EBase(multiWin){ font = qfont(json["font"].toString(), json["fontSize"].toInt(), json["fontBold"].toBool(), json["fontItalic"].toBool()); font.setUnderline(json["fontUnderline"].toBool()); textColor = json["textColor"].toString(); - auto color = json["backColor"].toString(); - backColor = color.isEmpty() ? QColor(0,0,0,0) : color; + backColor = json["backColor"].toString("#00000000"); init(); } @@ -97,17 +95,15 @@ QWidget* ETimer::attrWgt() { addBaseAttrWgt(vBox); - auto hBox = new QHBoxLayout(); - hBox->addWidget(new QLabel(tr("Basic Properties"))); + auto hBox = new HBox(vBox); + hBox->addLabel(translate("","Basic Properties")); - auto line = new QFrame(); + auto line = new QFrame; line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); hBox->addWidget(line, 1); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); hBox->addStretch(); auto fdCntDown = new QRadioButton(tr("Count Down")); auto fdCntUp = new QRadioButton(tr("Count Up")); @@ -125,28 +121,24 @@ QWidget* ETimer::attrWgt() { hBox->addWidget(fdCntUp); hBox->addStretch(); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Time"))); + hBox->addLabel(tr("Target Time")); - auto fdTime = new QDateTimeEdit(this->targetTime); - fdTime->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); - connect(fdTime, &QTimeEdit::dateTimeChanged, this, [this](const QDateTime &dateTime) { + auto edTime = new QDateTimeEdit(this->targetTime); + edTime->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); + connect(edTime, &QTimeEdit::dateTimeChanged, this, [this](const QDateTime &dateTime) { this->targetTime = dateTime; update(); }); - hBox->addWidget(fdTime); + hBox->addWidget(edTime); - auto wDateSelector = new LoDateSelector(); - connect(wDateSelector, &LoDateSelector::sDateSelected, fdTime, &QDateTimeEdit::setDate); - hBox->addWidget(wDateSelector); + auto btnTime = new CalendarButton; + connect(btnTime->calendar, &QCalendarWidget::clicked, edTime, &QDateTimeEdit::setDate); + hBox->addWidget(btnTime); hBox->addStretch(); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); hBox->addSpacing(6); auto fdHasDay = new QCheckBox(tr("Day")); @@ -190,9 +182,7 @@ QWidget* ETimer::attrWgt() { }); hBox->addWidget(fdIsMultiline); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); hBox->addSpacing(6); hBox->addWidget(new QLabel(tr("Text"))); @@ -204,9 +194,7 @@ QWidget* ETimer::attrWgt() { }); hBox->addWidget(fdText); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); hBox->addSpacing(6); auto fdFont = new QFontComboBox(); @@ -233,9 +221,7 @@ QWidget* ETimer::attrWgt() { hBox->addWidget(fdFontSize); hBox->addStretch(); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); hBox->addSpacing(6); auto fdFontBold = new QPushButton("B"); @@ -289,7 +275,6 @@ QWidget* ETimer::attrWgt() { update(); }); hBox->addWidget(fdBackColor); - vBox->addLayout(hBox); vBox->addStretch(); return wgtAttr; diff --git a/LedOK/program/etimer2.cpp b/LedOK/program/etimer2.cpp index ef767bd..d6a1240 100644 --- a/LedOK/program/etimer2.cpp +++ b/LedOK/program/etimer2.cpp @@ -2,7 +2,7 @@ #include "main.h" #include "gutil/qgui.h" #include "base/locolorselector.h" -#include "base/lodateselector.h" +#include "base/calendarbutton.h" #include #include #include @@ -80,7 +80,7 @@ QWidget* ETimer2::attrWgt() { addBaseAttrWgt(vBox); auto hBox = new HBox(vBox); - hBox->addLabel(tr("Basic Properties")); + hBox->addLabel(translate("","Basic Properties")); auto line = new QFrame; line->setFrameShape(QFrame::HLine); @@ -108,19 +108,19 @@ QWidget* ETimer2::attrWgt() { hBox = new HBox(vBox); hBox->addSpacing(6); - hBox->addLabel(tr("Time")); + hBox->addLabel(tr("Target Time")); - auto fdTime = new QDateTimeEdit(targetTime); - fdTime->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); - connect(fdTime, &QTimeEdit::dateTimeChanged, this, [this](const QDateTime &dateTime) { + auto edTime = new QDateTimeEdit(targetTime); + edTime->setDisplayFormat("yyyy-MM-dd HH:mm:ss"); + connect(edTime, &QTimeEdit::dateTimeChanged, this, [this](const QDateTime &dateTime) { targetTime = dateTime; update(); }); - hBox->addWidget(fdTime); + hBox->addWidget(edTime); - auto wDateSelector = new LoDateSelector; - connect(wDateSelector, &LoDateSelector::sDateSelected, fdTime, &QDateTimeEdit::setDate); - hBox->addWidget(wDateSelector); + auto btnCalendar = new CalendarButton; + connect(btnCalendar->calendar, &QCalendarWidget::clicked, edTime, &QDateTimeEdit::setDate); + hBox->addWidget(btnCalendar); hBox->addStretch(); diff --git a/LedOK/program/evideo.cpp b/LedOK/program/evideo.cpp index 3a9513a..0209fc3 100644 --- a/LedOK/program/evideo.cpp +++ b/LedOK/program/evideo.cpp @@ -2,6 +2,8 @@ #include "tools.h" #include "main.h" #include "base/ffutil.h" +#include "gutil/qwaitingdlg.h" +#include "videosplitthread.h" #include #include #include @@ -47,6 +49,8 @@ EVideo *EVideo::create(const JObj &ele, PageListItem *pageItem, EBase *multiWin) auto ins = new EVideo(dir, name, widget["pathRaw"].toString(), widget["fileRaw"].toString(), img, pageItem, multiWin); ins->setBaseAttr(ele); if(ins->_duration < 4) ins->_duration = dur; + ins->useSW = ele["useSW"].toBool(); + ins->isPreSplit = ele["isPreSplit"].toBool(); auto play = ele["play"]; ins->playTimes = (play.isNull() ? ele : play)["playTimes"].toInt(1); return ins; @@ -81,19 +85,17 @@ QWidget* EVideo::attrWgt() { addBaseAttrWgt(vBox); - auto hBox = new QHBoxLayout(); - hBox->addWidget(new QLabel(tr("Basic Properties"))); + auto hBox = new HBox(vBox); + hBox->addLabel(translate("","Basic Properties")); - auto line = new QFrame(); + auto line = new QFrame; line->setFrameShape(QFrame::HLine); 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"))); + hBox->addLabel(tr("File")); auto fdFileName = new QLineEdit(mRawName); fdFileName->setReadOnly(true); @@ -103,7 +105,7 @@ QWidget* EVideo::attrWgt() { bnSelectFile->setFixedWidth(30); bnSelectFile->setObjectName("bnSelectFile"); connect(bnSelectFile, &QPushButton::clicked, this, [=] { - auto rawFile = QFileDialog::getOpenFileName(wgtAttr, tr("Select File"), gFileHome, EVideo::filters()); + auto rawFile = QFileDialog::getOpenFileName(wgtAttr, translate("","Select File"), gFileHome, EVideo::filters()); if(rawFile.isEmpty()) return; QFileInfo rawInfo(rawFile); int64_t dur; @@ -127,11 +129,9 @@ QWidget* EVideo::attrWgt() { }); hBox->addWidget(bnSelectFile); - vBox->addLayout(hBox); - -// hBox = new QHBoxLayout(); +// hBox = new HBox(vBox); // hBox->addSpacing(6); -// hBox->addWidget(new QLabel(tr("AspectRatioMode"))); +// hBox->addLabel(tr("AspectRatioMode")); // auto wAspectRatioMode = new QComboBox(); // wAspectRatioMode->addItem(tr("IgnoreAspectRatio")); @@ -144,32 +144,46 @@ QWidget* EVideo::attrWgt() { // hBox->addWidget(wAspectRatioMode); // hBox->addStretch(); -// vBox->addLayout(hBox); + hBox = new HBox(vBox); + hBox->addLabel(tr("Play Properties")); - hBox = new QHBoxLayout(); - hBox->addWidget(new QLabel(tr("Play Properties"))); - - line = new QFrame(); + line = new QFrame; line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); hBox->addWidget(line, 1); - vBox->addLayout(hBox); - - hBox = new QHBoxLayout(); + hBox = new HBox(vBox); hBox->addSpacing(6); - hBox->addWidget(new QLabel(tr("Play Times"))); + hBox->addLabel(tr("Play Times")); - auto wPlayTimes = new QSpinBox(); - wPlayTimes->setRange(1, 99999); - wPlayTimes->setValue(playTimes); - connect(wPlayTimes, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { + auto edPlayTimes = new QSpinBox; + edPlayTimes->setRange(1, 99999); + edPlayTimes->setValue(playTimes); + connect(edPlayTimes, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) { playTimes = value; }); - hBox->addWidget(wPlayTimes); + hBox->addWidget(edPlayTimes); + hBox->addStretch(); + + hBox = new HBox(vBox); + hBox->addSpacing(6); + + auto edUseSW = new QCheckBox(tr("Use SW")); + edUseSW->setChecked(useSW); + connect(edUseSW, &QCheckBox::stateChanged, this, [this](int value) { + useSW = value==Qt::Checked; + }); + hBox->addWidget(edUseSW); + + auto edPreSplit = new QCheckBox(tr("Pre Split")+" ("+tr("No Effect")+")"); + edPreSplit->setChecked(isPreSplit); + connect(edPreSplit, &QCheckBox::stateChanged, this, [this](int value) { + isPreSplit = value==Qt::Checked; + }); + hBox->addWidget(edPreSplit); + hBox->addStretch(); - vBox->addLayout(hBox); vBox->addStretch(); return wgtAttr; } @@ -183,19 +197,19 @@ bool EVideo::save(const QString &pageDir) { else return false; QFile(oldFile).copy(saveFile); mDir = pageDir; - // 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(); - // } + if(gProgItem->maxLen && isPreSplit) { + 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; } @@ -206,8 +220,17 @@ JObj EVideo::attrJson() const { {"file", mName}, {"pathRaw", mRawDir}, {"fileRaw", mRawName}, + {"useSW", useSW}, + {"isPreSplit", isPreSplit}, {"playTimes", playTimes} }; + if(gProgItem->isVer) { + obj["outHeight"] = gProgItem->maxLen; + obj["outWidth"] = gProgItem->mWidth * (int)gProgItem->partLens.size(); + } else { + obj["outWidth"] = gProgItem->maxLen; + obj["outHeight"] = gProgItem->mHeight * (int)gProgItem->partLens.size(); + } addBaseAttr(obj); return obj; } @@ -245,7 +268,7 @@ QString EVideo::transcoding(QWidget *parent, QString rawFile, QString rawName, Q }); connect(&process, &QProcess::errorOccurred, &msgBox, [=, &msgBox](QProcess::ProcessError error) { msgBox.accept(); - QMessageBox::critical(parent, tr("Error"), QString(QMetaEnum::fromType().valueToKey(error))+" ("+QString::number(error)+")"); + QMessageBox::critical(parent, translate("","Error"), QString(QMetaEnum::fromType().valueToKey(error))+" ("+QString::number(error)+")"); }); connect(&process, &QProcess::readyReadStandardOutput, &msgBox, [&process] { auto data = process.readAllStandardOutput(); @@ -273,7 +296,7 @@ QString EVideo::transcoding(QWidget *parent, QString rawFile, QString rawName, Q process.start("ffmpeg", {"-y", "-i", rawFile, "-vcodec", "h264", "-s", QString::number(w)+"x"+QString::number(h), "-profile:v", "main", "-b:v", QString::number(w*h/150)+"k", outFile}); msgBox.exec(); if(err.right(32).contains("Conversion failed!")) { - QMessageBox::critical(parent, tr("Error"), err); + QMessageBox::critical(parent, translate("","Error"), err); return ""; } return outFile; diff --git a/LedOK/program/evideo.h b/LedOK/program/evideo.h index ed4ada5..2a7d664 100644 --- a/LedOK/program/evideo.h +++ b/LedOK/program/evideo.h @@ -38,6 +38,7 @@ public: protected: int aspectRatioMode = Qt::IgnoreAspectRatio; int playTimes = 1; + bool useSW = false, isPreSplit = false; PageListItem *mPageItem; }; diff --git a/LedOK/program/eweb.cpp b/LedOK/program/eweb.cpp index 58fe1ac..2b2550d 100644 --- a/LedOK/program/eweb.cpp +++ b/LedOK/program/eweb.cpp @@ -1,5 +1,6 @@ #include "eweb.h" #include "gutil/qgui.h" +#include "main.h" #include #include #include @@ -41,7 +42,7 @@ QWidget* EWeb::attrWgt() { addBaseAttrWgt(vBox); auto hBox = new HBox(vBox); - hBox->addLabel(tr("Basic Properties")); + hBox->addLabel(translate("","Basic Properties")); auto line = new QFrame; line->setFrameShape(QFrame::HLine); diff --git a/LedOK/program/gentmpthread.cpp b/LedOK/program/gentmpthread.cpp index 7cbb05d..4c3f630 100644 --- a/LedOK/program/gentmpthread.cpp +++ b/LedOK/program/gentmpthread.cpp @@ -142,10 +142,17 @@ JObj GenTmpThread::cvtPage(const JObj &pageJson) { auto startTime = isWin ? 0 : ele["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"]; + if(source["isPreSplit"].toBool()) { + source["left"] = 0; + source["top"] = 0; + source["width"] = ele["outWidth"]; + source["height"] = ele["outHeight"]; + } else { + source["left"] = geometry["x"]; + source["top"] = geometry["y"]; + source["width"] = geometry["w"]; + source["height"] = geometry["h"]; + } source["rotate"] = ele["rotate"]; source["opacity"] = ele["opacity"].toDouble(1); source["playTime"] = startTime; @@ -209,6 +216,7 @@ JObj GenTmpThread::cvtPage(const JObj &pageJson) { } return JObj{ {"repeatTimes", pageJson["repeat"]}, + {"waitAudio", pageJson["waitAudio"]}, {"schedules", schedules}, {"_program", JObj{ {"name", pageJson["name"].toString()}, @@ -226,11 +234,11 @@ JArray GenTmpThread::genSources(QString type, const JArray &eles) { if(type=="Text") source = genText(ele, sources); else if(type=="Image"||type=="Photo") source = genImage(ele); else if(type=="Video"||type=="Movie") { - //genProg(ele, dstDir, mProgItem); auto widget = ele["widget"]; if(widget.isNull()) widget = ele; auto path = widget["path"].toString(); auto name = widget["file"].toString(); + if(widget["isPreSplit"].toBool()) name += "-square.mp4"; auto srcFile = path + "/" + name; if(! QFileInfo(srcFile).isFile() && ! QFileInfo(srcFile = srcPageDir + "/" + name).isFile()) continue; auto id = Tools::fileMd5(srcFile); @@ -240,6 +248,8 @@ JArray GenTmpThread::genSources(QString type, const JArray &eles) { source["id"] = id; source["md5"] = id; source["name"] = name; + source["useSW"] = ele["useSW"]; + source["isPreSplit"] = ele["isPreSplit"]; auto play = ele["play"]; source["timeSpan"] = play.isNull() ? ele["duration"].toInt() * ele["playTimes"].toInt() : play["playDuration"].toInt() * play["playTimes"].toInt(); } else if(type=="Gif") source = convertGif(ele); @@ -259,6 +269,8 @@ JArray GenTmpThread::genSources(QString type, const JArray &eles) { 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"]; if(ele["hasBlink"].toBool()) source["blink"] = ele["blink"]; @@ -292,30 +304,47 @@ JObj GenTmpThread::genText(const JValue &ele, JArray &sources) { 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); + if(filenames.size()>1) { + JObj source; + source["_type"] = "Scroll"; + source["direct"] = direction; + source["speed"] = speed; + JArray imgs; + 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); + imgs.append(id); + } + source["imgs"] = imgs; + return source; + } else { + JObj source; + source["_type"] = "MultiPng"; + source["playMode"] = playMode; + JArray arrayPics; + for(auto &filename : filenames) { + auto file = filePrefix + filename.toString(); + QFile qFile(file); + if(! qFile.exists()) continue; + auto id = Tools::fileMd5(file); + qFile.copy(dstDir+"/"+id); - JObj arrayPic; - arrayPic["id"] = id; - if(direction=="left") arrayPic["effect"] = "right to left"; - else if(direction=="top") arrayPic["effect"] = "bottom to top"; - else if(direction=="right") arrayPic["effect"] = "left to right"; - else if(direction=="bottom") arrayPic["effect"] = "top to bottom"; - arrayPic["scrollSpeed"] = speed; - arrayPic["effectSpeed"] = 1000 / speed; - arrayPic["picDuration"] = 0; - arrayPics.append(arrayPic); + 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["picDuration"] = 0; + arrayPics.append(arrayPic); + } + source["arrayPics"] = arrayPics; + return source; } - source["arrayPics"] = arrayPics; - return source; } else { auto duration = ele["duration"].toInt(); for(auto &filename : filenames) { @@ -353,6 +382,8 @@ JObj GenTmpThread::genImage(const JValue &ele) { auto geometry = ele["geometry"]; auto width = geometry["w"].toInt(); auto height = geometry["h"].toInt(); + auto direct = ele["direct"].toStr(); + auto speed = ele["speed"].toInt(); /*if(mProgItem->maxLen) { auto scaled = img.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); QImage square(gProgItem->isVer ? gProgItem->mWidth*gProgItem->partLens.size() : gProgItem->maxLen, gProgItem->isVer ? gProgItem->maxLen : gProgItem->mHeight*gProgItem->partLens.size(), QImage::Format_ARGB32); @@ -387,26 +418,34 @@ JObj GenTmpThread::genImage(const JValue &ele) { file.close(); source["id"] = md5; source["md5"] = md5; - } else */if(img.width() > width*2 && img.height() > height*2) { + } else */ + auto isScroll = ! direct.isEmpty() && speed > 0; + QString md5; + if((isScroll && (img.width() != width || img.height() != height)) || (img.width() > width*2 && img.height() > height*2)) { QBuffer buf; img.scaled(width, height, Qt::IgnoreAspectRatio, Qt::SmoothTransformation).save(&buf, "PNG"); QCryptographicHash cryptoHash(QCryptographicHash::Md5); cryptoHash.addData(buf.data()); - auto md5 = QString::fromLatin1(cryptoHash.result().toHex()); + md5 = QString::fromLatin1(cryptoHash.result().toHex()); QFile file(dstDir+"/"+md5); if(! file.open(QFile::WriteOnly)) return source; file.write(buf.data()); file.close(); - source["id"] = md5; - source["md5"] = md5; } else { - auto md5 = Tools::fileMd5(srcFile); + md5 = Tools::fileMd5(srcFile); if(md5.isEmpty()) return source; QFile::copy(srcFile, dstDir+"/"+md5); + } + if(isScroll) { + source["_type"] = "Scroll"; + source["direct"] = direct; + source["speed"] = speed; + source["imgs"] = JArray{md5}; + } else { + source["_type"] = "Image"; source["id"] = md5; source["md5"] = md5; } - source["_type"] = "Image"; auto play = ele["play"]; source["timeSpan"] = play.isNull() ? ele["duration"] : play["playDuration"]; return source; @@ -419,7 +458,7 @@ JObj GenTmpThread::convertGif(const JValue &json) { QString srcFile = path + "/" + name; QFileInfo srcInfo(srcFile); if(! srcInfo.isFile()) return JObj(); - QString id = Tools::fileMd5(srcFile); + auto id = Tools::fileMd5(srcFile); if(id.isEmpty()) return JObj(); QFile::copy(srcFile, dstDir+"/"+id); JObj oRes; @@ -432,57 +471,79 @@ JObj GenTmpThread::convertGif(const JValue &json) { return oRes; } JObj GenTmpThread::convertDClock(const JValue &json){ - JObj oRes; - oRes["_type"] = "DigitalClockNew"; - oRes["name"] = "DigitalClockNew"; + JObj source; + source["_type"] = "DigitalClockNew"; + source["name"] = "DigitalClockNew"; auto widget = json["widget"]; - oRes["timeZone"] = widget["timeZone"]; - oRes["timezone"] = 8;//兼容旧播放器 - oRes["year"] = widget["year"]; - oRes["month"] = widget["month"]; - oRes["day"] = widget["day"]; - oRes["hour"] = widget["hour"]; - oRes["min"] = widget["min"]; - oRes["sec"] = widget["sec"]; - oRes["weekly"] = widget["weekly"]; - oRes["fullYear"] = widget["fullYear"]; - oRes["hour12"] = widget["12Hour"]; - oRes["AmPm"] = widget["AmPm"]; - oRes["dateStyle"] = widget["dateStyle"]; - oRes["timeStyle"] = widget["timeStyle"]; - oRes["multiline"] = widget["multiline"]; - - auto fontVal = widget["font"]; - auto textColor = Tools::int2Color(fontVal["color"].toInt()); - QFont font(fontVal["family"].toString()); - font.setPixelSize(fontVal["size"].toInt()); - font.setBold(fontVal["bold"].toBool()); - font.setItalic(fontVal["italics"].toBool()); - font.setUnderline(fontVal["underline"].toBool()); + QFont font; + QColor color; + if(widget.isNull()) { + widget = json; + source["year"] = json["hasYear"]; + source["month"] = json["hasMonth"]; + source["day"] = json["hasDay"]; + source["hour"] = json["hasHour"]; + source["min"] = json["hasMin"]; + source["sec"] = json["hasSec"]; + source["weekly"] = json["hasWeek"]; + source["fullYear"] = json["isFullYear"]; + source["hour12"] = json["is12Hour"]; + source["AmPm"] = json["hasAmPm"]; + source["multiline"] = json["isMultiline"]; + color = json["color"].toString("#ffff0000"); + font.setFamily(json["font"].toString()); + font.setPixelSize(json["fontSize"].toInt()); + font.setBold(json["fontBold"].toBool()); + font.setItalic(json["fontItalic"].toBool()); + font.setUnderline(json["fontUnderline"].toBool()); + } else { + source["year"] = widget["year"]; + source["month"] = widget["month"]; + source["day"] = widget["day"]; + source["hour"] = widget["hour"]; + source["min"] = widget["min"]; + source["sec"] = widget["sec"]; + source["weekly"] = widget["weekly"]; + source["fullYear"] = widget["fullYear"]; + source["hour12"] = widget["12Hour"]; + source["AmPm"] = widget["AmPm"]; + source["multiline"] = widget["multiline"]; + auto ft = widget["font"]; + color = Tools::int2Color(ft["color"].toInt()); + font.setFamily(ft["family"].toString()); + font.setPixelSize(ft["size"].toInt()); + font.setBold(ft["bold"].toBool()); + font.setItalic(ft["italics"].toBool()); + font.setUnderline(ft["underline"].toBool()); + } + source["timeZone"] = widget["timeZone"]; + source["timezone"] = 8;//兼容旧播放器 + source["dateStyle"] = widget["dateStyle"]; + source["timeStyle"] = widget["timeStyle"]; font.setStyleStrategy(gTextAntialiasing ? QFont::PreferAntialias : QFont::NoAntialias); QFontMetrics metric(font); - oRes["spaceWidth"] = metric.horizontalAdvance(" "); - QColor color(textColor); + source["spaceWidth"] = metric.horizontalAdvance(" "); + auto lineHeight = json["isMultiline"].toBool() ? json["lineHeight"].toInt() : 0; JArray imgs; - for(int i=0; i<=9; i++) Tools::saveImg2(dstDir, metric, font, color, imgs, QString::number(i), QString::number(i)); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("MON"), "MON"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("TUE"), "TUE"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("WED"), "WED"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("THU"), "THU"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("FRI"), "FRI"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("SAT"), "SAT"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("SUN"), "SUN"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("AM"), "AM"); - Tools::saveImg2(dstDir, metric, font, color, imgs, tr("PM"), "PM"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "年", "YEAR"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "月", "MONTH"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "日", "DAY"); - Tools::saveImg2(dstDir, metric, font, color, imgs, ":", "maohao"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "/", "xiegang"); - Tools::saveImg2(dstDir, metric, font, color, imgs, "-", "hengxian"); - oRes["arrayPics"] = imgs; - return oRes; + for(int i=0; i<=9; i++) Tools::saveImg2(dstDir, metric, font, color, imgs, QString::number(i), QString::number(i), lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("MON"), "MON", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("TUE"), "TUE", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("WED"), "WED", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("THU"), "THU", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("FRI"), "FRI", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("SAT"), "SAT", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("SUN"), "SUN", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("AM"), "AM", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, tr("PM"), "PM", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, "年", "YEAR", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, "月", "MONTH", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, "日", "DAY", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, ":", "maohao", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, "/", "xiegang", lineHeight); + Tools::saveImg2(dstDir, metric, font, color, imgs, "-", "hengxian", lineHeight); + source["arrayPics"] = imgs; + return source; } JObj GenTmpThread::convertAClock(const JValue &json) { auto widget = json["widget"]; diff --git a/LedOK/program/pageeditor.cpp b/LedOK/program/pageeditor.cpp index 6a560e3..a70779b 100644 --- a/LedOK/program/pageeditor.cpp +++ b/LedOK/program/pageeditor.cpp @@ -1,5 +1,5 @@ #include "pageeditor.h" -#include "tools.h" +#include "main.h" #include "ebase.h" #include #include @@ -164,7 +164,7 @@ void PageEditor::onDelete() { } void PageEditor::onClean() { - auto res = QMessageBox::information(this, tr("Tip Info"),tr("Clear all medias?"), QMessageBox::Ok, QMessageBox::Cancel); + auto res = QMessageBox::information(this, translate("","Tip"),tr("Clear all medias?"), QMessageBox::Ok, QMessageBox::Cancel); if(res == QMessageBox::Ok) { auto eles = sortedEles(); foreach(auto ele, eles) { diff --git a/LedOK/program/pagelistitem.cpp b/LedOK/program/pagelistitem.cpp index b465a84..f853abf 100644 --- a/LedOK/program/pagelistitem.cpp +++ b/LedOK/program/pagelistitem.cpp @@ -2,7 +2,7 @@ #include "main.h" #include "gutil/qgui.h" #include "base/ffutil.h" -#include "base/lodateselector.h" +#include "base/calendarbutton.h" #include "program/eaclock.h" #include "program/ebase.h" #include "program/edclock.h" @@ -15,13 +15,13 @@ #include "program/etimer2.h" #include "program/evideo.h" #include "program/eweb.h" -#include "tools.h" #include #include #include #include #include #include +#include class PageScene : public QGraphicsScene { public: @@ -259,6 +259,13 @@ QPushButton[ssName="weeklySelector"]:checked { }); hBox->addWidget(fdLoop); + auto edWaitAudio = new QCheckBox(tr("Wait Audio")); + edWaitAudio->setChecked(mAttr["waitAudio"].toBool()); + connect(edWaitAudio, &QCheckBox::toggled, this, [this](bool checked) { + mAttr["waitAudio"] = checked; + }); + hBox->addWidget(edWaitAudio); + hBox->addStretch(); vBox->addLayout(hBox); @@ -287,7 +294,7 @@ QPushButton[ssName="weeklySelector"]:checked { mAudiosList = new QListWidget; connect(btnAdd, &QPushButton::clicked, mAttrWgt, [this, fdTtlDur] { - auto files = QFileDialog::getOpenFileNames(mAttrWgt, tr("Select File"), gFileHome); + auto files = QFileDialog::getOpenFileNames(mAttrWgt, translate("","Select File"), gFileHome); int durs = fdTtlDur->text().toInt(); for(int i=0; isetDate(QDate::fromString(validDate["start"].toString(), "yyyy-MM-dd")); hBox->addWidget(fdStart); - auto bnDateStart = new LoDateSelector(); + auto bnDateStart = new CalendarButton; bnDateStart->setEnabled(isDateValid); - connect(bnDateStart, &LoDateSelector::sDateSelected, fdStart, &QDateEdit::setDate); + connect(bnDateStart->calendar, &QCalendarWidget::clicked, fdStart, &QDateEdit::setDate); hBox->addWidget(bnDateStart); hBox->addWidget(new QLabel("~")); @@ -472,9 +479,9 @@ QPushButton[ssName="weeklySelector"]:checked { }); hBox->addWidget(fdEnd); - auto bnDateEnd = new LoDateSelector(); + auto bnDateEnd = new CalendarButton; bnDateEnd->setEnabled(isDateValid); - connect(bnDateEnd, &LoDateSelector::sDateSelected, fdEnd, &QDateEdit::setDate); + connect(bnDateEnd->calendar, &QCalendarWidget::clicked, fdEnd, &QDateEdit::setDate); hBox->addWidget(bnDateEnd); hBox->addStretch(); diff --git a/LedOK/program/progeditorwin.cpp b/LedOK/program/progeditorwin.cpp index 639a3ed..f9fceca 100644 --- a/LedOK/program/progeditorwin.cpp +++ b/LedOK/program/progeditorwin.cpp @@ -28,7 +28,7 @@ #include #include -ProgItem *gProgItem{0}; +ProgItem *gProgItem = 0; ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(parent), mProgItem(progItem) { gProgItem = progItem; @@ -75,7 +75,7 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare // saveThread = QThread::create([this](){ // save(); // }); -// dlgTip->lock(tr("Saving..."),tr("Success"),tr("Save failed")); +// dlgTip->lock(tr("Saving..."),translate("","Success"),tr("Save failed")); // connect(saveThread, SIGNAL(finished()), dlgTip, SLOT(unlock()));//显示正在保存提示对话框 // connect(saveThread, SIGNAL(finished()), saveThread, SLOT(deleteLater())); // connect(saveThread, &QThread::finished, this, [this] { @@ -111,8 +111,8 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare ProgCreateDlg dlg(mProgItem->mName, mProgItem->mWidth, mProgItem->mHeight, mProgItem->mRemark, widthsStr, mProgItem->isVer, this); dlg.edIsInsert->setChecked(mProgItem->isInsert); if(dlg.exec() != QDialog::Accepted) return; - mProgItem->mWidth = dlg.fdWidth->value(); - mProgItem->mHeight = dlg.fdHeight->value(); + mProgItem->mWidth = gProgWidth = dlg.fdWidth->value(); + mProgItem->mHeight = gProgHeight = dlg.fdHeight->value(); mProgItem->mRemark = dlg.fdRemark->toPlainText(); mProgItem->isInsert = dlg.edIsInsert->isChecked(); mProgItem->partLens.clear(); @@ -195,6 +195,7 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare action = new QAction(QIcon(":/res/program/Timer.png"), tr("Timer")+"2"); action->setData(EBase::Timer2); toolBar->addAction(action); +#ifndef leyide 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"), QApplication::applicationDirPath()+"/Demos"); @@ -226,7 +227,7 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare } }); toolBar->addAction(action); - +#endif toolBar->addSeparator(); action = new QAction(QIcon(":/res/program/preview.png"), tr("Play")+"/"+tr("Stop")); @@ -294,7 +295,7 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare if(mNewEleY+iNewHeight>mProgItem->mHeight) mNewEleY=0; auto type = data.toInt(); if(type==EBase::Image) { - auto files = QFileDialog::getOpenFileNames(this, tr("Select File"), gFileHome, EPhoto::filters()); + auto files = QFileDialog::getOpenFileNames(this, translate("","Select File"), gFileHome, EPhoto::filters()); for(int i=0; icount() == 1) mPageEditor->onClean(); else if(listPage->count() > 1) { auto item = (PageListItem*) listPage->currentItem(); - auto res = QMessageBox::information(this, tr("Tip Info"), tr("Are you sure you want to delete this program page?"), QMessageBox::Ok, QMessageBox::Cancel); + auto res = QMessageBox::information(this, translate("","Tip"), tr("Are you sure you want to delete this program page?"), QMessageBox::Ok, QMessageBox::Cancel); if(res == QMessageBox::Ok) { delete item; if(listPage->count() > 0) listPage->setCurrentRow(0); @@ -517,14 +518,14 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scroll->setWidgetResizable(true); scroll->setPalette(backTrans); - mTabsAttr->addTab(scroll, tr("widget properties")); + mTabsAttr->addTab(scroll, tr("Widget Properties")); scroll = new QScrollArea(); scroll->setFrameShape(QFrame::NoFrame); scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); scroll->setWidgetResizable(true); scroll->setPalette(backTrans); - mTabsAttr->addTab(scroll, tr("Page properties")); + mTabsAttr->addTab(scroll, tr("Program Properties")); mTabsAttr->setCurrentIndex(0); hBox->addWidget(mTabsAttr); @@ -578,7 +579,7 @@ bool ProgEditorWin::isProgChanged() { void ProgEditorWin::closeEvent(QCloseEvent *event) { 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); + auto res = QMessageBox::question(this, translate("","Tip"), tr("Do you want to save the modifications?"), QMessageBox::Yes, QMessageBox::No, QMessageBox::Cancel); if(res == QMessageBox::Yes) onSave(); else if(res == QMessageBox::Cancel) event->ignore(); } @@ -592,18 +593,18 @@ bool ProgEditorWin::save() { //停止每个幻灯片的元素 int cnt = listPage->count(); for(int i=0; i(listPage->item(i))->mScene->items(); - foreach(auto item, items) static_cast(item)->freeFiles(); + auto items = ((PageListItem*) listPage->item(i))->mScene->items(); + for(auto item : items) ((EBase*) item)->freeFiles(); } QDir progDir(mProgItem->mProgDir); if(! progDir.exists() && ! progDir.mkdir(mProgItem->mProgDir)) { - QMessageBox::critical(this, tr("Error"), tr("Create Dir failed")+": "+mProgItem->mProgDir); + QMessageBox::critical(this, translate("","Error"), tr("Failed to Create Forder")+": "+mProgItem->mProgDir); return 0; } auto pageNames = progDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks); for(QString &pageName : pageNames) if(! progDir.rename(pageName, pageName + PAGEDEL_SUFFIX)) { rtn = 0; - QMessageBox::critical(this, tr("Error"), tr("Rename fail when saving")+" "+pageName); + QMessageBox::critical(this, translate("","Error"), tr("Failed to Rename Forder")+": "+pageName); } //保存每个页面的元素和页面属性到page.json文档 mPageJsons.clear(); @@ -617,27 +618,27 @@ bool ProgEditorWin::save() { } } pageNames = progDir.entryList(QStringList("*" PAGEDEL_SUFFIX)); - foreach(QString pageName, pageNames) { + for(auto pageName : pageNames) { if(! QDir(mProgItem->mProgDir + "/" + pageName).removeRecursively()) { rtn = 0; - QMessageBox::critical(this, tr("Error"), tr("Remove Recursively fail when saving")+" "+pageName); + QMessageBox::critical(this, translate("","Error"), tr("Failed to Remove Recursively")+" "+pageName); } } for(int i=0; i(listPage->item(i))->mScene->items(); - foreach(auto item, items) static_cast(item)->loadFiles(); + for(auto item : items) static_cast(item)->loadFiles(); } return rtn; } void ProgEditorWin::onSave() { - auto waitingDlg = new WaitingDlg(this, tr("Saving..."), tr("Success")); + auto waitingDlg = new WaitingDlg(this, tr("Saving..."), translate("","Success")); waitingDlg->setWindowFlag(Qt::WindowCloseButtonHint, 0); waitingDlg->show(); - if(save()) waitingDlg->success(); - else waitingDlg->close(); - waitingDlg->exec(); - mProgItem->onSetProgram(); + if(save()) { + waitingDlg->success(); + mProgItem->onSetProgram(); + } else waitingDlg->close(); } void ProgEditorWin::onAddPage() { @@ -665,7 +666,7 @@ ProgCreateDlg::ProgCreateDlg(QString name, int width, int height, QString remark #ifdef Q_OS_WIN setWindowFlag(Qt::WindowContextHelpButtonHint, 0); #endif - setWindowTitle(tr("Solution Information")); + setWindowTitle(tr("Solution Info")); auto vBox = new VBox(this); vBox->setContentsMargins(6,0,6,6); auto hBox = new HBox(vBox); diff --git a/LedOK/program/progitem.cpp b/LedOK/program/progitem.cpp index 3261442..c64c79e 100644 --- a/LedOK/program/progitem.cpp +++ b/LedOK/program/progitem.cpp @@ -76,7 +76,7 @@ QPushButton:hover{background-color: #cccccc;} auto fdPassword = new QLineEdit; fdPassword->setEchoMode(QLineEdit::Password); - fdPassword->setPlaceholderText(QObject::tr("Input password")); + fdPassword->setPlaceholderText(translate("","Input Password")); hBox->addWidget(fdPassword); auto fdDrives = new ListWgt; @@ -102,8 +102,8 @@ QPushButton:hover{background-color: #cccccc;} dlg.accept(); return; } - if(fdDrives->count() <= 0) QMessageBox::warning(&dlg, QObject::tr("Tip"), QObject::tr("No checked USB device")); - else QMessageBox::warning(&dlg, QObject::tr("Tip"), QObject::tr("please select usb device in list")); + if(fdDrives->count() <= 0) QMessageBox::warning(&dlg, translate("","Tip"), QObject::tr("No checked USB device")); + else QMessageBox::warning(&dlg, translate("","Tip"), QObject::tr("please select usb device in list")); }); vBox->addWidget(btnBox); diff --git a/LedOK/program/sendprogramdialog.cpp b/LedOK/program/sendprogramdialog.cpp index ff4c604..9034090 100644 --- a/LedOK/program/sendprogramdialog.cpp +++ b/LedOK/program/sendprogramdialog.cpp @@ -78,7 +78,7 @@ SendProgramDialog::SendProgramDialog(QString progName, QWidget *parent) : QDialo hBox->addStretch(); - auto btnRefresh = new QPushButton(tr("Refresh")); + auto btnRefresh = new QPushButton(translate("","Refresh")); connect(btnRefresh, &QPushButton::clicked, this, [=] { int cnt = gDevicePanel->mDeviceTable->topLevelItemCount(); for(int i=0; ibtnUnlock, &QPushButton::clicked, item, [=] { if(! item->isLocked) return; bool ok; - auto pwd = QInputDialog::getText(this, tr("Input password"), tr("Input password"), QLineEdit::Password, QString(), &ok); + auto pwd = QInputDialog::getText(this, translate("","Input Password"), translate("","Input Password"), QLineEdit::Password, QString(), &ok); if(! ok) return; JObj json; json.insert("_id", "VerifyPassword"); json.insert("_type", "VerifyPassword"); json.insert("pwd", pwd); - auto waitingDlg = new WaitingDlg(item->btnUnlock, tr("VerifyPassword")+" ..."); + auto waitingDlg = new WaitingDlg(item->btnUnlock, tr("Verify Password")+" ..."); waitingDlg->show(); - auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json); + auto reply = NetReq("http://"+card.ip+":2016/settings").post(json); ConnReply(reply, waitingDlg) [=] { - QJsonDocument json; - auto err = checkReplyForJson(reply, &json); + JValue json; + auto err = errStrWithJson(reply, &json); if(! err.isEmpty()) { waitingDlg->close(); - QMessageBox::critical(this, QObject::tr("Error"), err); + QMessageBox::critical(this, translate("","Error"), err); return; } if(! json["result"].toBool()) { waitingDlg->close(); - QMessageBox::warning(this, tr("Tip Info"), tr("password is wrong")); + QMessageBox::warning(this, translate("","Tip"), tr("password is wrong")); return; } waitingDlg->success(); @@ -181,7 +181,7 @@ SendProgramDialog::SendProgramDialog(QString progName, QWidget *parent) : QDialo table->addCol("id", "ID", 130).margin(4); table->addCol("online", tr("Online"), 40); table->addCol("ip", "IP", 100); - table->addCol("size", tr("Screen Size"), 80).alignC(), + table->addCol("size", translate("","Screen Size"), 80).alignC(), table->addCol("alias", tr("Alias"), 120); table->addCol("playerVer", "Player Ver", 70); table->addCol("encrypt", tr("Security"), 40); diff --git a/LedOK/program/sendprogthread.cpp b/LedOK/program/sendprogthread.cpp index 0bbce5d..51fe31e 100644 --- a/LedOK/program/sendprogthread.cpp +++ b/LedOK/program/sendprogthread.cpp @@ -41,6 +41,7 @@ void SendProgThread::run() { req.insert("files", files); req.insert("idList", JArray{"aaa"}); req.insert("zVer", "xixun1"); + //req.insert("isLauncher", true); auto resNum = tcp.write(JToBytes(req)); tcp.flush(); if(resNum == -1 || ! tcp.waitForBytesWritten() || ! tcp.waitForReadyRead()) { @@ -200,6 +201,17 @@ void SendProgThread::run() { return; } tcp.close(); + QString err; + auto json = JFrom(resp, &err); + if(! err.isEmpty()) { + emit emErr(err); + return; + } + err = json["msg"].toStr(); + if(! err.isEmpty()) { + emit emErr(err); + return; + } emit emProgress(100); emit emErr("OK"); } diff --git a/LedOK/program/videosplitthread.cpp b/LedOK/program/videosplitthread.cpp index d0a4295..c49d972 100644 --- a/LedOK/program/videosplitthread.cpp +++ b/LedOK/program/videosplitthread.cpp @@ -2,6 +2,7 @@ #include #include #include +#include extern "C"{ #include #include @@ -17,105 +18,107 @@ VideoSplitThread::VideoSplitThread(int elew, int eleh, int maxLen, int sph, std: } void VideoSplitThread::run() { - AVFormatContext *in_fmt = avformat_alloc_context(), *out_fmt = 0; + AVFormatContext *fmt_in = avformat_alloc_context(), *fmt_out = 0; AVCodecContext *de_ctx = 0, *en_ctx = 0; QString err; char buf[AV_ERROR_MAX_STRING_SIZE]; int ret; { - if((ret = avformat_open_input(&in_fmt, file.constData(), 0, 0)) < 0) { + if((ret = avformat_open_input(&fmt_in, file.constData(), 0, 0)) < 0) { err = QString("Couldn't open input stream. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); goto free; } - if((ret = avformat_find_stream_info(in_fmt, nullptr)) < 0) { + if((ret = avformat_find_stream_info(fmt_in, 0)) < 0) { err = QString("Couldn't find stream information. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); goto free; } auto outfile = file+"-square.mp4"; - if((ret = avformat_alloc_output_context2(&out_fmt, 0, "mp4", outfile.constData())) < 0) { + if((ret = avformat_alloc_output_context2(&fmt_out, 0, "mp4", outfile.constData())) < 0) { err = QString("avformat_alloc_output_context2 fail. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); goto free; } - int vi_idx = -1; - AVStream *out_vi_stream; - for(uint ss=0; ssnb_streams; ss++) { - AVStream *stream = in_fmt->streams[ss]; - qDebug()<<"codec_type"<codecpar->codec_type); - if(stream->codecpar->codec_type == AVMEDIA_TYPE_DATA) continue; - AVStream *out_stream = avformat_new_stream(out_fmt, 0); - if(vi_idx == -1 && stream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { - vi_idx = ss; - out_vi_stream = out_stream; - } else { - if((ret = avcodec_parameters_copy(out_stream->codecpar, stream->codecpar)) < 0) { - err = QString("avcodec_parameters_copy fail. ") + av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); - goto free; - } + int video_idx = -1; + AVStream *stream_out_video; + for(uint ss=0; ssnb_streams; ss++) { + auto streamIn = fmt_in->streams[ss]; + qDebug() << streamIn->index << av_get_media_type_string(streamIn->codecpar->codec_type); + if(streamIn->codecpar->codec_type == AVMEDIA_TYPE_DATA) continue; + auto streamOut = avformat_new_stream(fmt_out, 0); + if((ret = avcodec_parameters_copy(streamOut->codecpar, streamIn->codecpar)) < 0) { + err = QString("avcodec_parameters_copy fail. ") + av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); + goto free; + } + streamOut->time_base = streamIn->time_base; + streamOut->start_time = streamIn->start_time; + streamOut->duration = streamIn->duration; + if(video_idx == -1 && streamIn->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + video_idx = ss; + stream_out_video = streamOut; } - out_stream->time_base = stream->time_base; - out_stream->start_time = stream->start_time; - out_stream->duration = stream->duration; } - if(vi_idx == -1) { + if(video_idx == -1) { err = "Didn't find a Video Stream"; goto free; } - auto codecpar = in_fmt->streams[vi_idx]->codecpar; + auto par_in_video = fmt_in->streams[video_idx]->codecpar; - auto decoder = avcodec_find_decoder(codecpar->codec_id); + auto decoder = avcodec_find_decoder(par_in_video->codec_id); if(decoder==0) { err = "Could not found Video Decoder"; goto free; } de_ctx = avcodec_alloc_context3(decoder); de_ctx->thread_count = 4; - avcodec_parameters_to_context(de_ctx, codecpar); + avcodec_parameters_to_context(de_ctx, par_in_video); if(avcodec_open2(de_ctx, decoder, 0) < 0) { err = "Could not open Video decode Ctx"; goto free; } - auto outPar = out_vi_stream->codecpar; - outPar->codec_type = AVMEDIA_TYPE_VIDEO; - outPar->codec_id = AV_CODEC_ID_H264; - outPar->format = AV_PIX_FMT_YUV420P; + auto par_out_video = stream_out_video->codecpar; + par_out_video->codec_type = AVMEDIA_TYPE_VIDEO; + par_out_video->codec_id = AV_CODEC_ID_H264; + par_out_video->format = AV_PIX_FMT_YUV420P; + par_out_video->profile = 77; + par_out_video->level = 42; if(isVer) { - outPar->height = maxLen; - outPar->width = mSPH*mWidths.size(); + par_out_video->height = maxLen; + par_out_video->width = mSPH * (int)mWidths.size(); } else { - outPar->width = maxLen; - outPar->height = mSPH*mWidths.size(); + par_out_video->width = maxLen; + par_out_video->height = mSPH * (int)mWidths.size(); } + qDebug().nospace()<<"out "<width<<" x "<height; - auto encoder = avcodec_find_encoder(outPar->codec_id); + auto encoder = avcodec_find_encoder(par_out_video->codec_id); if(encoder==0) { fprintf(stderr, "Codec not found\n"); goto free; } en_ctx = avcodec_alloc_context3(encoder); en_ctx->thread_count = 4; - avcodec_parameters_to_context(en_ctx, outPar); - en_ctx->bit_rate = outPar->width * outPar->height * 6; + avcodec_parameters_to_context(en_ctx, par_out_video); + en_ctx->bit_rate = par_out_video->width * par_out_video->height * 6; en_ctx->gop_size = de_ctx->gop_size; - en_ctx->max_b_frames = 3; - en_ctx->time_base = out_vi_stream->time_base; + en_ctx->max_b_frames = 0; + en_ctx->time_base = stream_out_video->time_base; if((ret = avcodec_open2(en_ctx, encoder, 0)) < 0) { err = QString("Open video encode ctx failed. ") + av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); goto free; } - if(out_fmt->flags & AVFMT_NOFILE) qDebug()<<"AVFMT_NOFILE"; - else if((ret = avio_open(&out_fmt->pb, outfile.constData(), AVIO_FLAG_WRITE)) < 0) { + if(fmt_out->flags & AVFMT_NOFILE) qDebug()<<"AVFMT_NOFILE"; + else if((ret = avio_open(&fmt_out->pb, outfile.constData(), AVIO_FLAG_WRITE)) < 0) { err = QString("avio_open fail. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); goto free; } - if((ret = avformat_write_header(out_fmt, 0)) < 0) { + if((ret = avformat_write_header(fmt_out, 0)) < 0) { err = QString("avformat_write_header fail. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); goto free; } auto sws_ctx = sws_getContext(de_ctx->width, de_ctx->height, de_ctx->pix_fmt, mEleW, mEleH, AV_PIX_FMT_RGB32, SWS_FAST_BILINEAR, 0, 0, 0); - auto out_sws_ctx = sws_getContext(outPar->width, outPar->height, AV_PIX_FMT_RGB32, outPar->width, outPar->height, AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, 0, 0, 0); + auto out_sws_ctx = sws_getContext(par_out_video->width, par_out_video->height, AV_PIX_FMT_RGB32, par_out_video->width, par_out_video->height, AV_PIX_FMT_YUV420P, SWS_FAST_BILINEAR, 0, 0, 0); auto packet = av_packet_alloc(); auto frm = av_frame_alloc(); @@ -123,20 +126,24 @@ void VideoSplitThread::run() { uint8_t *img_data[4]{new uchar[img_linesize[0] * mEleH]}; QImage img(img_data[0], mEleW, mEleH, img_linesize[0], QImage::Format_ARGB32, imgCleanupHandler, img_data[0]); - int out_img_linesize[4]{(outPar->width*4+63)/64*64}; - uint8_t *out_img_data[4]{new uchar[out_img_linesize[0] * outPar->height]}; - QImage out_img(out_img_data[0], outPar->width, outPar->height, out_img_linesize[0], QImage::Format_ARGB32, imgCleanupHandler, out_img_data[0]); + int out_img_linesize[4]{(par_out_video->width*4+63)/64*64}; + uint8_t *out_img_data[4]{new uchar[out_img_linesize[0] * par_out_video->height]}; + QImage out_img(out_img_data[0], par_out_video->width, par_out_video->height, out_img_linesize[0], QImage::Format_ARGB32, imgCleanupHandler, out_img_data[0]); QPainter painter(&out_img); while(1) { - if((ret = av_read_frame(in_fmt, packet)) < 0) { + if((ret = av_read_frame(fmt_in, packet)) < 0) { if(ret!=AVERROR_EOF) { err = QString("Read packet fail: ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); break; } ret = avcodec_send_packet(de_ctx, 0); } else { - if(packet->stream_index != vi_idx) { - av_interleaved_write_frame(out_fmt, packet); + if(packet->stream_index != video_idx) { + ret = av_interleaved_write_frame(fmt_out, packet); + if(ret < 0) { + err = QString("write_frame(A) failed. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); + goto free2; + } continue; } ret = avcodec_send_packet(de_ctx, packet); @@ -171,40 +178,51 @@ void VideoSplitThread::run() { } } auto pts = frm->pts; + auto pkt_dts = frm->pkt_dts; auto dur = frm->pkt_duration; av_frame_unref(frm); frm->pts = pts; + frm->pkt_dts = pkt_dts; frm->pkt_duration = dur; frm->format = AV_PIX_FMT_YUV420P; - frm->width = outPar->width; - frm->height = outPar->height; + frm->width = par_out_video->width; + frm->height = par_out_video->height; if((ret = av_frame_get_buffer(frm, 0)) < 0) { err = QString("av_frame_get_buffer fail. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); goto free2; } - sws_scale(out_sws_ctx, out_img_data, out_img_linesize, 0, outPar->height, frm->data, frm->linesize); + sws_scale(out_sws_ctx, out_img_data, out_img_linesize, 0, par_out_video->height, frm->data, frm->linesize); ret = avcodec_send_frame(en_ctx, frm); - int pro = frm->pts*100/out_vi_stream->duration; - if(pro > lastPro) { - lastPro = pro; - emit emProgress(pro); + int progress = frm->pts * 100 / stream_out_video->duration; + if(progress > lastProgress) { + lastProgress = progress; + emit emProgress(progress); } } if(ret < 0) { - err = QString("avcodec_send_frame fail. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); + err = QString("avcodec_send_frame failed. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); goto free2; } while((ret = avcodec_receive_packet(en_ctx, packet)) != AVERROR(EAGAIN)) { if(ret < 0) { if(ret!=AVERROR_EOF) err = QString("Receive frame fail: ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); else { - av_interleaved_write_frame(out_fmt, 0); - av_write_trailer(out_fmt); + ret = av_interleaved_write_frame(fmt_out, 0); + if(ret < 0) { + err = QString("write_frame(0) failed. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); + goto free2; + } + av_write_trailer(fmt_out); emit emProgress(100); } goto free2; } else { - av_interleaved_write_frame(out_fmt, packet); + packet->stream_index = video_idx; + ret = av_interleaved_write_frame(fmt_out, packet); + if(ret < 0) { + err = QString("write_frame(V) failed. ")+av_make_error_string(buf, AV_ERROR_MAX_STRING_SIZE, ret); + goto free2; + } } } } @@ -218,8 +236,8 @@ void VideoSplitThread::run() { free: avcodec_free_context(&de_ctx); avcodec_free_context(&en_ctx); - avformat_close_input(&in_fmt); - avio_closep(&out_fmt->pb); - if(out_fmt) avformat_free_context(out_fmt); + avformat_close_input(&fmt_in); + avio_closep(&fmt_out->pb); + if(fmt_out) avformat_free_context(fmt_out); emit emErr(err); } diff --git a/LedOK/program/videosplitthread.h b/LedOK/program/videosplitthread.h index 69f8763..b798596 100644 --- a/LedOK/program/videosplitthread.h +++ b/LedOK/program/videosplitthread.h @@ -24,8 +24,8 @@ public slots: stoped = true; } private: - int lastPro{0}; - std::atomic_bool stoped{false}; + int lastProgress = 0; + std::atomic_bool stoped = false; }; #endif // VIDEOSPLITTHREAD_H diff --git a/LedOK/res.qrc b/LedOK/res.qrc index 1592669..c01339c 100644 --- a/LedOK/res.qrc +++ b/LedOK/res.qrc @@ -1,37 +1,48 @@ - res/signal-0.png - res/signal-1.png - res/signal-2.png - res/signal-3.png - res/signal-4.png - res/signal-5.png css.css res/AdvParam.png res/AppSetting.png res/AppSettingTip.png res/ArrowDropDown.png res/ArrowDropUp.png + res/Calendar-gray.png + res/Calendar.png res/CheckBoxChecked.png res/CheckBoxUnchecked.png - res/DeviceNum_All.png - res/FlashArrow.png - res/Lock.png - res/offline.png - res/online.png - res/UnLock.png - res/info.png - res/deviceReadbackPic.png res/DeviceManager_s.png res/DeviceManager_u.png + res/DeviceNum_All.png res/DeviceSetting_s.png res/DeviceSetting_u.png + res/FlashArrow.png res/GuangYingPin_s.png res/GuangYingPin_u.png res/Hdmi.png + res/Lock.png + res/Logo-citta.png + res/Logo-leyide.png res/Logo.png - res/Logo-leyide.png - res/Logo-citta.png + res/ProgramManager_s.png + res/ProgramManager_u.png + res/UnLock.png + res/WndClose.png + res/WndMaximize.png + res/WndMinimize.png + res/bnBrightnessAdjustMent_s.png + res/bnNetConfig_s.png + res/bnPowerControl_s.png + res/bnVerifyClock_s.png + res/deviceReadbackPic.png + res/encrypt.png + res/groupbox-checked.png + res/groupbox-unchecked.png + res/info.png + res/loop.png + res/next.png + res/offline.png + res/online.png + res/previous.png res/program/AClock.png res/program/Add.png res/program/AddPlan.png @@ -48,17 +59,7 @@ res/program/Copy.png res/program/Cut.png res/program/DClock.png - res/program/DateSelect.png - res/program/DateSelect_e.png - res/program/DateSelect_enable.png res/program/Delete.png - res/program/demo-video.png - res/program/TextAlignHC.png - res/program/TextAlignHL.png - res/program/TextAlignHR.png - res/program/TextAlignVB.png - res/program/TextAlignVC.png - res/program/TextAlignVT.png res/program/Gif.png res/program/GoDown.png res/program/GoUp.png @@ -79,6 +80,12 @@ res/program/Setting.png res/program/Temp.png res/program/Text.png + res/program/TextAlignHC.png + res/program/TextAlignHL.png + res/program/TextAlignHR.png + res/program/TextAlignVB.png + res/program/TextAlignVC.png + res/program/TextAlignVT.png res/program/TileFull.png res/program/TileH.png res/program/TileV.png @@ -86,30 +93,22 @@ res/program/Weather.png res/program/Web.png res/program/Window.png - res/program/preview.png - res/program/previewStop.png res/program/bnExport_s.png res/program/bnExport_u.png res/program/bnSearch.png res/program/bnSend_s.png res/program/bnSend_u.png - res/ProgramManager_s.png - res/ProgramManager_u.png - res/WndClose.png - res/WndMaximize.png - res/WndMinimize.png - res/bnBrightnessAdjustMent_s.png - res/bnNetConfig_s.png - res/bnPowerControl_s.png - res/bnVerifyClock_s.png - res/encrypt.png - res/groupbox-checked.png - res/groupbox-unchecked.png - res/loop.png - res/next.png - res/previous.png + res/program/demo-video.png + res/program/preview.png + res/program/previewStop.png res/random.png res/reddot.png + res/signal-0.png + res/signal-1.png + res/signal-2.png + res/signal-3.png + res/signal-4.png + res/signal-5.png res/splash.png res/test.png res/video-pre.png diff --git a/LedOK/res/program/DateSelect.png b/LedOK/res/Calendar-b.png similarity index 100% rename from LedOK/res/program/DateSelect.png rename to LedOK/res/Calendar-b.png diff --git a/LedOK/res/program/DateSelect_e.png b/LedOK/res/Calendar-gray.png similarity index 100% rename from LedOK/res/program/DateSelect_e.png rename to LedOK/res/Calendar-gray.png diff --git a/LedOK/res/program/DateSelect_enable.png b/LedOK/res/Calendar.png similarity index 100% rename from LedOK/res/program/DateSelect_enable.png rename to LedOK/res/Calendar.png diff --git a/LedOK/res/exclam.png b/LedOK/res/exclam.png new file mode 100644 index 0000000..55c70df Binary files /dev/null and b/LedOK/res/exclam.png differ diff --git a/LedOK/tools.cpp b/LedOK/tools.cpp index 3c56c70..dded232 100644 --- a/LedOK/tools.cpp +++ b/LedOK/tools.cpp @@ -94,12 +94,12 @@ void Tools::saveImg(const QString& dir, const QFontMetrics& metric, const QFont& file.close(); imgs.insert(name, md5); } -void Tools::saveImg2(const QString& dir, const QFontMetrics& metric, const QFont& font, const QColor& color, JArray& imgs, const QString& str, const QString& name) { +void Tools::saveImg2(const QString& dir, const QFontMetrics& metric, const QFont& font, const QColor& color, JArray& imgs, const QString& str, const QString& name, int height) { JObj obj{ {"name", name} }; if(! str.isEmpty()) { - QImage img(metric.horizontalAdvance(str), metric.lineSpacing(), QImage::Format_ARGB32); + QImage img(metric.horizontalAdvance(str), height ? height : metric.lineSpacing(), QImage::Format_ARGB32); obj.insert("picWidth", img.width()); obj.insert("picHeight", img.height()); img.fill(Qt::transparent); diff --git a/LedOK/tools.h b/LedOK/tools.h index 88af649..94e23a1 100644 --- a/LedOK/tools.h +++ b/LedOK/tools.h @@ -1,7 +1,6 @@ #ifndef TOOLS_H #define TOOLS_H -#include "program/progitem.h" #include "gutil/qjson.h" #include #include @@ -13,9 +12,6 @@ #include #include -extern QTextEdit *gFdResInfo; -extern ProgItem *gProgItem; - class Tools : public QObject { Q_OBJECT public: @@ -29,7 +25,7 @@ public: 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 void saveImg2(const QString&, const QFontMetrics&, const QFont&, const QColor&, JArray&, const QString&, const QString&, int = 0); static QColor int2Color(int value); static int color2Int(const QColor& color); static QBrush getBrush(const QColor& color); diff --git a/LedOK/ts/app_en.ts b/LedOK/ts/app_en.ts index 2e7546a..11842fb 100644 --- a/LedOK/ts/app_en.ts +++ b/LedOK/ts/app_en.ts @@ -2,1063 +2,537 @@ - ChangePasswordForm + - - Old password - Old password - - - - New password - New password - - - - Repeat again - Repeat again - - - - - - - - Tip - Tip - - - - Please input old password - Please input old password - - - - Old password is wrong - Old password is wrong - - - - Please enter a password with more than 3 characters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Error - - The new password is not consistent in two times + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Please select screen first - - Password changed successfully - Password changed successfully - - - - CtrlAdvancedPanel - - - Advanced - Advanced - - - - Screen Width(pixel) - Screen Width(pixel) - - - - Width - Width - - - - - Height - Height - - - - - - - Set - Set - - - - Alias - Alias - - - - Web (Plat 2) Address + + + + + + + + + + + + + + + + + + + + + + + + Success - - Setting Camera Range - - - - - - - Set Camera Range - - - - + + + + + + + Setting - - Traffic screen settings - - - - - Setting protocol ... - - - - - Set protocol - - - - - Getting protocol ... - - - - - Get protocol - - - - - - Port - - - - - Realtime (Plat 4) 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 - - - - 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 - - - - - SetScreenSize - Set Screen Size - - - - - - - - Success - Success - - - - Compant ID: - Company ID - - - - Compant ID - Company ID - - - - - SetOnlineAddr - Set Web server address - - - - - ClearRealtimeServer - Clear - - - - - - - - - SetRealtimeServer - Set realtimer address - - - - - 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 - - - - - - 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 - - - - - Upload error - - - - - Upgrading - - - - - 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 ... + + + + + + + Screen Size + + + + + + + + + - Get card work mode + Set - - Input password - Input password + + + + Getting + + + + + + Get + + + + + + + Unlock + + + + + + + + + + Uninstall + + + + + + + + Upload + + + + + + + + + Install + + + + + + Wait for + + + + + + + + + + + + + + + + Select File + - Change Password - Change Password - - - - Get Receive Card Num + + + + + + + + + + + + + + + + + + + Set - - Resolution Config + + + + + + + + Input Password - - Full screen - - - - - Part - - - - - Display Mode - - - - - Screen Position - - - - - Offset - - - - - Camera Distance - - - - Min - Min - - - - Hidden Settings - - - - - Click right button to hide - - - - - Get MCU Version - - - - - Baud Config - - - - - Model - - - - - Uart - - - - - Baud - - - - - + + Get - - Timing Reboot + + + + + + + + + + + + + + + + + + + + + + Readback - - Protocol + + + + + + + + Refresh - - Server + + Date + + Password + + + + + Lock + + + + + + + + Send + + + + + + + + + + + + + Clear + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - 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 - - - - - SetCardAlias - Set alias - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Tip - Tip - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NoSelectedController - Please select screen first - - - - InputWidthTip - Please enter the correct width pixel value - - - - InputHeightTip - Please enter the correct height pixel value - - - - Password is error - Password is error - - - - CtrlBrightPanel - + + + + + + + + + + + + + @@ -1077,24 +551,975 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tip - Tip + - - - - - - - - - - - - NoSelectedController - Please select screen first + + + + + + + + + + + + + + + + + + + + Close + + + + + + + + + + + + + + Device replied + + + + + + + Fail + + + + + + + + + + + + + + Basic Properties + + + + + Getting + + + + + CalendarButton + + + Select a Date + + + + + ChangePasswordForm + + + Old password + + + + + New password + + + + + Repeat again + + + + + Please input old password + + + + + Old password is wrong + + + + + Please enter a password with more than 3 characters + + + + + The new password is not consistent in two times + + + + + Password changed successfully + + + + + CtrlAdvancedPanel + + + Advanced + + + + + Screen Width(pixel) + + + + + Width + + + + + + Height + + + + + Alias + + + + + Web (Plat 2) Address + + + + + Traffic screen settings + + + + + Setting protocol ... + + + + + Set protocol + + + + + Getting protocol ... + + + + + Get protocol + + + + + + Port + + + + + Realtime (Plat 4) Address + + + + + Firmware Management + + + + + update or uninstall + + + + + Check Apk + + + + + Uninstall + + + + + Running check + + + + + Restart + + + + + Check Log + + + + + Start LedSet4.0 + Start LedSet4.0 (Apk Display2.0 and higher) + + + + Open ADB + Open ADB debugging function + + + + + + + + + Clear Program + + + + + Config + + + + + Restore to default + + + + + Taxi top screen configuration + + + + + + Service:High Out of service:Low + + + + + + Service:Low Out of service:High + + + + + Bind Taxihub identity certificate + + + + + Rotate + + + + + Min brightness + + + + + Max brightness + + + + + Compant ID: + Company ID + + + + Compant ID + Company ID + + + + + SetOnlineAddr + Set Web server address + + + + + ClearRealtimeServer + Clear + + + + + + + + + SetRealtimeServer + Set realtimer address + + + + + RestartAndroid + Restart + + + + + running + + + + + + no running + + + + + + Check Apk Version + + + + + + UninstallSoftware + Uninstall + + + + + Check apk running status + + + + + + OpenAdb + Open ADB debugging function + + + + + AliIotSetting + + + + + Software Version Info + + + + + Package + + + + + Version + + + + + + Package name is null + + + + + Clearing Program + + + + + + Timeout + + + + + + + + Failed + + + + + Getting Log + + + + + 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 + + + + + + Cannot Open File + + + + + Uploading + + + + + Update + + + + + + Set Display Mode + + + + + + Get Display Mode + + + + + + + + + + + + Screen Offset + + + + + Open file Failed + + + + + + No VehPlayer File + + + + + + Failed to Read File + + + + + Setting Wallpaper + + + + + + Set Wallpaper + + + + + System Updating + + + + + + System Update + + + + + Upload error + + + + + Identity Certificate + + + + + + + Lock Card + + + + + + + + + + + Binding certificate + + + + + Upgrading + + + + + Getting MCU Version + + + + + + MCU Version + + + + + 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 + + + + + Change Password + + + + + Get Receive Card Num + + + + + Player Debug + + + + + + Resolution Config + + + + + Full screen + + + + + Part + + + + + Display Mode + + + + + Screen Position + + + + + + Offset + + + + + + + + + Camera Distance + + + + + Hidden Settings + + + + + Click right button to hide + + + + + Get MCU Version + + + + + Baud Config + + + + + Model + + + + + Uart + + + + + Baud + + + + + 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 + + + + + Restore to default relolution + + + + + + SetHighForBusy + Set level for busy + + + + + GetStateForBusy + Get level of busy + + + + + SetCardAlias + Set alias + + + + InputWidthTip + Please enter the correct width pixel value + + + + InputHeightTip + Please enter the correct height pixel value + + + + Password is error + + + + + CtrlBrightPanel @@ -1154,7 +1579,7 @@ Save file - Save file + @@ -1202,12 +1627,12 @@ Start Time - Start Time + End Time - End Time + @@ -1220,12 +1645,6 @@ GetAutoBrightnessTask Get brightness schedule - - - - Error - Error - Brightness Config @@ -1234,17 +1653,17 @@ Auto - Auto + Manual - Manual + Schedule - Schedule + @@ -1264,87 +1683,57 @@ Sensitivity - Sensitivity + Minbrightness Minimum Brightness - - - - - Set - Set - - Upload - Upload file - - - - - - - Readback - Readback - - - - ReadbackTable - Readback - - - - Refresh - Refresh + Upload File + Cur Brigntness - Cur Brigntness + Brightness value - Brightness value + Default brightness - Default brightness + Add - Add - - - - Clear - Clear + Delete - Delete + Import - Import + Export - Export + Apply - Apply + @@ -1355,175 +1744,150 @@ CtrlHdmiPanel - + HDMI Configuration Video source configuration - + Manual - Manual + - + Schedule - Schedule + - - - - - Tip - Tip - - - - - - - NoSelectedController - Please select screen first - - - - + + + + SyncSwitch Switch video source from HDMI-IN port - - + + AnSyncSwitch Switch video source from Async box - + IsSync Readback video source - + Import File - + Save File Save file - - + + Sync Schedule - - + + SetTimingHdmiInTask Set video source form HDMI-IN schedule task - + GetTimingHdmiInTask Get video source form HDMI-IN schedule task - - + + Async - Async + - - Set - Set + + Auto Switch + - - - Readback - Readback - - - + Start Time - Start Time + - + End Time - End Time + - + SUN - SUN + - + MON - MON + - + TUE - TUE + - + WED - WED + - + THU - THU + - + FRI - FRI + - + SAT - SAT + - + Add - Add + - - + + Apply - Apply + - - Clear - Clear - - - + Delete - Delete + - + Import - Import + - + Export - Export + - + By default, the asynchronous content is played, and the synchronous signal content is played in the fixed time period By default, asynchronous content is played, and synchronous hdmi-in port input content is played in a fixed time period @@ -1531,185 +1895,128 @@ CtrlNetworkPanel - + Wire Enther(RJ45) Configuration - Wire Enther(RJ45) Configuration - - - - DHCP - + Specify IP - Specify IP + - + IP Address - IP Address + - + Gateway - Gateway + - + DNS Address - DNS Address + - - - - Set - Set + + WiFi Config + - - - - - Readback - Readback + + Enable WiFi + - - WIFI Configuration - WiFi Configuration - - - - WiFi Mode - WiFi Mode - - - + Cellular Config - Cellular Config + - + Enable Cellular Data - Enable Cellular Data + - + Get cellular network status information - Get cellular network status information + - + Through the check status button Through the "check status" button, you can automatically match the country code MCC, and then select "operator" to get the corresponding APN information. - + Country ID(mcc): - Country ID(mcc): + - - + + Carrier Name - Carrier Name + - + APN(Required) - APN(Required) + - + Flight Mode - Flight Mode + - + WiFi name - WiFi name + - - - + + + Password - Password + - - - Input password - Input password - - - + Scan - Scan + - - Ap Mode - AP + + Enable AP + - + OFF - OFF + - + ON - ON + - + AP name - AP name + - + Subnet mask - Subnet mask + - + Input ap name Input AP name - - - - - - - - - - - - - - Tip - Tip - - - - - - - - - - - - - - NoSelectedController - Please select screen first - @@ -1722,27 +2029,27 @@ Attention - Attention + Please input IP address! - Please input IP address! + Please input Mask address! - Please input Mask address! + Please input Gateway address! - Please input Gateway address! + Please input DNS address! - Please input DNS address! + @@ -1753,339 +2060,335 @@ DHCP IP - DHCP IP + STATIC IP - STATIC IP + - - - + + + + + ConfigurationWiFi Configuration WiFi - - - IsPortableHotSpot - Get AP or WiFi + + + Get AP or WiFi + - + GetWifiList Scan WiFi list - - - ConfigurationHotSpot - Configuration AP HotSpot + + + + + + + Config Hotspot + - - success - success - - - + WifiName - WifiName + - + ApName Ap Name - - + + GetCurrentAPN Get Current Apn - + GetSIMStatus Get SIM Status - - + + SetAPN Set APN - - 状态: - Status: + + Status + - - Error - Error - - - + 未知 unknown - + 锁定状态,需要用户的PIN码解锁 Lock status, need user's pin code to unlock - + 锁定状态,需要用户的PUK码解锁 In the locked state, the PUK code of the user is required to be unlocked - + 锁定状态,需要网络的PIN码解锁 In the locked state, the PIN code of the user is required to be unlocked - + 就绪 be ready - + no checked sim card - no checked sim card + - + 国家码: MCC: - + 号码: number: - + 用户: User name: - + 信号: Signal: - + 信号正常 Signal OK - + 不在服务区 Not in service area - + 仅限紧急呼叫 Emergency call only - + 射频已经关闭 RF off - + 网络: Network type: - + 网络类型未知 unKnown - + GPRS网络 GPRS - + EDGE网络 EDGE - + UMTS网络 UMTS - + CDMA网络,IS95A 或 IS95B. CDM - + EVDO网络, revision 0. EVDO,revision 0. - + EVDO网络, revision A. EVDO,revision A. - + 1xRTT网络 1xRTT - + HSDPA网络 HSDPA - + HSUPA网络 HSUPA - + HSPA网络 HSPA - + 漫游: roam: - + Yes - Yes + - + No - No + - + 数据连接状态: Data connection status: - + 断开 OFF - + 正在连接 connecting - + 已连接 Connected - + 暂停 suspend - + 数据活动休眠状态: Data active sleep state: - + 活动,但无数据发送和接收 Active, but no data sent and received - + 活动,正在接收数据 Activity, receiving data - + 活动,正在发送数据 Activity, sending data - + 活动,正在接收和发送数据 Activity, receiving and sending data - + 休眠状态 Sleep state - + 信号强度: Signal strength: - + Set APN Info - + User - + Type - + Server - + Port - + Proxy - + MMS Port - + MMS Proxy - - + + SetSwitchSimData - SetSwitchSimData + - - + + ContrFlightMode Set flight mode - - + + GetFlightModeState Readback flight mode state @@ -2104,25 +2407,7 @@ On - On - - - - - - - - Tip - Tip - - - - - - - - NoSelectedController - Please select screen first + @@ -2151,7 +2436,7 @@ PowerSchedule (*.pjs) - PowerSchedule (*.pjs) + @@ -2177,118 +2462,102 @@ Manual - Manual + Schedule - Schedule + Power - Power - - - - - Readback - Readback + Start Time - Start Time + End Time - End Time + SUN - SUN + MON - MON + TUE - TUE + WED - WED + THU - THU + FRI - FRI + SAT - SAT + Add - Add + Apply - Apply - - - - Clear - Clear + Delete - Delete + Import - Import + Export - Export + It is power off state outside the schedule time period - It is power off state outside the schedule time period + Clear Schedule Cancel Schedule - - - Tip Info - Tip Info - Clear schedule task? - Clear schedule task? + @@ -2302,28 +2571,28 @@ Set Password - Set Password + Original password - Original password + original password - original password + New password - New password + Repeat new password - Repeat new password + @@ -2331,36 +2600,17 @@ Set encryption - Set encryption + Cancel encryption - Cancel encryption + Enter again - Enter again - - - - - - - - - - - - Tip - Tip - - - - - NoSelectedController - Please select screen first + @@ -2383,15 +2633,10 @@ InputRepeatPasswordNotSameTip The two passwords are inconsistent - - - Tip Info - Tip Info - After setting the password, please remember the password and record it. If you forget the password, the device will be unable to operate. Are you sure you want to continue with this operation? - After setting the password, please remember the password and record it. If you forget the password, the device will be unable to operate. Are you sure you want to continue with this operation? + @@ -2401,24 +2646,12 @@ SetControllerPassword Set password - - - - Error - Error - - - - - Success - Success - Modify password - Modify password + @@ -2434,12 +2667,12 @@ Test Screen - Test Screen + Line test - Line test + @@ -2447,7 +2680,7 @@ Red - Red + @@ -2455,7 +2688,7 @@ Green - Green + @@ -2463,7 +2696,7 @@ Blue - Blue + @@ -2471,12 +2704,12 @@ White - White + Vertical - Vertical + @@ -2487,13 +2720,13 @@ Horizontal - Horizontal + Speed - Speed + @@ -2503,24 +2736,24 @@ Line Distance - Line Distance + Test - Test + Gradation test - Gradation test + Only the gray value is displayed - Only the gray value is displayed + @@ -2530,60 +2763,29 @@ Color test - Color test + Gradient - Gradient - - - - Clear - Clear + Reset Loop - - - Success - Success - Anycast - Anycast + Stop - Stop - - - - - - - - - - Tip - Tip - - - - - - - - - NoSelectedController - Please select screen first + @@ -2609,7 +2811,7 @@ Reset loop mode - Reset loop mode + @@ -2623,48 +2825,18 @@ Verify to Computer time - Verify to Computer time + Cur time of controller - Cur time of controller + LAN - LAN - - - - - - - - - - - - - - Tip - Tip - - - - - - - - - - - - - - NoSelectedController - Please select screen first + @@ -2711,7 +2883,7 @@ msec - msec + @@ -2737,22 +2909,22 @@ Lora identity - Lora identity + (min/time) - (min/time) + identification code - identification code + Time offset(msec) - Time offset(msec) + @@ -2762,7 +2934,7 @@ Volume - Volume + @@ -2773,74 +2945,56 @@ Slave - Slave + NTP Server - NTP Server + NTP Server address - NTP Server address + TimeZone Time zone - - - - - - - Set - Set - Language: - Language: + Enable Synchronous playing - Enable Synchronous playing + Sync time interval - Sync time interval - - - - - - - - Readback - Readback + Master - Master + Identification Code - Identification Code + SetNtpServer - SetNtpServer + @@ -2875,13 +3029,13 @@ SyncTime - SyncTime + GetNtpServer - GetNtpServer + @@ -2898,22 +3052,6 @@ CtrlVolumePanel - - - - - - Tip - Tip - - - - - - - NoSelectedController - Please select screen first - @@ -2956,118 +3094,102 @@ Volume Control - Volume Control + Manual - Manual + Schedule - Schedule + Volume - Volume - - - - Set - Set - - - - - Readback - Readback + Default volume - Default volume + Add - Add - - - - Clear - Clear + Delete - Delete + Import - Import + Export - Export + Volume value - Volume value + Start Time - Start Time + End Time - End Time + SUN - SUN + MON - MON + TUE - TUE + WED - WED + THU - THU + FRI - FRI + SAT - SAT + Apply - Apply + @@ -3075,41 +3197,6 @@ Reminder: the display screen is the default brightness outside the fixed time period - - Def - - - - - - - - - - - - - Device replied - - - - - - - - - - Success - Success - - - - - - Fail - Fail - - DevicePanel @@ -3123,14 +3210,7 @@ Online Online - Online - - - - - Refresh - Refresh - Refresh + @@ -3138,7 +3218,7 @@ Specify IP Specify IP - Specify IP + @@ -3147,14 +3227,14 @@ Current Screen - Current screen + none - none + @@ -3169,22 +3249,22 @@ FPGA Version - FPGA Version + Brightness Level - Brightness Level + Android OS Resolution - Android OS Resolution + Firmware Version - Firmware Version + @@ -3197,11 +3277,6 @@ Detail Info - Detail Info - - - - Getting @@ -3212,34 +3287,29 @@ Search - Search + Attention - Attention + Please input IP address! - Please input IP address! + Cancel - Cancel + Screen ID - Screen ID - - - - Screen Size - Screen Size + @@ -3250,7 +3320,7 @@ Screenshot - Screenshot + @@ -3267,12 +3337,12 @@ Brightness Adj. - Brightness Adj. + Power Control - Power Control + @@ -3282,7 +3352,7 @@ Time Sync - Time Sync + @@ -3292,12 +3362,12 @@ Password - Password + Advanced - Advanced + @@ -3307,13 +3377,13 @@ Test - Test + Multi screen operation - Multi screen operation + @@ -3321,157 +3391,125 @@ selected num Selected number - - - - Clear - Clear - More Info - More Info + Screen Brightness - Screen Brightness + Power Status - Power Status + Security encryption - - - Getting - - - - - - Error - Error - - - - Input password - Input password - - VerifyPassword - Verify Password - - - - Tip Info - Tip Info + Verify Password + password is wrong - password is wrong + 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 + @@ -3484,78 +3522,78 @@ X - X + Y - Y + W - W + H - H + Border - Border + - - + + None - None + - + Effect - Effect + Rotate - Rotate + Opacity - + - + Blink - Blink + Speed - Speed + Slow - Slow + Moderate - Moderate + Fast - Fast + @@ -3568,306 +3606,301 @@ - - - - + + + + s - + Duration - + Entry - - - - Random - - - - - - Expand horizontal - - - - - - Expand vertical - - - Expand to left + Random - Expand to top + Expand horizontal - Expand to right + Expand vertical - Expand to bottom + Expand to left - Zoom in + + Expand to top - Zoom in from left-top + + Expand to right - Zoom in from right-top + + Expand to bottom - Zoom in from right-bottom + Zoom in - Zoom in from left-bottom + Zoom in from left-top - - Rotate zoom + Zoom in from right-top - - Rotate zoom reverse + Zoom in from right-bottom - Fade in + Zoom in from left-bottom - Move to left + Rotate zoom - Move to top + Rotate zoom reverse - - Move to right + 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 - + Breathe - + - + Freq - + EDClock - - - MON - MON - - - - TUE - TUE - - - - WED - WED - - THU - THU + MON + - FRI - FRI + TUE + - SAT - SAT + WED + + THU + + + + + FRI + + + + + 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 + @@ -3875,27 +3908,27 @@ Temperature - Temperature + Humidity - Humidity + Noise - Noise + Wind Speed - Wind Speed + Wind Direction - Wind Direction + @@ -3950,75 +3983,60 @@ W - W + NW - - - Basic Properties - Basic properties - Title - Title + Compensation - Compensation + Left - Left + Center - Center + Right - Right + Single scroll - Single scroll + Speed - Speed + Back Color - Back Color + EGif - - Basic Properties - Basic properties - - - + File - File - - - - Select File - Select File + @@ -4031,35 +4049,35 @@ Media List - Media List + Text - Text + Photo - Photo + Video - Video + Gif - Gif + @@ -4075,47 +4093,70 @@ AClock Analog Clock - - - - - Select File - Select File - Environment - Environmental Monitoring + Timer - Timer + EPhoto - - Basic Properties - Basic properties - - - + File - File + - - Select File - Select File - - - + Image Read Error - Image Read Error + + + + + Direction + + + + + Scroll + + + + + No + + + + + Right -> Left + From right to left + + + + Bottom -> Top + From bottom to top + + + + Left -> Right + From left to right + + + + Top -> Bottom + Frome top to bottom + + + + Speed + @@ -4126,197 +4167,187 @@ EText - + Enter your text - Enter your text + - - Basic Properties - Basic properties - - - + Back Color - Back Color + - + Kerning - Kerning + - + Line Height - + PageCount: - PageCount: + - + page Page - + Import txt File - - Select File - Select File - - - + Fail - Fail + - + Cannot Open File - + Play Properties - + Flip - Flip + - + Scroll - Scroll + - + Static - Static + - + + New Format + + + + Text Color - + Colorful Text - - Head-Tail Spacing - Spacing + + Tail Spacing + - - Scroll Style - Direction + + 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 + + Speed + ETimer - + day Days - + hour Hours - + min Mins - + sec Secs - - Basic Properties - Basic properties - - - + Count Down - Count Down + - + Count Up - Count Up + - - Time - Target Time + + Target Time + + + + + Day + - Day - Day + Hour + - Hour - Hour + Min + - Min - Min - - - Sec - Sec + - + Multiline - Multiline + - + Text - Text + @@ -4324,159 +4355,138 @@ There are - + Days - + Hours - + Mins - + Secs - - - - - Basic Properties - Basic properties + Count Down - Count Down + Count Up - Count Up + - Time - Target Time + Target Time + Font Size - + Line Height - + Foreground Color - + Line Background - + Background Color - + EVideo - - Basic Properties - Basic properties - - - + File - File + - + Play Properties - - Select File - Select File - - - + Play Times - Play Times + - + + Use SW + + + + Video Transcoding - - + + Video Transcoding Progress - - - - Error - Error - Video - Video + Flash - Flash + EWeb - - Basic Properties - - - - + Zoom - + Refresh every - + - + Offset - + Scale - + @@ -4505,67 +4515,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 @@ -4583,15 +4593,7 @@ Transparent - Transparent - - - - LoDateSelector - - - Date selector - Date selector + @@ -4600,211 +4602,189 @@ Minimize - Minimize + Maximize - Maximize - - - - - Close - Close + Restore - Restore + MainWindow - + Language - Language + - - Help - Help - - - - Check for updates - Check for updates + Help + - - + + + Check for updates + + + + + firmware manager Firmware management - - - + + + Preferences - - - Info + + + + About - - - - 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 IP in Terminal Control - + - + 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! @@ -4816,24 +4796,18 @@ Connection Timeout - - - - Error - Error - PageEditor Zoom In - Zoom In + Zoom Out - Zoom Out + @@ -4848,7 +4822,7 @@ Clear all media - Clear all media + @@ -4873,17 +4847,17 @@ Fill the entire screen - Fill the entire screen + Fill the screen horizontally - Fill the screen horizontally + Fill the screen vertically - Fill the screen vertically + @@ -4893,7 +4867,7 @@ Center vertically - Center vertically + @@ -4903,22 +4877,17 @@ Align left - Align left + Center horizontally - Center horizontally + Align right - Align right - - - - Tip Info - Tip Info + @@ -4929,155 +4898,150 @@ PageListItem - + times Times - + Page name Program name - + New - New + - + Play times - Play times + - + Sources Repeat - - Audios - - - - - Total Dur + + Wait Audio - + 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 + PlanItemWgt - + M - M + - + Tu - Tu + - + W - W + - + Th - Th + - + F - F + - + Sa - Sa + - + Su - Su + PlayWin - + Move to Top Left - Move to Top Left - - - - Set Position - - Close - Close + + Set Position + PlayerBackSendThread - + Open file failed - Open file failed + - + Read file failed - Read file failed + @@ -5096,52 +5060,57 @@ ProgCreateDlg - + Resolution - Resolution + - - Solution Information - Solution Information + + Solution Info + - + Solution Name Solution Name - + Width - Width + - + Height - Height + - + Remarks - Remarks + + Is Insert + + + + Ultra-Long Screen Split - + Horizontal - Horizontal - - - - Vertical - Vertical + + Vertical + + + + Lengths of Parts @@ -5149,199 +5118,174 @@ ProgEditorWin - + Save - 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 - + + Copy page + + + + + Delete page + + + + + Are you sure you want to delete this program page? + + + + + Move up + + + + + Move down + + + + + Widget Properties + + + + + Program Properties + + + + + Do you want to save the modifications? + + + + + Failed to Create Forder + + + + Saving... - Saving... + - - Success - Success - - - + Convertering - Convertering - - - - Demos + Demos + + + + Open Demo - + Generate preview data - Generate preview data - - - - - - Error - Error - - - - Rename fail when saving - - Remove Recursively fail when saving + + Failed to Rename Forder + + + + + Failed to Remove Recursively @@ -5349,143 +5293,132 @@ 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)? + - - + + + Rename + + + + + 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 + ProgPortDlg - + Solution Name - Solution Name + - + Progress - Progress + - + Done - Done + @@ -5508,11 +5441,6 @@ ProgressesItem - - - Error - Error - Install Success @@ -5542,17 +5470,7 @@ Setting up the LedOK Express... - Setting up the LedOK Express... - - - - Input password - Input password - - - - Error - Error + @@ -5562,147 +5480,121 @@ 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 + SendProgThread - + Program is empty - Program is empty + - + Open file failed - Open file failed + - + Read file failed - Read file failed + SendProgramDialog - - + + Publish - Publish + - + success info - - Refresh - Refresh - - - + Alias - + Online - Online + - - Screen Size - Screen Size - - - + Security encryption - + Progress - Progress + - + Remarks - Remarks + - + This screen is encrypted - This screen is encrypted + - + Info - + Some player versions are too low and may not be compatible. It's recommended to update the player to 2.0. Or download the old version %1 from website - + Do you want to continue? - + Waiting - - Input password - Input password + + Verify Password + - - VerifyPassword - Verify Password - - - - Tip Info - Tip Info - - - + password is wrong - password is wrong + - + All - ALL + @@ -5710,43 +5602,43 @@ Update APK - Update APK + Select apk - Select apk + Upgrade - Upgrade + + + + + Failed to Read File + Uninstall - Uninstall + check running state - check running state + Select Fpga - Select Fpga + Upgrading - - - Refresh - Refresh - Alias @@ -5755,7 +5647,7 @@ Online - Online + @@ -5765,12 +5657,12 @@ Progress - Progress + State - State + @@ -5780,7 +5672,7 @@ This screen is encrypted - This screen is encrypted + @@ -5796,7 +5688,7 @@ Name - Name + @@ -5813,38 +5705,12 @@ Please select a file - - - - - Tip - Tip - - - - NoSelectedController - Please select screen first - - - - File Read Fail - - Downloading Online File - - - - - - - Error - Error - Online file is empty @@ -5870,11 +5736,6 @@ Don't power off during this process - - - Install error - - @@ -5899,16 +5760,6 @@ Uninstalling - Uninstalling - - - - Uninstall error - - - - - Uninstall success @@ -5924,32 +5775,22 @@ Running - Running + Not running - - - Input password - Input password - - VerifyPassword - Verify Password - - - - Tip Info - Tip Info + Verify Password + password is wrong - password is wrong + @@ -5964,15 +5805,7 @@ The encrypted control card can be upgraded directly - The encrypted control card can be upgraded directly - - - - WaitingDlg - - - Success - Success + @@ -5980,7 +5813,7 @@ Com - Com + @@ -5997,25 +5830,25 @@ BaudRate - BaudRate + DataBit - DataBit + OEBit - OEBit + No - No + @@ -6045,7 +5878,7 @@ StopBit - StopBit + @@ -6056,72 +5889,52 @@ Open - Open + Auxiliary - Auxiliary - - - - Refresh - Refresh + Param configuration - Param configuration + Resend times - Resend times + Delay millsecond - Delay millsecond - - - - Clear - Clear + Debug - Debug + Network - Network + Program number - Program number - - - - Send - Send + Brightness Screen Brightness - - - Set - Set - Screen Off - Screen Off + @@ -6133,50 +5946,24 @@ State:Off - State:Off + Screen On - Screen On - - - - - - - - - - - - - - - - - - - Close - Close + State:On - State:On - - - - - Tip - Tip + OpenPort COM failed - OpenPort COM failed + diff --git a/LedOK/ts/app_ja.ts b/LedOK/ts/app_ja.ts index f1b1512..3905b2b 100644 --- a/LedOK/ts/app_ja.ts +++ b/LedOK/ts/app_ja.ts @@ -2,1063 +2,537 @@ - ChangePasswordForm - - - Old password - 古いパスワード - - - - New password - 新しいパスワード - - - - Repeat again - 再び繰り返す - - - - - - - - Tip - 提示 - - - - Please input old password - 古いパスワードを入力してください - - - - Old password is wrong - 古いパスワードが間違っている - - - - Please enter a password with more than 3 characters - 3 文字以上のパスワードを入力してください - - - - The new password is not consistent in two times - 新しいパスワードは2回で一貫していません - - - - Password changed successfully - パスワードが正常に変更 - - - - CtrlAdvancedPanel - - - Advanced - 上級パラメータ - - - - Screen Width(pixel) - 画面幅(ピクセル) - - - - Width - - - - - - Height - 高さ - - - - - - - Set - セット - - - - Alias - 別名 - - - - Web (Plat 2) Address - Web (Plat 2) のアドレス - - - - Setting Camera Range - - - - - - - Set Camera Range - - - - - Setting - - - - - Traffic screen settings - - - - - Setting protocol ... - - - - - Set protocol - - - - - Getting protocol ... - - - - - Get protocol - - - - - - Port - ポート - - - - 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 - 番組をクリア - - - - 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 (Plat 4) Address - Realtime (Plat 4) のアドレス - - - - Min brightness - 最低輝度 - - - - Readback - 読み戻し - - - - Send - 送信 - - - - Max brightness - 最高輝度 - - - - - SetScreenSize - スクリーンのピクセルサイズを設定 - - - - - - - - Success - 成功 - - - - Compant ID: - 会社ID: - - - - Compant ID - 会社ID - - - - - SetOnlineAddr - ウェブサーバのアドレスを設定 - - - - - ClearRealtimeServer - クリア - - - - - - - - - SetRealtimeServer - RealTimerアドレスを設定 - - - - - 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 - スケジュール再起動を設定中 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Please select screen first + 先に大きいスクリーンを選んでください - - Set Timing Reboot - スケジュール再起動の設定 + + + + + + + + + + + + + + + + + + + + + + + + Success + 成功 - - Getting Timing Reboot - スケジュール再起動を取得中 + + + + + + + + Setting + セット - - Get Timing Reboot - スケジュール再起動の取得 + + + + + + + Screen Size + スクリーンサイズ - - totalResolution - トータル解像度 + + + + + + + + + + + Set + セット - - strCurDisplayResolution - 表示解像度 + + + + Getting + 取得 - - - File not exist - ファイルが存在しません + + + Get + 取得 - - Getting Player State - プレーヤーの状態を取得しています + + + + Unlock + ロックを解除する - - - - Get Player State - プレーヤーの状態の取得 + + + + + + + Uninstall + アンマウント - - - Player State - プレーヤーの状態 + + + + + Upload + アップロード - - - Cannot Open File - ファイルのオープンに失敗しました + + + + + + Install + インストール - - Uploading - アップロード中 + + + Wait for + 待機中 - - Update - 更新 - - - - - Set Display Mode - - - - - - Get Display Mode - - - - - - Set Screen Offset - - - - - - Get Screen Offset - - - - - Open file Failed - ファイルのオープンに失敗しました - - - - Setting Wallpaper - - - - - - Set Wallpaper - - - - - System Updating - - - - - - System Update - - - - - Upload error - アップロード エラー - - - - Upgrading - アップグレード中 - - - - Getting MCU Version - - - - - - MCU Version - - - - + + + + + + + + + + + + Select File ファイルを選択 - - Setting player background - + + + + + + + + + + + + + + + + + + + + Set + セット - - - 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 + + + + + + + + Input Password パスワードを入力 - - Change Password - パスワード変更 - - - - Get Receive Card Num - 受信カード数の取得 - - - - Resolution Config - 解像度設定 - - - - Full screen - フルスクリーン - - - - Part - セクション - - - - Display Mode - 表示モード - - - - Screen Position - - - - - Offset - - - - - Camera Distance - - - - Min - - - - - Hidden Settings - - - - - Click right button to hide - - - - - Get MCU Version - - - - - Baud Config - - - - - Model - - - - - Uart - - - - - Baud - - - - - + + Get 得る - - Timing Reboot - スケジュール再起動 + + + + + + + + + + + + + + + + + + + + + + Readback + 読み戻し - - Protocol - プロトコル + + + + + + + + Refresh + 更新 - - Server - サービス + + Date + 日付 - - Client - クライアント - - - - - SetScreenRotation - 画面の回転を設定する - - - - - SetMinBrightness - 最小輝度値を設定します - - - - - SetMaxBrightness - 輝度最大値を設定 - - - - - GetMinBrightness - 輝度最小値を取得 - - - - - GetMaxBrightness - 輝度最大値を取得 - - - - - Card work mode - - - - - - SetSpecialResolution - 解像度を設定 - - - - - GetSpecialResolution - 読み込み解像度 - - - - - CleanDisplayScreenSize - デフォルトの解像度を復元 - - - - - SetHighForBusy - 客レベルの設定 - - - - - GetStateForBusy - ゲストレベルを取得 - - - - - SetCardAlias - エイリアスの設定 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Tip - 提示 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NoSelectedController - 先に大きいスクリーンを選んでください - - - - InputWidthTip - 正しい幅のピクセル値を入力してください - - - - InputHeightTip - 正しい高さのピクセル値を入力してください - - - - Password is error + + Password パスワード - - - CtrlBrightPanel + + Lock + ロック + + + + + + + Send + 送信 + + + + + + + + + + + + Clear + クリア + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1077,24 +551,975 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tip 提示 - - - - - - - - - - - - NoSelectedController - 先に大きいスクリーンを選んでください + + + + + + + + + + + + + + + + + + + + Close + 閉じる + + + + + + + + + + + + + Device replied + デバイス応答 + + + + + + Fail + 失敗 + + + + + + + + + + + + + Basic Properties + 基本的な属性 + + + + Getting + 取得中 + + + + CalendarButton + + + Select a Date + 日付の選択 + + + + ChangePasswordForm + + + Old password + 古いパスワード + + + + New password + 新しいパスワード + + + + Repeat again + 再び繰り返す + + + + Please input old password + 古いパスワードを入力してください + + + + Old password is wrong + 古いパスワードが間違っている + + + + Please enter a password with more than 3 characters + 3 文字以上のパスワードを入力してください + + + + The new password is not consistent in two times + 新しいパスワードは2回で一貫していません + + + + Password changed successfully + パスワードが正常に変更 + + + + CtrlAdvancedPanel + + + Advanced + 上級パラメータ + + + + Screen Width(pixel) + 画面幅(ピクセル) + + + + Width + + + + + + Height + 高さ + + + + Alias + 別名 + + + + Web (Plat 2) Address + Web (Plat 2) のアドレス + + + + Traffic screen settings + + + + + Setting protocol ... + + + + + Set protocol + + + + + Getting protocol ... + + + + + Get protocol + + + + + + Port + ポート + + + + Firmware Management + ファームウェア管理 + + + + update or uninstall + 更新またはアンインストール + + + + Check Apk + APKを検出 + + + + Uninstall + アンマウント + + + + Running check + 運転状態モニタ + + + + Restart + 再起動 + + + + Check Log + ログを見る + + + + Start LedSet4.0 + + + + + Open ADB + ADBデバッグ機能を開く + + + + + + + + + Clear Program + 番組をクリア + + + + Config + の設定 + + + + Restore to default + 標準の値を復元 + + + + Taxi top screen configuration + タクシートップ画面の設定 + + + + + Service:High Out of service:Low + 客がいます:高 客がいません:低 + + + + + Service:Low Out of service:High + 客がいます:低 客がいません:高 + + + + Bind Taxihub identity certificate + テーピング Taxihub ユーザーID証明書 + + + + Rotate + 回転 + + + + Realtime (Plat 4) Address + Realtime (Plat 4) のアドレス + + + + Min brightness + 最低輝度 + + + + Max brightness + 最高輝度 + + + + Compant ID: + 会社ID: + + + + Compant ID + 会社ID + + + + + SetOnlineAddr + ウェブサーバのアドレスを設定 + + + + + ClearRealtimeServer + クリア + + + + + + + + + SetRealtimeServer + RealTimerアドレスを設定 + + + + + RestartAndroid + 再起動 + + + + + running + 実行中 + + + + + no running + 実行されていません + + + + + Check Apk Version + チェック APK バージョン + + + + + UninstallSoftware + アンマウント + + + + + Check apk running status + APK運転状態監視 + + + + + OpenAdb + ADBデバッグ機能を開く + + + + Identity Certificate + 身分証明書 + + + + + + + + + + Binding certificate + 証明書をバインド + + + + + AliIotSetting + + + + + Software Version Info + + + + + Package + + + + + Version + バージョン + + + + + Package name is null + パッケージ名は空です + + + + Clearing Program + プログラムクリア + + + + + Timeout + タイムアウト + + + + + + + Failed + 失敗 + + + + Getting Log + ログを取得中 + + + + 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 + プレーヤーの状態 + + + + + Cannot Open File + ファイルのオープンに失敗しました + + + + Uploading + アップロード中 + + + + Update + 更新 + + + + + Set Display Mode + + + + + + Get Display Mode + + + + + + + + + + + + Screen Offset + + + + + + + Lock Card + + + + + Open file Failed + ファイルのオープンに失敗しました + + + + + No VehPlayer File + + + + + + Failed to Read File + + + + + Setting Wallpaper + + + + + + Set Wallpaper + + + + + System Updating + + + + + + System Update + + + + + Upload error + アップロード エラー + + + + Upgrading + アップグレード中 + + + + Getting MCU Version + + + + + + MCU Version + + + + + 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 + + + + + Change Password + パスワード変更 + + + + Get Receive Card Num + 受信カード数の取得 + + + + Player Debug + + + + + + Resolution Config + 解像度設定 + + + + Full screen + フルスクリーン + + + + Part + セクション + + + + Display Mode + 表示モード + + + + Screen Position + + + + + + Offset + + + + + + + + + Camera Distance + + + + + Hidden Settings + + + + + Click right button to hide + + + + + Get MCU Version + + + + + Baud Config + + + + + Model + + + + + Uart + + + + + Baud + + + + + Timing Reboot + スケジュール再起動 + + + + Protocol + プロトコル + + + + Server + サービス + + + + Client + クライアント + + + + + SetScreenRotation + 画面の回転を設定する + + + + + SetMinBrightness + 最小輝度値を設定します + + + + + SetMaxBrightness + 輝度最大値を設定 + + + + + GetMinBrightness + 輝度最小値を取得 + + + + + GetMaxBrightness + 輝度最大値を取得 + + + + + Card work mode + + + + + + SetSpecialResolution + 解像度を設定 + + + + + GetSpecialResolution + 読み込み解像度 + + + + + Restore to default relolution + デフォルトの解像度を復元 + + + + + SetHighForBusy + 客レベルの設定 + + + + + GetStateForBusy + ゲストレベルを取得 + + + + + SetCardAlias + エイリアスの設定 + + + + InputWidthTip + 正しい幅のピクセル値を入力してください + + + + InputHeightTip + 正しい高さのピクセル値を入力してください + + + + Password is error + パスワード + + + + CtrlBrightPanel @@ -1220,12 +1645,6 @@ GetAutoBrightnessTask 取得タイミング輝度表 - - - - Error - エラー - Brightness Config @@ -1271,36 +1690,11 @@ Minbrightness 最小輝度 - - - - - Set - セット - - Upload + Upload File ファイルのアップロード - - - - - - Readback - 読み戻し - - - - ReadbackTable - 読み戻し - - - - Refresh - 更新 - Cur Brigntness @@ -1321,11 +1715,6 @@ Add 追加 - - - Clear - クリア - Delete @@ -1355,175 +1744,150 @@ CtrlHdmiPanel - + HDMI Configuration ビデオソースの設定 - + Manual 手動 - + Schedule スケジュール - - - - - Tip - 提示 - - - - - - - NoSelectedController - 先に大きいスクリーンを選んでください - - - - + + + + SyncSwitch スイッチのビデオソースをHDMI-IN - - + + AnSyncSwitch 異ステップモードを切り替え - + IsSync 同じ非同期モードを読み返す - + Import File インポートファイル - + Save File 保存 - - + + Sync Schedule 同期モードタイミングタスク - - + + SetTimingHdmiInTask 同期モードタイミングタスクの設定 - + GetTimingHdmiInTask 同期モードタイミングタスクの取得 - - + + Async アシュリン - - Set - セット + + Auto Switch + - - - Readback - 読み戻し - - - + Start Time 開始時間 - + End Time 終了時間 - + SUN 日曜日 - + MON 月曜日 - + TUE 火曜日 - + WED 水曜日 - + THU 木曜日 - + FRI 金曜日 - + SAT 土曜日 - + Add 追加 - - + + Apply 適用 - - Clear - クリア - - - + Delete 削除 - + Import インポート - + Export 出力 - + By default, the asynchronous content is played, and the synchronous signal content is played in the fixed time period 非同期のコンテンツをデフォルトで再生し、同期のHMI-INポートに入力します @@ -1531,190 +1895,133 @@ CtrlNetworkPanel - + Wire Enther(RJ45) Configuration 有線ネットワークの設定 - - DHCP - - - - + Specify IP 指定IP - + IP Address IPアドレス - + Gateway ゲートウェイ - + DNS Address DNSアドレス - - - - Set - セット - - - - - - - Readback - 読み戻し - - - - WIFI Configuration + + WiFi Config WiFiの設定 - - WiFi Mode + + Enable WiFi WiFi機能 - + Cellular Config セルラーデータ構成 - + Enable Cellular Data セルラーデータを有効にする - + Get cellular network status information セルラーネットワーク状態情報を取得する - + Through the check status button 「ステータスを取得」ボタンを使用すると、国コードに自動的に一致し、対応するAPN情報を取得するには「事業者」を選択します。 - + Set APN Info APN情報を設定する - + Country ID(mcc): 国号(mcc): - - + + Carrier Name 運営者 - + APN(Required) APN(必ず記入) - + Flight Mode 飛行モード - + WiFi name WiFiの名前 - - - + + + Password パスワード - - - Input password - パスワードを入力 - - - + Scan スキャン - - Ap Mode + + Enable AP APエネルギー - + OFF オフ - + ON オン - + AP name AP名 - + Subnet mask サブネットマスク - + Input ap name APの名前を入力 - - - - - - - - - - - - - - Tip - 提示 - - - - - - - - - - - - - - NoSelectedController - 先に大きいスクリーンを選んでください - @@ -1766,326 +2073,322 @@ 静的IP - - - + + + + + ConfigurationWiFi WiFiの設定 - - - IsPortableHotSpot + + + Get AP or WiFi ホットスポットとWiFiモードの取得 - + GetWifiList スキャンWiFi - - - ConfigurationHotSpot + + + + + + + Config Hotspot ホットスポットの設定 - - success - 成功 - - - + WifiName Wifiの名前 - + ApName AP名前 - - + + GetCurrentAPN APN情報の取得 - + GetSIMStatus SIM状態を取得 - - + + SetAPN APNの設定 - - 状态: - 状態: + + Status + 状態 - - Error - エラー - - - + 未知 不明 - + 锁定状态,需要用户的PIN码解锁 ロック状態は、ユーザのPINコードのロック解除が必要です - + 锁定状态,需要用户的PUK码解锁 ロック状態は、ユーザのPUKコードのアンロックが必要です - + 锁定状态,需要网络的PIN码解锁 ロック状態は、ユーザのPINコードのアンロックが必要です - + 就绪 準備完了 - + no checked sim card simカードが検出されませんでした - + 国家码: 国号: - + 号码: 番号: - + 用户: ユーザ: - + 信号: 信号: - + 信号正常 信号が正常である - + 不在服务区 サービスエリアにはいません - + 仅限紧急呼叫 緊急呼び出しのみ - + 射频已经关闭 無線周波数はすでに閉鎖されました - + 网络: ネットワークタイプ: - + 网络类型未知 不明 - + GPRS网络 GPRS - + EDGE网络 EDGE - + UMTS网络 UMTS - + CDMA网络,IS95A 或 IS95B. CDM - + EVDO网络, revision 0. EVDO,revision 0. - + EVDO网络, revision A. EVDO,revision A. - + 1xRTT网络 1xRTT - + HSDPA网络 HSDPA - + HSUPA网络 HSUPA - + HSPA网络 HSPA - + 漫游: ローミング: - + Yes - + No いいえ - + 数据连接状态: データ接続状態: - + 断开 切断 - + 正在连接 接続中 - + 已连接 接続済み - + 暂停 一時停止 - + 数据活动休眠状态: データアクティビティの休止状態: - + 活动,但无数据发送和接收 アクティブですが、データ送信と受信はありません - + 活动,正在接收数据 アクティブ、データ受信中 - + 活动,正在发送数据 イベント、データ送信中 - + 活动,正在接收和发送数据 イベント、データ受信と送信中 - + 休眠状态 スリープ状態 - + 信号强度: 信号の強度: - + User ユーザー - + Type タイプ - + Server サービス - + Port ポート - + Proxy プロキシ - + MMS Port MMS ポート - + MMS Proxy MMS プロキシ - - + + SetSwitchSimData 4G/5Gスイッチの設定 - - + + ContrFlightMode 飛行モードの設定 - - + + GetFlightModeState 飛行モード状態を取得 @@ -2106,24 +2409,6 @@ On 開く - - - - - - - Tip - 提示 - - - - - - - - NoSelectedController - 先に大きいスクリーンを選んでください - @@ -2189,12 +2474,6 @@ Power 電源 - - - - Readback - 読み戻し - Start Time @@ -2250,11 +2529,6 @@ Apply 適用 - - - Clear - クリア - Delete @@ -2280,11 +2554,6 @@ Clear Schedule タイミング指令をクリア - - - Tip Info - ヒント - Clear schedule task? @@ -2343,25 +2612,6 @@ Enter again 再入力 - - - - - - - - - - - Tip - 提示 - - - - - NoSelectedController - 先に大きいスクリーンを選んでください - @@ -2383,11 +2633,6 @@ InputRepeatPasswordNotSameTip 二回入力したパスワードが一致しません - - - Tip Info - ヒント - After setting the password, please remember the password and record it. If you forget the password, the device will be unable to operate. Are you sure you want to continue with this operation? @@ -2401,18 +2646,6 @@ SetControllerPassword 暗号化の設定 - - - - Error - エラー - - - - - Success - 成功 - @@ -2537,21 +2770,11 @@ Gradient グラデーション - - - Clear - クリア - Reset ループ - - - Success - 成功 - @@ -2564,27 +2787,6 @@ Stop 停止 - - - - - - - - - Tip - 提示 - - - - - - - - - NoSelectedController - 先に大きいスクリーンを選んでください - @@ -2636,36 +2838,6 @@ LAN LAN - - - - - - - - - - - - - Tip - 提示 - - - - - - - - - - - - - - NoSelectedController - 先に大きいスクリーンを選んでください - screenSwitch @@ -2791,15 +2963,6 @@ TimeZone タイムゾーン - - - - - - - Set - セット - Language: @@ -2816,15 +2979,6 @@ Sync time interval 同期時間間隔 - - - - - - - Readback - 読み戻し - @@ -2898,22 +3052,6 @@ CtrlVolumePanel - - - - - - Tip - 提示 - - - - - - - NoSelectedController - 先に大きいスクリーンを選んでください - @@ -2973,17 +3111,6 @@ Volume 音量 - - - Set - セット - - - - - Readback - 読み戻し - Default volume @@ -2994,11 +3121,6 @@ Add 追加 - - - Clear - クリア - Delete @@ -3075,41 +3197,6 @@ 注意:時間帯以外の時間表示はデフォルトの明るさです - - Def - - - - - - - - - - - - - Device replied - デバイス応答 - - - - - - - - - Success - 成功 - - - - - - Fail - 失敗 - - DevicePanel @@ -3124,13 +3211,6 @@ Online オンライン中 - - - - Refresh - 更新 - 更新 - @@ -3198,11 +3278,6 @@ Detail Info 詳細 - - - Getting - 取得中 - Specify IP list @@ -3235,11 +3310,6 @@ Screen ID ターミナルID - - - Screen Size - スクリーンサイズ - Alias @@ -3320,12 +3390,6 @@ selected num 選択された数 - - - - Clear - クリア - More Info @@ -3347,31 +3411,14 @@ 暗号化 - Getting - 取得中 - - - - - Error - エラー - - - - Input password - パスワードを入力 + 取得中 - VerifyPassword + Verify Password パスワードの検証 - - - Tip Info - ヒント - password is wrong @@ -3381,94 +3428,89 @@ 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 テキスト @@ -3508,14 +3550,14 @@ - - + + None なし - + Effect 特効 @@ -3532,7 +3574,7 @@ - + Blink きらめき @@ -3567,179 +3609,179 @@ スタート - - - - + + + + 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 フェードアウト - + Breathe - + Freq @@ -3747,124 +3789,119 @@ 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 複数行表示 @@ -3956,11 +3993,6 @@ NW - - - Basic Properties - 基本的な属性 - Title @@ -4005,20 +4037,10 @@ EGif - - Basic Properties - 基本的な属性 - - - + File ファイル - - - Select File - ファイルを選択 - EMultiWin @@ -4074,13 +4096,6 @@ AClock アナログ時計 - - - - - Select File - ファイルを選択 - @@ -4097,25 +4112,55 @@ EPhoto - - Basic Properties - 基本的な属性 - - - + File ファイル - - Select File - ファイルを選択 - - - + Image Read Error 画像読み込みエラー + + + Direction + 方向 + + + + Scroll + スクロール + + + + No + いいえ + + + + Right -> Left + 左へ + + + + Bottom -> Top + 上へ + + + + Left -> Right + 右へ + + + + Top -> Bottom + 下へ + + + + Speed + スピード + Images (*.png *.jpg *.jpeg *.bmp) @@ -4125,195 +4170,185 @@ EText - + Enter your text 内容を入力してください - - Basic Properties - 基本的な属性 - - - + Back Color 背景色 - + Kerning 字の間隔 - + Line Height 行の高さ - + PageCount: 総ページ数: - + page ページ - + Import txt File インポート txt ファイル - - Select File - ファイルを選択 - - - + Fail 失敗 - + Cannot Open File ファイルのオープンに失敗しました - + Play Properties 再生方法 - + Flip 次頁 - + Scroll スクロール - + Static スタティック - + + New Format + + + + Text Color テキスト色 - + Colorful Text まばゆい文字 - - Head-Tail Spacing + + Tail Spacing 首尾間隔 - - Scroll Style - スクロール方向 + + Direction + 方向 - + Right -> Left 左へ - + Bottom -> Top 上へ - + Left -> Right 右へ - + Top -> Bottom 下へ - - Scroll Speed - スクロールスピード + + Speed + スピード ETimer - + day - + hour - + min - + sec - - Basic Properties - 基本的な属性 - - - + Count Down カウントダウン - + Count Up カウントアップ - - Time + + Target Time 目標時間 - + Day - + Hour - + Min - + Sec - + Multiline 複数行表示 - + Text テキスト @@ -4349,25 +4384,20 @@ Secs - - - Basic Properties - 基本的な属性 - Count Down - カウントダウン + カウントダウン Count Up - カウントアップ + カウントアップ - Time - 目標時間 + Target Time + 目標時間 @@ -4377,7 +4407,7 @@ Line Height - 行の高さ + 行の高さ @@ -4398,47 +4428,36 @@ EVideo - - Basic Properties - 基本的な属性 - - - + File ファイル - + Play Properties 再生方法 - - Select File - ファイルを選択 - - - + Play Times 再生回数 - + + Use SW + + + + Video Transcoding - - + + Video Transcoding Progress ビデオ変換の進歩 - - - - Error - エラー - Video @@ -4453,27 +4472,22 @@ EWeb - - Basic Properties - 基本的な属性 - - - + Zoom - + Refresh every - + Offset - + Scale @@ -4504,67 +4518,67 @@ GenTmpThread - + MON 月曜日 - + TUE 火曜日 - + WED 水曜日 - + THU 木曜日 - + FRI 金曜日 - + SAT 土曜日 - + SUN 日曜日 - + AM 午前 - + PM 午後 - + day - + hour - + min - + sec @@ -4585,14 +4599,6 @@ 透明な - - LoDateSelector - - - Date selector - 日付セレクタ - - LoQTitleBar @@ -4608,12 +4614,6 @@ Maximize 最大化する - - - - Close - 閉じる - Restore @@ -4623,187 +4623,171 @@ 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 IP in Terminal Control - + 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に修正します。慎重に操作してください。 @@ -4815,12 +4799,6 @@ Connection Timeout 接続タイムアウト - - - - Error - エラー - PageEditor @@ -4914,11 +4892,6 @@ Align right 横位置 右詰め - - - Tip Info - ヒント - Clear all medias? @@ -4928,84 +4901,84 @@ PageListItem - + times - + Page name プログラム名 - + New 新規 - + Play times 再生回数 - + Sources Repeat ソースの繰り返し - + + Wait Audio + + + + 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 タイムスケジュール @@ -5013,37 +4986,37 @@ PlanItemWgt - + M - + Tu - + W - + Th - + F - + Sa - + Su @@ -5051,30 +5024,25 @@ PlayWin - + Move to Top Left 左上隅に移動 - + Set Position 設定位置 - - - Close - 閉じる - PlayerBackSendThread - + Open file failed ファイルのオープンに失敗しました - + Read file failed ファイルの読み込みに失敗しました @@ -5095,52 +5063,57 @@ ProgCreateDlg - + Resolution 解像度 - - Solution Information + + Solution Info スケジュール情報 - + Solution Name リスト名 - + Width - + Height 高さ - + Remarks 備考 + Is Insert + + + + Ultra-Long Screen Split 超ロングスクリーン分割 - + Horizontal 水平 - + Vertical 垂直 - + Lengths of Parts 部分の長さ @@ -5148,199 +5121,174 @@ ProgEditorWin - + Save 保存 - + 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 + + Widget Properties パッケージプロパティ - - Page properties + + Program Properties プログラムのプロパティ - + Do you want to save the modifications? 変更された内容を保存してもよろしいですか? - - Create Dir failed + + Failed to Create Forder ディレクトリの作成に失敗しました - + Saving... 保存中、少々お待ちください... - - Success - 成功 - - - + Convertering データを整理する - + Demos テスト素材 - + Open Demo テスト素材を開く - + Generate preview data プレビューデータの生成 - - - - Error - エラー - - - - Rename fail when saving + + Failed to Rename Forder - - Remove Recursively fail when saving + + Failed to Remove Recursively @@ -5348,141 +5296,130 @@ 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)? 解決策は既に存在します。既存の解決策を上書きしたいと思いますか? - - + + + Rename + 名前を変更 + + + + 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 - ヒント - ProgPortDlg - + Solution Name リスト名 - + Progress 程度 - + Done 完了 @@ -5492,40 +5429,35 @@ Alias - 別名 + 別名 Progress - 程度 + 程度 State - 状態 + 状態 ProgressesItem - - - Error - エラー - Install Success - インストールに成功しました + インストールに成功しました Same version, needn't update - 同じバージョン、更新不要 + 同じバージョン、更新不要 Install Failed - インストールに失敗しました + インストールに失敗しました @@ -5543,16 +5475,6 @@ Setting up the LedOK Express... 初期化LedOK Express… - - - Input password - パスワードを入力 - - - - Error - エラー - USB Update Program @@ -5569,12 +5491,6 @@ Convertering データを整理する - - - - Tip - 提示 - No checked USB device @@ -5590,17 +5506,17 @@ SendProgThread - + Program is empty プログラムは空です - + Open file failed ファイルのオープンに失敗しました - + Read file failed ファイルの読み込みに失敗しました @@ -5608,98 +5524,78 @@ SendProgramDialog - - + + Publish 転送 - + success info - - Refresh - 更新 - - - + Alias 別名 - + Online オンライン中 - - Screen Size - スクリーンサイズ - - - + Security 暗号化 - + Progress 程度 - + Remarks 備考 - + This screen is encrypted スクリーンは暗号化されています - + Info 情報 - + Some player versions are too low and may not be compatible. It's recommended to update the player to 2.0. Or download the old version %1 from website プレーヤーのバージョンが低すぎて、互換性のない問題がある可能性があります。プレーヤーを2.0に更新することをお勧めします。またはWebサイトから旧バージョンの %1 をダウンロードする - + Do you want to continue? 続行しますか? - + Waiting 待機中 - - Input password - パスワードを入力 - - - - VerifyPassword + + Verify Password パスワードの検証 - - Tip Info - ヒント - - - + password is wrong パスワードエラー - + All トータル @@ -5721,6 +5617,11 @@ Upgrade アップグレード + + + Failed to Read File + + Uninstall @@ -5741,11 +5642,6 @@ Upgrading アップグレード中 - - - Refresh - 更新 - Alias @@ -5812,38 +5708,12 @@ Please select a file ファイルを選択してください - - - - - Tip - 提示 - - - - NoSelectedController - 先に大きいスクリーンを選んでください - - - - File Read Fail - - Downloading Online File オンラインファイルをダウンロード中 - - - - - - - Error - エラー - Online file is empty @@ -5869,11 +5739,6 @@ Don't power off during this process アップグレード中は電源を切らないでください - - - Install error - インストール エラー - @@ -5900,16 +5765,6 @@ Uninstalling アンマウント中 - - - Uninstall error - アンインストール エラー - - - - Uninstall success - アンインストールに成功しました - Check apk running status @@ -5930,21 +5785,11 @@ Not running 実行されていません - - - Input password - パスワードを入力 - - VerifyPassword + Verify Password パスワードの検証 - - - Tip Info - ヒント - password is wrong @@ -5966,14 +5811,6 @@ 暗号化されたコントロールカードを直接アップグレードすることができます - - WaitingDlg - - - Success - 成功 - - mGuangYingPinWidget @@ -6062,11 +5899,6 @@ Auxiliary 副設備 - - - Refresh - 更新 - Param configuration @@ -6082,11 +5914,6 @@ Delay millsecond 遅延(マイクロ秒) - - - Clear - クリア - Debug @@ -6102,21 +5929,11 @@ Program number 番組番号 - - - Send - 送信 - Brightness スクリーン輝度 - - - Set - セット - Screen Off @@ -6139,38 +5956,12 @@ Screen On 気絶する - - - - - - - - - - - - - - - - - - Close - 閉じる - State:On 状態:接続 - - - - Tip - 提示 - diff --git a/LedOK/ts/app_pt.ts b/LedOK/ts/app_pt.ts index 2938596..aa1b51d 100644 --- a/LedOK/ts/app_pt.ts +++ b/LedOK/ts/app_pt.ts @@ -2,1059 +2,537 @@ - ChangePasswordForm - - - Old password - Senha anterior - - - - New password - Nova Senha - - - - Repeat again - Repetir - - - - - - - - Tip - Dica - - - - Please input old password - Entre com a senha anterior - - - - Old password is wrong - Senha anterior esta errada - - - - Please enter a password with more than 3 characters - Entre com senha de mais de 3 caracteres - - - - The new password is not consistent in two times - - - - - Password changed successfully - Senha alterada com sucesso - - - - CtrlAdvancedPanel - - - Advanced - Avançado - - - - Screen Width(pixel) - Largura do display(pixel) - - - - Width - Largura - - - - - Height - Altura - - - - - - - Set - Config - - - - Alias - Apelido - - - - Web (Plat 2) Address - Endereço do Web (Plat 2) - - - - Setting Camera Range - - - - - - - Set Camera Range - - - - - Setting - - - - - Getting Baud Rate - - - - - Traffic screen settings - - - - - Setting protocol ... - - - - - Set protocol - - - - - Getting protocol ... - - - - - Get protocol - - - - - - Port - - - - - Model - - - - - Realtime (Plat 4) Address - Servidor de Realtime (Plat 4) - - - - 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 - - - - 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 - - - - - SetScreenSize - Conf. tamanho do painel - - - - - - - - Success - Successo - - - - Compant ID: - ID da empresa - - - - Compant ID - ID da empresa - - - - - SetOnlineAddr - Config o webserver - - - - - ClearRealtimeServer - Limpar - - - - - - - - - SetRealtimeServer - Config o server de realtimer - - - - - 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 - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Please select screen first + Selecione o display - - - 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 - - - - - 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 - - - - Upload error - Erro ao atualizar - - - - Upgrading - Actualização - - - - 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 - + + + + + + + + + + + + + + + + + + + + + + + + Success + Successo + + + + + + - Input password - Entre com a senha + Setting + - - Change Password - Troque a senha + + + + + + + Screen Size + Tamanho do display - - Get Receive Card Num - Obter o número de cartões receptores + + + + + + + + + + + Set + - - Resolution Config - Config de resolução + + + + Getting + Obtendo - - Full screen - Full screen - - - - Part - Parte - - - - Display Mode - Modo do display - - - - Screen Position - Posição da tela - - - - Offset - Offset - - - - Camera Distance - - - - - Hidden Settings - Esconder Config - - - - Click right button to hide - Clique com o botão direito para esconder - - - - Get MCU Version - Versão de MCU - - - - Baud Config - Config Baudrate - - - - Uart - Uart - - - - Baud - Baud - - - - - Get + + + Get Obter - - Firmware Management - + + + + Unlock + Desbloquear - - Timing Reboot - Reiniciando + + + + + + + Uninstall + Desinstalar - - Protocol - Protocolo + + + + + Upload + Atualizar - - Server - Servidor + + + + + + Install + Instalar + + + Wait for + Aguarde + + + + + + + + + + + + + + + Select File + Seleccionar o Ficheiro + + + + + + + + + + + + + + + + + + + + + + Set + Definir + + + + + + + + + + Input Password + Introduzir a senha + + + + + Get + Get + + + + + + + + + + + + + + + + + + + + + + + + Readback + Readback + + + + + + + + + + Refresh + Refreshar + + + + Date + Data + + + + Password + Senha + + + + Lock + Bloqueio + + + + + + + Send + Enviar + + + + + + + + + + + + Clear + Limpar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - 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 - - - - - SetCardAlias - Config apelido - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Tip - Dica - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NoSelectedController - Selecionar o display - - - - InputWidthTip - Entre com a correta largura - - - - InputHeightTip - Entre com a correta altura - - - - Password is error - Senha esta errada - - - - CtrlBrightPanel - + + + + + + + + + + + + + @@ -1073,24 +551,975 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tip Dica - - - - - - - - - - - - NoSelectedController - Selecione o display + + + + + + + + + + + + + + + + + + + + Close + Fechar + + + + + + + + + + + + + Device replied + Equipamento replicado + + + + + + Fail + Falhou + + + + + + + + + + + + + Basic Properties + Propriedades Básicas + + + + Getting + Obtendo info + + + + CalendarButton + + + Select a Date + Seleccionar uma Data + + + + ChangePasswordForm + + + Old password + Senha anterior + + + + New password + Nova Senha + + + + Repeat again + Repetir + + + + Please input old password + Entre com a senha anterior + + + + Old password is wrong + Senha anterior esta errada + + + + Please enter a password with more than 3 characters + Entre com senha de mais de 3 caracteres + + + + The new password is not consistent in two times + + + + + Password changed successfully + Senha alterada com sucesso + + + + CtrlAdvancedPanel + + + Advanced + Avançado + + + + Screen Width(pixel) + Largura do display(pixel) + + + + Width + Largura + + + + + Height + Altura + + + + Alias + Apelido + + + + Web (Plat 2) Address + Endereço do Web (Plat 2) + + + + + No VehPlayer File + + + + + + Failed to Read File + Não foi possível ler o Ficheiro + + + + Getting Baud Rate + + + + + Traffic screen settings + + + + + Setting protocol ... + + + + + Set protocol + + + + + Getting protocol ... + + + + + Get protocol + + + + + + Port + + + + + Model + + + + + Realtime (Plat 4) Address + Servidor de Realtime (Plat 4) + + + + update or uninstall + + + + + Check Apk + Conferi Apk + + + + Uninstall + Desinstalar + + + + Running check + Conferir + + + + Restart + Reiniciar + + + + Check Log + Conferir Log + + + + Start LedSet4.0 + Iniciar LedSet4.0 (Apk Display2.0 and higher) + + + + Open ADB + Abri ADB debug + + + + + + + + + Clear Program + Limpar Programa + + + + Config + Config + + + + 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 + + + + Bind Taxihub identity certificate + Certificado de identidade do Taxihub Bind + + + + Rotate + Rotacionar + + + + Min brightness + Brilho minimo + + + + Max brightness + Brilho Maximo + + + + Compant ID: + ID da empresa + + + + Compant ID + ID da empresa + + + + + SetOnlineAddr + Config o webserver + + + + + ClearRealtimeServer + Limpar + + + + + + + + + SetRealtimeServer + Config o server de realtimer + + + + + 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 + + + + Identity Certificate + Certificado de identidade + + + + + + + + + + Binding certificate + Certificado vinculativo + + + + + AliIotSetting + + + + + Software Version Info + + + + + Package + + + + + Version + + + + + + Package name is null + + + + + Clearing Program + + + + + + Timeout + Tempo esgotado + + + + + + + Failed + Falhou + + + + Getting Log + Obtendo log + + + + 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 + + + + + + + + + + + + Screen Offset + Display Offset + + + + totalResolution + Resolução total de FPGA + + + + strCurDisplayResolution + Resolução do display + + + + + File not exist + Arquivo não encontrado + + + + + Cannot Open File + Não pode abrir arquivo + + + + Uploading + Atualizando + + + + Update + Atualizar + + + + + Set Display Mode + Config Display + + + + + + Lock Card + + + + + Open file Failed + Falaha em abrir + + + + Setting Wallpaper + Config plano fundo + + + + + Set Wallpaper + Config plano fundo + + + + System Updating + Atualizando + + + + + System Update + Sistema atualizado + + + + Upload error + Erro ao atualizar + + + + Upgrading + Actualização + + + + Getting MCU Version + Obtendo versão + + + + + MCU Version + Verão de MCU + + + + 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 + + + + + Change Password + Troque a senha + + + + Get Receive Card Num + Obter o número de cartões receptores + + + + Player Debug + + + + + + 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 + + + + + + + + Camera Distance + + + + + Hidden Settings + Esconder Config + + + + Click right button to hide + Clique com o botão direito para esconder + + + + Get MCU Version + Versão de MCU + + + + Baud Config + Config Baudrate + + + + Uart + Uart + + + + Baud + Baud + + + + 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 + + + + + Restore to default relolution + Restaurar resolução + + + + + SetHighForBusy + Set level for busy + + + + + GetStateForBusy + Get level of busy + + + + + SetCardAlias + Config apelido + + + + InputWidthTip + Entre com a correta largura + + + + InputHeightTip + Entre com a correta altura + + + + Password is error + Senha esta errada + + + + CtrlBrightPanel @@ -1216,12 +1645,6 @@ GetAutoBrightnessTask Obter tabela de brilho - - - - Error - Erro - Brightness Config @@ -1267,36 +1690,11 @@ Minbrightness Brilho minimo - - - - - Set - Config - - Upload + Upload File Atualizar arquivo - - - - - - Readback - Ler - - - - ReadbackTable - Ler - - - - Refresh - Atualizar - Cur Brigntness @@ -1317,11 +1715,6 @@ Add Add - - - Clear - Limpar - Delete @@ -1351,175 +1744,150 @@ CtrlHdmiPanel - + HDMI Configuration Config de video - + Manual Manual - + Schedule Agendado - - - - - Tip - Dica - - - - - - - NoSelectedController - Selecione o display - - - - + + + + SyncSwitch Altere a entrada para porta HDMI-IN - - + + AnSyncSwitch Altere a entrada para Async - + IsSync Ler tipo de entrada - + Save File Salvar arquivo - - + + Sync Schedule Sinc agendamento - - + + SetTimingHdmiInTask Config entrada HDMI-IN - + GetTimingHdmiInTask Obter agendamento de entrada de video - - + + Async Async - + Import File - - Set - Config + + Auto Switch + - - - Readback - Ler - - - + Start Time Hora de inicio - + End Time Hora final - + SUN Dom - + MON Seg - + TUE Ter - + WED Qua - + THU Qui - + FRI Sex - + SAT Sab - + Add Adicionar - - + + Apply Aplicar - - Clear - Limpar - - - + Delete Deletar - + Import Importar - + Export Exportar - + By default, the asynchronous content is played, and the synchronous signal content is played in the fixed time period Por padrão, o conteudo asynchronous é aplicadop, e o conteudo synchronous pela porta hdmi-in é aplicado quando fixado o periodo @@ -1527,180 +1895,123 @@ CtrlNetworkPanel - + Wire Enther(RJ45) Configuration Wire Enther(RJ45) Configuração - - DHCP - DHCP - - - + Specify IP IP - + IP Address Endereço IP - + Gateway Gateway - - - - Set - Config - - - - - - - Readback - Ler - - - - WIFI Configuration + + WiFi Config Config WiFi - - WiFi Mode - Modo WiFi + + Enable WiFi + Modo WiFi - + Cellular Config Config Celular - + Enable Cellular Data Habilitar celular - + Get cellular network status information Obter informação da rede - + Through the check status button Atraves do botão de status, voce pode escolher automaticamente o codigo MCC do pais;selecione para obtera correta informação de APN . - + Country ID(mcc): ID do país(mcc): - - + + Carrier Name Operadora - + APN(Required) APN(requerida) - + Flight Mode Modo avião - + WiFi name Nome WiFi - - - + + + Password Senha - - - Input password - Entre com a senha - - - + Scan Escanear - - Ap Mode - AP + + Enable AP + - + OFF Desligar - + ON Ligar - + AP name Nome do AP - + Subnet mask Mascara subnet - + Input ap name Entre com nome do AP - - - - - - - - - - - - - - Tip - Dica - - - - - - - - - - - - - - NoSelectedController - Selecione o display - @@ -1752,336 +2063,332 @@ IP estático - - - + + + + + ConfigurationWiFi Configuração WiFi - - - IsPortableHotSpot + + + Get AP or WiFi Obter AP ou WiFi - + GetWifiList Escanear lista WiFi - - - ConfigurationHotSpot - Configuração do AP + + + + + + + Config Hotspot + Config do Hotspot - - success - successo - - - + WifiName Nome Wifi - + ApName Nome Ap - - + + GetCurrentAPN Obter APN atual - + GetSIMStatus Obter estatus do SIM - - + + SetAPN Config APN - - 状态: - Estatus: + + Status + Estatus - - Error - Erro - - - + 未知 Desconhecido - + 锁定状态,需要用户的PIN码解锁 Travar; necessita de pin para alterar - + 锁定状态,需要用户的PUK码解锁 Travado, necessário PUK para destravar - + 锁定状态,需要网络的PIN码解锁 Travado, necessário PUK para destravar - + 就绪 Lendo - + no checked sim card SIM card não checado - + 国家码: MCC: - + 号码: numero: - + 用户: Nome de usuário: - + 信号: Sinal: - + 信号正常 Sinal OK - + 不在服务区 Fora da area de serviço - + 仅限紧急呼叫 Apenas chamadas de emergencia - + 射频已经关闭 RF desligado - + 网络: Tipo de network: - + 网络类型未知 desconhecido - + GPRS网络 GPRS - + EDGE网络 EDGE - + UMTS网络 UMTS - + CDMA网络,IS95A 或 IS95B. CDM - + EVDO网络, revision 0. EVDO,revision 0. - + EVDO网络, revision A. EVDO,revision A. - + 1xRTT网络 1xRTT - + HSDPA网络 HSDPA - + HSUPA网络 HSUPA - + HSPA网络 HSPA - + 漫游: roam: - + Yes Sim - + No Não - + 数据连接状态: Status: - + 断开 Desligado - + 正在连接 conectando - + 已连接 Conectado - + 暂停 Suspenso - + 数据活动休眠状态: Dados ativo, estado suspenso : - + 活动,但无数据发送和接收 Ativo, mas sen enviar / receber dados - + 活动,正在接收数据 Ativo, recebendo dados - + 活动,正在发送数据 Ativo enviando ddos - + 活动,正在接收和发送数据 Ativo, enviando e recebendo dados - + 休眠状态 Modo suspenso - + 信号强度: Nível de sinal: - + DNS Address Endereço DNS - + Set APN Info Config APN - + User Usuario - + Type Tipo - + Server Server - + Port Porta - + Proxy Proxy - + MMS Port Porta - + MMS Proxy Proxy - - + + SetSwitchSimData Selec SIM - - + + ContrFlightMode Selec modo avião - - + + GetFlightModeState Ler estado modo avião @@ -2102,24 +2409,6 @@ On Ligado - - - - - - - Tip - Dica - - - - - - - - NoSelectedController - Selecione o display - @@ -2185,12 +2474,6 @@ Power Funcioando - - - - Readback - Ler - Start Time @@ -2246,11 +2529,6 @@ Apply Aplicar - - - Clear - Limpar - Delete @@ -2276,11 +2554,6 @@ Clear Schedule Cancelar agendamento - - - Tip Info - Dica Info - Clear schedule task? @@ -2339,25 +2612,6 @@ Enter again Entre novamente - - - - - - - - - - - Tip - Dica - - - - - NoSelectedController - Selecione o display - @@ -2379,11 +2633,6 @@ InputRepeatPasswordNotSameTip As senhas são diferentes - - - Tip Info - Dica Info - After setting the password, please remember the password and record it. If you forget the password, the device will be unable to operate. Are you sure you want to continue with this operation? @@ -2397,18 +2646,6 @@ SetControllerPassword Config a senha - - - - Error - Erro - - - - - Success - Successo - @@ -2533,21 +2770,11 @@ Gradient Gradiente - - - Clear - Limpar - Reset Loop - - - Success - Successo - @@ -2560,27 +2787,6 @@ Stop Parar - - - - - - - - - Tip - TDicas - - - - - - - - - NoSelectedController - Selecione o display - @@ -2632,36 +2838,6 @@ LAN LAN - - - - - - - - - - - - - Tip - Dica - - - - - - - - - - - - - - NoSelectedController - Selecione o display - screenSwitch @@ -2787,15 +2963,6 @@ TimeZone Fuso horário - - - - - - - Set - Config - Language: @@ -2812,15 +2979,6 @@ Sync time interval Sincronizar intervalo de tempo - - - - - - - Readback - Ler - @@ -2894,22 +3052,6 @@ CtrlVolumePanel - - - - - - Tip - Dica - - - - - - - NoSelectedController - Selecione o display - @@ -2969,17 +3111,6 @@ Volume Volume - - - Set - Config - - - - - Readback - Ler - Default volume @@ -2990,11 +3121,6 @@ Add Adicionar - - - Clear - Limpar - Delete @@ -3071,41 +3197,6 @@ Recordar: o display esta com o brilho padrão the display fora do periodo - - Def - - - - - - - - - - - - - Device replied - Equipamento replicado - - - - - - - - - Success - Successo - - - - - - Fail - Falhou - - DevicePanel @@ -3121,13 +3212,6 @@ Online Online - - - - Refresh - Refresh - Atializar - @@ -3195,11 +3279,6 @@ Detail Info Detalhe de informação - - - Getting - Obtendo info - Specify IP list @@ -3232,11 +3311,6 @@ Screen ID ID do display - - - Screen Size - Tamanho do display - @@ -3312,12 +3386,6 @@ selected num Selecionar numero - - - - Clear - Limpar - More Info @@ -3344,31 +3412,14 @@ encriptação - Getting - Obter - - - - - Error - Erro - - - - Input password - Introduzir a senha + Obter - VerifyPassword + Verify Password Verifique a senha - - - Tip Info - Dica - password is wrong @@ -3378,94 +3429,89 @@ 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 @@ -3505,14 +3551,14 @@ - - + + None None - + Effect Efeito @@ -3529,7 +3575,7 @@ - + Blink Piscar @@ -3564,179 +3610,179 @@ - - - - + + + + s s - + Duration Duração - + Entry - - - - Random - - - - - - Expand horizontal - - - - - - Expand vertical - - - Expand to left + Random - Expand to top + Expand horizontal - Expand to right + Expand vertical - Expand to bottom + Expand to left - Zoom in + + Expand to top - Zoom in from left-top + + Expand to right - Zoom in from right-top + + Expand to bottom - Zoom in from right-bottom + Zoom in - Zoom in from left-bottom + Zoom in from left-top - - Rotate zoom + Zoom in from right-top - - Rotate zoom reverse + Zoom in from right-bottom - Fade in + Zoom in from left-bottom - Move to left + Rotate zoom - Move to top + Rotate zoom reverse - - Move to right + Fade in - Move to bottom - Mover para baixo + 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 - + Breathe - + Freq @@ -3744,124 +3790,119 @@ 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 @@ -3953,11 +3994,6 @@ NW - - - Basic Properties - Basic properties - Title @@ -4002,20 +4038,10 @@ EGif - - Basic Properties - Propriedades - - - + File Arquivo - - - Select File - Selecionar arq. - EMultiWin @@ -4071,18 +4097,11 @@ AClock Rel. analogico - - - - - Select File - Selecionar arquivo - Environment - Environmental Monitoring + Ambiente @@ -4094,25 +4113,55 @@ EPhoto - - Basic Properties - Propriedades - - - + File Arquivo - - Select File - Selec Arquivo - - - + Image Read Error Erro ao ler iamgem + + + Direction + Direção + + + + Scroll + Rodar + + + + No + + + + + Right -> Left + Da direita para esquerda + + + + Bottom -> Top + de baixo para cima + + + + Left -> Right + Da esquerda para direita + + + + Top -> Bottom + De cima para baixo + + + + Speed + Velocidade + Images (*.png *.jpg *.jpeg *.bmp) @@ -4122,195 +4171,185 @@ EText - + Enter your text Entre com o texto - - Basic Properties - Propriedades - - - + Back Color Cor de fundo - + Kerning Kerning - + Line Height Altura da Linha - + 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 - + + New Format + + + + Text Color Cor do texto - + Colorful Text Texto colorido - - Head-Tail Spacing + + Tail Spacing Espaçado - - Scroll Style + + Direction 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 + + Speed + Velocidade ETimer - + day Dias - + hour Horas - + min Min - + sec Seg - - Basic Properties - Propriedades - - - + Count Down Contador regressivo - + Count Up Contador progressivo - - Time - Target Time + + Target Time + - + Day Dia - + Hour Hora - + Min Min - + Sec Seg - + Multiline Multilinha - + Text Texto @@ -4346,25 +4385,20 @@ Secs - - - Basic Properties - - Count Down - Contador regressivo + Contador regressivo Count Up - Contador progressivo + Contador progressivo - Time - Target Time + Target Time + @@ -4374,7 +4408,7 @@ Line Height - Altura da Linha + Altura da Linha @@ -4395,47 +4429,36 @@ EVideo - - Basic Properties - Propriedades - - - + File Arquivo - + Play Properties - - Select File - Selecionar arquivo - - - + Play Times Repetições - + + Use SW + + + + Video Transcoding Transcodificação de video - - + + Video Transcoding Progress Processando - - - - Error - Erro - Video @@ -4450,27 +4473,22 @@ EWeb - - Basic Properties - Propriedades - - - + Zoom - + Refresh every - + Offset - Offset + Offset - + Scale @@ -4501,67 +4519,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 @@ -4582,14 +4600,6 @@ Transparente - - LoDateSelector - - - Date selector - Seletor de data - - LoQTitleBar @@ -4605,12 +4615,6 @@ Maximize Maximizar - - - - Close - Fechar - Restore @@ -4620,187 +4624,171 @@ 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 IP in Terminal Control - + 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! @@ -4812,12 +4800,6 @@ Connection Timeout Tempo esgotado - - - - Error - Erro - PageEditor @@ -4911,11 +4893,6 @@ Align right Alinhar pela direita - - - Tip Info - Info - Clear all medias? @@ -4925,84 +4902,84 @@ PageListItem - + times Repetições - + Page name Nome programa - + New Novo - + Play times Repetições - + Sources Repeat - + + Wait Audio + + + + 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 @@ -5010,37 +4987,37 @@ PlanItemWgt - + M Seg - + Tu Ter - + W Qua - + Th Qui - + F Sex - + Sa Sab - + Su Dom @@ -5048,30 +5025,25 @@ PlayWin - + Move to Top Left Mover superior esquerdo - + Set Position Config posição - - - Close - Fechar - PlayerBackSendThread - + Open file failed Abrir aqrquivo - + Read file failed Ler arquivo @@ -5092,52 +5064,57 @@ ProgCreateDlg - + Resolution Resolução - - Solution Information - ID + + Solution Info + - + Solution Name Nome - + Width Largura - + Height Altura - + Remarks Observações + Is Insert + + + + Ultra-Long Screen Split Dividir o Ecrã Ultralongo - + Horizontal - + Vertical - + Lengths of Parts Comprimento das peças @@ -5145,341 +5122,305 @@ ProgEditorWin - + Save Salvar - + Setting Configuração - + Text Texto - + Photo Foto - + Video Video - + Gif Gif - + Clock Relógio - + Analog Clock Relógio analogico - + Environment - Monitoramento ambiente + 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 + + Widget Properties Propriedade - - Page properties + + Program Properties Propriedades do programa - + Do you want to save the modifications? Você quer salvar esta modificação? - - Create Dir failed + + Failed to Create Forder Criação falhou - + Saving... Salvando... - - Success - Successo - - - + Convertering Convertendo - + Demos - + Open Demo - + Generate preview data Gerar dados de visualização - - - - Error - Erro + + Failed to Rename Forder + - - Rename fail when saving - Falha em renomear - - - - Remove Recursively fail when saving - Falha ao remover + + Failed to Remove Recursively + 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? - - + + + Rename + + + + + 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 - ProgPortDlg - + Solution Name Nome - + Progress Progresso - + Done Concluido @@ -5489,40 +5430,35 @@ Alias - Apelido + Apelido Progress - Progresso + Progresso State - Estado + Estado ProgressesItem - - - Error - Erro - Install Success - Sucesso + Sucesso Same version, needn't update - A mesma versão, não é necessária actualização + A mesma versão, não é necessária actualização Install Failed - A instalação falhou + A instalação falhou @@ -5540,16 +5476,6 @@ Setting up the LedOK Express... Configurando... - - - Input password - Digite a senha - - - - Error - Erro - USB Update Program @@ -5566,12 +5492,6 @@ Convertering Convertendo - - - - Tip - Dica - No checked USB device @@ -5587,17 +5507,17 @@ SendProgThread - + Program is empty Programa em branco - + Open file failed Falaha ao abrir - + Read file failed Ler arquivo com falha @@ -5605,98 +5525,78 @@ SendProgramDialog - - + + Publish Publicar - + success info Sucesso - + Info Info - + Some player versions are too low and may not be compatible. It's recommended to update the player to 2.0. Or download the old version %1 from website Algumas versões do jogador são muito baixas e podem não ser compatíveis É Recomendado para atualizar o jogador para 2.0 Ou baixe a versão antiga %1 do site - + Do you want to continue? Continuar? - - Refresh - Atualizar - - - + Online Online - Screen Size - Tamanho do display - - - Alias Apelido - + Security Encriptado - + Progress Progresso - + Remarks Observações - + This screen is encrypted Este display esta encriptado - + Waiting À espera - - Input password - Digite a senha - - - - VerifyPassword + + Verify Password Verifique a senha - - Tip Info - Info - - - + password is wrong A senha esta errada - + All Todos @@ -5733,16 +5633,16 @@ Select Fpga Selecionar FPGA + + + Failed to Read File + Não foi possível ler o Ficheiro + Upgrading Actualização - - - Refresh - Atualizar - Online @@ -5804,38 +5704,12 @@ Please select a file Selecione um arquivo - - - - - Tip - Dica - - - - NoSelectedController - Selecione o display - - - - File Read Fail - - Downloading Online File Atualizando arquivo - - - - - - - Error - Erro - Online file is empty @@ -5861,11 +5735,6 @@ Don't power off during this process Desligou durante o processo - - - Install error - Erro de instalação - @@ -5892,16 +5761,6 @@ Uninstalling Desinstalando... - - - Uninstall error - Erro ao desinstalar - - - - Uninstall success - Sucesso - Check apk running status @@ -5922,21 +5781,11 @@ Not running Parado - - - Input password - Introduzir a senha - - VerifyPassword + Verify Password Verifique a senha - - - Tip Info - Dica - password is wrong @@ -5963,14 +5812,6 @@ O upograde pode ser realizado automaticamente - - WaitingDlg - - - Success - Successo - - mGuangYingPinWidget @@ -6059,11 +5900,6 @@ Auxiliary Auxiliar - - - Refresh - Atualizar - Param configuration @@ -6079,11 +5915,6 @@ Delay millsecond Atraso de milisegundos - - - Clear - Limpar - Debug @@ -6099,21 +5930,11 @@ Program number Numero do programa - - - Send - Enviar - Brightness Brilho do display - - - Set - Config - Screen Off @@ -6136,38 +5957,12 @@ Screen On Ligar - - - - - - - - - - - - - - - - - - Close - Fechar - State:On Estado:Ligado - - - - Tip - Dica - diff --git a/LedOK/ts/app_zh_CN.ts b/LedOK/ts/app_zh_CN.ts index 09a04b6..c6d3428 100644 --- a/LedOK/ts/app_zh_CN.ts +++ b/LedOK/ts/app_zh_CN.ts @@ -2,1059 +2,537 @@ - ChangePasswordForm - - - Old password - 旧密码 - - - - New password - 新密码 - - - - Repeat again - 重复一遍 - - - - - - - - Tip - 提示 - - - - Please input old password - 请输入旧密码 - - - - Old password is wrong - 旧密码错误 - - - - Please enter a password with more than 3 characters - 请输入超过 3 个字符的密码 - - - - The new password is not consistent in two times - 新密码两次不一致 - - - - Password changed successfully - 密码更改成功 - - - - CtrlAdvancedPanel - - - Advanced - 高级设置 - - - - Screen Width(pixel) - 屏幕宽(像素) - - - - Width - - - - - - Height - - - - - - - - Set - 设置 - - - - Alias - 别名 - - - - Web (Plat 2) Address - Web (2平台) 地址 - - - - Setting Camera Range - - - - - - - Set Camera Range - - - - - Setting - 正在设置 - - - - Traffic screen settings - 交通屏设置 - - - - Setting protocol ... - 正在设置协议 ... - - - - Set protocol - 设置协议 - - - - Getting protocol ... - 正在回读协议 ... - - - - Get protocol - 回读协议 - - - - - Port - 端口 - - - - Realtime (Plat 4) Address - Realtime (4平台) 地址 - - - - 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 - 清除节目 - - - - 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 - 最高亮度 - - - - - SetScreenSize - 设置屏幕像素尺寸 - - - - - - - - Success - 成功 - - - - Compant ID: - 公司ID: - - - - Compant ID - 公司ID - - - - - SetOnlineAddr - 设置web服务器地址 - - - - - ClearRealtimeServer - 清除 - - - - - - - - - SetRealtimeServer - 设置RealTimer地址 - - - - - 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 - 正在设置定时重启 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Please select screen first + 请先选择大屏幕 - - Set Timing Reboot - 设置定时重启 + + + + + + + + + + + + + + + + + + + + + + + + Success + 成功 - - Getting Timing Reboot - 正在获取定时重启 + + + + + + + + Setting + 正在设置 - - Get Timing Reboot - 获取定时重启 + + + + + + + Screen Size + 屏幕像素 - - totalResolution - 包括行场数的分辨率 + + + + + + + + + + + Set + 设置 - - strCurDisplayResolution - 当前显示屏分辨率 + + + + Getting + 正在获取 - - - File not exist - 文件不存在 + + + Get + 获取 - - Getting Player State - 正在获取播放器状态 + + + + Unlock + 解锁 - - - - Get Player State - 获取播放器状态 + + + + + + + Uninstall + 卸载 - - - Player State - 播放器状态 + + + + + Upload + 上传 - - - Cannot Open File - 文件打开失败 + + + + + + Install + 安装 - - Uploading - 正在上传 + + + Wait for + 等待 - - Update - 更新 - - - - - Set Display Mode - 设置显示模式 - - - - - Get Display Mode - 获取显示模式 - - - - - Set Screen Offset - 设置屏幕偏移 - - - - - Get Screen Offset - 获取屏幕偏移 - - - - Open file Failed - 文件打开失败 - - - - Setting Wallpaper - 正在设置系统桌面背景 - - - - - Set Wallpaper - 设置系统桌面背景 - - - - System Updating - 系统升级中 - - - - - System Update - 系统升级 - - - - Upload error - 上传错误 - - - - Upgrading - 升级中 - - - - Getting MCU Version - 正在获取单片机版本 - - - - - MCU Version - 单片机版本 - - - + + + + + + + + + + + + Select File 选择文件 - - Setting player background - 正在设置播放器背景 + + + + + + + + + + + + + + + + + + + + Set + 设置 - - - 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 + + + + + + + + Input Password 输入密码 - - Change Password - 修改密码 - - - - Get Receive Card Num - 获取接收卡数量 - - - - Resolution Config - 分辨率配置 - - - - Full screen - 全屏 - - - - Part - 局部 - - - - Display Mode - 显示模式 - - - - Screen Position - 屏幕位置 - - - - Offset - 偏移 - - - - Camera Distance - 摄像头距离 - - - - Hidden Settings - 隐藏的设置 - - - - Click right button to hide - 点击右键隐藏 - - - - Get MCU Version - 获取单片机版本 - - - - Baud Config - 波特率配置 - - - - Model - 设备型号 - - - - Uart - 串口节点 - - - - Baud - 波特率 - - - - + + Get 获取 - - Timing Reboot - 定时重启 + + + + + + + + + + + + + + + + + + + + + + Readback + 回读 - - Protocol - 协议 + + + + + + + + Refresh + 刷新 - - Server - 服务端 + + Date + 日期 + + Password + 密码 + + + + Lock + 加锁 + + + + + + + Send + 发送 + + + + + + + + + + + + Clear + 清空 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - Client - 客户端 - - - - - SetScreenRotation - 设置屏幕旋转 - - - - - SetMinBrightness - 设置最小的亮度值 - - - - - SetMaxBrightness - 设置亮度最大值 - - - - - GetMinBrightness - 获取亮度最小值 - - - - - GetMaxBrightness - 获取亮度最大值 - - - - - Card work mode - 控制卡工作模式 - - - - - SetSpecialResolution - 设置分辨率 - - - - - GetSpecialResolution - 读取分辨率 - - - - - CleanDisplayScreenSize - 恢复默认分辨率 - - - - - SetHighForBusy - 设置有无客电平 - - - - - GetStateForBusy - 获取有无客电平 - - - - - SetCardAlias - 设置别名 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Tip - 提示 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NoSelectedController - 请先选择大屏幕 - - - - InputWidthTip - 请输入正确的宽度像素值 - - - - InputHeightTip - 请输入正确的高度像素值 - - - - Password is error - 密码错误 - - - - CtrlBrightPanel - + + + + + + + + + + + + + @@ -1073,24 +551,975 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tip 提示 - - - - - - - - - - - - NoSelectedController - 请先选择大屏幕 + + + + + + + + + + + + + + + + + + + + Close + 关闭 + + + + + + + + + + + + + Device replied + 设备回复 + + + + + + Fail + 失败 + + + + + + + + + + + + + Basic Properties + 基本属性 + + + + Getting + 正在获取 + + + + CalendarButton + + + Select a Date + 选择日期 + + + + ChangePasswordForm + + + Old password + 旧密码 + + + + New password + 新密码 + + + + Repeat again + 重复一遍 + + + + Please input old password + 请输入旧密码 + + + + Old password is wrong + 旧密码错误 + + + + Please enter a password with more than 3 characters + 请输入超过 3 个字符的密码 + + + + The new password is not consistent in two times + 新密码两次不一致 + + + + Password changed successfully + 密码更改成功 + + + + CtrlAdvancedPanel + + + Advanced + 高级设置 + + + + Screen Width(pixel) + 屏幕宽(像素) + + + + Width + + + + + + Height + + + + + Alias + 别名 + + + + Web (Plat 2) Address + Web (2平台) 地址 + + + + Traffic screen settings + 交通屏设置 + + + + Setting protocol ... + 正在设置协议 ... + + + + Set protocol + 设置协议 + + + + Getting protocol ... + 正在回读协议 ... + + + + Get protocol + 回读协议 + + + + + Port + 端口 + + + + Realtime (Plat 4) Address + Realtime (4平台) 地址 + + + + Firmware Management + 固件管理 + + + + update or uninstall + 更新或卸载 + + + + Check Apk + 检查Apk + + + + Uninstall + 卸载 + + + + Running check + 运行状态监测 + + + + Restart + 重启 + + + + Check Log + 查看日志 + + + + Start LedSet4.0 + 使用 LedSet4.0 配置LED模组(Apk Display2.0以上版本) + + + + Open ADB + 打开ADB调试功能 + + + + + + + + + Clear Program + 清除节目 + + + + Config + 配置 + + + + Restore to default + 恢复默认值 + + + + Taxi top screen configuration + 车顶有无客电平配置 + + + + + Service:High Out of service:Low + 有客:高电平 无客:低电平 + + + + + Service:Low Out of service:High + 有客:低电平 无客:高电平 + + + + Bind Taxihub identity certificate + 绑定Taxihub用户身份凭证 + + + + Rotate + 旋转 + + + + Min brightness + 最低亮度 + + + + Max brightness + 最高亮度 + + + + Compant ID: + 公司ID: + + + + Compant ID + 公司ID + + + + + SetOnlineAddr + 设置web服务器地址 + + + + + ClearRealtimeServer + 清除 + + + + + + + + + SetRealtimeServer + 设置RealTimer地址 + + + + + RestartAndroid + 重启 + + + + + running + 正在运行 + + + + + no running + 没有运行 + + + + + Check Apk Version + 查询已安装apk版本 + + + + + UninstallSoftware + 卸载 + + + + + Check apk running status + 监测APK运行状态 + + + + + OpenAdb + 打开ADB调试功能 + + + + Identity Certificate + 身份凭证 + + + + + + + + + + Binding certificate + 绑定证书 + + + + + AliIotSetting + + + + + Software Version Info + 软件版本信息 + + + + Package + 包名 + + + + Version + 版本 + + + + + Package name is null + 包名为空 + + + + Clearing Program + 正在清除节目 + + + + + Timeout + 超时 + + + + + + + Failed + 失败 + + + + Getting Log + 正在获取日志 + + + + 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 + 播放器状态 + + + + + Cannot Open File + 文件打开失败 + + + + Uploading + 正在上传 + + + + Update + 更新 + + + + + Set Display Mode + 设置显示模式 + + + + + Get Display Mode + 获取显示模式 + + + + + + + + + + + Screen Offset + 屏幕偏移 + + + + + + Lock Card + 锁卡 + + + + Open file Failed + 文件打开失败 + + + + + No VehPlayer File + + + + + + Failed to Read File + 文件读取失败 + + + + Setting Wallpaper + 正在设置系统桌面背景 + + + + + Set Wallpaper + 设置系统桌面背景 + + + + System Updating + 系统升级中 + + + + + System Update + 系统升级 + + + + Upload error + 上传错误 + + + + Upgrading + 升级中 + + + + Getting MCU Version + 正在获取单片机版本 + + + + + MCU Version + 单片机版本 + + + + 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 + 回读控制卡工作模式 + + + + Change Password + 修改密码 + + + + Get Receive Card Num + 获取接收卡数量 + + + + Player Debug + 播放器查问题 + + + + + Resolution Config + 分辨率配置 + + + + Full screen + 全屏 + + + + Part + 局部 + + + + Display Mode + 显示模式 + + + + Screen Position + 屏幕位置 + + + + + Offset + 偏移 + + + + + + + + Camera Distance + 摄像头距离 + + + + Hidden Settings + 隐藏的设置 + + + + Click right button to hide + 点击右键隐藏 + + + + Get MCU Version + 获取单片机版本 + + + + Baud Config + 波特率配置 + + + + Model + 设备型号 + + + + Uart + 串口节点 + + + + Baud + 波特率 + + + + Timing Reboot + 定时重启 + + + + Protocol + 协议 + + + + Server + 服务端 + + + + Client + 客户端 + + + + + SetScreenRotation + 设置屏幕旋转 + + + + + SetMinBrightness + 设置最小的亮度值 + + + + + SetMaxBrightness + 设置亮度最大值 + + + + + GetMinBrightness + 获取亮度最小值 + + + + + GetMaxBrightness + 获取亮度最大值 + + + + + Card work mode + 控制卡工作模式 + + + + + SetSpecialResolution + 设置分辨率 + + + + + GetSpecialResolution + 读取分辨率 + + + + + Restore to default relolution + 恢复默认分辨率 + + + + + SetHighForBusy + 设置有无客电平 + + + + + GetStateForBusy + 获取有无客电平 + + + + + SetCardAlias + 设置别名 + + + + InputWidthTip + 请输入正确的宽度像素值 + + + + InputHeightTip + 请输入正确的高度像素值 + + + + Password is error + 密码错误 + + + + CtrlBrightPanel @@ -1216,12 +1645,6 @@ GetAutoBrightnessTask 获取定时亮度表 - - - - Error - 错误 - Brightness Config @@ -1267,36 +1690,11 @@ Minbrightness 最小亮度值 - - - - - Set - 设置 - - Upload + Upload File 上传配置文件 - - - - - - Readback - 回读 - - - - ReadbackTable - 回读 - - - - Refresh - 刷新 - Cur Brigntness @@ -1317,11 +1715,6 @@ Add 添加 - - - Clear - 清空 - Delete @@ -1351,175 +1744,150 @@ CtrlHdmiPanel - + HDMI Configuration 画面输入源配置 - + Manual 手动 - + Schedule 定时 - - - - - Tip - 提示 - - - - - - - NoSelectedController - 请先选择大屏幕 - - - - + + + + SyncSwitch 切换同步模式 - - + + AnSyncSwitch 切换异步模式 - + IsSync 回读同异步模式 - + Import File 导入文件 - + Save File 保存文件 - - + + Sync Schedule 同步定时任务 - - + + SetTimingHdmiInTask 设置同步模式定时任务 - + GetTimingHdmiInTask 获取同步模式定时任务 - - + + Async 异步 - - Set - 设置 + + Auto Switch + 自动识别 - - - Readback - 回读 - - - + Start Time 开始时间 - + End Time 结束时间 - + SUN 星期日 - + MON 星期一 - + TUE 星期二 - + WED 星期三 - + THU 星期四 - + FRI 星期五 - + SAT 星期六 - + Add 添加 - - + + Apply 应用 - - Clear - 清空 - - - + Delete 删除 - + Import 导入 - + Export 导出 - + By default, the asynchronous content is played, and the synchronous signal content is played in the fixed time period 默认播放异步内容,定时时间段内播放同步HDMI-IN端口输入内容 @@ -1527,190 +1895,133 @@ CtrlNetworkPanel - + Wire Enther(RJ45) Configuration 有线网配置 - - DHCP - - - - + Specify IP 指定IP - + IP Address IP地址 - + Gateway 网关 - + DNS Address DNS地址 - - - - Set - 设置 - - - - - - - Readback - 回读 - - - - WIFI Configuration + + WiFi Config WiFi配置 - - WiFi Mode - 使用WiFi + + Enable WiFi + 开启WiFi - + Cellular Config 蜂窝数据配置 - + Enable Cellular Data - 启用蜂窝数据 + 开启蜂窝数据 - + Get cellular network status information 获取蜂窝网络状态信息 - + Through the check status button 通过“获取状态”按钮可以自动匹配国家码,然后选择“运营商”可获取到相应的APN信息。 - + Set APN Info 设置APN信息 - + Country ID(mcc): 国家码(mcc): - - + + Carrier Name 运营商 - + APN(Required) APN(必填) - + Flight Mode 飞行模式 - + WiFi name WiFi名称 - - - + + + Password 密码 - - - Input password - 输入密码 - - - + Scan 扫描 - - Ap Mode - 使用热点 + + Enable AP + 开启热点 - + OFF - + ON - + AP name 热点名称 - + Subnet mask 子网掩码 - + Input ap name 输入AP名称 - - - - - - - - - - - - - - Tip - 提示 - - - - - - - - - - - - - - NoSelectedController - 请先选择大屏幕 - @@ -1762,326 +2073,322 @@ 静态IP - - - + + + + + ConfigurationWiFi 配置WiFi - - - IsPortableHotSpot + + + Get AP or WiFi 获取热点和WiFi模式 - + GetWifiList 扫描WiFi - - - ConfigurationHotSpot + + + + + + + Config Hotspot 配置热点 - - success - 成功 - - - + WifiName Wifi名称 - + ApName 热点名称 - - + + GetCurrentAPN 获取APN信息 - + GetSIMStatus 获取SIM状态 - - + + SetAPN 设置APN - - 状态: - 状态: + + Status + 状态 - - Error - 错误 - - - + 未知 未知 - + 锁定状态,需要用户的PIN码解锁 锁定状态,需要用户的PIN码解锁 - + 锁定状态,需要用户的PUK码解锁 锁定状态,需要用户的PUK码解锁 - + 锁定状态,需要网络的PIN码解锁 锁定状态,需要网络的PIN码解锁 - + 就绪 就绪 - + no checked sim card 检测不到sim卡 - + 国家码: 国家码: - + 号码: 号码: - + 用户: 用户: - + 信号: 信号: - + 信号正常 信号正常 - + 不在服务区 不在服务区 - + 仅限紧急呼叫 仅限紧急呼叫 - + 射频已经关闭 射频已经关闭 - + 网络: 网络: - + 网络类型未知 未知 - + GPRS网络 GPRS - + EDGE网络 EDGE - + UMTS网络 UMTS - + CDMA网络,IS95A 或 IS95B. CDM - + EVDO网络, revision 0. EVDO,revision 0. - + EVDO网络, revision A. EVDO,revision A. - + 1xRTT网络 1xRTT - + HSDPA网络 HSDPA - + HSUPA网络 HSUPA - + HSPA网络 HSPA - + 漫游: 漫游: - + Yes - + No - + 数据连接状态: 数据连接状态: - + 断开 断开 - + 正在连接 正在连接 - + 已连接 已连接 - + 暂停 暂停 - + 数据活动休眠状态: 数据活动休眠状态: - + 活动,但无数据发送和接收 活动,但无数据发送和接收 - + 活动,正在接收数据 活动,正在接收数据 - + 活动,正在发送数据 活动,正在发送数据 - + 活动,正在接收和发送数据 活动,正在接收和发送数据 - + 休眠状态 休眠状态 - + 信号强度: - + User 用户 - + Type 类型 - + Server 服务端 - + Port 端口 - + Proxy 代理 - + MMS Port 彩信端口 - + MMS Proxy 彩信代理 - - + + SetSwitchSimData 设置4G/5G开关 - - + + ContrFlightMode 配置飞行模式 - - + + GetFlightModeState 获取飞行模式状态 @@ -2102,24 +2409,6 @@ On - - - - - - - Tip - 提示 - - - - - - - - NoSelectedController - 请先选择大屏幕 - @@ -2185,12 +2474,6 @@ Power 电源 - - - - Readback - 回读 - Start Time @@ -2246,11 +2529,6 @@ Apply 应用 - - - Clear - 清空 - Delete @@ -2276,11 +2554,6 @@ Clear Schedule 清除定时 - - - Tip Info - 提示 - Clear schedule task? @@ -2339,25 +2612,6 @@ Enter again 再次输入 - - - - - - - - - - - Tip - 提示 - - - - - NoSelectedController - 请先选择大屏幕 - @@ -2379,11 +2633,6 @@ InputRepeatPasswordNotSameTip 两次输入的密码不一致 - - - Tip Info - 提示 - After setting the password, please remember the password and record it. If you forget the password, the device will be unable to operate. Are you sure you want to continue with this operation? @@ -2397,18 +2646,6 @@ SetControllerPassword 设置加密 - - - - Error - 错误 - - - - - Success - 成功 - @@ -2533,21 +2770,11 @@ Gradient 渐变 - - - Clear - 清空 - Reset 循环 - - - Success - 成功 - @@ -2560,27 +2787,6 @@ Stop 停止 - - - - - - - - - Tip - 提示 - - - - - - - - - NoSelectedController - 请先选择大屏幕 - @@ -2632,36 +2838,6 @@ LAN 局域网 - - - - - - - - - - - - - Tip - 提示 - - - - - - - - - - - - - - NoSelectedController - 请先选择大屏幕 - screenSwitch @@ -2787,15 +2963,6 @@ TimeZone 时区 - - - - - - - Set - 设置 - Language: @@ -2812,15 +2979,6 @@ Sync time interval 同步时间间隔 - - - - - - - Readback - 回读 - @@ -2894,22 +3052,6 @@ CtrlVolumePanel - - - - - - Tip - 提示 - - - - - - - NoSelectedController - 请先选择大屏幕 - @@ -2969,17 +3111,6 @@ Volume 音量 - - - Set - 设置 - - - - - Readback - 回读 - Default volume @@ -2990,11 +3121,6 @@ Add 添加 - - - Clear - 清空 - Delete @@ -3071,41 +3197,6 @@ 提醒:定时时间段以外的时间显示屏为默认亮度 - - Def - - - - - - - - - - - - - Device replied - 设备回复 - - - - - - - - - Success - 成功 - - - - - - Fail - 失败 - - DevicePanel @@ -3121,13 +3212,6 @@ 在线 在线 - - - - Refresh - 刷新 - 刷新 - @@ -3195,11 +3279,6 @@ Detail Info 详细信息 - - - Getting - 正在获取 - Specify IP list @@ -3232,11 +3311,6 @@ Screen ID 屏幕ID - - - Screen Size - 屏幕像素 - Alias @@ -3317,12 +3391,6 @@ selected num 选中数目 - - - - Clear - 清空 - More Info @@ -3343,32 +3411,11 @@ Security 加密 - - - Getting - 正在获取 - - - - - Error - 错误 - - - - Input password - 输入密码 - - VerifyPassword + Verify Password 验证密码 - - - Tip Info - 提示 - password is wrong @@ -3378,94 +3425,89 @@ 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 文本 @@ -3505,14 +3547,14 @@ - - + + None - + Effect 特效 @@ -3529,7 +3571,7 @@ - + Blink 闪烁 @@ -3564,179 +3606,179 @@ 开始 - - - - + + + + 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 淡出 - + Breathe 呼吸 - + Freq 频率 @@ -3744,124 +3786,119 @@ 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 多行显示 @@ -3953,11 +3990,6 @@ NW 西北 - - - Basic Properties - 基本属性 - Title @@ -4002,20 +4034,10 @@ EGif - - Basic Properties - 基本属性 - - - + File 文件 - - - Select File - 选择文件 - EMultiWin @@ -4071,13 +4093,6 @@ AClock 模拟时钟 - - - - - Select File - 选择文件 - @@ -4094,25 +4109,55 @@ EPhoto - - Basic Properties - 基本属性 - - - + File 文件 - - Select File - 选择文件 - - - + Image Read Error 图片读取错误 + + + Direction + 方向 + + + + Scroll + 滚动 + + + + No + + + + + Right -> Left + 向左 + + + + Bottom -> Top + 向上 + + + + Left -> Right + 向右 + + + + Top -> Bottom + 向下 + + + + Speed + 速度 + Images (*.png *.jpg *.jpeg *.bmp) @@ -4122,195 +4167,185 @@ EText - + Enter your text 请输入内容 - - Basic Properties - 基本属性 - - - + Back Color 背景色 - + Kerning 字距 - + Line Height 行高 - + PageCount: 总页数: - + page - + Import txt File 导入 txt 文件 - - Select File - 选择文件 - - - + Fail 失败 - + Cannot Open File 文件打开失败 - + Play Properties 播放方式 - + Flip 翻页 - + Scroll 滚动 - + Static 静态 - + + New Format + 新格式 + + + Text Color 文字颜色 - + Colorful Text 炫彩文字 - - Head-Tail Spacing + + Tail Spacing 首尾间隔 - - Scroll Style - 滚动方向 + + Direction + 方向 - + Right -> Left 向左 - + Bottom -> Top 向上 - + Left -> Right 向右 - + Top -> Bottom 向下 - - Scroll Speed - 滚动速度 + + Speed + 速度 ETimer - + day - + hour - + min - + sec - - Basic Properties - 基本属性 - - - + Count Down 倒计时 - + Count Up 正计时 - - Time + + Target Time 目标时间 - + Day - + Hour - + Min - + Sec - + Multiline 多行显示 - + Text 文本 @@ -4346,11 +4381,6 @@ Secs - - - Basic Properties - 基本属性 - Count Down @@ -4363,7 +4393,7 @@ - Time + Target Time 目标时间 @@ -4395,47 +4425,36 @@ EVideo - - Basic Properties - 基本属性 - - - + File 文件 - + Play Properties 播放方式 - - Select File - 选择文件 - - - + Play Times 播放次数 - + + Use SW + 使用软解码 + + + Video Transcoding 视频转码 - - + + Video Transcoding Progress 视频转码进度 - - - - Error - 错误 - Video @@ -4450,27 +4469,22 @@ EWeb - - Basic Properties - 基本属性 - - - + Zoom 缩放 - + Refresh every 刷新间隔 - + Offset 偏移 - + Scale 拉伸 @@ -4501,67 +4515,67 @@ GenTmpThread - + MON 星期一 - + TUE 星期二 - + WED 星期三 - + THU 星期四 - + FRI 星期五 - + SAT 星期六 - + SUN 星期日 - + AM 上午 - + PM 下午 - + day - + hour - + min - + sec @@ -4582,14 +4596,6 @@ 透明 - - LoDateSelector - - - Date selector - 日期选择器 - - LoQTitleBar @@ -4605,12 +4611,6 @@ Maximize 最小化 - - - - Close - 关闭 - Restore @@ -4620,187 +4620,171 @@ 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 IP in Terminal Control 在终端控制显示IP - + 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,请谨慎操作! @@ -4812,12 +4796,6 @@ Connection Timeout 连接超时 - - - - Error - 错误 - PageEditor @@ -4911,11 +4889,6 @@ Align right 水平靠右 - - - Tip Info - 提示 - Clear all medias? @@ -4925,84 +4898,84 @@ PageListItem - + times - + Page name 节目名称 - + New 新建 - + Play times 播放次数 - + Sources Repeat 素材循环 - + + Wait Audio + 等待音频 + + + 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 时间计划表 @@ -5010,37 +4983,37 @@ PlanItemWgt - + M - + Tu - + W - + Th - + F - + Sa - + Su @@ -5048,30 +5021,25 @@ PlayWin - + Move to Top Left 移动到左上角 - + Set Position 设置位置 - - - Close - 关闭 - PlayerBackSendThread - + Open file failed 文件读取失败 - + Read file failed 文件读取失败 @@ -5092,52 +5060,57 @@ ProgCreateDlg - + Resolution 分辨率 - - Solution Information + + Solution Info 节目信息 - + Solution Name 节目名称 - + Width - + Height - + Remarks 备注 + Is Insert + 插播节目 + + + Ultra-Long Screen Split 超长屏打折 - + Horizontal 水平 - + Vertical 垂直 - + Lengths of Parts 每段长度 @@ -5145,199 +5118,174 @@ ProgEditorWin - + Save 保存 - + 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 + + Widget Properties 组件属性 - - Page properties + + Program Properties 节目属性 - + Do you want to save the modifications? 是否保存修改? - - Create Dir failed + + Failed to Create Forder 创建目录失败 - + Saving... 正在保存... - - Success - 成功 - - - + Convertering 整理数据中 - + Demos 测试素材 - + Open Demo 打开测试素材 - + Generate preview data 生成预览数据 - - - - Error - 错误 - - - - Rename fail when saving + + Failed to Rename Forder 重命名文件夹失败 - - Remove Recursively fail when saving + + Failed to Remove Recursively @@ -5345,141 +5293,130 @@ 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)? :节目已存在。是否确实要覆盖现有节目? - - + + + Rename + 重命名 + + + + 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 - 提示 - ProgPortDlg - + Solution Name 节目名称 - + Progress 进度 - + Done 完成 @@ -5504,11 +5441,6 @@ ProgressesItem - - - Error - 错误 - Install Success @@ -5540,16 +5472,6 @@ Setting up the LedOK Express... 初始化LedOK Express... - - - Input password - 输入密码 - - - - Error - 错误 - USB Update Program @@ -5566,12 +5488,6 @@ Convertering 整理数据中 - - - - Tip - 提示 - No checked USB device @@ -5587,17 +5503,17 @@ SendProgThread - + Program is empty 节目为空 - + Open file failed 文件打开失败 - + Read file failed 文件读取失败 @@ -5605,98 +5521,78 @@ SendProgramDialog - - + + Publish 发布 - + success info - - Refresh - 刷新 - - - + Alias 别名 - + Online 在线 - - Screen Size - 屏幕像素 - - - + Security 加密 - + Progress 进度 - + Remarks 备注 - + This screen is encrypted 屏幕已加密 - + Info 信息 - + Some player versions are too low and may not be compatible. It's recommended to update the player to 2.0. Or download the old version %1 from website 有播放器版本过低,可能存在不兼容问题。建议更新播放器到2.0。或从官网下载旧版本 %1 - + Do you want to continue? 是否继续? - + Waiting 等待中 - - Input password - 输入密码 - - - - VerifyPassword + + Verify Password 验证密码 - - Tip Info - 提示 - - - + password is wrong 密码错误 - + All 总数 @@ -5718,6 +5614,11 @@ Upgrade 升级 + + + Failed to Read File + 文件读取失败 + Uninstall @@ -5738,11 +5639,6 @@ Upgrading 升级中 - - - Refresh - 刷新 - Alias @@ -5809,38 +5705,12 @@ Please select a file 请选择一个文件 - - - - - Tip - 提示 - - - - NoSelectedController - 请先选择大屏幕 - - - - File Read Fail - 文件读取失败 - Downloading Online File 正在下载在线文件 - - - - - - - Error - 错误 - Online file is empty @@ -5866,11 +5736,6 @@ Don't power off during this process 升级过程中请勿断电 - - - Install error - 安装错误 - @@ -5897,16 +5762,6 @@ Uninstalling 正在卸载 - - - Uninstall error - 卸载错误 - - - - Uninstall success - 卸载成功 - Check apk running status @@ -5927,21 +5782,11 @@ Not running 没有运行 - - - Input password - 输入密码 - - VerifyPassword + Verify Password 验证密码 - - - Tip Info - 提示 - password is wrong @@ -5963,14 +5808,6 @@ 加密控制卡可以直接升级 - - WaitingDlg - - - Success - 成功 - - mGuangYingPinWidget @@ -6059,11 +5896,6 @@ Auxiliary 副设备 - - - Refresh - 刷新 - Param configuration @@ -6079,11 +5911,6 @@ Delay millsecond 延时(微秒) - - - Clear - 清空 - Debug @@ -6099,21 +5926,11 @@ Program number 节目号 - - - Send - 发送 - Brightness 屏体亮度 - - - Set - 设置 - Screen Off @@ -6136,38 +5953,12 @@ Screen On 开屏 - - - - - - - - - - - - - - - - - - Close - 关闭 - State:On 状态:连接 - - - - Tip - 提示 - diff --git a/LedOK/ts/app_zh_TW.ts b/LedOK/ts/app_zh_TW.ts index 88554f3..15f29e0 100644 --- a/LedOK/ts/app_zh_TW.ts +++ b/LedOK/ts/app_zh_TW.ts @@ -2,1059 +2,537 @@ - ChangePasswordForm - - - Old password - 舊密碼 - - - - New password - 新密碼 - - - - Repeat again - 重複一遍 - - - - - - - - Tip - 提示 - - - - Please input old password - 請輸入舊密碼 - - - - Old password is wrong - 舊密碼錯誤 - - - - Please enter a password with more than 3 characters - 請輸入超過 3 個字元的密碼 - - - - The new password is not consistent in two times - 新密碼兩次不一致 - - - - Password changed successfully - 密碼更改成功 - - - - CtrlAdvancedPanel - - - Advanced - 高級設定 - - - - Screen Width(pixel) - 螢幕寬(點數) - - - - Width - - - - - - Height - - - - - - - - Set - 設定 - - - - Alias - 別名 - - - - Web (Plat 2) Address - Web (2平臺) 地址 - - - - Setting Camera Range - - - - - - - Set Camera Range - - - - - Setting - 正在設定 - - - - Traffic screen settings - 交通屏設定 - - - - Setting protocol ... - 正在設定協定 - - - - Set protocol - 設定協定 - - - - Getting protocol ... - 正在回讀協定 ... - - - - Get protocol - 回讀協定 - - - - - Port - - - - - Realtime (Plat 4) Address - Realtime (4平臺) 地址 - - - - 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 - 清除節目 - - - - 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 - 最高亮度 - - - - - SetScreenSize - 設定螢幕點數尺寸 - - - - - - - - Success - 成功 - - - - Compant ID: - 公司ID: - - - - Compant ID - 公司ID - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - NoSelectedController - 請先選擇大螢幕 - - - - - SetOnlineAddr - 設定web伺服器地址 - - - - - ClearRealtimeServer - 清除 - - - - - - - - - SetRealtimeServer - 設定RealTimer地址 - - - - - 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 - 正在設定定時重啓 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Please select screen first + 請先選擇大螢幕 - - Set Timing Reboot - 設定定時重啓 + + + + + + + + + + + + + + + + + + + + + + + + Success + 成功 - - Getting Timing Reboot - 正在獲取定時重啓 + + + + + + + + Setting + 正在設定 - - Get Timing Reboot - 獲取定時重啓 + + + + + + + Screen Size + 螢幕點數 - - totalResolution - 行数を含む解像度 + + + + + + + + + + + Set + 設定 - - strCurDisplayResolution - 當前顯示分辯率 + + + + Getting + 正在獲取 - - - File not exist - 檔案不存在 + + + Get + 獲取 - - Getting Player State - 正在獲取播放機狀態 + + + + Unlock + 解鎖 - - - - Get Player State - 獲取播放機狀態 + + + + + + + Uninstall + 卸載 - - - Player State - 播放機狀態 + + + + + Upload + 上傳 - - - Cannot Open File - 檔案打開失敗 + + + + + + Install + 安裝 - - Uploading - 正在上傳 + + + Wait for + 等待 - - Update - 更新 - - - - - Set Display Mode - 設定顯示模式 - - - - - Get Display Mode - 獲取顯示模式 - - - - - Set Screen Offset - 設定螢幕偏移 - - - - - Get Screen Offset - 獲取螢幕偏移 - - - - Open file Failed - 檔案打開失敗 - - - - Setting Wallpaper - 正在設定系統桌面背景 - - - - - Set Wallpaper - 設定系統桌面背景 - - - - System Updating - 系統升級中 - - - - - System Update - 系統升級 - - - - Upload error - 上傳錯誤 - - - - Upgrading - 陞級中 - - - - Getting MCU Version - 正在獲取單片機版本 - - - - - MCU Version - 單片機版本 - - - + + + + + + + + + + + + Select File 選擇檔案 - - Setting player background - 正在設定播放機背景 + + + + + + + + + + + + + + + + + + + + Set + 設定 - - - 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 + + + + + + + + Input Password 輸入密碼 - - Change Password - 修改密碼 - - - - Get Receive Card Num - 獲取接收卡數量 - - - - Resolution Config - 分辯率配寘 - - - - Full screen - 全屏 - - - - Part - 局部 - - - - Display Mode - 顯示模式 - - - - Screen Position - 螢幕位置 - - - - Offset - 偏移 - - - - Camera Distance - 監視器距離 - - - - Hidden Settings - 隱藏的設定 - - - - Click right button to hide - 點擊右鍵隱藏 - - - - Get MCU Version - 獲取單片機版本 - - - - Baud Config - 串列傳輸速率配寘 - - - - Model - 設備型號 - - - - Uart - 串口節點 - - - - Baud - 串列傳輸速率 - - - - + + Get 讀取 - - Timing Reboot - 定時重啓 + + + + + + + + + + + + + + + + + + + + + + Readback + 回讀 - - Protocol - 協定 + + + + + + + + Refresh + 檢測 - - Server - 服務端 + + Date + 日期 + + Password + 密碼 + + + + Lock + 加鎖 + + + + + + + Send + 發送 + + + + + + + + + + + + Clear + 清空 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - Client - 用戶端 - - - - - SetScreenRotation - 設定螢幕旋轉 - - - - - SetMinBrightness - 設定最小的亮度值 - - - - - SetMaxBrightness - 設定亮度最大值 - - - - - GetMinBrightness - 獲取亮度最小值 - - - - - GetMaxBrightness - 獲取亮度最大值 - - - - - Card work mode - 控制卡工作模式 - - - - - SetSpecialResolution - 設定分辯率 - - - - - GetSpecialResolution - 讀取分辯率 - - - - - CleanDisplayScreenSize - 恢復默認分辯率 - - - - - SetHighForBusy - 設定有無客電平 - - - - - GetStateForBusy - 獲取有無客電平 - - - - - SetCardAlias - 設定別名 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Tip - 提示 - - - - InputWidthTip - 請輸入正確的寬度點數值 - - - - InputHeightTip - 請輸入正確的高度點數值 - - - - Password is error - 密碼錯誤 - - - - CtrlBrightPanel - + + + + + + + + + + + + + @@ -1073,24 +551,975 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Tip 提示 - - - - - - - - - - - - NoSelectedController - 請先選擇大螢幕 + + + + + + + + + + + + + + + + + + + + Close + 關閉 + + + + + + + + + + + + + Device replied + 設備回復 + + + + + + Fail + 失敗 + + + + + + + + + + + + + Basic Properties + 基本屬性 + + + + Getting + 正在獲取 + + + + CalendarButton + + + Select a Date + 選擇日期 + + + + ChangePasswordForm + + + Old password + 舊密碼 + + + + New password + 新密碼 + + + + Repeat again + 重複一遍 + + + + Please input old password + 請輸入舊密碼 + + + + Old password is wrong + 舊密碼錯誤 + + + + Please enter a password with more than 3 characters + 請輸入超過 3 個字元的密碼 + + + + The new password is not consistent in two times + 新密碼兩次不一致 + + + + Password changed successfully + 密碼更改成功 + + + + CtrlAdvancedPanel + + + Advanced + 高級設定 + + + + Screen Width(pixel) + 螢幕寬(點數) + + + + Width + + + + + + Height + + + + + Alias + 別名 + + + + Web (Plat 2) Address + Web (2平臺) 地址 + + + + Traffic screen settings + 交通屏設定 + + + + Setting protocol ... + 正在設定協定 + + + + Set protocol + 設定協定 + + + + Getting protocol ... + 正在回讀協定 ... + + + + Get protocol + 回讀協定 + + + + + Port + + + + + Realtime (Plat 4) Address + Realtime (4平臺) 地址 + + + + Firmware Management + 固件管理 + + + + update or uninstall + 更新或卸載 + + + + Check Apk + 檢查Apk + + + + Uninstall + 卸載 + + + + Running check + 運行狀態監測 + + + + Restart + 重啓 + + + + Check Log + 查看日誌 + + + + Start LedSet4.0 + + + + + Open ADB + 打開ADB調試功能 + + + + + + + + + Clear Program + 清除節目 + + + + Config + 配寘 + + + + Restore to default + 恢復預設值 + + + + Taxi top screen configuration + 車頂有無客電平配寘 + + + + + Service:High Out of service:Low + 有客:高電平無客:低電平 + + + + + Service:Low Out of service:High + 有客:低電平 無客:高電平 + + + + Bind Taxihub identity certificate + 綁定Taxihub用戶身份憑證 + + + + Rotate + 旋轉 + + + + Min brightness + 最低亮度 + + + + Max brightness + 最高亮度 + + + + Compant ID: + 公司ID: + + + + Compant ID + 公司ID + + + + + SetOnlineAddr + 設定web伺服器地址 + + + + + ClearRealtimeServer + 清除 + + + + + + + + + SetRealtimeServer + 設定RealTimer地址 + + + + + RestartAndroid + 重啓 + + + + + running + 正在運行 + + + + + no running + 沒有運行 + + + + + Check Apk Version + 査詢已安裝apk版本 + + + + + UninstallSoftware + 卸載 + + + + + Check apk running status + 監測APK運行狀態 + + + + + OpenAdb + 打開ADB調試功能 + + + + Identity Certificate + 身份憑證 + + + + + + + + + + Binding certificate + 綁定證書 + + + + + AliIotSetting + + + + + Software Version Info + 軟體版本資訊 + + + + Package + 包名 + + + + Version + 版本 + + + + + Package name is null + 包名為空 + + + + Clearing Program + 正在清除節目 + + + + + Timeout + 超時 + + + + + + + Failed + 失敗 + + + + Getting Log + 讀取日誌 + + + + 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 + 播放機狀態 + + + + + Cannot Open File + 檔案打開失敗 + + + + Uploading + 正在上傳 + + + + Update + 更新 + + + + + Set Display Mode + 設定顯示模式 + + + + + Get Display Mode + 獲取顯示模式 + + + + + + + + + + + Screen Offset + 螢幕偏移 + + + + + + Lock Card + 鎖卡 + + + + Open file Failed + 檔案打開失敗 + + + + + No VehPlayer File + + + + + + Failed to Read File + 檔案讀取失敗 + + + + Setting Wallpaper + 正在設定系統桌面背景 + + + + + Set Wallpaper + 設定系統桌面背景 + + + + System Updating + 系統升級中 + + + + + System Update + 系統升級 + + + + Upload error + 上傳錯誤 + + + + Upgrading + 陞級中 + + + + Getting MCU Version + 正在獲取單片機版本 + + + + + MCU Version + 單片機版本 + + + + 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 + 回讀控制卡工作模式 + + + + Change Password + 修改密碼 + + + + Get Receive Card Num + 獲取接收卡數量 + + + + Player Debug + + + + + + Resolution Config + 分辯率配寘 + + + + Full screen + 全屏 + + + + Part + 局部 + + + + Display Mode + 顯示模式 + + + + Screen Position + 螢幕位置 + + + + + Offset + 偏移 + + + + + + + + Camera Distance + 監視器距離 + + + + Hidden Settings + 隱藏的設定 + + + + Click right button to hide + 點擊右鍵隱藏 + + + + Get MCU Version + 獲取單片機版本 + + + + Baud Config + 串列傳輸速率配寘 + + + + Model + 設備型號 + + + + Uart + 串口節點 + + + + Baud + 串列傳輸速率 + + + + Timing Reboot + 定時重啓 + + + + Protocol + 協定 + + + + Server + 服務端 + + + + Client + 用戶端 + + + + + SetScreenRotation + 設定螢幕旋轉 + + + + + SetMinBrightness + 設定最小的亮度值 + + + + + SetMaxBrightness + 設定亮度最大值 + + + + + GetMinBrightness + 獲取亮度最小值 + + + + + GetMaxBrightness + 獲取亮度最大值 + + + + + Card work mode + 控制卡工作模式 + + + + + SetSpecialResolution + 設定分辯率 + + + + + GetSpecialResolution + 讀取分辯率 + + + + + Restore to default relolution + 恢復默認分辯率 + + + + + SetHighForBusy + 設定有無客電平 + + + + + GetStateForBusy + 獲取有無客電平 + + + + + SetCardAlias + 設定別名 + + + + InputWidthTip + 請輸入正確的寬度點數值 + + + + InputHeightTip + 請輸入正確的高度點數值 + + + + Password is error + 密碼錯誤 + + + + CtrlBrightPanel @@ -1221,12 +1650,6 @@ GetAutoBrightnessTask 獲取定時亮度錶 - - - - Error - 錯誤 - Brightness Config @@ -1272,36 +1695,11 @@ Minbrightness 最小亮度值 - - - - - Set - 設定 - - Upload + Upload File 上傳設定檔 - - - - - - Readback - 回讀 - - - - ReadbackTable - 回讀 - - - - Refresh - 檢測 - Cur Brigntness @@ -1322,11 +1720,6 @@ Add 添加 - - - Clear - 清空 - Delete @@ -1356,175 +1749,150 @@ CtrlHdmiPanel - + HDMI Configuration 畫面輸入源配寘 - + Manual 手動 - + Schedule 定時 - - - - - Tip - 提示 - - - - - - - NoSelectedController - 請先選擇大螢幕 - - - - + + + + SyncSwitch 切換同步模式 - - + + AnSyncSwitch 切換異步模式 - + IsSync 回讀同非同步模式 - + Import File 導入檔案 - + Save File 保存 - - + + Sync Schedule 同步定時任務 - - + + SetTimingHdmiInTask 設定同步模式定時任務 - + GetTimingHdmiInTask 獲取同步模式定時任務 - - + + Async BOX - - Set - 設定 + + Auto Switch + - - - Readback - 回讀 - - - + Start Time 開始時間 - + End Time 結束時間 - + SUN 星期日 - + MON 星期一 - + TUE 星期二 - + WED 星期三 - + THU 星期四 - + FRI 星期五 - + SAT 星期六 - + Add 添加 - - + + Apply 應用 - - Clear - 清空 - - - + Delete 删除 - + Import 導入 - + Export 匯出 - + By default, the asynchronous content is played, and the synchronous signal content is played in the fixed time period 默認播放非同步內容,定時時間段內播放同步HDMI-IN埠輸入內容 @@ -1532,190 +1900,133 @@ CtrlNetworkPanel - + Wire Enther(RJ45) Configuration 有線網配寘 - - DHCP - - - - + Specify IP 指定IP - + IP Address IP地址 - + Gateway 閘道 - + DNS Address DNS地址 - - - - Set - 設定 - - - - - - - Readback - 回讀 - - - - WIFI Configuration + + WiFi Config WiFi配寘 - - WiFi Mode - 使用WiFi + + Enable WiFi + 开啟WiFi - + Cellular Config 蜂窩數據配寘 - + Enable Cellular Data 啟用蜂窩數據 - + Get cellular network status information 獲取蜂窩網絡狀態資訊 - + Through the check status button 通過“獲取狀態”按鈕可以自動匹配國家碼,然後選擇“運營商”可獲取到相應的APN資訊。 - + Set APN Info 設定APN資訊 - + Country ID(mcc): 国家码(mcc):國家碼(mcc): - - + + Carrier Name 運營商 - + APN(Required) APN(必填) - + Flight Mode 飛行模式 - + WiFi name WiFi名稱 - - - + + + Password 密碼 - - - Input password - 輸入密碼 - - - + Scan 掃描 - - Ap Mode - 使用熱點 + + Enable AP + 开啟熱點 - + OFF - + ON - + AP name 熱點名稱 - + Subnet mask 子網路遮罩 - + Input ap name 輸入AP名稱 - - - - - - - - - - - - - - Tip - 提示 - - - - - - - - - - - - - - NoSelectedController - 請先選擇大螢幕 - @@ -1767,326 +2078,322 @@ 靜態IP - - - + + + + + ConfigurationWiFi 配寘WiFi - - - IsPortableHotSpot + + + Get AP or WiFi 獲取熱點和WiFi模式 - + GetWifiList 掃描WiFi - - - ConfigurationHotSpot + + + + + + + Config Hotspot 配寘熱點 - - success - 成功 - - - + WifiName Wifi名稱 - + ApName 熱點名稱 - - + + GetCurrentAPN 獲取APN資訊 - + GetSIMStatus 獲取SIM狀態 - - + + SetAPN 設定APN - - 状态: - 狀態: + + Status + 狀態 - - Error - 錯誤 - - - + 未知 未知 - + 锁定状态,需要用户的PIN码解锁 鎖定狀態,需要用戶的PIN碼解鎖 - + 锁定状态,需要用户的PUK码解锁 鎖定狀態,需要用戶的PUK碼解鎖 - + 锁定状态,需要网络的PIN码解锁 鎖定狀態,需要網絡的PIN碼解鎖 - + 就绪 就緒 - + no checked sim card 檢測不到sim卡 - + 国家码: 國家碼: - + 号码: 號碼: - + 用户: 用戶: - + 信号: 信号: - + 信号正常 訊號正常 - + 不在服务区 不在服務區 - + 仅限紧急呼叫 僅限緊急呼叫 - + 射频已经关闭 射頻已經關閉 - + 网络: 網絡: - + 网络类型未知 未知 - + GPRS网络 GPRS - + EDGE网络 EDGE - + UMTS网络 UMTS - + CDMA网络,IS95A 或 IS95B. CDM - + EVDO网络, revision 0. EVDO,revision 0. - + EVDO网络, revision A. EVDO,revision A. - + 1xRTT网络 1xRTT - + HSDPA网络 HSDPA - + HSUPA网络 HSUPA - + HSPA网络 HSPA - + 漫游: 漫遊: - + Yes - + No - + 数据连接状态: 數據連接狀態: - + 断开 斷開 - + 正在连接 正在連接 - + 已连接 已連接 - + 暂停 暫停 - + 数据活动休眠状态: 數據活動休眠狀態: - + 活动,但无数据发送和接收 活動,但無數據發送和接收 - + 活动,正在接收数据 活動,正在接收數據 - + 活动,正在发送数据 活動,正在發送數據 - + 活动,正在接收和发送数据 活動,正在接收和發送數據 - + 休眠状态 休眠狀態 - + 信号强度: 信號強度: - + User 用戶 - + Type 型態 - + Server 服務端 - + Port - + Proxy 代理 - + MMS Port 彩信埠 - + MMS Proxy 彩信代理 - - + + SetSwitchSimData 設定4G/5G開關 - - + + ContrFlightMode 配寘飛行模式 - - + + GetFlightModeState 獲取飛行模式狀態 @@ -2107,24 +2414,6 @@ On - - - - - - - Tip - 提示 - - - - - - - - NoSelectedController - 請先選擇大螢幕 - @@ -2190,12 +2479,6 @@ Power 電源 - - - - Readback - 回讀 - Start Time @@ -2251,11 +2534,6 @@ Apply 應用 - - - Clear - 清空 - Delete @@ -2281,11 +2559,6 @@ Clear Schedule 清除定時 - - - Tip Info - 提示 - Clear schedule task? @@ -2344,25 +2617,6 @@ Enter again 再次輸入 - - - - - - - - - - - Tip - 提示 - - - - - NoSelectedController - 請先選擇大螢幕 - @@ -2384,11 +2638,6 @@ InputRepeatPasswordNotSameTip 兩次輸入的密碼不一致 - - - Tip Info - 提示 - After setting the password, please remember the password and record it. If you forget the password, the device will be unable to operate. Are you sure you want to continue with this operation? @@ -2402,18 +2651,6 @@ SetControllerPassword 設定加密 - - - - Error - 錯誤 - - - - - Success - 成功 - @@ -2538,21 +2775,11 @@ Gradient 漸變 - - - Clear - 清空 - Reset 迴圈 - - - Success - 成功 - @@ -2565,27 +2792,6 @@ Stop 停止 - - - - - - - - - Tip - 提示 - - - - - - - - - NoSelectedController - 請先選擇大螢幕 - @@ -2637,36 +2843,6 @@ LAN 局域網 - - - - - - - - - - - - - Tip - 提示 - - - - - - - - - - - - - - NoSelectedController - 請先選擇大螢幕 - screenSwitch @@ -2792,15 +2968,6 @@ TimeZone 時區 - - - - - - - Set - 設定 - Language: @@ -2817,15 +2984,6 @@ Sync time interval 同步時間間隔 - - - - - - - Readback - 回讀 - @@ -2899,22 +3057,6 @@ CtrlVolumePanel - - - - - - Tip - 提示 - - - - - - - NoSelectedController - 請先選擇大螢幕 - @@ -2974,17 +3116,6 @@ Volume 音量 - - - Set - 設定 - - - - - Readback - 回讀 - Default volume @@ -2995,11 +3126,6 @@ Add 添加 - - - Clear - 清空 - Delete @@ -3076,41 +3202,6 @@ 提醒:定時時間段以外的時間顯示幕為默認亮度 - - Def - - - - - - - - - - - - - Device replied - 設備回復 - - - - - - - - - Success - 成功 - - - - - - Fail - 失敗 - - DevicePanel @@ -3125,12 +3216,6 @@ 在线 線上 - - - - Refresh - 檢測 - @@ -3198,11 +3283,6 @@ Detail Info 詳細資訊 - - - Getting - 正在獲取 - Specify IP list @@ -3235,11 +3315,6 @@ Screen ID 螢幕ID - - - Screen Size - 螢幕點數 - Alias @@ -3320,12 +3395,6 @@ selected num 選中數目 - - - - Clear - 清空 - More Info @@ -3346,32 +3415,11 @@ Security 加密 - - - Getting - 正在獲取 - - - - - Error - 錯誤 - - - - Input password - 輸入密碼 - - VerifyPassword + Verify Password 驗證密碼 - - - Tip Info - 提示 - password is wrong @@ -3381,94 +3429,89 @@ 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 文字 @@ -3508,14 +3551,14 @@ - - + + None - + Effect 特效 @@ -3532,7 +3575,7 @@ - + Blink 閃爍 @@ -3567,179 +3610,179 @@ 開始 - - - - + + + + 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 淡出 - + Breathe 呼吸 - + Freq 頻率 @@ -3747,124 +3790,119 @@ 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 多行顯示 @@ -3956,11 +3994,6 @@ NW 西北 - - - Basic Properties - 基本屬性 - Title @@ -4005,20 +4038,10 @@ EGif - - Basic Properties - 基本屬性 - - - + File 檔案 - - - Select File - 選擇檔案 - EMultiWin @@ -4074,13 +4097,6 @@ AClock 圓形時鐘 - - - - - Select File - 選擇檔案 - @@ -4097,25 +4113,55 @@ EPhoto - - Basic Properties - 基本屬性 - - - + File 檔案 - - Select File - 選擇檔案 - - - + Image Read Error 圖片讀取錯誤 + + + Direction + 方向 + + + + Scroll + 滾動 + + + + No + + + + + Right -> Left + 向左 + + + + Bottom -> Top + 向上 + + + + Left -> Right + 向右 + + + + Top -> Bottom + 向下 + + + + Speed + 速度 + Images (*.png *.jpg *.jpeg *.bmp) @@ -4125,195 +4171,185 @@ EText - + Enter your text 請輸入內容 - - Basic Properties - 基本屬性 - - - + Back Color 背景色 - + Kerning 字距 - + Line Height 行高 - + PageCount: 總頁數: - + page - + Import txt File 導入 txt 檔案 - - Select File - 選擇檔案 - - - + Fail 失敗 - + Cannot Open File 檔案打開失敗 - + Play Properties 播放管道 - + Flip 翻頁 - + Scroll 滾動 - + Static 靜態 - + + New Format + + + + Text Color 文字顏色 - + Colorful Text 炫彩文字 - - Head-Tail Spacing + + Tail Spacing 首尾間隔 - - Scroll Style - 滾動方向 + + Direction + 方向 - + Right -> Left 向左 - + Bottom -> Top 向上 - + Left -> Right 向右 - + Top -> Bottom 向下 - - Scroll Speed - 滾動速度 + + Speed + 速度 ETimer - + day - + hour - + min - + sec - - Basic Properties - 基本屬性 - - - + Count Down 倒數計時 - + Count Up 正計時 - - Time + + Target Time 目標時間 - + Day - + Hour - + Min - + Sec - + Multiline 多行顯示 - + Text 文字 @@ -4349,11 +4385,6 @@ Secs - - - Basic Properties - 基本屬性 - Count Down @@ -4366,7 +4397,7 @@ - Time + Target Time 目標時間 @@ -4398,47 +4429,36 @@ EVideo - - Basic Properties - 基本屬性 - - - + File 檔案 - + Play Properties 播放管道 - - Select File - 選擇檔案 - - - + Play Times 播放次數 - + + Use SW + 使用軟解碼 + + + Video Transcoding - - + + Video Transcoding Progress 視頻轉碼進度 - - - - Error - 錯誤 - Video @@ -4453,27 +4473,22 @@ EWeb - - Basic Properties - 基本屬性 - - - + Zoom 縮放 - + Refresh every 重繪間隔 - + Offset 偏移 - + Scale 拉伸 @@ -4504,67 +4519,67 @@ GenTmpThread - + MON 星期一 - + TUE 星期二 - + WED 星期三 - + THU 星期四 - + FRI 星期五 - + SAT 星期六 - + SUN 星期日 - + AM 上午 - + PM 下午 - + day - + hour - + min - + sec @@ -4585,14 +4600,6 @@ 透明 - - LoDateSelector - - - Date selector - 日期選擇器 - - LoQTitleBar @@ -4608,12 +4615,6 @@ Maximize 最大化 - - - - Close - 關閉 - Restore @@ -4623,187 +4624,171 @@ 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 IP in Terminal Control 在終端控制顯示IP - + 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,請謹慎操作! @@ -4815,12 +4800,6 @@ Connection Timeout 連接超時 - - - - Error - 錯誤 - PageEditor @@ -4914,11 +4893,6 @@ Align right 水准靠右 - - - Tip Info - 提示 - Clear all medias? @@ -4928,84 +4902,84 @@ PageListItem - + times - + Page name 節目名稱 - + New 新建 - + Play times 播放次數 - + Sources Repeat 素材迴圈 - + + Wait Audio + 等待音訊 + + + 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 時間計畫表 @@ -5013,37 +4987,37 @@ PlanItemWgt - + M - + Tu - + W - + Th - + F - + Sa - + Su @@ -5051,30 +5025,25 @@ PlayWin - + Move to Top Left 移動到左上角 - + Set Position 設定位置 - - - Close - 關閉 - PlayerBackSendThread - + Open file failed 檔案打開失敗 - + Read file failed 檔案讀取失敗 @@ -5095,52 +5064,57 @@ ProgCreateDlg - + Resolution 分辯率 - - Solution Information + + Solution Info 節目資訊 - + Solution Name 節目名稱 - + Width - + Height - + Remarks 備註 + Is Insert + + + + Ultra-Long Screen Split 超長屏打折 - + Horizontal 水平 - + Vertical 垂直 - + Lengths of Parts 每段長度 @@ -5148,199 +5122,174 @@ ProgEditorWin - + Save 保存 - + 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 + + Widget Properties 組件内容 - - Page properties + + Program Properties 節目内容 - + Do you want to save the modifications? 是否保存修改? - - Create Dir failed + + Failed to Create Forder 創建目錄失敗 - + Saving... 正在保存… - - Success - 成功 - - - + Convertering 整理數據中 - + Demos 測試素材 - + Open Demo 打開測試素材 - + Generate preview data 生成預覽數據 - - - - Error - 錯誤 - - - - Rename fail when saving + + Failed to Rename Forder - - Remove Recursively fail when saving + + Failed to Remove Recursively @@ -5348,141 +5297,130 @@ 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)? :節目已存在。是否確實要覆蓋現有節目? - - + + + Rename + 重命名 + + + + 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 - 提示 - ProgPortDlg - + Solution Name 節目名稱 - + Progress 進度 - + Done 完成 @@ -5507,11 +5445,6 @@ ProgressesItem - - - Error - 錯誤 - Install Success @@ -5543,16 +5476,6 @@ Setting up the LedOK Express... 初始化LedOK Express… - - - Input password - 輸入密碼 - - - - Error - 錯誤 - USB Update Program @@ -5569,12 +5492,6 @@ Convertering 整理數據中 - - - - Tip - 提示 - No checked USB device @@ -5590,17 +5507,17 @@ SendProgThread - + Program is empty 節目為空 - + Open file failed 檔案打開失敗 - + Read file failed 檔案讀取失敗 @@ -5608,98 +5525,78 @@ SendProgramDialog - - + + Publish 發佈 - + success info - - Refresh - 檢測 - - - + Alias 別名 - + Online 線上 - - Screen Size - 螢幕點數 - - - + Security 加密 - + Progress 進度 - + Remarks 備註 - + This screen is encrypted 螢幕已加密 - + Info 資訊 - + Some player versions are too low and may not be compatible. It's recommended to update the player to 2.0. Or download the old version %1 from website 有播放機版本過低,可能存在不相容問題。建議更新播放機到2.0。 或從官網下載舊版本%1 - + Do you want to continue? 是否繼續? - + Waiting 等待中 - - Input password - 輸入密碼 - - - - VerifyPassword + + Verify Password 驗證密碼 - - Tip Info - 提示 - - - + password is wrong 密碼錯誤 - + All 總數 @@ -5721,6 +5618,11 @@ Upgrade 陞級 + + + Failed to Read File + 檔案讀取失敗 + Uninstall @@ -5741,11 +5643,6 @@ Upgrading 陞級中 - - - Refresh - 檢測 - Alias @@ -5812,38 +5709,12 @@ Please select a file 請選擇一個檔案 - - - - - Tip - 提示 - - - - NoSelectedController - 請先選擇大螢幕 - - - - File Read Fail - 檔案讀取失敗 - Downloading Online File 正在下載線上檔案 - - - - - - - Error - 錯誤 - Online file is empty @@ -5869,11 +5740,6 @@ Don't power off during this process 陞級過程中請勿斷電 - - - Install error - 安裝錯誤 - @@ -5900,16 +5766,6 @@ Uninstalling 正在卸載 - - - Uninstall error - 卸載錯誤 - - - - Uninstall success - 卸載成功 - Check apk running status @@ -5930,21 +5786,11 @@ Not running 沒有運行 - - - Input password - 輸入密碼 - - VerifyPassword + Verify Password 驗證密碼 - - - Tip Info - 提示 - password is wrong @@ -5966,14 +5812,6 @@ 加密控制卡可以直接陞級 - - WaitingDlg - - - Success - 成功 - - mGuangYingPinWidget @@ -6062,11 +5900,6 @@ Auxiliary 副設備 - - - Refresh - 檢測 - Param configuration @@ -6082,11 +5915,6 @@ Delay millsecond 延時(微秒) - - - Clear - 清空 - Debug @@ -6102,21 +5930,11 @@ Program number 節目號 - - - Send - 發送 - Brightness 屏体亮度 - - - Set - 設定 - Screen Off @@ -6139,38 +5957,12 @@ Screen On 開屏 - - - - - - - - - - - - - - - - - - Close - 關閉 - State:On 狀態:連接 - - - - Tip - 提示 - diff --git a/daylite/Daylite.pro b/daylite/Daylite.pro new file mode 100644 index 0000000..5b351eb --- /dev/null +++ b/daylite/Daylite.pro @@ -0,0 +1,39 @@ +QT += core gui widgets +QT += network + +CONFIG -= debug_and_release +CONFIG += c++17 + +LIBS += -lwinmm +LIBS += -lDbghelp + +RESOURCES += res.qrc + +win32:RC_ICONS = icon.ico + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + gutil/qcore.cpp \ + gutil/qgui.cpp \ + gutil/qjson.cpp \ + gutil/qnetwork.cpp \ + gutil/qwaitingdlg.cpp \ + main.cpp \ + mainwindow.cpp + +HEADERS += \ + gutil/qcore.h \ + gutil/qgui.h \ + gutil/qjson.h \ + gutil/qnetwork.h \ + gutil/qwaitingdlg.h \ + main.h \ + mainwindow.h + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target diff --git a/daylite/gutil/cpp.cpp b/daylite/gutil/cpp.cpp new file mode 100644 index 0000000..218248c --- /dev/null +++ b/daylite/gutil/cpp.cpp @@ -0,0 +1,2 @@ +//#include "cpp.h" + diff --git a/daylite/gutil/cpp.h b/daylite/gutil/cpp.h new file mode 100644 index 0000000..2a36e87 --- /dev/null +++ b/daylite/gutil/cpp.h @@ -0,0 +1,325 @@ +#ifndef CPP_H +#define CPP_H + +#include +#include + +inline int64_t steady_milli() { + return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); +} +inline int64_t system_milli() { + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); +} +inline int64_t steady_micro() { + return std::chrono::duration_cast(std::chrono::steady_clock::now().time_since_epoch()).count(); +} +inline int64_t system_micro() { + return std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); +} + + +template +struct SharedData { + size_t cnt{1}; + T data; +}; +template +class SharedPtr { +public: + SharedPtr(SharedData *ptr = 0) : ptr{ptr} {} + ~SharedPtr() { + if(ptr==0) return; + if(ptr->cnt > 1) ptr->cnt--; + else delete ptr; + } + + SharedPtr(const SharedPtr &other) : ptr{other.ptr} { + if(ptr) ptr->cnt++; + } + SharedPtr &operator=(const SharedPtr &other) { + this->~SharedPtr(); + new (this) SharedPtr(other); + return *this; + } + SharedPtr(SharedPtr &&other) noexcept : ptr(other.ptr) { + other.ptr = 0; + } + SharedPtr &operator=(SharedPtr &&other) noexcept { + auto aaa = ptr; + ptr = other.ptr; + other.ptr = aaa; + return *this; + } + + bool isNull() const noexcept {return ptr==0;} + bool empty() const noexcept { + return ptr ? ptr->data.empty() : true; + } + size_t size() const noexcept { + return ptr ? ptr->data.size() : 0; + } + + T &operator*() const { + if(ptr==0) ptr = new SharedData; + return ptr->data; + } + T *operator->() const { + if(ptr==0) ptr = new SharedData; + return &ptr->data; + } + bool operator==(const SharedPtr &other) const { + if(ptr==other.ptr) return true; + auto siz = size(); + if(siz!=other.size()) return false; + if(siz==0) return true; + return ptr->data==other.ptr->data; + } + bool operator!=(const SharedPtr &other) const { + return ! (*this==other); + } + mutable SharedData *ptr = 0; +}; + + +template +class Vector : public SharedPtr> { +public: + using SharedPtr>::SharedPtr; + + using iterator = std::_Vector_iterator>>; + using const_iterator = std::_Vector_const_iterator>>; + + Vector(std::initializer_list _Ilist) { + this->ptr = new SharedData>{1, _Ilist}; + } + + Vector &append(const V &val) { + (*this)->push_back(val); + return *this; + } + Vector &append(V&& val) { + (*this)->push_back(_STD move(val)); + return *this; + } + Vector &operator<<(const V &val) { + (*this)->push_back(val); + return *this; + } + Vector &operator<<(V&& val) { + (*this)->push_back(_STD move(val)); + return *this; + } + + V &operator[](const uint64_t pos) noexcept { + return (**this)[pos]; + } + const V &operator[](const uint64_t pos) const noexcept { + return (**this)[pos]; + } + + iterator begin() const noexcept { + return this->ptr ? this->ptr->data.begin() : iterator(); + } + iterator end() const noexcept { + return this->ptr ? this->ptr->data.end() : iterator(); + } +}; + + +struct NodeBase { + NodeBase *next{this}; + NodeBase *prev{this}; +}; +template +struct _Node : NodeBase { + P value; + ~_Node() { + if(next) delete (_Node

*) next; + } +}; + +template +class LinkedMapIterator { +public: + LinkedMapIterator(_Node

*node) : node(node) {} + bool operator==(const LinkedMapIterator& other) const noexcept { + return node == other.node; + } + bool operator!=(const LinkedMapIterator& other) const noexcept { + return node != other.node; + } + LinkedMapIterator& operator++() { + node = (_Node

*) node->next; + return *this; + } + LinkedMapIterator& operator--() { + node = (_Node

*) node->prev; + return *this; + } + const LinkedMapIterator operator++(int) { + auto rtn = *this; + node = (_Node

*) node->next; + return rtn; + } + const LinkedMapIterator operator--(int) { + auto rtn = *this; + node = (_Node

*) node->prev; + return rtn; + } + P &operator*() const noexcept { + return node->value; + } + P *operator->() const noexcept { + return &node->value; + } + _Node

*node{0}; +}; + +template +struct LinkedMapPri : NodeBase { + size_t cnt = 1; + std::unordered_map>*> map; + ~LinkedMapPri() { + if(prev) prev->next = 0; + if(next) delete (_Node>*) next; + } +}; +template +class LinkedMap { +public: + using Node = _Node>; + + using iterator = LinkedMapIterator>; + using const_iterator = LinkedMapIterator>; + + LinkedMap() {} + LinkedMap(std::initializer_list> pairs) : _pri{new LinkedMapPri} { + for(auto &pair : pairs) insert(pair.first, pair.second); + } + LinkedMap(std::unordered_map &&map) : _pri{new LinkedMapPri{0, 0, map}} { + _pri->next = _pri->prev = _pri; + } + ~LinkedMap() { + if(_pri==0) return; + if(_pri->cnt > 1) _pri->cnt--; + else delete _pri; + } + + LinkedMap(const LinkedMap &other) : _pri{other._pri} { + if(_pri) _pri->cnt++; + } + LinkedMap &operator=(const LinkedMap &other) { + this->~LinkedMap(); + new (this) LinkedMap(other); + return *this; + } + LinkedMap(LinkedMap &&other) noexcept : _pri(other._pri) { + other._pri = 0; + } + LinkedMap &operator=(LinkedMap &&other) noexcept { + auto aaa = _pri; + _pri = other._pri; + other._pri = aaa; + return *this; + } + + bool empty() const noexcept { + return _pri==0 || _pri->map.empty(); + } + size_t size() const noexcept { + return _pri ? _pri->map.size() : 0; + } + + iterator find(const K &k) const { + if(_pri==0) return iterator((Node*) _pri); + auto it = _pri->map.find(k); + if(it==_pri->map.end()) return iterator((Node*) _pri); + return iterator(it->second); + } + const V operator()(const K &k) const { + return (*this)[k]; + } + const V operator[](const K &k) const { + if(_pri==0) return V(); + auto it = _pri->map.find(k); + if(it==_pri->map.end()) return V(); + return it->second->value.second; + } + V &operator[](const K &k) { + if(_pri==0) _pri = new LinkedMapPri; + auto pair = _pri->map.emplace(k, nullptr); + if(pair.second) { + auto node = new Node{_pri, _pri->prev, {k, V()}}; + _pri->prev->next = node; + _pri->prev = node; + pair.first->second = node; + } + return pair.first->second->value.second; + } + + LinkedMap &insert(const K &k, const V &v) { + if(_pri==0) _pri = new LinkedMapPri; + auto pair = _pri->map.emplace(k, nullptr); + if(pair.second) { + auto node = new Node{_pri, _pri->prev, {k, v}}; + _pri->prev->next = node; + _pri->prev = node; + pair.first->second = node; + } else pair.first->second->value.second = v; + return *this; + } + V remove(const K& k) { + if(_pri==0) return V(); + auto it = _pri->map.find(k); + if(it==_pri->map.end()) return V(); + auto node = it->second; + _pri->map.erase(it); + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + auto v = node->value.second; + delete node; + return v; + } + void erase(const K& k) { + if(_pri==0) return; + auto it = _pri->map.find(k); + if(it==_pri->map.end()) return; + auto node = it->second; + _pri->map.erase(it); + node->prev->next = node->next; + node->next->prev = node->prev; + node->next = 0; + node->prev = 0; + delete node; + } + + bool operator==(const LinkedMap &other) const { + if(_pri==other._pri) return true; + auto siz = size(); + if(siz!=other.size()) return false; + if(siz==0) return true; + auto aaa = begin(); + auto bbb = other.begin(); + while(aaa!=end()) { + if(aaa->first != bbb->first || aaa->second != bbb->second) return false; + ++aaa; + ++bbb; + } + return true; + } + bool operator!=(const LinkedMap &other) const { + return ! (*this==other); + } + + iterator begin() const { + return iterator((Node*) (_pri ? _pri->next : 0)); + } + iterator end() const { + return iterator((Node*) _pri); + } + LinkedMapPri *_pri = 0; +}; + +#endif // CPP_H diff --git a/daylite/gutil/qcore.cpp b/daylite/gutil/qcore.cpp new file mode 100644 index 0000000..4eae95f --- /dev/null +++ b/daylite/gutil/qcore.cpp @@ -0,0 +1 @@ +#include "qcore.h" diff --git a/daylite/gutil/qcore.h b/daylite/gutil/qcore.h new file mode 100644 index 0000000..bf21dcc --- /dev/null +++ b/daylite/gutil/qcore.h @@ -0,0 +1,53 @@ +#ifndef QCORE_H +#define QCORE_H +#include +#include +#include + +#define ToStr QString::number + +inline QString toStr(int num, int base=10) {return QString::number(num, base);} +inline QString toStr(uint num, int base=10) {return QString::number(num, base);} +inline QString toStr(long num, int base=10) {return QString::number(num, base);} +inline QString toStr(ulong num, int base=10) {return QString::number(num, base);} +inline QString toStr(qlonglong num, int base=10) {return QString::number(num, base);} +inline QString toStr(qulonglong num, int base=10) {return QString::number(num, base);} +inline QString toStr(double num, char format='g', int precision=6) {return QString::number(num, format, precision);} + +inline QString gUrlSuffix(const QString &url, int size, bool withDot = false) { + auto ss = url.lastIndexOf('/')+1; + if(ss==url.size()) return QString(); + ss++; + auto ee = url.indexOf('?', ss); + if(ee==-1) ee = url.size(); + int end = ee-size-1; + if(end=end; --i) if(url[i]=='.') return withDot ? url.mid(i, ee-i) : url.mid(i+1, ee-i-1); + return QString(); +} + +inline QString byteSizeStr(double size) { + const char *units[]{"B", "KB", "MB", "GB", "TB", "PB"}; + auto i = 0; + for(; size >= 1024 && i < 5; i++) size /= 1024; + return QString::number(size, 'g', 3)+" "+units[i]; +} + +inline void wait(int msec, QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents) { + QTimer timer; + timer.setSingleShot(true); + QEventLoop loop; + QObject::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); + timer.start(msec); + loop.exec(flags); +} + +template +inline QThread *ThreadStart(Func &&f) { + QThread* thread = QThread::create(f); + QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater); + thread->start(); + return thread; +} + +#endif diff --git a/daylite/gutil/qgui.cpp b/daylite/gutil/qgui.cpp new file mode 100644 index 0000000..978d815 --- /dev/null +++ b/daylite/gutil/qgui.cpp @@ -0,0 +1,153 @@ +#include "qgui.h" +#include +#include + +const Qt::Alignment AlignRight = Qt::AlignRight | Qt::AlignVCenter; + +int operator*(const QString& key, QTreeView &table) { + return ((TreeWidget&)table).fdmap.at(key); +} +int operator*(const char *key, QTreeView &table) { + return ((TreeWidget&)table).fdmap.at(key); +} +int operator|(const QVariant &value, int def) { + return value.isValid() ? value.toInt() : def; +} + +TreeWidget::TreeWidget(std::initializer_list colAttrs, QWidget *parent) : QTreeWidget{parent} { + header()->setMinimumSectionSize(16); + int i = 0; + auto item = headerItem(); + for(auto attr = colAttrs.begin(); attr < colAttrs.end(); ++attr) { + item->setText(i, attr->text); + item->setData(i, FieldRole, attr->field); + if(attr->width > 0) header()->resizeSection(i, attr->width); + if(attr->resizeMode != QHeaderView::Interactive) { + if(attr->resizeMode==QHeaderView::Stretch && attr->width > 0) { + item->setData(i, WidthRole, attr->width); + noStretch = false; + } else header()->setSectionResizeMode(i, attr->resizeMode); + } + fdmap.emplace(attr->field, i++); + } + hasRowNum = i && colAttrs.begin()->field=="_num_"; + connect(header(), &QHeaderView::sectionResized, this, &TreeWidget::onSectionResized); + header()->installEventFilter(this); +} +bool TreeWidget::eventFilter(QObject *watched, QEvent *event) { + if(isSectionResized && event->type()==QEvent::Leave && watched==header()) { + isSectionResized = false; + auto item = headerItem(); + for(int cc=0; ccdata(cc, WidthRole).isValid()) item->setData(cc, WidthRole, header()->sectionSize(cc)); + } + return QTreeWidget::eventFilter(watched, event); +} +void TreeWidget::resizeEvent(QResizeEvent *event) { + QTreeWidget::resizeEvent(event); + if(noStretch || event->size().width() == event->oldSize().width()) return; + adjSections(-1, 0); +} +void TreeWidget::drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const { + QTreeWidget::drawRow(painter, options, index); + if(columnWidth(0)>40) return; + if(hasRowNum) { + QRect rect(options.rect.left(), options.rect.top(), columnWidth(0), options.rect.height()); + painter->fillRect(rect, header()->palette().button()); + painter->drawText(rect, Qt::AlignCenter, QString::number(index.row()+1)); + } + if(hasGrid) { + QBrush color({128, 128, 128, 128}); + QRect rec(options.rect.left()-1, options.rect.top(), 1, options.rect.height()); + auto last = columnCount() - 1; + if(hasGrid > 1) for(int i=0; ifillRect(rec, color); + } else { + int ttlwidth = columnWidth(last); + for(int i=0; ifillRect(rec, color); + ttlwidth += width; + } + painter->fillRect(options.rect.left(), options.rect.bottom(), ttlwidth, 1, color); + } + } +} +void TreeWidget::onSectionResized(int logicalIndex, int oldSize, int newSize) { + if(blocked || noStretch || newSize==0 || oldSize==0) return; + if(! headerItem()->data(logicalIndex, WidthRole).isValid()) return; + if(adjSections(logicalIndex, newSize)) isSectionResized = true; +} +bool TreeWidget::adjSections(int index, int size) { + auto item = headerItem(); + int remain = header()->width() - size, stretchWidth = 0, width; + for(int cc=0; ccisSectionHidden(cc)) { + width = item->data(cc, WidthRole)|-1; + if(width > -1) { + if(width==0) item->setData(cc, WidthRole, width = header()->sectionSize(cc)); + stretchWidth += width; + } else remain -= header()->sectionSize(cc); + } + if(remain<=0 || stretchWidth==0) return false; + auto min = header()->minimumSectionSize(); + blocked = true; + for(int cc=0; ccisSectionHidden(cc) && (width = item->data(cc, WidthRole)|-1) > -1) header()->resizeSection(cc, qMax(min, width * remain / stretchWidth)); + blocked = false; + return true; +} + +Table::Table(std::initializer_list colAttrs, int rows, QWidget *parent) : QTableWidget{rows, (int)colAttrs.size(), parent} { + int i = 0; + for(auto attr = colAttrs.begin(); attr < colAttrs.end(); ++attr) { + auto item = horizontalHeaderItem(i); + if(item==0) setHorizontalHeaderItem(i, item = new QTableWidgetItem); + item->setText(attr->text); + item->setData(FieldRole, attr->field); + if(attr->width > 0) horizontalHeader()->resizeSection(i, attr->width); + if(attr->resizeMode != QHeaderView::Interactive) { + if(attr->resizeMode==QHeaderView::Stretch && attr->width > 0) { + item->setData(WidthRole, attr->width); + noStretch = false; + } else horizontalHeader()->setSectionResizeMode(i, attr->resizeMode); + } + fdmap.emplace(attr->field, i++); + } + connect(horizontalHeader(), &QHeaderView::sectionResized, this, &Table::onSectionResized); + horizontalHeader()->installEventFilter(this); +} +bool Table::eventFilter(QObject *watched, QEvent *event) { + if(isSectionResized && event->type()==QEvent::Leave && watched==horizontalHeader()) { + isSectionResized = false; + QTableWidgetItem *item; + for(int cc=0; ccdata(WidthRole).isValid()) item->setData(WidthRole, horizontalHeader()->sectionSize(cc)); + } + return QTableWidget::eventFilter(watched, event); +} +void Table::resizeEvent(QResizeEvent *event) { + QTableWidget::resizeEvent(event); + if(noStretch || event->size().width() == event->oldSize().width()) return; + adjSections(-1, 0); +} +void Table::onSectionResized(int logicalIndex, int oldSize, int newSize) { + if(blocked || noStretch || newSize==0 || oldSize==0) return; + if(! horizontalHeaderItem(logicalIndex)->data(WidthRole).isValid()) return; + if(adjSections(logicalIndex, newSize)) isSectionResized = true; +} +bool Table::adjSections(int index, int size) { + QTableWidgetItem *item; + int remain = horizontalHeader()->width() - size, stretchWidth = 0, width; + for(int cc=0; ccisSectionHidden(cc) && (item = horizontalHeaderItem(cc))) { + width = item->data(WidthRole)|-1; + if(width > -1) { + if(width==0) item->setData(WidthRole, width = horizontalHeader()->sectionSize(cc)); + stretchWidth += width; + } else remain -= horizontalHeader()->sectionSize(cc); + } + if(remain<=0 || stretchWidth==0) return false; + auto min = horizontalHeader()->minimumSectionSize(); + blocked = true; + for(int cc=0; ccisSectionHidden(cc) && (item = horizontalHeaderItem(cc)) && (width = item->data(WidthRole)|-1) > -1) horizontalHeader()->resizeSection(cc, qMax(min, width * remain / stretchWidth)); + blocked = false; + return true; +} diff --git a/daylite/gutil/qgui.h b/daylite/gutil/qgui.h new file mode 100644 index 0000000..d81c8df --- /dev/null +++ b/daylite/gutil/qgui.h @@ -0,0 +1,592 @@ +#ifndef QGUI_H +#define QGUI_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MainMust \ +#if(QT_VERSION_MAJOR > 5) \ + QImageReader::setAllocationLimit(0);\ +#else\ + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);\ + QGuiApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);\ + QGuiApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);\ +#endif + + +extern const Qt::Alignment AlignRight; + +inline QWidget *parentWgt(QObject *obj) { + while(obj && ! obj->isWidgetType()) obj = obj->parent(); + return (QWidget*) obj; +} +inline QWidget *parentWin(QObject *obj) { + while(obj) { + if(obj->isWidgetType()) return ((QWidget*) obj)->window(); + obj = obj->parent(); + } + return (QWidget*) obj; +} + +inline int SetCurData(QComboBox *combo, const QVariant &data) { + auto idx = combo->findData(data); + if(idx>-1) combo->setCurrentIndex(idx); + return idx; +} +inline int SetCurText(QComboBox *combo, const QString& text) { + auto idx = combo->findText(text); + if(idx>-1) combo->setCurrentIndex(idx); + return idx; +} +inline void gFont(QWidget *wgt, int size, bool bold = false, bool italic = false) { + auto ft = wgt->font(); + ft.setPixelSize(size); + if(bold) ft.setBold(true); + if(italic) ft.setItalic(true); + wgt->setFont(ft); +} +inline void gFont(QWidget *wgt, const QString& family, int size = 0, bool bold = false, bool italic = false) { + auto ft = wgt->font(); + ft.setFamily(family); + if(size) ft.setPixelSize(size); + if(bold) ft.setBold(true); + if(italic) ft.setItalic(true); + wgt->setFont(ft); +} +inline QFont qfont(const QString& family, int pixelSize, bool bold = false, bool italic = false) { + QFont ft(family); + ft.setPixelSize(pixelSize); + if(bold) ft.setBold(true); + if(italic) ft.setItalic(true); + return ft; +} +inline void gAppendText(QTextEdit *wgt, const QString& text, const QColor &color) { + auto c0 = wgt->textColor(); + wgt->setTextColor(color); + wgt->append(text); + wgt->setTextColor(c0); +} +inline QToolButton *NewToolBtn(const QIcon &icon, const QString& text, Qt::ToolButtonStyle style = Qt::ToolButtonTextUnderIcon) { + auto btn = new QToolButton; + btn->setIcon(icon); + btn->setText(text); + btn->setToolButtonStyle(style); + return btn; +} + +class VBox : public QBoxLayout { +public: + VBox(QWidget *parent=nullptr) : QBoxLayout(TopToBottom, parent) {} + VBox(QBoxLayout *parent) : QBoxLayout(TopToBottom) { + parent->addLayout(this); + }; + VBox(QStackedLayout *stack) : QBoxLayout(TopToBottom, new QWidget) { + stack->addWidget(parentWidget()); + setContentsMargins(0,0,0,0); + }; + VBox(QSplitter *splitter) : QBoxLayout(TopToBottom, new QWidget) { + splitter->addWidget(parentWidget()); + setContentsMargins(0,0,0,0); + }; + QLabel *addLabel() { + auto lb = new QLabel; + addWidget(lb); + return lb; + } + QLabel *addLabel(const QString& text) { + auto lb = new QLabel(text); + addWidget(lb); + return lb; + } + QDialogButtonBox *addBtnBox(QDialog *dlg = 0) { + auto btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + if(dlg) connect(btnBox, &QDialogButtonBox::rejected, dlg, &QDialog::reject); + addWidget(btnBox); + return btnBox; + } +}; +class HBox : public QBoxLayout { +public: + HBox(QWidget *parent=nullptr) : QBoxLayout(LeftToRight, parent) {} + HBox(QBoxLayout *parent) : QBoxLayout(LeftToRight) { + parent->addLayout(this); + }; + HBox(QStackedLayout *stack) : QBoxLayout(LeftToRight, new QWidget) { + stack->addWidget(parentWidget()); + setContentsMargins(0,0,0,0); + }; + HBox(QSplitter *splitter) : QBoxLayout(LeftToRight, new QWidget) { + splitter->addWidget(parentWidget()); + setContentsMargins(0,0,0,0); + }; + QLabel *addLabel() { + auto lb = new QLabel; + addWidget(lb); + return lb; + } + QLabel *addLabel(const QString& text) { + auto lb = new QLabel(text); + addWidget(lb); + return lb; + } +}; +class Grid : public QGridLayout { +public: + using QGridLayout::QGridLayout; + Grid(QBoxLayout *parent) { + parent->addLayout(this); + }; + Grid(QStackedLayout *stack) : QGridLayout(new QWidget) { + stack->addWidget(parentWidget()); + }; + Grid(QSplitter *splitter) : QGridLayout(new QWidget) { + splitter->addWidget(parentWidget()); + }; + QLabel *addLabel(const QString& text) { + auto lb = new QLabel(text); + addWidget(lb); + return lb; + } +}; + +class ListWgt : public QListWidget { +public: + using QListWidget::QListWidget; + + using QListWidget::addItem; + auto addItem(const QString& text, const QVariant &value) { + auto item = new QListWidgetItem(text); + item->setData(Qt::UserRole, value); + insertItem(count(), item); + return this; + } +}; + +struct ColAttr { + ColAttr(const QString& field, const QString& text, int width=0, QHeaderView::ResizeMode resizeMode = QHeaderView::Interactive) : field(field), text(text), width(width), resizeMode(resizeMode) {} + ColAttr(const QString& field, const QString& text, QHeaderView::ResizeMode resizeMode) : field(field), text(text), resizeMode(resizeMode) {} + QString field; + QString text; + int width{0}; + QHeaderView::ResizeMode resizeMode; +}; +enum TableItemDataRole { + FieldRole = 0xfe, + WidthRole +}; + +int operator*(const QString& key, QTreeView &table); +int operator*(const char *key, QTreeView &table); + +class TreeWidgetItem : public QTreeWidgetItem { +public: + using QTreeWidgetItem::QTreeWidgetItem; + + using QTreeWidgetItem::checkState; + auto checkState(const QString& column) { + return checkState(column**treeWidget()); + } + using QTreeWidgetItem::setCheckState; + auto setCheckState(const QString& column, Qt::CheckState state) { + setCheckState(column**treeWidget(), state); + return this; + } + + using QTreeWidgetItem::text; + auto text(const QString& column) { + return text(column**treeWidget()); + } + using QTreeWidgetItem::setText; + auto setText(const QString& column, const QString& text) { + setText(column**treeWidget(), text); + return this; + } + auto setText(const QString& column, const QString& text, const QVariant &value) { + auto idx = column**treeWidget(); + setText(idx, text); + setData(idx, Qt::UserRole, value); + return this; + } + + using QTreeWidgetItem::background; + auto background(const QString& column) { + return background(column**treeWidget()); + } + using QTreeWidgetItem::setBackground; + auto setBackground(const QString& column, const QBrush &brush) { + setBackground(column**treeWidget(), brush); + return this; + } + using QTreeWidgetItem::foreground; + auto foreground(const QString& column) { + return foreground(column**treeWidget()); + } + using QTreeWidgetItem::setForeground; + auto setForeground(const QString& column, const QBrush &brush) { + setForeground(column**treeWidget(), brush); + return this; + } + + using QTreeWidgetItem::data; + auto data(int col) { + return data(col, Qt::UserRole); + } + auto data(const QString& column, int role = Qt::UserRole) { + return data(column**treeWidget(), role); + } + using QTreeWidgetItem::setData; + auto setData(int col, const QVariant &value) { + setData(col, Qt::UserRole, value); + return this; + } + auto setData(const QString& column, const QVariant &value) { + setData(column**treeWidget(), Qt::UserRole, value); + return this; + } + auto setData(const QString& column, int role, const QVariant &value) { + setData(column**treeWidget(), role, value); + return this; + } + + auto itemWidget(int column) { + return treeWidget()->itemWidget(this, column); + } + auto itemWidget(const QString& column) { + return treeWidget()->itemWidget(this, column**treeWidget()); + } + void setItemWidget(int column, QWidget *widget) { + treeWidget()->setItemWidget(this, column, widget); + } + void setItemWidget(const QString& column, QWidget *widget) { + treeWidget()->setItemWidget(this, column**treeWidget(), widget); + } +}; + +class TreeWidget : public QTreeWidget { + Q_OBJECT +public: + using QTreeWidget::QTreeWidget; + TreeWidget(std::initializer_list colAttrs, QWidget *parent = 0); + + auto setDefs() { + if(! hasRowNum) setIndentation(0); + setAlternatingRowColors(true); + header()->setStretchLastSection(false); + return this; + } + + auto setColFit() { + header()->setSectionResizeMode(QHeaderView::ResizeToContents); + return this; + } + auto setColWidth(int value, QHeaderView::ResizeMode mode = QHeaderView::Interactive) { + header()->setDefaultSectionSize(value); + if(mode!=QHeaderView::Interactive) header()->setSectionResizeMode(mode); + return this; + } + + auto setHeaderText(const QString& column, const QString& text) { + headerItem()->setText(fdmap.at(column), text); + return this; + } + + using QTreeWidget::showColumn; + void showColumn(const QString& column) { + showColumn(fdmap.at(column)); + } + using QTreeWidget::hideColumn; + void hideColumn(const QString& column) { + hideColumn(fdmap.at(column)); + } + + auto item(int idx) const { + return (TreeWidgetItem*) topLevelItem(idx); + } + auto selectedItem() const { + auto is = selectedItems(); + return is.isEmpty() ? 0 : (TreeWidgetItem*) is.at(0); + } + auto curItem() const { + return (TreeWidgetItem*) currentItem(); + } + + QString field(int column) const { + return headerItem()->data(column, FieldRole).toString(); + } + QString sortField() const { + return field(sortColumn()); + } + using QTreeWidget::sortItems; + void sortItems(const QString& column, Qt::SortOrder order = Qt::AscendingOrder) { + sortItems(fdmap.at(column), order); + } + + std::unordered_map fdmap; + char hasGrid = 1; + bool hasRowNum = false; +signals: + void updGeos(); +protected: + bool eventFilter(QObject *watched, QEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void updateGeometries() override { + QTreeWidget::updateGeometries(); + emit updGeos(); + }; + void drawRow(QPainter *painter, const QStyleOptionViewItem &options, const QModelIndex &index) const override; + void onSectionResized(int logicalIndex, int oldSize, int newSize); + bool adjSections(int index, int size); + bool noStretch = true; + bool isSectionResized = false; + bool blocked = false; +}; + +class Table : public QTableWidget { + Q_OBJECT +public: + using QTableWidget::QTableWidget; + Table() {} + Table(std::initializer_list colAttrs, int rows = 0, QWidget *parent = 0); + + auto setDefs() { + setSelectionBehavior(QTableWidget::SelectRows); + setEditTriggers(QAbstractItemView::NoEditTriggers); + setAlternatingRowColors(true); + return this; + } + auto setColStretch() { + horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); + return this; + } + auto setRowStretch() { + verticalHeader()->setSectionResizeMode(QHeaderView::Stretch); + return this; + } + auto setColFit() { + horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + return this; + } + auto setRowFit() { + verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + return this; + } + + auto setColWidth(int value) { + if(horizontalHeader()->minimumSectionSize() > value) horizontalHeader()->setMinimumSectionSize(value); + horizontalHeader()->setDefaultSectionSize(value); + return this; + } + auto setColResize(QHeaderView::ResizeMode mode) { + horizontalHeader()->setSectionResizeMode(mode); + return this; + } + auto setRowHeight(int value) { + if(verticalHeader()->minimumSectionSize() > value) verticalHeader()->setMinimumSectionSize(value); + verticalHeader()->setDefaultSectionSize(value); + return this; + } + auto setRowResize(QHeaderView::ResizeMode mode) { + verticalHeader()->setSectionResizeMode(mode); + return this; + } + + auto setHeaderText(int col, const QString& text) { + auto item = horizontalHeaderItem(col); + if(item==0) setHorizontalHeaderItem(col, item = new QTableWidgetItem()); + item->setText(text); + return item; + } + auto setHeaderText(const QString& column, const QString& text) { + return setHeaderText(fdmap.at(column), text); + } + + auto setVHeaderText(int row, const QString& text) { + auto item = verticalHeaderItem(row); + if(item==0) setVerticalHeaderItem(row, item = new QTableWidgetItem()); + item->setText(text); + return item; + } + + auto appendRow() { + auto value = rowCount(); + setRowCount(value + 1); + return value; + } + + using QTableWidget::item; + auto item(int row, const QString& column) { + return item(row, fdmap.at(column)); + } + auto itemValid(int row, int col) { + auto itm = item(row, col); + if(itm==0) setItem(row, col, itm = new QTableWidgetItem); + return itm; + } + auto itemValid(int row, const QString& column) { + return itemValid(row, fdmap.at(column)); + } + using QTableWidget::setItem; + void setItem(int row, const QString& column, QTableWidgetItem *item) { + setItem(row, fdmap.at(column), item); + } + + auto text(int row, int col) { + auto itm = item(row, col); + if(itm==0) return QString(); + return itm->text(); + } + auto text(int row, const QString& column) { + return text(row, fdmap.at(column)); + } + + auto setText(int row, int col, const QString& text) { + auto itm = item(row, col); + if(itm) itm->setText(text); + else setItem(row, col, itm = new QTableWidgetItem(text)); + return itm; + } + auto setText(int row, const QString& column, const QString& text) { + return setText(row, fdmap.at(column), text); + } + auto setText(int row, int col, const QString& text, const QVariant &value) { + auto itm = item(row, col); + if(itm) itm->setText(text); + else setItem(row, col, itm = new QTableWidgetItem(text)); + itm->setData(Qt::UserRole, value); + return itm; + } + auto setText(int row, const QString& column, const QString& text, const QVariant &value) { + return setText(row, fdmap.at(column), text, value); + } + + auto data(int row, int col) { + auto itm = item(row, col); + if(itm==0) return QVariant(); + return itm->data(Qt::UserRole); + } + auto data(int row, const QString& column) { + return data(row, fdmap.at(column)); + } + + auto setData(int row, int col, const QVariant &value) { + auto itm = item(row, col); + if(itm==0) setItem(row, col, itm = new QTableWidgetItem); + itm->setData(Qt::UserRole, value); + return itm; + } + auto setData(int row, const QString& column, const QVariant &value) { + return setData(row, fdmap.at(column), value); + } + + using QTableWidget::cellWidget; + auto cellWidget(int row, const QString& column) { + return cellWidget(row, fdmap.at(column)); + } + using QTableWidget::setCellWidget; + void setCellWidget(int row, const QString& column, QWidget *widget) { + setCellWidget(row, fdmap.at(column), widget); + } + + using QTableWidget::sortItems; + void sortItems(const QString& column, Qt::SortOrder order) { + sortItems(fdmap.at(column), order); + } + + std::unordered_map fdmap; +public Q_SLOTS: + void clearRows() {setRowCount(0);} +signals: + void updGeos(); +protected: + bool eventFilter(QObject *watched, QEvent *event) override; + void resizeEvent(QResizeEvent *event) override; + void updateGeometries() override { + QTableWidget::updateGeometries(); + emit updGeos(); + }; + void onSectionResized(int logicalIndex, int oldSize, int newSize); + bool adjSections(int index, int size); + bool noStretch = true; + bool isSectionResized = false; + bool blocked = false; +}; + + +template +class Wrp { +public: + T *obj; + Wrp(T *obj = nullptr){ + this->obj = obj; + }; + Wrp& operator()(T *obj){ + this->obj = obj; + return *this; + } + Wrp& operator()(T *obj, QLayout *layout){ + this->obj = obj; + layout->addWidget(obj); + return *this; + } + Wrp& addTo(QLayout *layout){ + layout->addWidget(obj); + return *this; + } + Wrp& margin(int a){ + obj->setMargin(a); + return *this; + } + Wrp& font(const QFont &font){ + obj->setFont(font); + return *this; + } + Wrp& font(int size){ + auto font = obj->font(); + font.setPixelSize(size); + obj->setFont(font); + return *this; + } + + Wrp& width(int w){ + obj->setFixedWidth(w); + return *this; + } + Wrp& height(int h){ + obj->setFixedHeight(h); + return *this; + } + Wrp& padding(int wAdd, int hAdd, int minW = 32, int minH = 16){ + wAdd+=8; + hAdd+=8; + QSize size = obj->fontMetrics().size(Qt::TextShowMnemonic, obj->text()); + int &rwidth = size.rwidth(); + rwidth += wAdd; + if(rwidth < minW) rwidth = minW; + int &rheight = size.rheight(); + rheight += hAdd; + if(rheight < minH) rheight = minH; + obj->setFixedSize(size); + return *this; + } + + Wrp& alignC(){ + obj->setAlignment(Qt::AlignCenter); + return *this; + } + Wrp& alignR(){ + obj->setAlignment(Qt::AlignRight); + return *this; + } +}; + +#endif diff --git a/daylite/gutil/qjson.cpp b/daylite/gutil/qjson.cpp new file mode 100644 index 0000000..574a13e --- /dev/null +++ b/daylite/gutil/qjson.cpp @@ -0,0 +1,220 @@ +#include "qjson.h" +#include "qdebug.h" + +QDebug operator<<(QDebug debug, const JValue &val) { + auto old = debug.autoInsertSpaces(); + debug.noquote().nospace() << JToBytes(val, "\t"); + debug.setAutoInsertSpaces(old); + return debug; +} + +JValue JParser::readValue() { + if(ch=='{') { + JObj obj; + while(true) { + do skipSpace(); //ch有三种可能 + while(ch==','); + if(ch=='}') return obj; + QString key; + if(ch=='"') key = readStr(); + else if(ch!='n' || readOne()!='u' || readOne()!='l' || readOne()!='l') throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting double-quote to start field name or null"; + skipSpace(); + if(ch!=':') throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting a colon to separate field name and value"; + skipSpace(); + obj.insert(key, readValue()); + skipSpace(); //ch有两种可能 + if(ch=='}') return obj; + if(ch!=',') throw QString("Unexpected char ")+(char)ch+"' (code "+QString::number(ch)+"): was expecting } to end Object or comma to separate Object entries"; + } + } + if(ch=='[') { + JArray list; + while(true) { + do skipSpace(); //ch有三种可能 + while(ch==','); + if(ch==']') return list; + list->push_back(readValue()); + skipSpace(); //ch有两种可能 + if(ch==']') return list; + if(ch!=',') throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting ] to end Array or comma to separate Array entries"; + } + } + if(ch=='"') return readStr(); + if((ch>='0' && ch<='9') || ch=='-') { + QByteArray buf; + buf += ch; + bool isInt = true; + while(readOne()) { + if((ch>'*' && ch<':' && ch!=',' && ch!='/') || ch=='e' || ch=='E') { + buf.append(ch); + if(isInt && ch=='.') isInt = false; + } else { + bk = ch; + break; + } + } + bool ok; + if(isInt) { + auto num = buf.toLongLong(&ok); + if(! ok) throw "Illegal number: "+buf; + return num; + } else { + auto num = buf.toDouble(&ok); + if(! ok) throw "Illegal number: "+buf; + return num; + } + } + if(ch=='n') { + if(readOne()=='u' && readOne()=='l' && readOne()=='l') return JValue(); + else throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting null"; + } + if(ch=='t') { + if(readOne()=='r' && readOne()=='u' && readOne()=='e') return true; + else throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting true"; + } + if(ch=='f') { + if(readOne()=='a' && readOne()=='l' && readOne()=='s' && readOne()=='e') return false; + else throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting false"; + } + throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting {}, [], \"string\", number, null, true or false"; +} +inline int toHex(unsigned char ch) { + if(ch<'0') return -1; + if(ch<='9') return ch-'0'; + if(ch<'A') return -1; + if(ch<='F') return ch-55; + if(ch<'a') return -1; + if(ch<='f') return ch-87; + return -1; +} +QString JParser::readStr() { + QByteArray buf; + while(readOne() != '"') { + if(ch==0) throw "Unexpected end-of-input: was expecting closing quote for string"; + if(ch=='\\') { + if(readOne()==0) throw "Unexpected end-of-input in char escape sequence"; + if(ch=='"' || ch=='\\' || ch=='/') buf.append(ch); + else if(ch=='n') buf.append('\n'); + else if(ch=='r') buf.append('\r'); + else if(ch=='t') buf.append('\t'); + else if(ch=='f') buf.append('\f'); + else if(ch=='b') buf.append('\b'); + else if(ch=='u') { + uint hex = 0; + for(int i=3; i>=0; i--) { + if(readOne()==0) throw "Unexpected end-of-input in char escape sequence"; + auto h = toHex(ch); + if(h==-1) throw "Illegal hex-digits in char escape sequence: \\u"+(hex==0?"":QString::number(hex, 16)+(char)ch); + hex |= h<<(i<<2); + } + buf.append(QString(QChar(hex)).toUtf8()); + } else throw QString("Unrecognized char-escape ")+(char)ch+" (code "+QString::number(ch)+") after '\\'"; + } else buf.append(ch); + } + return QString::fromUtf8(buf); +} +void JParser::skipSpace() { + if(bk) { + bk = 0; + if(ch>=33) return; + } + do { + in >> ch; + if(ch==0) throw "Unexpected end-of-input"; + } while(ch < 33); // || ch==65279 + if(ch=='/') { + in >> ch; + if(ch=='/') { //skipComment + do { + in >> ch; + if(ch==0) throw "Unexpected end-of-input"; + } while(ch!='\n' && ch!='\r'); + skipSpace(); + return; + } + if(ch=='*') { //skipMultiComment + int last; + do { + last = ch; + in >> ch; + if(ch==0) throw "Unexpected end-of-input"; + } while(ch!='/' || last!='*'); + skipSpace(); + return; + } + throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+")"; + } +} + +void JOut::write(const JValue &value) { + if(value.type==JValue::Null) out << "null"; + else if(value.type==JValue::Str) writeStr(value.toStr()); + else if(value.type==JValue::Obj) writeMap(value.toObj()); + else if(value.type==JValue::Array) writeList(value.toArray()); + else out << value.toStr(); + out.flush(); +} +void JOut::writeStr(const QString &str) { + out << '"'; + QChar ch; + for(int i=0; i +#include + +class JValue; +using JObj = LinkedMap; +using JArray = Vector; + +QDebug operator<<(QDebug debug, const JValue &val); + +class JValue { +public: + int64_t data = 0; + enum Type { + Null, Long, Ulong, Double, Bool, Obj, Array, Str + }; + Type type = Null; + + JValue(Type = Null) {} + JValue(bool b) : type(Bool) {data = b;} + JValue(int n) : type(Long) {data = n;} + JValue(qint64 n) : type(Long) {data = n;} + JValue(quint64 n) : type(Ulong) {*(quint64*) &data = n;} + JValue(double d) : type(Double) {*(double*) &data = d;} + JValue(const JObj &o) : type(Obj) {new (&data) JObj(o);} + JValue(const JArray &a) : type(Array) {new (&data) JArray(a);} + JValue(JObj &&o) : type(Obj) {new (&data) JObj(std::move(o));} + JValue(JArray &&a) : type(Array) {new (&data) JArray(std::move(a));} + JValue(const QString &s) : type(Str) {*(SharedData**) &data = new SharedData{1, s};} + JValue(QString &&s) : type(Str) {*(SharedData**) &data = new SharedData{1, std::move(s)};} + JValue(const char *s) : JValue(QString::fromUtf8(s)) {} + ~JValue() { + if(type < Obj) return; + else if(type==Obj) ((JObj*) &data)->~JObj(); + else if(type==Array) ((JArray*) &data)->~JArray(); + else if(type==Str) { + auto ptr = *(SharedData**) &data; + if(ptr->cnt > 1) ptr->cnt--; + else delete ptr; + } + } + + JValue(const JValue &other) { + type = other.type; + if(type==Obj) new (&data) JObj(*(JObj*) &other.data); + else if(type==Array) new (&data) JArray(*(JArray*) &other.data); + else { + data = other.data; + if(type==Str) (*(SharedData**) &data)->cnt++; + } + } + JValue &operator=(const JValue &other) { + this->~JValue(); + new (this) JValue(other); + return *this; + } + JValue(JValue &&other) noexcept : data(other.data), type(other.type) { + other.data = 0; + other.type = Null; + } + JValue &operator=(JValue &&other) noexcept { + std::swap(data, other.data); + std::swap(type, other.type); + return *this; + } + + bool isNull() const {return type==Null;} + bool isStr() const {return type==Str;} + bool isObj() const {return type==Obj;} + bool isArray() const {return type==Array;} + + bool toBool(bool def = false) const { + return type==Null ? def : data; + } + int toInt(int def = 0) const { + return toLong(def); + } + qint64 toLong(qint64 def = 0) const { + if(type==Long || type==Bool) return data; + if(type==Double) return *(double*) &data; + if(type==Ulong) return *(quint64*) &data; + return def; + } + quint64 toULong(quint64 def = 0) const { + if(type==Ulong) return *(quint64*) &data; + if(type==Long || type==Bool) return data; + if(type==Double) return *(double*) &data; + return def; + } + double toDouble(double def = 0) const { + if(type==Double) return *(double*) &data; + if(type==Long || type==Bool) return data; + if(type==Ulong) return *(quint64*) &data; + return def; + } + QString toStr(const QString &def = "") const { + if(type==Str) return (*(SharedData**) &data)->data; + if(type==Long) return QString::number(data); + if(type==Double) return QString::number(*(double*) &data); + if(type==Bool) return data ? "true" : "false"; + if(type==Ulong) return QString::number(*(quint64*) &data); + return def; + } + QString toString(const QString &def = "") const { + return toStr(def); + } + JObj toObj() const { + if(type==Obj) return *(JObj*) &data; + return JObj(); + } + JArray toArray() const { + if(type==Array) return *(JArray*) &data; + return JArray(); + } + + const JValue operator[](const QString &key) const { + return type==Obj ? (*(const JObj*) &data)[key] : JValue(); + } + const JValue operator[](uint64_t i) const { + return type==Array ? (*(const JArray*) &data)[i] : JValue(); + } + + JValue &ref(const QString &key) { + return (*(JObj*) &data)[key]; + } + JValue &ref(uint64_t i) { + return (*(JArray*) &data)[i]; + } + + JArray::iterator begin() const noexcept { + return type==Array ? ((const JArray*) &data)->begin() : JArray::iterator(); + } + JArray::iterator end() const noexcept { + return type==Array ? ((const JArray*) &data)->end() : JArray::iterator(); + } + bool empty() const noexcept { + if(type==Array) return ((const JArray*) &data)->empty(); + else if(type==Obj) return ((const JObj*) &data)->empty(); + return 0; + } + size_t size() const noexcept { + if(type==Array) return ((const JArray*) &data)->size(); + else if(type==Obj) return ((const JObj*) &data)->size(); + return 0; + } + + bool operator==(const JValue &other) const { + if(type==other.type) { + if(data==other.data) return true; + if(type==Null) return true; + if(type<=Double) return false; + if(type==Bool) return ((bool)data)==(bool)other.data; + if(type==Str) return (*(SharedData**) &data)->data==(*(SharedData**) &other.data)->data; + if(type==Obj) return *(JObj*) &data == *(JObj*) &other.data; + if(type==Array) return *(JArray*) &data == *(JArray*) &other.data; + } else { + if(type>Double || other.type>Double || type==Null || other.type==Null) return false; + if(type==Double || other.type==Double) return toDouble()==other.toDouble(); + if(type==Long) return data==other.toLong(); + else return toLong()==other.data; + } + return false; + } + bool operator!=(const JValue &other) const { + return ! (*this==other); + } +private: + JValue(const void *) = delete; // avoid implicit conversions from char * to bool +}; + +class JParser { +public: + JParser(QDataStream &in) : in(in) {} + + JValue read() { + in >> ch; + if(ch==0) throw "Unexpected end-of-input"; + if(ch==0xEF && (readOne()!=0xBB || readOne()!=0xBF)) throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting an UTF-8 BOM"; + if(ch<33) skipSpace(); + return readValue(); + } +protected: + JValue readValue(); + QString readStr(); + void skipSpace(); + unsigned char readOne() { + in >> ch; + return ch; + } + + QDataStream ∈ + unsigned char ch{0}, bk{0}; +}; + +inline JValue JFrom(const QByteArray &json, QString *err = 0) { + QDataStream in(json); + try { + return JParser(in).read(); + } catch (QString anerr) { + if(err) *err = anerr; + } catch (const char *anerr) { + if(err) *err = anerr; + } catch (...) { + if(err) *err = "unknow error"; + } + return JValue(); +} +inline JValue JFrom(QIODevice *device, QString *err = 0) { + QDataStream in(device); + try { + return JParser(in).read(); + } catch (QString anerr) { + if(err) *err = anerr; + } catch (const char *anerr) { + if(err) *err = anerr; + } catch (...) { + if(err) *err = "unknow error"; + } + return JValue(); +} + +class JOut { +public: + JOut(QTextStream &out, QString indent = "") : out(out), indent(indent) { +#if(QT_VERSION_MAJOR < 6) + out.setCodec("UTF-8"); +#endif + } + + void write(const JValue &value); + void writeStr(const QString &str); + void writeMap(const JObj &map); + void writeList(const JArray &objs); +protected: + QTextStream &out; + QString indent; + int cnt{0}; +}; + +inline QString JToStr(const JValue &value, QString indent = "") { + QString json; + QTextStream out(&json); + JOut(out, indent).write(value); + return json; +} +inline QByteArray JToBytes(const JValue &value, QString indent = "") { + QByteArray json; + QTextStream out(&json); + JOut(out, indent).write(value); + return json; +} +inline QTextStream::Status JWrite(const JValue &value, QIODevice *device, QString indent = "") { + QTextStream out(device); + JOut(out, indent).write(value); + return out.status(); +} + +#endif // QJSON_H diff --git a/daylite/gutil/qnetwork.cpp b/daylite/gutil/qnetwork.cpp new file mode 100644 index 0000000..2f8dc22 --- /dev/null +++ b/daylite/gutil/qnetwork.cpp @@ -0,0 +1,100 @@ +#include "qnetwork.h" + +#include +#include + +const char *const FormBoundary = "----GangphonQtBoundary_.oOo._"; + +QNetworkAccessManager *netAccess() { + static QNetworkAccessManager access; + return &access; +}; + +QString errStr(QNetworkReply *reply) { + reply->deleteLater(); + auto error = reply->error(); + if(error != QNetworkReply::NoError) { + if(error==QNetworkReply::OperationCanceledError) return "TimeoutError ("+QString::number(QNetworkReply::TimeoutError)+") "+QCoreApplication::translate("Net","Connection Timeout"); + auto errStr = reply->errorString(); + if(error!=QNetworkReply::InternalServerError || ! errStr.endsWith("replied: Unknown")) return QString(QMetaEnum::fromType().valueToKey(error))+" ("+QString::number(error)+") "+errStr; + } + auto status = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); + if(status != 200) return QString::number(status)+" "+reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString(); + return ""; +} +QString errStrWithData(QNetworkReply *reply, JValue *outJson) { + auto err = errStr(reply); + if(! err.isEmpty()) { + auto data = reply->readAll(); + if(! data.isEmpty()) err += "\n"+data; + return err; + } + if(outJson) { + auto data = reply->readAll(); + QString error; + *outJson = JFrom(data, &error); + if(! error.isEmpty()) return "JSON "+QCoreApplication::translate("Net","Error")+": "+error+"\n"+data; + } + return ""; +} + +QString errStrWithData(QNetworkReply *reply, QJsonDocument *outJson) { + auto err = errStr(reply); + if(! err.isEmpty()) { + auto data = reply->readAll(); + if(! data.isEmpty()) err += "\n"+data; + return err; + } + if(outJson) { + auto data = reply->readAll(); + QJsonParseError jsonErr; + *outJson = QJsonDocument::fromJson(data, &jsonErr); + if(jsonErr.error != QJsonParseError::NoError) return "JSON "+QCoreApplication::translate("Net","Error")+": "+jsonErr.errorString()+"\n"+data; + } + return ""; +} + + +const char* socketErrKey(int value) { + static auto metaEnum = QMetaEnum::fromType(); + return metaEnum.valueToKey(value); +} + +bool TcpSocket::waitForConnected(int msecs) { + if(state() == ConnectedState) return true; + QEventLoop loop; + connect(this, &QTcpSocket::connected, &loop, &QEventLoop::quit); + return connAndExec(msecs, &loop); +} +bool TcpSocket::waitForDisconnected(int msecs) { + if(state() == UnconnectedState) return true; + QEventLoop loop; + connect(this, &QTcpSocket::disconnected, &loop, &QEventLoop::quit); + return connAndExec(msecs, &loop); +} +bool TcpSocket::waitForBytesWritten(int msecs) { + if(bytesToWrite() == 0) return true; + QEventLoop loop; + connect(this, &QTcpSocket::bytesWritten, &loop, &QEventLoop::quit); + return connAndExec(msecs, &loop); +} +bool TcpSocket::waitForReadyRead(int msecs) { + if(bytesAvailable()) return true; + QEventLoop loop; + connect(this, &QTcpSocket::readyRead, &loop, &QEventLoop::quit); + return connAndExec(msecs, &loop); +} + +bool TcpSocket::connAndExec(int msecs, QEventLoop *loop) { + connect(this, &QTcpSocket::errorOccurred, loop, [loop] { + loop->exit(1); + }); + if(timerId) { + killTimer(timerId); + timerId = 0; + } + if(msecs > 0) startTimer(msecs); + auto res = loop->exec(); + stopTimer(); + return res==0; +} diff --git a/daylite/gutil/qnetwork.h b/daylite/gutil/qnetwork.h new file mode 100644 index 0000000..423951a --- /dev/null +++ b/daylite/gutil/qnetwork.h @@ -0,0 +1,160 @@ +#ifndef QNETWORK_H +#define QNETWORK_H + +#include "qjson.h" +#include +#include +#include +#include +#include + +extern const char *const FormBoundary; + +QNetworkAccessManager *netAccess(); + +class NetReq : public QNetworkRequest { +public: +#if(QT_VERSION_MAJOR > 5) + using QNetworkRequest::QNetworkRequest; + explicit NetReq(const QString &url) : QNetworkRequest{url} {}; + explicit NetReq(QNetworkAccessManager *access) : mAccess(access) {}; +#else + NetReq() {init();}; + explicit NetReq(const QString &url) : QNetworkRequest{url} {init();}; + explicit NetReq(const QUrl &url) : QNetworkRequest{url} {init();}; + explicit NetReq(QNetworkAccessManager *access) : mAccess(access) {init();}; + inline void init() { + setAttribute(QNetworkRequest::RedirectPolicyAttribute, QNetworkRequest::NoLessSafeRedirectPolicy); + } +#endif + using QNetworkRequest::url; + inline NetReq &url(const QUrl &url) { + setUrl(url); + return *this; + } + inline NetReq &access(QNetworkAccessManager *access) { + mAccess = access; + return *this; + } + inline NetReq &header(const QByteArray &headerName, const QByteArray &value) { + setRawHeader(headerName, value); + return *this; + } + inline NetReq &header(KnownHeaders header, const QVariant &value) { + setHeader(header, value); + return *this; + } + + inline NetReq &type(const QByteArray &value) { + setRawHeader("Content-Type", value); + return *this; + } + inline NetReq &typeJson() { + setRawHeader("Content-Type", "application/json"); + return *this; + } + inline NetReq &timeout(int timeout) { + setTransferTimeout(timeout); + return *this; + } + + inline QNetworkReply *get() { + if(mAccess==0) mAccess = netAccess(); + return mAccess->get(*this); + } + inline QNetworkReply *post(const QByteArray &data) { + if(mAccess==0) mAccess = netAccess(); + return mAccess->post(*this, data); + } + inline QNetworkReply *post(const char *data) { + if(mAccess==0) mAccess = netAccess(); + return mAccess->post(*this, data); + } + + inline QNetworkReply *post(const JValue &json) { + setRawHeader("Content-Type", "application/json"); + return post(JToBytes(json)); + } + inline QNetworkReply *post(const QJsonDocument &json) { + setRawHeader("Content-Type", "application/json"); + return post(json.toJson(QJsonDocument::Compact)); + } + inline QNetworkReply *post(const QJsonObject &json) { + return post(QJsonDocument{json}); + } + inline QNetworkReply *post(const QJsonArray &json) { + return post(QJsonDocument{json}); + } + inline QNetworkReply *post(QHttpMultiPart *multiPart) { + if(mAccess==0) mAccess = netAccess(); + return mAccess->post(*this, multiPart); + } + QNetworkAccessManager *mAccess{0}; +}; + +QString errStr(QNetworkReply *); +QString errStrWithData(QNetworkReply *, JValue * = 0); +QString errStrWithData(QNetworkReply *, QJsonDocument *); + +inline int waitFinished(QNetworkReply *reply, QObject *context, bool excludeUser = false) { + if(reply->isFinished()) return 0; + QEventLoop loop; + QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); + if(context) QObject::connect(context, &QObject::destroyed, &loop, [&] { + reply->deleteLater(); + loop.exit(1); + }); + return excludeUser ? loop.exec(QEventLoop::ExcludeUserInputEvents) : loop.exec(); +} + +#define ConnReply(reply, context)\ + QObject::connect(context, &QObject::destroyed, reply, &QNetworkReply::deleteLater);\ + QObject::connect(reply, &QNetworkReply::finished, context, + +const char* socketErrKey(int value); + +class TcpSocket : public QTcpSocket { + Q_OBJECT +public: + using QTcpSocket::QTcpSocket; + ~TcpSocket() { + if(timerId) killTimer(timerId); + }; + + void abort() { + stopTimer(); + QTcpSocket::abort(); + } + void close() override { + stopTimer(); + QTcpSocket::close(); + } + bool waitForConnected(int msecs = 30000) override; + bool waitForDisconnected(int msecs = 30000) override; + bool waitForBytesWritten(int msecs = 30000) override; + bool waitForReadyRead(int msecs = 30000) override; + void startTimer(int interval, Qt::TimerType timerType = Qt::CoarseTimer) { + if(timerId) killTimer(timerId); + timerId = QTcpSocket::startTimer(interval, timerType); + } + void stopTimer() { + if(timerId==0) return; + killTimer(timerId); + timerId = 0; + } + int timerId{0}; + +protected: + void timerEvent(QTimerEvent *e) override { + if(e->timerId()!=timerId) QTcpSocket::timerEvent(e); + else { + abort(); + setSocketError(SocketTimeoutError); + setErrorString(QCoreApplication::translate("QAbstractSocket", "Socket operation timed out")); + emit errorOccurred(QAbstractSocket::SocketTimeoutError); + } + }; + bool connAndExec(int msecs, QEventLoop *loop); +}; + +#endif // QNETWORK_H diff --git a/daylite/gutil/qwaitingdlg.cpp b/daylite/gutil/qwaitingdlg.cpp new file mode 100644 index 0000000..c1c9189 --- /dev/null +++ b/daylite/gutil/qwaitingdlg.cpp @@ -0,0 +1,120 @@ +#include "qwaitingdlg.h" +#include "qgui.h" +#include +#include +#include + +WaitingDlg::WaitingDlg(QWidget *parent, QString text, QString sucText) : QDialog{parent, Qt::Tool}, sucText(sucText) { + setAttribute(Qt::WA_DeleteOnClose); + setModal(true); + + auto vBox = new VBox(this); + + mIndicator = new WaitingIndicator(this); + mIndicator->setFixedSize(100, 100); + vBox->addWidget(mIndicator, 0, Qt::AlignCenter); + + fdText = new QLabel(text); + fdText->setAlignment(Qt::AlignCenter); + gFont(fdText, 18, true); + vBox->addWidget(fdText); +} + +void WaitingDlg::closeEvent(QCloseEvent *event) { + if(showTimerId) { + killTimer(showTimerId); + showTimerId = 0; + } + if(closeTimerId) { + killTimer(closeTimerId); + closeTimerId = 0; + } + QDialog::closeEvent(event); +} +void WaitingDlg::timerEvent(QTimerEvent *event) { + if(showTimerId==event->timerId()) { + killTimer(showTimerId); + showTimerId = 0; + show(); + } else if(closeTimerId==event->timerId()) { + killTimer(closeTimerId); + closeTimerId = 0; + close(); + } else QDialog::timerEvent(event); +} +void WaitingDlg::show() { + QDialog::show(); + raise(); + activateWindow(); +} +void WaitingDlg::showLater() { + if(isVisible()) return; + if(showTimerId) killTimer(showTimerId); + showTimerId = startTimer(200); +} +void WaitingDlg::success() { + fdText->setText(sucText.isEmpty() ? tr("Success") : sucText); + mIndicator->success(); + if(showTimerId) { + killTimer(showTimerId); + showTimerId = 0; + } + if(! isVisible()) show(); + if(closeTimerId) killTimer(closeTimerId); + closeTimerId = startTimer(keepTime); +} + + +void WaitingIndicator::success() { + if(timerId > 0) killTimer(timerId); + timerId = -1; + angle = 0; + update(); +} + +void WaitingIndicator::timerEvent(QTimerEvent *event) { + if(timerId!=event->timerId()) QWidget::timerEvent(event); + else if(isVisible()) { + angle += 30; + if(angle>=360) angle -= 360; + update(); + } else if(timerId > 0) { + killTimer(timerId); + timerId = 0; + angle = 0; + } +} + +void WaitingIndicator::paintEvent(QPaintEvent *) { + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + if(timerId > 0) { + int radius = qMin(width(), height()) * 0.33; + int innerRadius = radius >> 1; + QPen pen(mColor, radius / 6, Qt::SolidLine, Qt::RoundCap); + painter.translate(width()>>1, height()>>1); + auto color = mColor; + for(int i=0; i<12; ++i) { + if(i) { + color.setAlphaF(1 - i/12.0); + pen.setColor(color); + painter.rotate(-30); + } else if(angle) painter.rotate(angle); + painter.setPen(pen); + painter.drawLine(0, innerRadius, 0, radius); + } + } else if(timerId==0) timerId = startTimer(33); + else { + int radius = qMin(width(), height()) >> 1; + int lineWidth = radius / 8; + radius -= lineWidth>>1; + QPen pen(QColor(0x00aa00), lineWidth, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin); + painter.setPen(pen); + painter.translate(width()>>1, height()>>1); + painter.drawEllipse(QPoint(0, 0), radius, radius); + QPainterPath path({-0.8*radius, 0}); + path.lineTo(-0.25*radius, 0.6*radius); + path.lineTo(0.6*radius, -0.5*radius); + painter.drawPath(path); + } +} diff --git a/daylite/gutil/qwaitingdlg.h b/daylite/gutil/qwaitingdlg.h new file mode 100644 index 0000000..efc5651 --- /dev/null +++ b/daylite/gutil/qwaitingdlg.h @@ -0,0 +1,43 @@ +#ifndef QWAITINGDLG_H +#define QWAITINGDLG_H + +#include +#include +#include + +class WaitingIndicator : public QWidget { + Q_OBJECT +public: + using QWidget::QWidget; + QColor mColor{0x0088ff}; +public slots: + void success(); +protected: + void timerEvent(QTimerEvent * event) override; + void paintEvent(QPaintEvent * event) override; + + int angle{0}; + int timerId{0}; +}; + +class WaitingDlg : public QDialog { + Q_OBJECT +public: + explicit WaitingDlg(QWidget *parent = nullptr, QString text = 0, QString sucText = 0); + + QLabel *fdText; + QString sucText; + WaitingIndicator *mIndicator; + int keepTime = 750; +public slots: + void show(); + void showLater(); + void success(); +protected: + void timerEvent(QTimerEvent *) override; + void closeEvent(QCloseEvent *) override; +private: + int closeTimerId{0}, showTimerId{0}; +}; + +#endif // QWAITINGDLG_H diff --git a/daylite/icon.ico b/daylite/icon.ico new file mode 100644 index 0000000..0b202f9 Binary files /dev/null and b/daylite/icon.ico differ diff --git a/daylite/icon.png b/daylite/icon.png new file mode 100644 index 0000000..0c54496 Binary files /dev/null and b/daylite/icon.png differ diff --git a/daylite/main.cpp b/daylite/main.cpp new file mode 100644 index 0000000..b763255 --- /dev/null +++ b/daylite/main.cpp @@ -0,0 +1,61 @@ +#include "main.h" +#include "mainwindow.h" +#include "gutil/qnetwork.h" +#include +#include + +#ifdef _MSC_VER //MSVC编译器 +#include +#include +LONG WINAPI handleException(_EXCEPTION_POINTERS *excep) { + auto errCode = QString::number(excep->ExceptionRecord->ExceptionCode, 16); + auto errAddr = QString::number((uint64_t)excep->ExceptionRecord->ExceptionAddress, 16); + auto hDumpFile = CreateFile(L"daylite-crash.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if(hDumpFile == INVALID_HANDLE_VALUE) { + qCritical()<<"CreateFile daylite-crash.dmp Failed! ExceptionCode"<An Error Occurred!
Please send 'daylite-crash.dmp' file to gangphon@qq.com"); + return EXCEPTION_EXECUTE_HANDLER; +} +#endif + +int main(int argc, char *argv[]) { + QApplication::setStyle("Fusion"); + QApplication a(argc, argv); + a.setStyleSheet("QPushButton:checked{background:#0b0;}"); + auto pal = a.palette(); + pal.setBrush(QPalette::Inactive, QPalette::Highlight, pal.brush(QPalette::Active, QPalette::Highlight)); + pal.setBrush(QPalette::Window, QColor(0xdddddd)); + a.setPalette(pal); + auto ft = a.font(); + ft.setPixelSize(18); + a.setFont(ft); + +#ifdef _MSC_VER + SetUnhandledExceptionFilter(handleException); +#endif + MainWindow w; + return a.exec(); +} + + + +QString errStrWithJson(QNetworkReply *reply, JValue *outJson, QByteArray *outData) { + auto err = errStr(reply); + auto data = reply->readAll(); + if(outData) *outData = data; + if(! err.isEmpty()) { + if(! data.isEmpty()) err = err+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; + return err; + } + QString error; + auto json = JFrom(data, &error); + if(! error.isEmpty()) return "JSON Error: "+error+"\n"+QCoreApplication::translate("Def","Device replied")+": "+data; + if(! json["success"].toBool()) return QCoreApplication::translate("Def","Fail")+". "+QCoreApplication::translate("Def","Device replied")+": "+data; + if(outJson) *outJson = json; + return ""; +} diff --git a/daylite/main.h b/daylite/main.h new file mode 100644 index 0000000..6be9155 --- /dev/null +++ b/daylite/main.h @@ -0,0 +1,9 @@ +#ifndef MAIN_H +#define MAIN_H + +#include "gutil/qjson.h" +#include + +QString errStrWithJson(QNetworkReply *, JValue * = 0, QByteArray * = 0); + +#endif // MAIN_H diff --git a/daylite/mainwindow.cpp b/daylite/mainwindow.cpp new file mode 100644 index 0000000..7593696 --- /dev/null +++ b/daylite/mainwindow.cpp @@ -0,0 +1,480 @@ +#include "mainwindow.h" +#include "main.h" +#include "gutil/qnetwork.h" +#include "gutil/qwaitingdlg.h" +#include +#include +#include +#include +#include +#include + +MainWindow::MainWindow() { + resize(1180, 680); + + auto vBox = new VBox(this); + vBox->setContentsMargins(0,0,0,0); + + QIcon green(":/res/green.png"); + QIcon yellow(":/res/yellow.png"); + QIcon plus(":/res/plus.png"); + QIcon red(":/res/red.png"); + iconss = {{green, green}, {yellow, yellow, yellow}, {yellow, yellow, plus}, {red, red, red}}; + + auto hBox = new HBox(vBox); + hBox->setSpacing(0); + + auto vv = new VBox(hBox); + addPart(vv); + + auto line = new QFrame; + line->setFrameStyle(QFrame::Sunken); + line->setFrameShape(QFrame::VLine); + hBox->addWidget(line); + + vv = new VBox(hBox); + addPart(vv); + + hBox = new HBox(vBox); + hBox->addSpacing(80); + hBox->addStretch(); + auto lb = hBox->addLabel("Daylite® Terminal Control"); + auto ft = lb->font(); + ft.setPixelSize(28); + lb->setFont(ft); + hBox->addStretch(); + + btnChg = new QPushButton("Change Password"); + btnChg->hide(); + connect(btnChg, &QPushButton::clicked, this, [=] { + bool ok = false; + auto pwd = QInputDialog::getText(this, "Input New Password", "New Password", QLineEdit::Password, "", &ok); + if(! ok) return; + if(pwd.isEmpty()) { + QMessageBox::warning(this, "Error", "Password is Empty"); + return; + } + auto pwdaga = QInputDialog::getText(this, "Confirm Your New Password", "Confirm Password", QLineEdit::Password, "", &ok); + if(! ok) return; + if(pwd.isEmpty()) { + QMessageBox::warning(this, "Error", "Password is Empty"); + return; + } + if(pwd!=pwdaga) { + QMessageBox::warning(this, "Error", "Two Inputs are Different"); + return; + } + QCryptographicHash cryptoHash(QCryptographicHash::Md5); + cryptoHash.addData(pwd.toUtf8()); + auto md5 = QString::fromLatin1(cryptoHash.result().toHex()); + cfg["pwd"] = md5; + QFile file("cfg.json"); + if(! file.open(QFile::WriteOnly)) return; + file.write(JToBytes(cfg, "\t")); + file.close(); + }); + hBox->addWidget(btnChg); + + btnCcl = new QPushButton("Cancel"); + btnCcl->setMinimumWidth(100); + btnCcl->hide(); + connect(btnCcl, &QPushButton::clicked, this, [=] { + btnChg->hide(); + btnCcl->hide(); + btnOK->hide(); + btnEdit->show(); + for(auto &card : cards) { + card.edId->hide(); + card.edName->hide(); + card.lbName->show(); + for(int i=0; ihide(); + card.btns[i]->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + } + } + }); + hBox->addWidget(btnCcl); + + btnOK = new QPushButton("OK"); + btnOK->setMinimumWidth(100); + btnOK->hide(); + connect(btnOK, &QPushButton::clicked, this, [=] { + btnChg->hide(); + btnCcl->hide(); + btnOK->hide(); + btnEdit->show(); + JArray jCards; + for(auto &card : cards) { + auto name = card.edName->text(); + card.lbName->setText(name); + card.id = card.edId->currentText(); + card.lbAlias->setText(card.id); + auto idx = card.edId->findText(card.id); + if(idx>-1) { + card.ip = card.edId->itemData(idx).toString(); + card.online = card.edId->itemData(idx, Qt::UserRole+1).toBool(); + card.lbStatus->setText("Online"); + auto pal = card.lbStatus->palette(); + pal.setColor(QPalette::WindowText, 0x00aa00); + card.lbStatus->setPalette(pal); + getNames(card); + } else { + card.ip = ""; + card.online = false; + card.lbStatus->setText("Offline"); + auto pal = card.lbStatus->palette(); + pal.setColor(QPalette::WindowText, 0x777777); + card.lbStatus->setPalette(pal); + card.lbCur->setText(""); + } + card.edId->hide(); + card.edName->hide(); + card.lbName->show(); + JArray cmds; + for(int i=0; isetText(card.edits[i]->text()); + cmds.append(card.edits[i]->text()); + card.edits[i]->hide(); + card.btns[i]->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + } + jCards.append(JObj{{"name", name}, {"id", card.id}, {"cmds", cmds}}); + } + cfg["cards"] = jCards; + QFile file("cfg.json"); + if(! file.open(QFile::WriteOnly)) return; + file.write(JToBytes(cfg, "\t")); + file.close(); + }); + hBox->addWidget(btnOK); + + btnEdit = new QPushButton(QIcon(":/res/settings.png"), "Edit"); + btnEdit->setIconSize({32,32}); + connect(btnEdit, &QPushButton::clicked, this, [=] { + auto pwdmd5 = cfg["pwd"].toStr(); + if(! pwdmd5.isEmpty()) { + bool ok = false; + auto pwd = QInputDialog::getText(this, "Input Your Password", "Password", QLineEdit::Password, "", &ok); + if(! ok) return; + if(pwd.isEmpty()) { + QMessageBox::warning(this, "Error", "Password is Empty"); + return; + } + QCryptographicHash cryptoHash(QCryptographicHash::Md5); + cryptoHash.addData(pwd.toUtf8()); + auto md5 = QString::fromLatin1(cryptoHash.result().toHex()); + if(md5!=pwdmd5) { + QMessageBox::warning(this, "Error", "Password Error"); + return; + } + } + btnEdit->hide(); + btnChg->show(); + btnCcl->show(); + btnOK->show(); + for(auto &card : cards) { + card.edName->setText(card.lbName->text()); + card.edId->setCurrentText(card.id); + card.lbName->hide(); + card.edName->show(); + card.edId->show(); + for(int i=0; isetText(card.btns[i]->text()); + card.btns[i]->setToolButtonStyle(Qt::ToolButtonIconOnly); + card.edits[i]->show(); + } + } + }); + hBox->addWidget(btnEdit); + + // fdPort->setSizeAdjustPolicy(QComboBox::AdjustToContents); + + show(); + readfile(); + JArray jCards; + if(cfg.empty() || (jCards = cfg["cards"].toArray()).empty()) { + cfg["cards"] = jCards = JArray{ + JObj{{"name", "Card 1"}, {"cmds", JArray{"AAA","AAA", "BBB","BBB","BBB", "BBB","BBB","CCC", "DDD","DDD","DDD"}}}, + JObj{{"name", "Card 2"}, {"cmds", JArray{"AAA","AAA", "BBB","BBB","BBB", "BBB","BBB","CCC", "DDD","DDD","DDD"}}} + }; + } + for(int cc=0; ccsetText(jCards[cc]["name"].toStr()); + cards[cc].lbAlias->setText(cards[cc].id); + auto cmds = jCards[cc]["cmds"]; + for(int bb=0; bbsetText(cmds[bb].toStr()); + } + + connect(&mUdpSocket, &QUdpSocket::readyRead, this, [this] { + while(mUdpSocket.hasPendingDatagrams()) { + auto gram = mUdpSocket.receiveDatagram(); + auto data = gram.data(); + if(data.isEmpty()) continue; + auto senderAddress = gram.senderAddress(); + bool ok = true; + if(senderAddress.protocol()==QUdpSocket::IPv6Protocol) senderAddress.setAddress(senderAddress.toIPv4Address(&ok)); + auto addr = ok ? senderAddress.toString() : ""; + QString error; + auto json = JFrom(gram.data(), &error); + if(! error.isEmpty()) { + qDebug()<<"UDP read Json Error: "+error; + continue; + } + auto cardId = json["cardId"].toString(); + for(auto &card : cards) if(card.id==cardId) { + card.ip = addr; + card.online = true; + card.lbStatus->setText("Online"); + auto pal = card.lbStatus->palette(); + pal.setColor(QPalette::WindowText, 0x00aa00); + card.lbStatus->setPalette(pal); + getNames(card); + } + int cnt = cards[0].edId->count(); + for(int i=0; iitemText(i)==cardId) { + for(auto &card : cards) { + card.edId->setItemData(i, addr); + card.edId->setItemData(i, true, Qt::UserRole+1); + } + goto end; + } + for(auto &card : cards) { + auto iii = card.edId->currentIndex(); + card.edId->addItem(cardId, addr); + if(iii==-1) card.edId->setCurrentIndex(-1); + card.edId->setItemData(cnt, true, Qt::UserRole+1); + } + end:; + } + }); + sendGetInfo(); + timerId = startTimer(10000); +} +void MainWindow::readfile() { + QFile file("cfg.json"); + if(! file.open(QFile::ReadOnly)) return; + QString err; + auto json = JFrom(&file, &err); + if(! err.isEmpty()) return; + cfg = json.toObj(); +} + +void MainWindow::addPart(VBox *vv) { + vv->addStretch(); + auto lbName = new QLabel; + auto ft = lbName->font(); + ft.setPixelSize(22); + lbName->setFont(ft); + vv->addWidget(lbName, 0, Qt::AlignCenter); + auto edName = new QLineEdit; + edName->hide(); + vv->addWidget(edName); + + auto edId = new QComboBox; + edId->setEditable(true); + edId->hide(); + vv->addWidget(edId); + + vv->addStretch(); + + auto hh = new HBox(vv); + auto lb = hh->addLabel("Status: "); + lb->setMinimumWidth(120); + lb->setAlignment(Qt::AlignVCenter | Qt::AlignRight); + auto lbStatus = hh->addLabel("Offline"); + auto pal = lbStatus->palette(); + pal.setColor(QPalette::WindowText, 0x777777); + lbStatus->setPalette(pal); + hh->addStretch(); + + vv->addStretch(); + + hh = new HBox(vv); + lb = hh->addLabel("Aktuell: "); + lb->setMinimumWidth(120); + lb->setAlignment(Qt::AlignVCenter | Qt::AlignRight); + auto lbAlias = hh->addLabel(); + hh->addLabel(" / "); + auto lbCur = hh->addLabel(); + hh->addStretch(); + cards.push_back({lbName, edName, edId, lbStatus, lbAlias, lbCur, new QButtonGroup(hh)}); + + vv->addStretch(); + + QSize siz{100, 100}; + auto &card = cards.back(); + auto cccc = cards.size()-1; + for(auto &icons : iconss) { + auto hh = new HBox(vv); + vv->addStretch(); + hh->addStretch(1); + for(auto &icon : icons) { + auto vvv = new VBox; + hh->addLayout(vvv, 4); + vvv->setSpacing(0); + auto btn = new QToolButton; + btn->setStyleSheet("QToolButton{border: none;} QToolButton:checked,QToolButton:hover {border: 1px solid #aaa;}"); + btn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon); + btn->setIcon(icon); + btn->setIconSize(siz); + vvv->addWidget(btn, 0, Qt::AlignCenter); + card.btnGrp->addButton(btn, (int)card.btns.size()); + card.btns.emplace_back(btn); + auto ed = new QLineEdit; + ed->setAlignment(Qt::AlignCenter); + ed->hide(); + vvv->addWidget(ed, 1); + card.edits.emplace_back(ed); + } + hh->addStretch(1); + } + + connect(card.btnGrp, &QButtonGroup::idClicked, this, [=](int id) { + auto &card = cards[cccc]; + if(card.ip.isEmpty()) QMessageBox::critical(this, "Error", "No IP"); + else { + auto name = card.btnGrp->button(id)->text(); + if(QMessageBox::question(this, "Confirm", "Send "+name+"?")==QMessageBox::Yes && SendAnycastCmd(id + 1, card)) card.lbCur->setText(name); + } + }); +} + +void MainWindow::sendGetInfo() { + auto data = JToBytes(JObj{{"action", "getInfo"}}); + uchar ccc[]{0x7E, 0x7E, 0x7E, 0x90, 0x42, 0x72, 0x6F, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x21, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1C, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x9F}; + if(mUdpSocket.writeDatagram(data, QHostAddress("255.255.255.255"), 22222) != data.length()) qDebug() << "getInfo write to 255.255.255.255 failed"; + if(mUdpSocket.writeDatagram((char *)ccc, sizeof(ccc), QHostAddress("255.255.255.255"), 31296) != sizeof(ccc)) qDebug() << "getInfo write to 255.255.255.255 failed"; + auto networkinterfaces = QNetworkInterface::allInterfaces(); + for(auto &face : networkinterfaces) { + auto flags = face.flags(); + bool can = (flags & QNetworkInterface::IsRunning) && (flags & QNetworkInterface::CanBroadcast) && ! (flags & QNetworkInterface::IsLoopBack); + if(! can) continue; + auto addrEntries = face.addressEntries(); + for(QNetworkAddressEntry &addrEntry : addrEntries) { + auto ip = addrEntry.ip(); + if(ip.protocol()!=QAbstractSocket::IPv4Protocol) continue; + auto broadcast = addrEntry.broadcast(); + if(mUdpSocket.writeDatagram(data, broadcast, 22222) != data.length()) qDebug() << "getInfo write failed." << ip.toString() << "->" << broadcast.toString(); + } + } +} + +unsigned char GetCheckCodeIn8(unsigned char *str, unsigned int size) { + unsigned char checkCode = 0; + for(int i=0; i<(int)size; i++) checkCode += str[i]; + return (~checkCode) & 0xff; +} + +struct ST_ANSY_PROGRAM_PACKET { + unsigned char SyncHead[3]{0x7e, 0x7e, 0x55}; + unsigned char ucCommType; + int iBaoLiu; + unsigned int iLength; + unsigned char pDataBuffer[20]; +}; +class LocalObj : public QObject { +public : + int cnt = 1; + void reset() { + cnt = 0; + } +}; +bool MainWindow::SendAnycastCmd(int progIdx, const Card &card) { + ST_ANSY_PROGRAM_PACKET tempStreadPakcet; + 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"); + auto waitingDlg = new WaitingDlg(this, action+" ..."); + LocalObj lll; + connect(waitingDlg, &QTextEdit::destroyed, &lll, &LocalObj::reset); + waitingDlg->setAttribute(Qt::WA_DeleteOnClose); + waitingDlg->show(); + + TcpSocket tcp; + tcp.connectToHost(card.ip, 31299); + if(! tcp.waitForConnected(10000)) { + tcp.close(); + if(lll.cnt) { + waitingDlg->close(); + QMessageBox::critical(this, tr("Tip"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitConnected\n"); + } + return false; + } + auto resNum = tcp.write(data); + tcp.flush(); + if(resNum == -1 || ! tcp.waitForBytesWritten(10000)) { + tcp.close(); + if(lll.cnt) { + waitingDlg->close(); + QMessageBox::critical(this, tr("Tip"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at write\n"); + } + return false; + } + if(! tcp.waitForReadyRead(10000)) { + tcp.close(); + if(lll.cnt) { + waitingDlg->close(); + QMessageBox::critical(this, tr("Tip"), QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" at WaitRead\n"); + } + return false; + } + tcp.close(); + if(lll.cnt) waitingDlg->success(); + return true; +} + +MainWindow::~MainWindow() { + mUdpSocket.close(); + if(timerId) killTimer(timerId); +} + +void MainWindow::getNames(const Card &card) { + JObj json; + json.insert("_id", "GetProgramName"); + json.insert("_type", "GetProgramName"); + auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(10000).post(json); + connect(reply, &QNetworkReply::finished, this, [=] { + JValue json; + auto err = errStrWithJson(reply, &json); + if(! err.isEmpty()) return; + card.lbCur->setText(json["programName"].toStr()); + }); + json = JObj(); + json.insert("_id", "GetCardAlias"); + json.insert("_type", "GetCardAlias"); + reply = NetReq("http://"+card.ip+":2016/settings").timeout(10000).post(json); + connect(reply, &QNetworkReply::finished, this, [=] { + JValue json; + auto err = errStrWithJson(reply, &json); + if(! err.isEmpty()) return; + auto alias = json["alias"].toStr(); + if(! alias.isEmpty()) card.lbAlias->setText(QString::fromUtf8(QByteArray::fromBase64(alias.toLatin1()))); + }); +} + +void MainWindow::timerEvent(QTimerEvent *event) { + if(timerId!=event->timerId()) return; + for(auto &card : cards) if(card.online) card.online = false; + else { + card.lbStatus->setText("Offline"); + auto pal = card.lbStatus->palette(); + pal.setColor(QPalette::WindowText, 0x777777); + card.lbStatus->setPalette(pal); + } + int cnt = cards[0].edId->count(); + for(int i=0; iitemData(i, Qt::UserRole+1).toBool()) for(auto &card : cards) card.edId->setItemData(i, false, Qt::UserRole+1); + else { + for(auto &card : cards) card.edId->removeItem(i); + i--; + cnt--; + } + sendGetInfo(); +} diff --git a/daylite/mainwindow.h b/daylite/mainwindow.h new file mode 100644 index 0000000..cf1309a --- /dev/null +++ b/daylite/mainwindow.h @@ -0,0 +1,47 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include "gutil/qgui.h" +#include "gutil/qjson.h" +#include +#include +#include + +struct Card { + QLabel *lbName; + QLineEdit *edName; + QComboBox *edId; + QLabel *lbStatus; + QLabel *lbAlias, *lbCur; + QButtonGroup *btnGrp; + QString id; + QString ip; + std::vector btns; + std::vector edits; + bool online = false; +}; +class MainWindow : public QWidget { + Q_OBJECT +public: + MainWindow(); + ~MainWindow(); + + void readfile(); + void addPart(VBox *); + void click(); + void edit(); + void sendGetInfo(); + bool SendAnycastCmd(int, const Card &); + void getNames(const Card &); + + JObj cfg; + QPushButton *btnEdit, *btnOK, *btnCcl, *btnChg; + QUdpSocket mUdpSocket; + std::vector cards; + std::vector> iconss; + int timerId = 0; +protected: + void timerEvent(QTimerEvent *event); +}; + +#endif // MAINWINDOW_H diff --git a/daylite/res.qrc b/daylite/res.qrc new file mode 100644 index 0000000..c42021b --- /dev/null +++ b/daylite/res.qrc @@ -0,0 +1,9 @@ + + + res/green.png + res/plus.png + res/red.png + res/settings.png + res/yellow.png + + diff --git a/daylite/res/green.png b/daylite/res/green.png new file mode 100644 index 0000000..d917751 Binary files /dev/null and b/daylite/res/green.png differ diff --git a/daylite/res/plus.png b/daylite/res/plus.png new file mode 100644 index 0000000..af21c6c Binary files /dev/null and b/daylite/res/plus.png differ diff --git a/daylite/res/red.png b/daylite/res/red.png new file mode 100644 index 0000000..556ff29 Binary files /dev/null and b/daylite/res/red.png differ diff --git a/daylite/res/settings.png b/daylite/res/settings.png new file mode 100644 index 0000000..d652408 Binary files /dev/null and b/daylite/res/settings.png differ diff --git a/daylite/res/yellow.png b/daylite/res/yellow.png new file mode 100644 index 0000000..2b37a7b Binary files /dev/null and b/daylite/res/yellow.png differ