Compare commits

..

No commits in common. "332897f9cfb6fad0d2c224e9aed51d055862bb52" and "a711980263bb7303dcb1a4a42e85274f093b9d8b" have entirely different histories.

147 changed files with 13891 additions and 11476 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 140 KiB

View File

@ -1,245 +1,242 @@
QT += core gui widgets
QT += multimedia
QT += network
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 += lrelease
CONFIG += embed_translations
# CONFIG += console
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
VERSION = 1.5.1
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
msvc {
contains(QT_ARCH, i386) {
QMAKE_LFLAGS += /LARGEADDRESSAWARE
}
CONFIG += force_debug_info
CONFIG += separate_debug_info
}
win32 {
CONFIG -= debug_and_release
LIBS += -lwinmm
LIBS += -lDbghelp
RC_ICONS = res/Logo.ico
}
osx {
QMAKE_MACOSX_DEPLOYMENT_TARGET = 11.0
-mmacosx-version-min=11.0
ICON = res/Logo-raw.png
}
copydir.files += AClock
copydir.files += borders
copydir.files += Demos
copydir.files += translations
copydir.files += rk_lcd_parameters
copydir.files += $$quote(files)
win32 {
EXE_SUFFIX = .exe
contains(QT_ARCH, i386) {
DIR_SUFFIX = -32
copy.files += $$files(OpenSSL/*.dll) # for https requests
}
copy.files += $$files(ffmpeg$$DIR_SUFFIX/bin/*.dll)
copy.files += 7z/7z.dll
copy.files += 7z/7z.exe
copy.path = $$OUT_PWD
copydir.path = $$OUT_PWD
CONFIG += file_copies
COPIES += copy
COPIES += copydir
}
osx {
DIR_SUFFIX = -mac
copy.path = Contents/MacOS
copydir.path = Contents/MacOS
QMAKE_BUNDLE_DATA += copy
QMAKE_BUNDLE_DATA += copydir
}
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
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += res.qrc
SOURCES += \
base/changepasswordform.cpp \
base/switchcontrol.cpp \
base/extendedgroupbox.cpp \
base/ffutil.cpp \
base/locolorselector.cpp \
base/lodateselector.cpp \
base/loqtitlebar.cpp \
base/loqtreewidget.cpp \
gutil/qcore.cpp \
gutil/qwaitingdlg.cpp \
basedlg.cpp \
basewin.cpp \
cfg.cpp \
device/ctrlhdmipanel.cpp \
device/ctrlnetworkpanel.cpp \
device/ctrlpowerpanel.cpp \
device/ctrlpwdpanel.cpp \
device/ctrltestpanel.cpp \
device/ctrlvolumepanel.cpp \
deviceitem.cpp \
devicepanel.cpp \
ffplayer.cpp \
globaldefine.cpp \
gutil/cpp.cpp \
gutil/qgui.cpp \
gutil/qjson.cpp \
gutil/qnetwork.cpp \
main.cpp \
mainwindow.cpp \
mguangyingpinwidget.cpp \
player/eleanaclock.cpp \
player/eleborder.cpp \
player/eledigiclock.cpp \
player/elegif.cpp \
player/elescroll.cpp \
player/eletimer.cpp \
player/elevideo.cpp \
player/playwin.cpp \
player/posdlg.cpp \
player/srccopy.cpp \
progpanel.cpp \
synctimer.cpp \
tools.cpp \
device/ctrladvancedpanel.cpp \
device/ctrlbrightpanel.cpp \
device/ctrlverifyclockpanel.cpp \
device/upgradeapkdialog.cpp \
program/copydirthread.cpp \
program/eaclock.cpp \
program/ebase.cpp \
program/edclock.cpp \
program/eenviron.cpp \
program/egif.cpp \
program/emultiwin.cpp \
program/ephoto.cpp \
program/etext.cpp \
program/etimer.cpp \
program/evideo.cpp \
program/eweb.cpp \
program/gentmpthread.cpp \
program/pageeditor.cpp \
program/pagelistitem.cpp \
program/progeditorwin.cpp \
program/progitem.cpp \
program/sendprogramdialog.cpp \
program/sendprogthread.cpp \
program/videosplitthread.cpp
HEADERS += \
base/changepasswordform.h \
base/switchcontrol.h \
base/extendedgroupbox.h \
base/locolorselector.h \
base/lodateselector.h \
base/loqtitlebar.h \
base/loqtreewidget.h \
gutil/qcore.h \
gutil/qwaitingdlg.h \
basedlg.h \
basewin.h \
cfg.h \
device/ctrlhdmipanel.h \
device/ctrlnetworkpanel.h \
device/ctrlpowerpanel.h \
device/ctrlpwdpanel.h \
device/ctrltestpanel.h \
device/ctrlvolumepanel.h \
deviceitem.h \
devicepanel.h \
ffplayer.h \
globaldefine.h \
gutil/cpp.h \
gutil/qgui.h \
gutil/qjson.h \
gutil/qnetwork.h \
mainwindow.h \
mguangyingpinwidget.h \
player/eleanaclock.h \
player/eleborder.h \
player/eledigiclock.h \
player/elegif.h \
player/elescroll.h \
player/eletimer.h \
player/elevideo.h \
player/playwin.h \
player/posdlg.h \
player/srccopy.h \
progpanel.h \
synctimer.h \
tools.h \
device/ctrladvancedpanel.h \
device/ctrlbrightpanel.h \
device/ctrlverifyclockpanel.h \
device/upgradeapkdialog.h \
program/copydirthread.h \
program/eaclock.h \
program/ebase.h \
program/edclock.h \
program/eenviron.h \
program/egif.h \
program/emultiwin.h \
program/ephoto.h \
program/etext.h \
program/etimer.h \
program/evideo.h \
program/eweb.h \
program/gentmpthread.h \
program/pageeditor.h \
program/pagelistitem.h \
program/progeditorwin.h \
program/progitem.h \
program/sendprogramdialog.h \
program/sendprogthread.h \
program/videosplitthread.h
TRANSLATIONS += \
ts/app_zh_CN.ts \
ts/app_zh_TW.ts \
ts/app_en.ts \
ts/app_ja.ts \
ts/app_pt.ts
include(./xlsx/qtxlsx.pri)
QT += core gui widgets
QT += multimedia
QT += network
QT += concurrent
QT += serialport
QT += opengl
QT += webenginewidgets
greaterThan(QT_MAJOR_VERSION, 5) {
QT += openglwidgets
}
CONFIG += c++17
CONFIG += lrelease
CONFIG += embed_translations
# CONFIG += console
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# 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
TARGET = $$quote(LedOK Express)
VERSION = 1.4.1
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
msvc {
contains(QT_ARCH, i386) {
QMAKE_LFLAGS += /LARGEADDRESSAWARE
#QMAKE_LFLAGS += -Wl,--large-address-aware
}
lessThan(QT_MAJOR_VERSION, 6) {
QMAKE_CXXFLAGS += -execution-charset:utf-8
QMAKE_CXXFLAGS += -source-charset:utf-8
}
CONFIG += force_debug_info
CONFIG += separate_debug_info
}
win32 {
CONFIG -= debug_and_release
LIBS += -lwinmm
LIBS += -lDbghelp
RC_ICONS = res/Logo.ico
}
osx {
ICON = res/Logo-raw.png
}
copydir.files += AClock
copydir.files += borders
copydir.files += translations
copydir.files += $$quote(y50 param)
copydir.files += $$quote(files)
win32 {
EXE_SUFFIX = .exe
copy.files += $$files(ffmpeg/bin/*.dll)
copy.files += 7z/7z.dll
copy.files += 7z/7z.exe
copy.files += $$files(OpenSSL/*.dll) # for https requests
copy.path = $$OUT_PWD
copydir.path = $$OUT_PWD
CONFIG += file_copies
COPIES += copy
COPIES += copydir
}
osx {
DIR_SUFFIX = -mac
copy.path = Contents/MacOS
copydir.path = Contents/MacOS
QMAKE_BUNDLE_DATA += copy
QMAKE_BUNDLE_DATA += copydir
}
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
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += res.qrc
SOURCES += \
base/changepasswordform.cpp \
base/switchcontrol.cpp \
base/extendedgroupbox.cpp \
base/ffutil.cpp \
base/locolorselector.cpp \
base/lodateselector.cpp \
base/loqtitlebar.cpp \
base/loqtreewidget.cpp \
gutil/qwaitingdlg.cpp \
basedlg.cpp \
basewin.cpp \
cfg.cpp \
device/ctrlhdmipanel.cpp \
device/ctrlnetworkpanel.cpp \
device/ctrlpowerpanel.cpp \
device/ctrlpwdpanel.cpp \
device/ctrltestpanel.cpp \
device/ctrlvolumepanel.cpp \
deviceitem.cpp \
devicepanel.cpp \
ffplayer.cpp \
globaldefine.cpp \
gutil/cpp.cpp \
gutil/qgui.cpp \
gutil/qjson.cpp \
gutil/qnetwork.cpp \
main.cpp \
mainwindow.cpp \
mguangyingpinwidget.cpp \
player/digiclock.cpp \
player/eleanaclock.cpp \
player/elebase.cpp \
player/eleborder.cpp \
player/elegif.cpp \
player/eleimg.cpp \
player/elemultipng.cpp \
player/elescroll.cpp \
player/eletimer.cpp \
player/elevideo.cpp \
player/playwin.cpp \
player/posdlg.cpp \
progpanel.cpp \
synctimer.cpp \
tools.cpp \
device/ctrladvancedpanel.cpp \
device/ctrlbrightpanel.cpp \
device/ctrlverifyclockpanel.cpp \
device/upgradeapkdialog.cpp \
program/copydirthread.cpp \
program/eaclock.cpp \
program/ebase.cpp \
program/edclock.cpp \
program/eenviron.cpp \
program/egif.cpp \
program/emultiwin.cpp \
program/ephoto.cpp \
program/etext.cpp \
program/etimer.cpp \
program/evideo.cpp \
program/eweb.cpp \
program/gentmpthread.cpp \
program/pageeditor.cpp \
program/pagelistitem.cpp \
program/progeditorwin.cpp \
program/progitem.cpp \
program/sendprogramdialog.cpp \
program/sendprogthread.cpp \
program/videosplitthread.cpp \
HEADERS += \
base/changepasswordform.h \
base/switchcontrol.h \
base/extendedgroupbox.h \
base/locolorselector.h \
base/lodateselector.h \
base/loqtitlebar.h \
base/loqtreewidget.h \
gutil/qwaitingdlg.h \
basedlg.h \
basewin.h \
cfg.h \
device/ctrlhdmipanel.h \
device/ctrlnetworkpanel.h \
device/ctrlpowerpanel.h \
device/ctrlpwdpanel.h \
device/ctrltestpanel.h \
device/ctrlvolumepanel.h \
deviceitem.h \
devicepanel.h \
ffplayer.h \
globaldefine.h \
gutil/cpp.h \
gutil/qgui.h \
gutil/qjson.h \
gutil/qnetwork.h \
mainwindow.h \
mguangyingpinwidget.h \
player/digiclock.h \
player/eleanaclock.h \
player/elebase.h \
player/eleborder.h \
player/elegif.h \
player/eleimg.h \
player/elemultipng.h \
player/elescroll.h \
player/eletimer.h \
player/elevideo.h \
player/playwin.h \
player/posdlg.h \
progpanel.h \
synctimer.h \
tools.h \
device/ctrladvancedpanel.h \
device/ctrlbrightpanel.h \
device/ctrlverifyclockpanel.h \
device/upgradeapkdialog.h \
program/copydirthread.h \
program/eaclock.h \
program/ebase.h \
program/edclock.h \
program/eenviron.h \
program/egif.h \
program/emultiwin.h \
program/ephoto.h \
program/etext.h \
program/etimer.h \
program/evideo.h \
program/eweb.h \
program/gentmpthread.h \
program/pageeditor.h \
program/pagelistitem.h \
program/progeditorwin.h \
program/progitem.h \
program/sendprogramdialog.h \
program/sendprogthread.h \
program/videosplitthread.h \
TRANSLATIONS += \
ts/app_zh_CN.ts \
ts/app_zh_TW.ts \
ts/app_en.ts \
ts/app_ja.ts \
ts/app_pt.ts
include(./xlsx/qtxlsx.pri)

View File

@ -53,16 +53,16 @@ ChangePasswordForm::ChangePasswordForm(QWidget *parent) : QDialog(parent) {
return;
}
QSettings settings;
auto pwdRaw = settings.value("advUiPs");
QString pwd = pwdRaw.isNull() ? "888" : QString::fromUtf8(QByteArray::fromBase64(pwdRaw.toString().toLatin1()));
QString pwdRaw = settings.value("advUiPs").toString();
QString pwd = pwdRaw.isEmpty() ? "888" : QString::fromUtf8(QByteArray::fromBase64(pwdRaw.toLatin1()));
if(pwd != pwdOld) {
QMessageBox::critical(this, tr("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"));
if(pwdNew.length() < 6) {
QMessageBox::warning(this, tr("Tip"), tr("Please enter a password with more than 6 characters"));
fdNew->setFocus();
return;
}

View File

@ -4,10 +4,7 @@
void LoQTreeWidget::addFd() {
fdCheckAll = new QCheckBox(this);
connect(fdCheckAll, &QCheckBox::stateChanged, this, [=](int state) {
if(state==Qt::PartiallyChecked) {
fdCheckAll->setCheckState(Qt::Checked);
return;
}
if(state==Qt::PartiallyChecked) return;
int cnt = topLevelItemCount();
for(int rr=0; rr<cnt; rr++) if(! topLevelItem(rr)->isHidden()) topLevelItem(rr)->setCheckState(1, (Qt::CheckState) state);
emit selChanged();

View File

@ -5,6 +5,6 @@
const QString UpdVerUrl = "https://www.ledok.cn/download/LedOK Express Updates.json";
QString programsDir() {
static auto rtn = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/programs";
static auto rtn = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) + "/" + QApplication::applicationName() + "/NPrograms";
return rtn;
}

View File

@ -1,6 +1,6 @@
#include "ctrladvancedpanel.h"
#include "globaldefine.h"
#include "gutil/qwaitingdlg.h"
#include "base/waitingdlg.h"
#include "base/changepasswordform.h"
#include "tools.h"
#include "gutil/qgui.h"
@ -30,14 +30,9 @@
CtrlAdvancedPanel::CtrlAdvancedPanel() {
setFocusPolicy(Qt::StrongFocus);
auto vBox = new VBox(this);
vBox->setContentsMargins(6,6,6,0);
auto vBox = new QVBoxLayout(this);
lbTitle = new QLabel;
auto ft = lbTitle->font();
ft.setPixelSize(16);
ft.setBold(true);
lbTitle->setFont(ft);
lbTitle->setAlignment(Qt::AlignCenter);
vBox->addWidget(lbTitle);
@ -124,7 +119,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
auto item = findItem(card.id);
if(item) {
item->mCard.alias = alias;
item->setText("alias", alias);
item->setText(DeviceTable_Remark, alias);
}
});
} else {
@ -137,7 +132,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
auto item = findItem(card.id);
if(item) {
item->mCard.alias = alias;
item->setText("alias", alias);
item->setText(DeviceTable_Remark, alias);
}
});
}
@ -177,10 +172,21 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
auto serverAddr = fdWebServerAddr->currentText();
QString serverAddr = fdWebServerAddr->currentText();
if(serverAddr.isEmpty()) {
QMessageBox::information(this, tr("Tip"),tr("InputWebServerAddressTip"));
fdWebServerAddr->setFocus();
return;
}
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?"));
// if(res != QMessageBox::Yes) return;
if(companyId.isEmpty()) {
QMessageBox::information(this, tr("Tip"),tr("InputCompanyIdTip"));
fdCompanyId->setFocus();
return;
}
auto res = QMessageBox::question(this, tr("Tip Info"), tr("Do you want to modify webserveraddress and companyId?"));
if(res != QMessageBox::Yes) return;
QJsonObject json;
json.insert("_id", "SetOnlineAddr");
json.insert("_type", "SetOnlineAddr");
@ -203,10 +209,12 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
hBox->addStretch();
hBox = new HBox(vBox);
hBox->addWidget(lbRealtime = new QLabel);
label = new QLabel;
hBox->addWidget(label);
fdRealtimeServer = new QComboBox;
fdRealtimeServer->addItem("www.ledokcloud.com/realtime");
fdRealtimeServer->addItem(tr("www.ledokcloud.com/realtime"));
fdRealtimeServer->setMinimumWidth(260);
fdRealtimeServer->setEditable(true);
hBox->addWidget(fdRealtimeServer);
@ -271,7 +279,8 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
btnWareUpdate->setMinimumSize(100, 30);
btnWareUpdate->setProperty("ssType", "progManageTool");
connect(btnWareUpdate, &QPushButton::clicked, this, [=] {
new UpgradeApkDialog(this);
UpgradeApkDialog dlg(this);
dlg.exec();
});
hBox->addWidget(btnWareUpdate);
@ -308,7 +317,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
infoDlg->setWindowTitle(tr("Software Version Info"));
auto vBox = new QVBoxLayout(infoDlg);
vBox->setContentsMargins(0, 0, 0, 0);
auto table = new TableWidget{
auto table = new Table{
{"apk", "Apk"},
{"ver", tr("Version")},
{"pkg", tr("Package")}
@ -478,7 +487,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
tcp->connectToHost(card.ip, 3333);
tcp->startTimer(10000);
} else {
for(auto &card : gSelCards) {
foreach(auto card, gSelCards) {
auto tcp = new TcpSocket;
auto cardId = card.id;
connect(tcp, &QTcpSocket::connected, tcp, [=] {
@ -599,211 +608,28 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
waitingDlg->show();
auto card = gSelCards[0];
auto reply = NetReq("http://"+card.ip+":2016/download?file=logs").timeout(120000).get();
ConnReply(reply, waitingDlg) [=] {
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
waitingDlg->close();
QString err = checkReply(reply);
if(! err.isEmpty()) {
QMessageBox::critical(this, tr("Error"), err);
return;
}
auto wgt = new QWidget(this, Qt::Window);
wgt->setAttribute(Qt::WA_DeleteOnClose);
wgt->resize(800, 800);
auto vv = new VBox(wgt);
vv->setContentsMargins(0,0,0,0);
auto fdLog = new QTextEdit;
fdLog->setPlainText(reply->readAll());
vv->addWidget(fdLog);
wgt->show();
wgt->raise();
wgt->activateWindow();
QString logFile = QApplication::applicationDirPath()+"/card-log.txt";
QFile file(logFile);
if(! file.open(QIODevice::WriteOnly)) {
QMessageBox::critical(this, tr("Error"), "Open for Write Fail");
return;
}
file.write(reply->readAll());
file.close();
QProcess::execute("notepad", {logFile});
});
}
});
hBox->addWidget(btnGetLog);
hBox->addStretch();
hBox = new HBox(vBox);
auto btnViewProg = new QPushButton("View Prog JSON");
btnViewProg->setProperty("ssType", "progManageTool");
connect(btnViewProg, &QPushButton::clicked, this, [this] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
JObj json{{"_type", "GetFile"}, {"name", "program"}};
auto fd = new QTextEdit;
fd->setAttribute(Qt::WA_DeleteOnClose);
fd->setTabStopDistance(26);
auto ft = fd->font();
ft.setFamily("Consolas");
fd->setFont(ft);
fd->setWindowTitle("program");
fd->resize(600, 900);
fd->show();
for(auto &card : gSelCards) {
auto tcp = new TcpSocket;
auto cardId = card.id;
connect(fd, &QTextEdit::destroyed, tcp, &QTcpSocket::deleteLater);
connect(tcp, &QTcpSocket::connected, tcp, [=] {
tcp->stopTimer();
tcp->write(JToBytes(json));
tcp->startTimer(10000);
});
connect(tcp, &QTcpSocket::readyRead, fd, [=] {
tcp->stopTimer();
auto resp = tcp->readAll();
tcp->close();
tcp->deleteLater();
fd->append(cardId+" Prog JSON");
fd->append(resp);
fd->append("");
});
connect(tcp, &QTcpSocket::errorOccurred, fd, [=](QAbstractSocket::SocketError err) {
tcp->close();
tcp->deleteLater();
fd->append(cardId+" View Prog JSON "+socketErrKey(err)+" ("+QString::number(err)+") "+tcp->errorString());
});
tcp->connectToHost(card.ip, 3333);
tcp->startTimer(10000);
}
});
hBox->addWidget(btnViewProg);
auto btnListFiles = new QPushButton("List Prog Files");
btnListFiles->setProperty("ssType", "progManageTool");
connect(btnListFiles, &QPushButton::clicked, this, [this] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
JObj json{{"_type", "ListProgFiles"}};
auto fd = new QTextEdit;
fd->setAttribute(Qt::WA_DeleteOnClose);
auto ft = fd->font();
ft.setFamily("Consolas");
fd->setFont(ft);
fd->setWindowTitle("List Prog Files");
fd->resize(600, 900);
fd->show();
for(auto &card : gSelCards) {
auto tcp = new TcpSocket;
auto cardId = card.id;
connect(fd, &QTextEdit::destroyed, tcp, &QTcpSocket::deleteLater);
connect(tcp, &QTcpSocket::connected, tcp, [=] {
tcp->stopTimer();
tcp->write(JToBytes(json));
tcp->startTimer(10000);
});
connect(tcp, &QTcpSocket::readyRead, fd, [=] {
tcp->stopTimer();
auto resp = tcp->readAll();
tcp->close();
tcp->deleteLater();
fd->append(cardId+" Prog Files");
fd->append(resp);
fd->append("");
});
connect(tcp, &QTcpSocket::errorOccurred, fd, [=](QAbstractSocket::SocketError err) {
tcp->close();
tcp->deleteLater();
fd->append(cardId+" List Prog Files "+socketErrKey(err)+" ("+QString::number(err)+") "+tcp->errorString());
});
tcp->connectToHost(card.ip, 3333);
tcp->startTimer(10000);
}
});
hBox->addWidget(btnListFiles);
auto btnGetPlayerInfo = new QPushButton("Get Player Info");
btnGetPlayerInfo->setProperty("ssType", "progManageTool");
connect(btnGetPlayerInfo, &QPushButton::clicked, this, [this] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
JObj json{{"_type", "GetInfo"}};
auto fd = new QTextEdit;
fd->setAttribute(Qt::WA_DeleteOnClose);
auto ft = fd->font();
ft.setFamily("Consolas");
fd->setFont(ft);
fd->setWindowTitle("Get Player Info");
fd->resize(600, 900);
fd->show();
for(auto &card : gSelCards) {
auto tcp = new TcpSocket;
auto cardId = card.id;
connect(fd, &QTextEdit::destroyed, tcp, &QTcpSocket::deleteLater);
connect(tcp, &QTcpSocket::connected, tcp, [=] {
tcp->stopTimer();
tcp->write(JToBytes(json));
tcp->startTimer(10000);
});
connect(tcp, &QTcpSocket::readyRead, fd, [=] {
tcp->stopTimer();
auto resp = tcp->readAll();
tcp->close();
tcp->deleteLater();
fd->append(cardId+" Player Info");
fd->append(resp);
fd->append("");
});
connect(tcp, &QTcpSocket::errorOccurred, fd, [=](QAbstractSocket::SocketError err) {
tcp->close();
tcp->deleteLater();
fd->append(cardId+" Get Player Info "+socketErrKey(err)+" ("+QString::number(err)+") "+tcp->errorString());
});
tcp->connectToHost(card.ip, 3333);
tcp->startTimer(10000);
}
});
hBox->addWidget(btnGetPlayerInfo);
auto GetBuf = new QPushButton("Get Player Log");
GetBuf->setProperty("ssType", "progManageTool");
connect(GetBuf, &QPushButton::clicked, this, [this] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
JObj json{{"_type", "GetLog"}};
auto fd = new QTextEdit;
fd->setAttribute(Qt::WA_DeleteOnClose);
auto ft = fd->font();
ft.setFamily("Consolas");
fd->setFont(ft);
fd->setWindowTitle("Get Player Log");
fd->resize(600, 900);
fd->show();
for(auto &card : gSelCards) {
auto tcp = new TcpSocket;
auto cardId = card.id;
connect(fd, &QTextEdit::destroyed, tcp, &QTcpSocket::deleteLater);
connect(tcp, &QTcpSocket::connected, tcp, [=] {
tcp->stopTimer();
tcp->write(JToBytes(json));
tcp->startTimer(5000);
});
connect(tcp, &QTcpSocket::readyRead, fd, [=] {
tcp->stopTimer();
auto resp = tcp->readAll();
if(fd->document()->isEmpty()) fd->append(cardId+" Player Log");
fd->append(resp);
});
connect(tcp, &QTcpSocket::errorOccurred, fd, [=](QAbstractSocket::SocketError err) {
tcp->close();
tcp->deleteLater();
if(fd->document()->isEmpty() || err!=QAbstractSocket::SocketTimeoutError) fd->append(cardId+" Get Player Log "+socketErrKey(err)+" ("+QString::number(err)+") "+tcp->errorString());
});
tcp->connectToHost(card.ip, 3333);
tcp->startTimer(8000);
}
});
hBox->addWidget(GetBuf);
hBox->addStretch();
hBox = new HBox(vBox);
hBox->addWidget(lbTimingReboot = new QLabel);
@ -877,8 +703,8 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
auto hBox = new HBox(grpY50);
auto fdY50Resolu = new QComboBox;
auto params = QDir(QApplication::applicationDirPath()+"/rk_lcd_parameters").entryList(QDir::Files);
for(auto &param : params) fdY50Resolu->addItem(param);
auto dirs = QDir(QApplication::applicationDirPath()+"/y50 param").entryList(QDir::Dirs | QDir::NoDotAndDotDot);
foreach(auto dir, dirs) fdY50Resolu->addItem(dir);
fdY50Resolu->setMinimumWidth(160);
hBox->addWidget(fdY50Resolu);
@ -889,14 +715,14 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
auto file = QApplication::applicationDirPath()+"/rk_lcd_parameters/"+fdY50Resolu->currentText();
QFile qFile(file);
auto filePath = QApplication::applicationDirPath()+"/y50 param/"+fdY50Resolu->currentText()+"/rk_lcd_parameters";
QFile qFile(filePath);
if(! qFile.exists()) {
QMessageBox::information(this, tr("Tip"), tr("File not exist"));
return;
}
if(! qFile.open(QIODevice::ReadOnly)) {
QMessageBox::information(this, tr("Tip"), tr("Cannot Open File")+": "+qFile.errorString()+"\n"+file);
QMessageBox::information(this, tr("Tip"), tr("Cannot Open File")+": "+qFile.errorString()+"\n"+filePath);
return;
}
auto fileData = qFile.readAll();
@ -912,7 +738,8 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
waitingDlg->show();
NetReq req("http://"+gSelCards[0].ip+":2016/upload?type=update_display");
auto reply = req.timeout(120000).type("multipart/form-data; boundary="+Boundary).post(data);
ConnReply(reply, waitingDlg) [=] {
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
QString err = checkReply(reply);
if(! err.isEmpty()) {
waitingDlg->close();
@ -990,7 +817,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
connect(reply, &QNetworkReply::finished, this, [=] {
Def_CtrlSingleGetReply
waitingDlg->success();
SetCurData(fdDisMode, json["result"].toInt());
setCurrentData(fdDisMode, json["result"].toInt());
});
} else {
foreach(auto card, gSelCards) {
@ -1097,66 +924,11 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
btnLedSet->setProperty("ssType", "progManageTool");
connect(btnLedSet, &QPushButton::clicked, btnLedSet, [] {
QFileInfo file("LedSet4.0/LedSet4.0.exe");
if(file.exists()) QProcess::startDetached(file.absoluteFilePath(), QStringList(), file.absolutePath());
if(file.exists()) QProcess::startDetached(file.absoluteFilePath(), QStringList());
});
hBox->addWidget(btnLedSet);
hBox->addStretch();
hBox = new HBox(vBox);
btnReceCardsGet = new QPushButton;
btnReceCardsGet->setProperty("ssType", "progManageTool");
connect(btnReceCardsGet, &QPushButton::clicked, this, [=] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
QJsonObject json;
json.insert("_id", "GetReceCards");
json.insert("_type", "GetReceCards");
if(gSelCards.count() == 1) {
auto waitingDlg = new WaitingDlg(this, btnReceCardsGet->text() + " ...");
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, this, [=] {
Def_CtrlSingleGetReply
waitingDlg->close();
QMessageBox::information(this, btnReceCardsGet->text(), QString::number(json["receCardNum"].toInt()));
});
} else {
foreach(auto card, gSelCards) {
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
auto cardId = card.id;
connect(reply, &QNetworkReply::finished, this, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(err.isEmpty()) err = QString::number(json["receCardNum"].toInt());
gFdResInfo->append(cardId+" "+btnReceCardsGet->text()+" "+err);
});
}
}
});
hBox->addWidget(btnReceCardsGet);
// auto btnTool = new QPushButton("本地监控");
// btnTool->setMinimumHeight(30);
// btnTool->setProperty("ssType", "progManageTool");
// connect(btnTool, &QPushButton::clicked, btnTool, [] {
// QFileInfo file("EasyTool/EasyTool.exe");
// if(file.exists()) QProcess::startDetached(file.absoluteFilePath(), QStringList(), file.absolutePath());
// });
// hBox->addWidget(btnTool);
// auto btnVMS = new QPushButton("平台监控");
// btnVMS->setMinimumHeight(30);
// btnVMS->setProperty("ssType", "progManageTool");
// connect(btnVMS, &QPushButton::clicked, btnVMS, [] {
// QFileInfo file("EasyVMS/EasyVMS.exe");
// if(file.exists()) QProcess::startDetached(file.absoluteFilePath(), QStringList(), file.absolutePath());
// });
// hBox->addWidget(btnVMS);
hBox->addStretch();
#ifndef Q_OS_WIN
btnLedSet->setVisible(false);
#endif
@ -1201,7 +973,8 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
auto waitingDlg = new WaitingDlg(this, tr("InvokeTaxiAppFunction"));
waitingDlg->show();
auto reply = NetReq("http://"+gSelCards[0].ip+":3000").timeout(120000).post(json);
ConnReply(reply, waitingDlg) [=] {
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
QString err = checkReply(reply);
if(! err.isEmpty()) {
waitingDlg->close();
@ -1585,7 +1358,8 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
waitingDlg->show();
NetReq req("http://"+gSelCards[0].ip+":2016/upload?type=mcu_update");
auto reply = req.timeout(120000).type("multipart/form-data; boundary="+Boundary).post(data);
ConnReply(reply, waitingDlg) [=] {
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
QString err = checkReply(reply);
if(! err.isEmpty()) {
waitingDlg->close();
@ -1649,7 +1423,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
auto file = QFileDialog::getOpenFileName(this, tr("Select File"), gFileHome, EPhoto::filters());
QString file = QFileDialog::getOpenFileName(this, tr("Select File"), gFileHome, EPhoto::filters());
if(file.isEmpty()) return;
QFileInfo info(file);
if(! info.isFile()) return;
@ -1786,19 +1560,6 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
fdM80Resolu = new QComboBox;
fdM80Resolu->setMinimumWidth(160);
fdM80Resolu->addItem("480x4096", "550x4500");
fdM80Resolu->addItem("576x3840", "625x3960");
fdM80Resolu->addItem("720x3200", "750x3300");
fdM80Resolu->addItem("864x2672", "900x2750");
fdM80Resolu->addItem("1080x1920", "1125x2200");
fdM80Resolu->addItem("1280x1760", "1320x1850");
fdM80Resolu->addItem("1472x1536", "1500x1650");
fdM80Resolu->addItem("1536x1472", "1650x1500");
fdM80Resolu->addItem("1920x1080", "2200x1125");
fdM80Resolu->addItem("2672x864", "2750x900");
fdM80Resolu->addItem("3200x720", "3300x750");
fdM80Resolu->addItem("3840x576", "3960x625");
fdM80Resolu->addItem("4096x480", "4500x550");
hBox->addWidget(fdM80Resolu);
btnM80Set = new QPushButton();
@ -1892,7 +1653,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
lbRotate = new QLabel;
hBox->addWidget(lbRotate);
hBox->addSpacing(12);
hBox->addSpacing(20);
auto fdDeg0 = new QRadioButton("");
hBox->addWidget(fdDeg0);
@ -1974,42 +1735,6 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
hBox->addStretch();
hBox = new HBox(vBox);
lbChargingStation = new QLabel(tr("Charging Station")+" ID:");
hBox->addWidget(lbChargingStation);
auto fdChargingStation = new QLineEdit;
fdChargingStation->setMaximumWidth(120);
hBox->addWidget(fdChargingStation);
btnChargingStationSet = new QPushButton;
btnChargingStationSet->setProperty("ssType", "progManageTool");
connect(btnChargingStationSet, &QPushButton::clicked, this, [=] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
QJsonObject json;
json.insert("_id", "SetChargingStationID");
json.insert("_type", "SetChargingStationID");
json.insert("number", fdChargingStation->text());
if(gSelCards.count() == 1) {
auto waitingDlg = new WaitingDlg(this, tr("Setting ")+tr("Charging Station")+" ID ...");
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, this, [=] {
Def_CtrlSetReqAfter
});
} else {
foreach(auto card, gSelCards) {
Def_CtrlSetMulti(tr("Set")+" "+tr("Charging Station")+" ID")
}
}
});
hBox->addWidget(btnChargingStationSet);
hBox->addStretch();
hBox = new HBox(vBox);
lbBaudCfg = new QLabel;
@ -2207,54 +1932,10 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
});
hBox->addWidget(btnSendCustomJson);
btnCustomJsonGet = new QPushButton;
btnCustomJsonGet->setProperty("ssType", "progManageTool");
connect(btnCustomJsonGet, &QPushButton::clicked, this, [=] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
auto text = fdCustomJson->toPlainText().toUtf8();
if(text.isEmpty()) {
QMessageBox::information(this, tr("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);
return;
}
if(! json.isObj()) {
QMessageBox::information(this, tr("Tip"), tr("Json isn't an Object"));
return;
}
if(gSelCards.count() == 1) {
auto waitingDlg = new WaitingDlg(this, "Custom Json Getting ...");
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, this, [=] {
waitingDlg->close();
auto err = errStrWithData(reply);
if(! err.isEmpty()) QMessageBox::critical(this, tr("Error"), err);
else QMessageBox::information(this, tr("Info"), reply->readAll());
});
} else {
foreach(auto card, gSelCards) {
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, gFdResInfo, [=] {
auto err = errStrWithData(reply);
gFdResInfo->append(card.id+" Custom Json Get "+(err.isEmpty()?reply->readAll():err));
});
}
}
});
hBox->addWidget(btnCustomJsonGet);
hBox->addStretch();
fdCustomJson = new QTextEdit;
fdCustomJson->setMinimumHeight(120);
fdCustomJson->setPlainText("{\"_id\":\"0\",\"_type\":\"\"}");
vBox->addWidget(fdCustomJson);
@ -2311,7 +1992,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
connect(reply, &QNetworkReply::finished, this, [=] {
Def_CtrlSingleGetReply
waitingDlg->success();
SetCurData(fdTraficProtocol, json["protocolType"].toInt());
setCurrentData(fdTraficProtocol, json["protocolType"].toInt());
});
} else {
foreach(auto card, gSelCards) {
@ -2398,7 +2079,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
connect(reply, &QNetworkReply::finished, this, [=] {
Def_CtrlSingleGetReply
waitingDlg->success();
SetCurData(fdServerType, json["serverType"].toInt());
setCurrentData(fdServerType, json["serverType"].toInt());
fdPort->setValue(json["port"].toInt());
});
} else {
@ -2425,31 +2106,8 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
hBox->addStretch();
}
vBox->addWidget(grpBoxHiddenSettings);
hBox = new HBox(vBox);
auto btn = new QPushButton("List Card Infos");
btn->setProperty("ssType", "progManageTool");
connect(btn, &QPushButton::clicked, this, [this] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
auto fd = new QTextEdit;
fd->setAttribute(Qt::WA_DeleteOnClose);
auto ft = fd->font();
ft.setFamily("Consolas");
fd->setFont(ft);
fd->setWindowTitle("List Card Infos");
fd->resize(600, 900);
fd->show();
for(auto &card : gSelCards) fd->append(card.id+", "+card.ip+", "+QString::number(card.mWidth)+" x "+QString::number(card.mHeight)+", "+card.alias+", "+QString::number(card.bright)+"%, "+(card.isScreenOn?"On":"Off"));
});
hBox->addWidget(btn);
hBox->addStretch();
vBox->addStretch();
if(QSettings().value("advUiPs", "888").toString().isEmpty()) isPassed = true;
connect(gDevicePanel, &DevicePanel::sigSelectedDeviceList, this, [this] {
if(isVisible()) init();
});
@ -2492,8 +2150,8 @@ void CtrlAdvancedPanel::init() {
vBox->addWidget(btnBox);
connect(btnBox, &QDialogButtonBox::accepted, &dlg, [=, &dlg] {
auto pwdVar = QSettings().value("advUiPs");
auto password = pwdVar.isNull() ? "888" : QString::fromUtf8(QByteArray::fromBase64(pwdVar.toString().toLatin1()));
QString pwdRaw = QSettings().value("advUiPs").toString();
QString password = pwdRaw.isEmpty() ? "888" : QString::fromUtf8(QByteArray::fromBase64(pwdRaw.toLatin1()));
if(fdPassword->text() == password) dlg.accept();
else QMessageBox::critical(&dlg, tr("Tip"),tr("Password is error"));
});
@ -2505,6 +2163,7 @@ void CtrlAdvancedPanel::init() {
bool isSingle = gSelCards.count()==1;
btnApkCheck->setEnabled(isSingle);
btnRestart->setEnabled(isSingle);
btnGetLog->setEnabled(isSingle);
if(! isSingle) {
@ -2519,36 +2178,33 @@ void CtrlAdvancedPanel::init() {
auto isM80 = card.id.startsWith("M8", Qt::CaseInsensitive);
grpM80->setVisible(isM80);
// if(isM80) {
// QJsonObject json;
// json.insert("_id", "GetAllScreenSizeM80");
// json.insert("_type", "GetAllScreenSizeM80");
// auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json);
// connect(reply, &QNetworkReply::finished, this, [this, reply] {
// QJsonDocument json;
// QString err = checkReplyForJson(reply, &json);
// if(! err.isEmpty()) return;
// auto sizes = json["result"].toObject();
// fdM80Resolu->clear();
// auto send = sizes.constEnd();
// for(auto size=sizes.constBegin(); size<send; size++) fdM80Resolu->addItem(size.key(), size.value().toString());
// });
// }
if(isM80) {
QJsonObject json;
json.insert("_id", "GetAllScreenSizeM80");
json.insert("_type", "GetAllScreenSizeM80");
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, this, [this, reply] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
auto sizes = json["result"].toObject();
fdM80Resolu->clear();
auto send = sizes.constEnd();
for(auto size=sizes.constBegin(); size<send; size++) fdM80Resolu->addItem(size.key(), size.value().toString());
});
}
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("m7s", Qt::CaseInsensitive)
|| card.id.startsWith("y1", Qt::CaseInsensitive)
|| card.id.startsWith("y4", Qt::CaseInsensitive)
|| card.id.startsWith("y5", Qt::CaseInsensitive);
|| card.id.startsWith("m5s", Qt::CaseInsensitive)
|| card.id.startsWith("m6s", Qt::CaseInsensitive)
|| card.id.startsWith("m7s", Qt::CaseInsensitive)
|| card.id.startsWith("y5", Qt::CaseInsensitive);
grpY50->setVisible(isY50);
QJsonObject json;
json.insert("_id", "GetOnlineAddr");
json.insert("_type", "GetOnlineAddr");
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json);
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);
@ -2560,10 +2216,10 @@ void CtrlAdvancedPanel::init() {
json = QJsonObject();
json.insert("_id", "GetRealtimeServer");
json.insert("_type", "GetRealtimeServer");
reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json);
reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, this, [this, reply] {
QJsonDocument json;
auto err = checkReplyForJson(reply, &json);
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
fdRealtimeServer->setCurrentText(json["server"].toString());
});
@ -2576,7 +2232,6 @@ void CtrlAdvancedPanel::transUi() {
btnBindTaxiIc->setText(tr("Binding *.ic account indentity voucher"));
btnGetTopLevel->setText(tr("Readback"));
btnLedSet->setText(tr("Start LedSet4"));
btnReceCardsGet->setText(tr("Get Receive Card Num"));
grpM80->setTitle("M80 "+tr("Config"));
btnM80Refresh->setText(tr("Refresh"));
@ -2607,7 +2262,6 @@ void CtrlAdvancedPanel::transUi() {
lbRotate->setText(tr("Rotate"));
btnRotateSet->setText(tr("Set"));
btnRotateGet->setText(tr("Get"));
btnChargingStationSet->setText(tr("Set"));
grpBoxHiddenSettings->setTitle(tr("Hidden Settings")+" ("+tr("Click right button to hide")+")");
btnSysUpd->setText(tr("System Update"));
@ -2622,10 +2276,9 @@ void CtrlAdvancedPanel::transUi() {
fdIsOpenADB->setText(tr("Open ADB"));
lbCustomJson->setText(tr("Post Custom JSON"));
btnSendCustomJson->setText(tr("Send"));
btnCustomJsonGet->setText(tr("Get"));
grpHighForBusy->setTitle(tr("Taxi top screen configuration"));
lbRealtime->setText(tr("Realtime Address:"));
label->setText(tr("Realtimer Server Address:"));
lbTitle->setText(tr("Advanced"));
lbCompanyId->setText(tr("Compant ID:"));
labelWebServer->setText(tr("Web Server Address:"));
@ -2715,11 +2368,22 @@ void PlayerBackSendThread::run() {
auto remain = info.size();
auto req = QJsonObject();
req.insert("_type", "proStart");
req.insert("proName", "program");
req.insert("proSize", remain);
req.insert("zVer","xixun1");
auto resNum = tcp.write(QJsonDocument(req).toJson(QJsonDocument::Compact));
if(resNum == -1 || ! tcp.waitForBytesWritten()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when write 'proStart'");
tcp.close();
return;
}
req = QJsonObject();
req.insert("_type", "imgFileStart");
req.insert("id", baseName);
req.insert("size", remain);
req.insert("zVer","xixun1");
auto resNum = tcp.write(QJsonDocument(req).toJson(QJsonDocument::Compact));
resNum = tcp.write(QJsonDocument(req).toJson(QJsonDocument::Compact));
if(resNum == -1 || ! tcp.waitForBytesWritten()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when write 'imgFileStart'");
tcp.close();
@ -2761,18 +2425,28 @@ void PlayerBackSendThread::run() {
req.insert("zVer","xixun1");
resNum = tcp.write(QJsonDocument(req).toJson(QJsonDocument::Compact));
if(resNum == -1 || ! tcp.waitForBytesWritten()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when write 'imgFileEnd'");
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when write 'fileEnd'");
tcp.close();
return;
}
req = QJsonObject();
req.insert("_type", "proEnd");
req.insert("proName", "program");
req.insert("zVer","xixun1");
resNum = tcp.write(QJsonDocument(req).toJson(QJsonDocument::Compact));
if(resNum == -1 || ! tcp.waitForBytesWritten()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when write 'proEnd'");
tcp.close();
return;
};
if(! tcp.waitForReadyRead()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when waitForRead 'imgFileEnd'");
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when waitForRead 'proEnd'");
tcp.close();
return;
}
auto resp = tcp.readAll();
if(resp.isEmpty()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when read 'imgFileEnd'");
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when read 'proEnd'");
tcp.close();
return;
}

View File

@ -43,7 +43,7 @@ private:
QLabel *lbCompanyId;
QLineEdit *fdCompanyId;
QPushButton *btnWebServerSet;
QLabel *lbRealtime;
QLabel *label;
QComboBox *fdRealtimeServer;
QPushButton *btnRealtimeServerSet;
QPushButton *btnRealtimeClear;
@ -78,7 +78,7 @@ private:
QPushButton *btnHighForBusySet;
QPushButton *btnGetTopLevel;
QPushButton *btnLedSet;
QPushButton *btnReceCardsGet, *btnBindTaxiIc;
QPushButton *btnBindTaxiIc;
QGroupBox *grpMinMaxBrightness;
QLabel *lbMinBright;
@ -92,13 +92,13 @@ private:
QGroupBox *grpBoxHiddenSettings;
QPushButton *btnSysUpd, *btnMcuUpd, *btnMcuGet;
QPushButton *btnRotateSet, *btnRotateGet, *btnChargingStationSet;
QLabel *lbRotate, *lbChargingStation, *lbBaudCfg, *lbBaudModel, *lbUart, *lbBaud;
QPushButton *btnRotateSet, *btnRotateGet;
QLabel *lbRotate, *lbBaudCfg, *lbBaudModel, *lbUart, *lbBaud;
QPushButton *btnBaudSet, *btnBaudGet;
QCheckBox *fdIsOpenADB;
QLabel *lbCustomJson;
QTextEdit *fdCustomJson;
QPushButton *btnSendCustomJson, *btnCustomJsonGet;
QPushButton *btnSendCustomJson;
QLabel *lbTraficProtocol, *lbCardMode, *lbTraficPort;
QComboBox *fdServerType;

View File

@ -1,5 +1,5 @@
#include "ctrlbrightpanel.h"
#include "gutil/qwaitingdlg.h"
#include "base/waitingdlg.h"
#include "gutil/qnetwork.h"
#include "globaldefine.h"
#include "tools.h"
@ -17,15 +17,16 @@
CtrlBrightPanel::CtrlBrightPanel() {
auto vBox = new VBox(this);
vBox->setContentsMargins(6,6,6,0);
vBox->setContentsMargins(0,0,0,0);
vBox->addSpacing(8);
lbTitle = new QLabel;
auto ft = lbTitle->font();
ft.setPixelSize(16);
ft.setBold(true);
lbTitle->setFont(ft);
lbTitle->setAlignment(Qt::AlignCenter);
vBox->addWidget(lbTitle);
lbBrightCfg = new QLabel;
auto font = lbBrightCfg->font();
font.setPixelSize(font.pixelSize()+2);
font.setBold(true);
lbBrightCfg->setFont(font);
lbBrightCfg->setAlignment(Qt::AlignCenter);
vBox->addWidget(lbBrightCfg);
vBox->addSpacing(9);
auto hBox = new HBox(vBox);
@ -527,7 +528,7 @@ CtrlBrightPanel::CtrlBrightPanel() {
auto item = findItem(card.id);
if(item) {
item->mCard.bright = bright;
item->setText("brightness", QString::number(bright)+"%");
item->setData(DeviceTable_Brightness, 0, QString::number(bright)+"%");
}
});
} else {
@ -543,7 +544,7 @@ CtrlBrightPanel::CtrlBrightPanel() {
auto item = findItem(card.id);
if(item) {
item->mCard.bright = bright;
item->setText("brightness", err);
item->setData(DeviceTable_Brightness, 0, err);
}
}
gFdResInfo->append(card.id+" "+tr("Brightness")+" "+err);
@ -617,6 +618,7 @@ CtrlBrightPanel::CtrlBrightPanel() {
btnScheClear = new QPushButton;
btnScheClear->setMinimumSize(60, 30);
btnScheClear->setProperty("ssType", "progManageTool");
connect(btnScheClear, &QPushButton::clicked, this, [this] {tableSche->setRowCount(0);});
hBox->addWidget(btnScheClear);
hBox->addStretch();
@ -717,17 +719,15 @@ CtrlBrightPanel::CtrlBrightPanel() {
hBox->addWidget(btnScheExport);
tableSche = new TableWidget{
tableSche = new Table({
{"bright", "", 300},
{"start", "", 100},
{"end", "", 100}
};
});
tableSche->setDefs();
tableSche->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
vBox->addWidget(tableSche);
connect(btnScheClear, &QPushButton::clicked, tableSche, &TableWidget::clearRows);
hBox = new HBox(vBox);
hBox->addStretch();
@ -866,7 +866,7 @@ void CtrlBrightPanel::changeEvent(QEvent *event) {
if(event->type() == QEvent::LanguageChange) transUi();
}
void CtrlBrightPanel::transUi() {
lbTitle->setText(tr("Brightness Config"));
lbBrightCfg->setText(tr("Brightness Configuration"));
radioAuto->setText(tr("Auto"));
radioManual->setText(tr("Manual"));
radioSchedule->setText(tr("Schedule"));

View File

@ -20,7 +20,7 @@ protected:
private:
bool restoreScheduleJson(QJsonDocument &, int);
void getScheduleJson(QJsonObject &, int);
QLabel *lbTitle;
QLabel *lbBrightCfg;
QRadioButton *radioAuto;
QRadioButton *radioManual;
QRadioButton *radioSchedule;
@ -59,7 +59,7 @@ private:
QSlider *fdDefBright;
QPushButton *btnScheImport;
QPushButton *btnScheExport;
TableWidget *tableSche;
Table *tableSche;
QPushButton *btnScheSet;
QPushButton *btnScheGet;
};

View File

@ -3,7 +3,7 @@
#include "gutil/qnetwork.h"
#include "tools.h"
#include "globaldefine.h"
#include "gutil/qwaitingdlg.h"
#include "base/waitingdlg.h"
#include <QMessageBox>
#include <QButtonGroup>
#include <QTimeEdit>
@ -13,18 +13,16 @@
CtrlHdmiPanel::CtrlHdmiPanel() {
auto vBox = new QVBoxLayout(this);
vBox->setContentsMargins(6,6,6,0);
lbHdmiCfg = new QLabel;
auto ft = lbHdmiCfg->font();
ft.setPixelSize(16);
ft.setBold(true);
lbHdmiCfg->setFont(ft);
lbHdmiCfg->setAlignment(Qt::AlignCenter);
vBox->addWidget(lbHdmiCfg);
vBox->addSpacing(9);
auto hBox = new HBox(vBox);
auto line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
vBox->addWidget(line);
auto hBox = new QHBoxLayout();
hBox->addStretch();
fdManual = new QRadioButton;
@ -35,6 +33,8 @@ CtrlHdmiPanel::CtrlHdmiPanel() {
hBox->addWidget(fdSchedule);
hBox->addStretch();
vBox->addLayout(hBox);
auto stacked = new QStackedLayout(vBox);
{
auto vBox = new VBox(stacked);
@ -150,7 +150,7 @@ CtrlHdmiPanel::CtrlHdmiPanel() {
auto hBox = new HBox(vBox);
hBox->setSpacing(10);
tableSche = new TableWidget{
tableSche = new Table({
{"start", "", 100},
{"end", "", 100},
{"0", "", 60},
@ -160,8 +160,9 @@ CtrlHdmiPanel::CtrlHdmiPanel() {
{"4", "", 60},
{"5", "", 60},
{"6", "", 60}
};
});
tableSche->setDefs();
tableSche->setStyleSheet("Table {selection-background-color: #8ce;}");
btnScheAdd = new QPushButton;
btnScheAdd->setMinimumSize(QSize(60, 30));
@ -198,7 +199,7 @@ CtrlHdmiPanel::CtrlHdmiPanel() {
btnScheClear = new QPushButton;
btnScheClear->setMinimumSize(QSize(60, 30));
btnScheClear->setProperty("ssType", "progManageTool");
connect(btnScheClear, &QPushButton::clicked, tableSche, &TableWidget::clearRows);
connect(btnScheClear, &QPushButton::clicked, tableSche, &Table::clearRows);
hBox->addWidget(btnScheClear);
hBox->addStretch();

View File

@ -23,7 +23,7 @@ private:
QRadioButton *fdManual, *fdSchedule, *fdAsync, *fdHdmi, *fdHdmi2;
QPushButton *btnSyncSet, *btnSyncGet;
TableWidget *tableSche;
Table *tableSche;
QPushButton *btnScheAdd;
QPushButton *btnScheDel;
QPushButton *btnScheClear;

View File

@ -1,5 +1,5 @@
#include "ctrlnetworkpanel.h"
#include "gutil/qwaitingdlg.h"
#include "base/waitingdlg.h"
#include "globaldefine.h"
#include "tools.h"
#include "devicepanel.h"
@ -346,7 +346,7 @@ CtrlNetworkPanel::CtrlNetworkPanel() {
if(gSelCards.count() == 1) {
auto waitingDlg = new WaitingDlg(this, tr("ConfigurationWiFi")+" ...");
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, waitingDlg, [=] {
connect(reply, &QNetworkReply::finished, this, [=] {
QString err = checkReplyForJson(reply);
if(! err.isEmpty()) {
waitingDlg->close();
@ -354,7 +354,8 @@ CtrlNetworkPanel::CtrlNetworkPanel() {
return;
}
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json2);
ConnReply(reply, waitingDlg) [=] {
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
Def_CtrlSetReqAfter
});
});

View File

@ -2,7 +2,7 @@
#include "globaldefine.h"
#include "deviceitem.h"
#include "devicepanel.h"
#include "gutil/qwaitingdlg.h"
#include "base/waitingdlg.h"
#include "gutil/qnetwork.h"
#include "tools.h"
#include <QMessageBox>
@ -12,16 +12,10 @@
CtrlPowerPanel::CtrlPowerPanel() {
auto vBox = new VBox(this);
vBox->setContentsMargins(6,6,6,0);
lbScreenCfg = new QLabel;
auto ft = lbScreenCfg->font();
ft.setPixelSize(16);
ft.setBold(true);
lbScreenCfg->setFont(ft);
lbScreenCfg->setAlignment(Qt::AlignCenter);
vBox->addWidget(lbScreenCfg);
vBox->addSpacing(9);
auto hBox = new HBox(vBox);
hBox->addStretch();
@ -98,8 +92,8 @@ CtrlPowerPanel::CtrlPowerPanel() {
auto item = findItem(card.id);
if(item) {
item->mCard.isScreenOn = json["on"].toBool();
item->setForeground("power", item->mCard.isScreenOn ? Qt::green : Qt::red);
item->setText("power", item->mCard.isScreenOn ? tr("On") : tr("Off"));
item->setForeground(DeviceTable_Power, item->mCard.isScreenOn ? Qt::green : Qt::red);
item->setData(DeviceTable_Power, 0, item->mCard.isScreenOn ? tr("On") : tr("Off"));
}
});
} else {
@ -113,8 +107,8 @@ CtrlPowerPanel::CtrlPowerPanel() {
auto item = findItem(card.id);
if(item) {
item->mCard.isScreenOn = json["on"].toBool();
item->setForeground("power", item->mCard.isScreenOn ? Qt::green : Qt::red);
item->setText("power", err);
item->setForeground(DeviceTable_Power, item->mCard.isScreenOn ? Qt::green : Qt::red);
item->setData(DeviceTable_Power, 0, err);
}
}
gFdResInfo->append(card.id+" "+tr("IsScreenOn")+" "+err);
@ -130,7 +124,7 @@ CtrlPowerPanel::CtrlPowerPanel() {
auto hBox = new HBox(vBox);
hBox->setSpacing(10);
tableSche = new TableWidget{
tableSche = new Table({
{"start", "", 100},
{"end", "", 100},
{"0", "", 60},
@ -140,7 +134,7 @@ CtrlPowerPanel::CtrlPowerPanel() {
{"4", "", 60},
{"5", "", 60},
{"6", "", 60}
};
});
tableSche->setDefs();
pushButtonAdd = new QPushButton;
@ -178,7 +172,7 @@ CtrlPowerPanel::CtrlPowerPanel() {
pushButtonClear = new QPushButton;
pushButtonClear->setMinimumSize(QSize(60, 30));
pushButtonClear->setProperty("ssType", "progManageTool");
connect(pushButtonClear, &QPushButton::clicked, tableSche, &TableWidget::clearRows);
connect(pushButtonClear, &QPushButton::clicked, tableSche, &Table::clearRows);
hBox->addWidget(pushButtonClear);
hBox->addStretch();

View File

@ -34,7 +34,7 @@ private:
QPushButton *pushButtonImport;
QPushButton *pushButtonExport;
QLabel *labelPowerScheduleTip;
TableWidget *tableSche;
Table *tableSche;
QPushButton *pushButtonApply;
QPushButton *pushButtonClearSchedule;
QPushButton *pushButtonReadback;

View File

@ -1,7 +1,7 @@
#include "ctrlpwdpanel.h"
#include "gutil/qgui.h"
#include "gutil/qnetwork.h"
#include "gutil/qwaitingdlg.h"
#include "base/waitingdlg.h"
#include "QFileDialog"
#include <QMessageBox>
#include <QJsonObject>
@ -12,13 +12,7 @@
CtrlPwdPanel::CtrlPwdPanel() {
auto vBox = new VBox(this);
vBox->setContentsMargins(6,6,6,0);
lbPwdConfig = new QLabel;
auto font = lbPwdConfig->font();
font.setPixelSize(16);
font.setBold(true);
lbPwdConfig->setFont(font);
lbPwdConfig->setAlignment(Qt::AlignCenter);
vBox->addWidget(lbPwdConfig);
vBox->addSpacing(20);

View File

@ -2,7 +2,7 @@
#include "tools.h"
#include "gutil/qgui.h"
#include "gutil/qnetwork.h"
#include "gutil/qwaitingdlg.h"
#include "base/waitingdlg.h"
#include <QFileDialog>
#include <QLineEdit>
#include <QJsonObject>
@ -177,9 +177,9 @@ CtrlTestPanel::CtrlTestPanel() {
hhh = new HBox(vv);
hhh->addStretch();
btnStopTest = new QPushButton;
btnStopTest->setMinimumSize(QSize(60, 30));
hhh->addWidget(btnStopTest);
pushButtonStopTest = new QPushButton;
pushButtonStopTest->setMinimumSize(QSize(60, 30));
hhh->addWidget(pushButtonStopTest);
hhh->addStretch();
vv->addStretch();
@ -192,12 +192,14 @@ CtrlTestPanel::CtrlTestPanel() {
vv = new VBox(hBox);
fdAnycast = new QLineEdit;
fdAnycast->setValidator(new QIntValidator(0, 100, this));
fdAnycast->setMinimumHeight(36);
fdAnycast->setStyleSheet("color: #0f0; background: #000;");
fdAnycast->setAlignment(Qt::AlignCenter);
vv->addWidget(fdAnycast);
lineEdit = new QLineEdit;
lineEdit->setMinimumSize(QSize(0, 36));
lineEdit->setMaximumSize(QSize(194, 16777215));
lineEdit->setAutoFillBackground(false);
lineEdit->setStyleSheet(QString::fromUtf8("color: rgb(0, 255, 0);\n"
"background-color: rgb(0, 0, 0);"));
lineEdit->setAlignment(Qt::AlignCenter);
vv->addWidget(lineEdit);
auto gridLayout = new Grid(vv);
@ -219,47 +221,20 @@ CtrlTestPanel::CtrlTestPanel() {
gridLayout->addWidget(btngrp->button(9), 2, 2);
gridLayout->addWidget(btngrp->button(0), 3, 0);
connect(btngrp, &QButtonGroup::idClicked, this, [=](int id) {
if(fdAnycast->text().contains("-")) fdAnycast->clear();
fdAnycast->setText(fdAnycast->text() + QString::number(id));
if(lineEdit->text().contains("-")) lineEdit->clear();
lineEdit->setText(lineEdit->text() + QString::number(id));
btnAnycast->setEnabled(true);
});
btnAnycastClear = new QPushButton;
btnAnycastClear->setFixedSize(60, 30);
btnAnycastClear->setProperty("ssType", "progManageTool");
connect(btnAnycastClear, &QPushButton::clicked, this, [=] {
fdAnycast->clear();
btnAnycast->setEnabled(false);
});
gridLayout->addWidget(btnAnycastClear, 3, 1, 1, 1);
pushButton_11 = new QPushButton;
pushButton_11->setFixedSize(QSize(60, 30));
gridLayout->addWidget(pushButton_11, 3, 1, 1, 1);
btnAnycastReset = new QPushButton;
btnAnycastReset->setFixedSize(60, 30);
btnAnycastReset->setProperty("ssType", "progManageTool");
connect(btnAnycastReset, &QPushButton::clicked, this, [=] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
SendAnycastCmd(0);
fdAnycast->setText("- "+tr("Loop Mode")+" -");
btnAnycast->setEnabled(false);
});
gridLayout->addWidget(btnAnycastReset, 3, 2, 1, 1);
pushButton_12 = new QPushButton;
pushButton_12->setFixedSize(QSize(60, 30));
gridLayout->addWidget(pushButton_12, 3, 2, 1, 1);
btnAnycast = new QPushButton;
btnAnycast->setEnabled(false);
btnAnycast->setMinimumHeight(36);
btnAnycast->setProperty("ssType", "progManageTool");
connect(btnAnycast, &QPushButton::clicked, this, [=] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
SendAnycastCmd(fdAnycast->text().toInt());
fdAnycast->setText(tr("Anycast")+" - "+fdAnycast->text());
btnAnycast->setEnabled(false);
});
vv->addWidget(btnAnycast);
vv->addStretch();
@ -269,7 +244,10 @@ CtrlTestPanel::CtrlTestPanel() {
pushButtonStartLine->setProperty("ssType", "progManageTool");
pushButtonStartGray->setProperty("ssType", "progManageTool");
pushButtonStartColor->setProperty("ssType", "progManageTool");
btnStopTest->setProperty("ssType", "progManageTool");
pushButtonStopTest->setProperty("ssType", "progManageTool");
pushButton_11->setProperty("ssType", "progManageTool");
pushButton_12->setProperty("ssType", "progManageTool");
btnAnycast->setProperty("ssType", "progManageTool");
spinBoxLineSpeed->setValue(10);
spinBoxLineDistance->setValue(15);
@ -393,7 +371,7 @@ CtrlTestPanel::CtrlTestPanel() {
}
}
});
connect(btnStopTest, &QPushButton::clicked, this, [this] {
connect(pushButtonStopTest, &QPushButton::clicked, this, [this] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
@ -414,6 +392,38 @@ CtrlTestPanel::CtrlTestPanel() {
}
}
});
connect(pushButton_11, &QPushButton::clicked, this, [=] {
lineEdit->clear();
btnAnycast->setEnabled(false);
});
connect(pushButton_12, &QPushButton::clicked, this, [=] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
int iIndex = lineEdit->text().toInt();
if(gSelCards.count()==1) SendAnycastCmd(gSelCards[0], 0, true);
else {
foreach(auto card, gSelCards) SendAnycastCmd(card, iIndex, false);
}
lineEdit->setText("-"+tr("loopback mode")+"-");
btnAnycast->setEnabled(false);
});
connect(btnAnycast, &QPushButton::clicked, this, [=] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
int iIndex = lineEdit->text().toInt();
if(gSelCards.count()==1) SendAnycastCmd(gSelCards[0], iIndex, true);
else foreach(auto card, gSelCards) SendAnycastCmd(card, iIndex, false);
lineEdit->setText(tr("Anycast")+" - "+lineEdit->text());
btnAnycast->setEnabled(false);
});
btnAnycast->setEnabled(false);
lineEdit->setValidator(new QIntValidator(0, 100, this));
transUi();
}
@ -457,74 +467,43 @@ void CtrlTestPanel::transUi() {
radioButton_Green->setText(tr("Green"));
radioButton_Blue->setText(tr("Blue"));
radioButton_White->setText(tr("White"));
btnStopTest->setText(tr("Stop"));
btnAnycastClear->setText(tr("Clear"));
btnAnycastReset->setText(tr("Reset"));
pushButtonStopTest->setText(tr("Stop"));
pushButton_11->setText(tr("Clear"));
pushButton_12->setText(tr("Reset"));
btnAnycast->setText(tr("Anycast"));
}
void CtrlTestPanel::SendAnycastCmd(int progIdx) {
void CtrlTestPanel::SendAnycastCmd(LedCard card, int iProgramIndex, bool isSingle) {
QTcpSocket *send = new QTcpSocket();
connect(send, SIGNAL(connected()), this, SLOT(connect_sucessful()));
connect(send, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(show_error(QAbstractSocket::SocketError)));
send->connectToHost(QHostAddress(card.ip),31299);
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<char*>(&tempStreadPakcet), iLenPacket);
auto action = progIdx==0 ? tr("Reset loop mode") : tr("Anycast");
if(gSelCards.count() == 1) {
auto waitingDlg = new WaitingDlg(this, action+" ...");
waitingDlg->show();
auto card = gSelCards[0];
auto tcp = new TcpSocket;
connect(waitingDlg, &WaitingDlg::rejected, tcp, [=] {
tcp->abort();
tcp->deleteLater();
});
connect(tcp, &QTcpSocket::connected, tcp, [=] {
tcp->stopTimer();
tcp->write(data);
tcp->startTimer(10000);
});
connect(tcp, &QTcpSocket::readyRead, tcp, [=] {
tcp->stopTimer();
tcp->close();
tcp->deleteLater();
waitingDlg->success();
});
connect(tcp, &QTcpSocket::errorOccurred, tcp, [=](QAbstractSocket::SocketError err) {
tcp->close();
tcp->deleteLater();
waitingDlg->close();
QMessageBox::critical(this, tr("Tip"), QString(socketErrKey(err))+" ("+QString::number(err)+") "+tcp->errorString());
});
tcp->connectToHost(card.ip, 31299);
tcp->startTimer(10000);
} else {
for(auto &card : gSelCards) {
auto tcp = new TcpSocket;
auto cardId = card.id;
connect(tcp, &QTcpSocket::connected, tcp, [=] {
tcp->stopTimer();
tcp->write(data);
tcp->startTimer(10000);
});
connect(tcp, &QTcpSocket::readyRead, tcp, [=] {
tcp->stopTimer();
tcp->close();
tcp->deleteLater();
gFdResInfo->append(cardId+" "+action+" "+tr("Success"));
});
connect(tcp, &QTcpSocket::errorOccurred, tcp, [=](QAbstractSocket::SocketError err) {
tcp->close();
tcp->deleteLater();
gFdResInfo->append(cardId+" "+action+" "+socketErrKey(err)+" ("+QString::number(err)+") "+tcp->errorString());
});
tcp->connectToHost(card.ip, 31299);
tcp->startTimer(10000);
}
tempStreadPakcet.ucCommType=0x97;
tempStreadPakcet.iBaoLiu=0;
tempStreadPakcet.iLength=4;
unsigned char uctemp[4]={0};
uctemp[0]=iProgramIndex;
memcpy(tempStreadPakcet.pDataBuffer,uctemp,4);
tempStreadPakcet.pDataBuffer[tempStreadPakcet.iLength]=GetCheckCodeIn8(&tempStreadPakcet.ucCommType,tempStreadPakcet.iLength+sizeof(tempStreadPakcet.iBaoLiu)+sizeof(tempStreadPakcet.ucCommType)+sizeof(tempStreadPakcet.iLength));
int iLenPacket=3*sizeof(unsigned char)+sizeof(char)+sizeof(int)+sizeof(int)+tempStreadPakcet.iLength+sizeof(char);/////除正文外的协议结构大小;
QByteArray databuf = QByteArray(reinterpret_cast<char*>(&tempStreadPakcet), iLenPacket);
if(!send->waitForConnected(10000)) //等待连接返回
{
if(isSingle) QMessageBox::information(this, tr("Tip"), tr("Connect timeout"));
else gFdResInfo->append(card.id+":"+tr("receive")+"<-"+tr("Connect")+":"+tr("timeout"));
send->close();
delete send;
return;
}
send->write(databuf);
if(send->waitForBytesWritten(3000)) {
send->read(send->bytesAvailable());
if(isSingle) QMessageBox::information(this, tr("Tip"), (iProgramIndex==0 ? tr("Reset loop mode") : tr("Anycast"))+":"+tr("success"));
else gFdResInfo->append(card.id+":"+tr("receive")+"<-"+tr("Anycast")+":"+tr("success"));
}
send->close();
delete send;
}

View File

@ -1,6 +1,7 @@
#ifndef CTRLTESTPANEL_H
#define CTRLTESTPANEL_H
#include "globaldefine.h"
#include <QScrollArea>
#include <QGroupBox>
#include <QRadioButton>
@ -19,7 +20,7 @@ protected:
signals:
void sigSend(QJsonObject &,QString);
private:
void SendAnycastCmd(int);
void SendAnycastCmd(LedCard, int, bool);
QLabel *labelTestScreen;
QGroupBox *groupBox;
@ -57,10 +58,10 @@ private:
QRadioButton *radioButton_Blue;
QRadioButton *radioButton_White;
QPushButton *pushButtonStartColor;
QPushButton *btnStopTest;
QLineEdit *fdAnycast;
QPushButton *btnAnycastClear;
QPushButton *btnAnycastReset;
QPushButton *pushButtonStopTest;
QLineEdit *lineEdit;
QPushButton *pushButton_11;
QPushButton *pushButton_12;
QPushButton *btnAnycast;
};

View File

@ -1,5 +1,5 @@
#include "ctrlverifyclockpanel.h"
#include "gutil/qwaitingdlg.h"
#include "base/waitingdlg.h"
#include "gutil/qnetwork.h"
#include "globaldefine.h"
#include "gutil/qgui.h"

View File

@ -1,6 +1,6 @@
#include "ctrlvolumepanel.h"
#include "globaldefine.h"
#include "gutil/qwaitingdlg.h"
#include "base/waitingdlg.h"
#include "gutil/qnetwork.h"
#include "tools.h"
#include <QMessageBox>
@ -11,16 +11,10 @@
CtrlVolumePanel::CtrlVolumePanel() {
auto vBox = new VBox(this);
vBox->setContentsMargins(6,6,6,0);
lbVolumeControl = new QLabel;
auto ft = lbVolumeControl->font();
ft.setPixelSize(16);
ft.setBold(true);
lbVolumeControl->setFont(ft);
lbVolumeControl->setAlignment(Qt::AlignCenter);
vBox->addWidget(lbVolumeControl);
vBox->addSpacing(9);
auto hBox = new HBox(vBox);
hBox->addStretch();
@ -186,6 +180,7 @@ CtrlVolumePanel::CtrlVolumePanel() {
btnScheClear = new QPushButton;
btnScheClear->setMinimumSize(60, 30);
btnScheClear->setProperty("ssType", "progManageTool");
connect(btnScheClear, &QPushButton::clicked, this, [this] {tableSche->setRowCount(0);});
hBox->addWidget(btnScheClear);
lbDefBright = new QLabel;
@ -239,7 +234,7 @@ CtrlVolumePanel::CtrlVolumePanel() {
});
hBox->addWidget(btnScheExport);
tableSche = new TableWidget{
tableSche = new Table({
{"vol", "", 300},
{"start", "", 100},
{"end", "", 100},
@ -250,10 +245,9 @@ CtrlVolumePanel::CtrlVolumePanel() {
{"4", "", 60},
{"5", "", 60},
{"6", "", 60}
};
});
tableSche->setDefs();
vBox->addWidget(tableSche);
connect(btnScheClear, &QPushButton::clicked, tableSche, &TableWidget::clearRows);
hBox = new HBox(vBox);
hBox->addStretch();

View File

@ -36,7 +36,7 @@ private:
QSlider *fdDefBright;
QPushButton *btnScheImport;
QPushButton *btnScheExport;
TableWidget *tableSche;
Table *tableSche;
QPushButton *btnScheSet;
QPushButton *btnScheGet;
};

View File

@ -2,7 +2,7 @@
#include "gutil/qcore.h"
#include "gutil/qgui.h"
#include "gutil/qnetwork.h"
#include "gutil/qwaitingdlg.h"
#include "base/waitingdlg.h"
#include "devicepanel.h"
#include "deviceitem.h"
#include <QAction>
@ -14,55 +14,55 @@
#include <QJsonArray>
#include <QHttpMultiPart>
#include <QDialogButtonBox>
#include <QJsonObject>
#include <QInputDialog>
UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
resize(1280, 720);
setWindowFlag(Qt::WindowMaximizeButtonHint);
setWindowState(Qt::WindowMaximized);
setWindowTitle(tr("Update APK"));
auto vBox = new VBox(this);
vBox->setContentsMargins(6, 0, 6, 0);
auto hBox = new HBox(vBox);
auto btnSelectOnlineApk = new QPushButton(tr("Select Online APK"));
btnSelectOnlineApk->setMinimumSize(QSize(100, 30));
btnSelectOnlineApk->setProperty("ssType", "progManageTool");
hBox->addWidget(btnSelectOnlineApk);
auto btnSelectApk = new QPushButton(tr("Select apk"));
btnSelectApk->setMinimumSize(QSize(100, 30));
btnSelectApk->setProperty("ssType", "progManageTool");
hBox->addWidget(btnSelectApk);
auto btnSelectFpga = new QPushButton(tr("Select Fpga"));
btnSelectFpga->setMinimumSize(QSize(100, 30));
btnSelectFpga->setProperty("ssType", "progManageTool");
hBox->addWidget(btnSelectFpga);
auto fdFileName = new QLineEdit;
fdFileName->setReadOnly(true);
fdFileName->setMinimumWidth(200);
auto fdFileName = new QLabel;
fdFileName->setMinimumSize(200, 30);
fdFileName->setStyleSheet("background-color: #fff;");
hBox->addWidget(fdFileName);
connect(btnSelectApk, &QPushButton::clicked, this, [=] {
auto aaa = QFileDialog::getOpenFileName(this, "Open file", gApkHome, "apk package (*.apk *.zip)");
if(aaa.isEmpty()) return;
QFileInfo info(filePath = aaa);
gApkHome = info.absolutePath();
fdFileName->setText(info.fileName());
filePath = QFileDialog::getOpenFileName(this, "Open file", QString(), "apk package (*.apk *.zip)");
if(filePath.isEmpty()) return;
fileId = "";
fdFileName->setText(QFileInfo(filePath).fileName());
});
connect(btnSelectFpga, &QPushButton::clicked, this, [=] {
auto aaa = QFileDialog::getOpenFileName(this, "Open File", gApkHome, "rpd package (*.rpd)");
if(aaa.isEmpty()) return;
QFileInfo info(filePath = aaa);
gApkHome = info.absolutePath();
fdFileName->setText(info.fileName());
filePath = QFileDialog::getOpenFileName(this, "Open File", QString(), "rpd package (*.rpd)");
if(filePath.isEmpty()) return;
fileId = "";
fdFileName->setText(QFileInfo(filePath).fileName());
});
connect(btnSelectOnlineApk, &QPushButton::clicked, this, [=] {
NetReq req("https://www.ledokcloud.com/aips4/screen/upgrade/getGeneric?type=0&page=1&limit=10");
req.setRawHeader("token","e183653f716cb150ebf3b4f8a83c95e7");
auto reply = req.timeout(60000).post("");
ConnReply(reply, this) [=] {
JValue json;
connect(reply, &QNetworkReply::finished, this, [=] {
QJsonDocument json;
auto err = errStrWithData(reply, &json);
if(! err.isEmpty()) {
QMessageBox::critical(this, "Error", err);
@ -73,7 +73,7 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
return;
}
auto files = json["page"]["list"].toArray();
if(files.empty()) {
if(files.isEmpty()) {
QMessageBox::critical(this, "Error", tr("No Files"));
return;
}
@ -87,24 +87,23 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
auto vBox = new VBox(&dlg);
vBox->setContentsMargins(0,0,0,0);
auto table = new TreeWidget;
table->addCol("#", "", 20);
table->addCol("name", tr("Name"), 200, QHeaderView::Stretch);
table->addCol("size", tr("Size"), 80).alignR().margin(4);
table->addCol("createTime", tr("Create Time"), 150).margin(2);
table->setDefs()->setHeaderAlignC();
table->minRowHeight = 28;
for(auto &file : files) {
auto item = new TreeWidgetItem(table);
item->setText("name", file["fileName"].toString()+"."+file["suffix"].toString());
item->setText("size", byteSizeStr(file["fileSize"].toInt()));
item->setText("createTime", file["createTime"].toString());
item->setData(0, file["fileId"].toString());
auto table = new Table{
{"name", tr("Name"), 200, QHeaderView::Stretch},
{"size", tr("Size"), 80},
{"createTime", tr("Create Time"), 150}
};
table->setDefs();
table->setSelectionMode(QAbstractItemView::SingleSelection);
foreach(QJsonValue file, files) {
auto rr = table->appendRow();
table->setText(rr, "name", file["fileName"].toString()+"."+file["suffix"].toString());
table->setText(rr, "size", byteSizeStr(file["fileSize"].toInt()))->setTextAlignment(AlignRight);
table->setText(rr, "createTime", file["createTime"].toString());
table->setData(rr, 0, file["fileId"].toString());
}
connect(table, &TreeWidget::itemDoubleClicked, &dlg, [=, &dlg](QTreeWidgetItem *itm) {
auto item = (TreeWidgetItem*) itm;
fdFileName->setText(item->text("name"));
fileId = item->data(0).toString();
connect(table, &Table::cellDoubleClicked, &dlg, [=, &dlg](int row) {
fdFileName->setText(table->text(row, "name"));
fileId = table->data(row, 0).toString();
filePath = "";
dlg.accept();
});
@ -114,13 +113,14 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
auto btnBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Close);
connect(btnBox, &QDialogButtonBox::rejected, &dlg, &QDialog::reject);
connect(btnBox, &QDialogButtonBox::accepted, &dlg, [=, &dlg] {
auto item = table->selectedItem();
if(item==0) {
auto sels = table->selectedRanges();
if(sels.isEmpty()) {
QMessageBox::warning(&dlg, "Warning", tr("Please select a file"));
return;
}
fdFileName->setText(item->text("name"));
fileId = item->data(0).toString();
auto row = sels[0].topRow();
fdFileName->setText(table->text(row, "name"));
fileId = table->data(row, 0).toString();
filePath = "";
dlg.accept();
});
@ -130,16 +130,25 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
});
});
auto btnUpdate = new QPushButton(tr("Upgrade"));
connect(btnUpdate, &QPushButton::clicked, this, [=] {
auto btnUpgread = new QPushButton(tr("Upgrade"));
btnUpgread->setMinimumSize(QSize(80, 30));
btnUpgread->setProperty("ssType", "progManageTool");
connect(btnUpgread, &QPushButton::clicked, this, [=] {
auto fileName = fdFileName->text();
if(fileName.length() < 3) return;
int cnt = table->topLevelItemCount();
QList<UpdateApkItem *> items;
UpdateApkItem *item;
for(int rr=0; rr<cnt; rr++) if(! (item = (UpdateApkItem*) table->topLevelItem(rr))->isHidden() && item->checkState("id") == Qt::Checked && ! item->isUpdating) {
if(item->isLocked) item->setResult(tr("This screen is encrypted"), Qt::red);
else items.append(item);
QList<wUpgradeApkItem *> items;
for(int i=0; i<cnt; i++) if(table->topLevelItem(i)->checkState(0) == Qt::Checked) {
auto item = static_cast<wUpgradeApkItem *>(table->topLevelItem(i));
if(item->isUpdating) {
QMessageBox::information(this, tr("Tip"), tr("Is upgrading now. Please wait"));
return;
}
if(item->mCard.hasPassword && item->mCard.isLocked && item->m_lockFlag) {
item->setResult(tr("This screen is encrypted"), Qt::red);
return;
}
items.append(item);
}
if(items.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
@ -152,19 +161,17 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
if(! file.open(QIODevice::ReadOnly)) return;
fileData = file.readAll();
file.close();
if(fileData.size() != file.size()) {
QMessageBox::information(this, tr("Tip"), tr("File Read Fail"));
return;
}
} else if(! fileId.isEmpty()) {
auto waitingDlg = new WaitingDlg(this, tr("Downloading Online File")+" ...");
waitingDlg->show();
auto reply = NetReq("https://www.ledokcloud.com/aips4/sys/file/download/"+fileId).timeout(60000).get();
auto reply = NetReq("https://www.ledokcloud.com/aips4/sys/file/download/"+fileId).timeout(120000).get();
QEventLoop loop;
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
connect(reply, &QNetworkReply::downloadProgress, waitingDlg, [=](qint64 bytesReceived, qint64 bytesTotal) {
if(bytesTotal==0) return;
waitingDlg->fdText->setText(tr("Downloading Online File")+" "+QString::number(bytesReceived*100/bytesTotal)+" %");
});
if(waitFinished(reply, waitingDlg)) return;
loop.exec(QEventLoop::ExcludeUserInputEvents);
waitingDlg->close();
auto err = errStr(reply);
fileData = reply->readAll();
@ -177,9 +184,6 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
QMessageBox::critical(this, tr("Error"), tr("Online file is empty"));
return;
}
} else {
QMessageBox::critical(this, tr("Error"), tr("File is empty"));
return;
}
auto nameBytes = fileName.toUtf8();
auto Boundary = "----QtLedOK_.oOo._"+QUuid::createUuid().toByteArray(QUuid::WithoutBraces);
@ -188,25 +192,25 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
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");
bool isApk = ! fileName.endsWith(".rpd", Qt::CaseInsensitive);
for(auto item : items) {
item->isUpdating = true;
foreach(auto item, items) {
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);
connect(reply, &QNetworkReply::uploadProgress, item, [item](qint64 bytesSent, qint64 bytesTotal) {
item->mProgress->setValue(0);
item->isUpdating = true;
NetReq req("http://"+item->mCard.ip+":2016/upload?type="+(isApk ? "software":"hardware"));
auto reply = req.timeout(120000).type("multipart/form-data; boundary="+Boundary).post(data);
connect(reply, &QNetworkReply::uploadProgress, item->mProgress, [item](qint64 bytesSent, qint64 bytesTotal) {
if(bytesTotal==0) return;
item->fdProgress->setValue(bytesSent*100/bytesTotal);
item->mProgress->setValue(bytesSent*100/bytesTotal);
});
ConnReply(reply, item) [=] {
auto err = errStrWithData(reply);
connect(reply, &QNetworkReply::finished, item->mProgress, [=] {
QString err = errStrWithData(reply);
if(! err.isEmpty()) {
item->setResult(tr("Upload error")+": "+err, Qt::red);
item->isUpdating = false;
return;
}
item->fdProgress->setValue(100);
auto info = tr("Upgrading")+" ...";
item->mProgress->setValue(100);
auto info = tr("Installing")+" ...";
QJsonObject json;
if(isApk) {
json.insert("_id", "UpgradeSoftware");
@ -214,40 +218,33 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
json.insert("fileName", fileName);
json.insert("isCustom", true);
} else {
info += " ("+tr("Don't power off during this process")+")";
info += tr("Don't power off during this process");
json.insert("_id", "SynchronousHardwareVersion");
json.insert("_type", "SynchronousHardwareVersion");
}
item->setResult(info);
auto reply = NetReq("http://"+item->text("ip")+":2016/settings").timeout(60000).post(json);
ConnReply(reply, item) [=] {
if(item->treeWidget()==0) return;
QJsonDocument json;
auto err = checkReplyForJson(reply, &json);
auto reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, item->mProgress, [=] {
item->isUpdating = false;
QString err = errStrWithData(reply);
if(! err.isEmpty()) {
item->isUpdating = false;
item->setResult(tr("Install error")+": "+err, Qt::red);
return;
}
if(isApk || ! json["hasProgress"].toBool()) {
item->isUpdating = false;
item->setResult(tr("Install Success"), Qt::darkGreen);
if(isApk) item->OnCheckSoftVersions(1);
else item->OnCheckFpgaVersions();
} else {
sendProgress(item);
item->fdProgress->setValue(0);
}
item->setResult(tr("Install success"), Qt::darkGreen);
if(isApk) item->OnCheckSoftVersions();
else item->OnCheckFpgaVersions();
});
});
}
});
hBox->addWidget(btnUpdate);
hBox->addWidget(btnUpgread);
hBox->addStretch();
hBox->addWidget(new QLabel("APK:"));
auto fdApk = new QComboBox;
fdApk->setMinimumWidth(200);
fdApk->setEditable(true);
fdApk->addItem("com.xixun.xixunplayer");
fdApk->addItem("com.xixun.joey.cardsystem");
@ -261,6 +258,8 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
hBox->addWidget(fdApk);
auto btnUninstall = new QPushButton(tr("Uninstall"));
btnUninstall->setMinimumSize(80, 30);
btnUninstall->setProperty("ssType", "progManageTool");
connect(btnUninstall, &QPushButton::clicked, this, [this, fdApk] {
auto strApkName = fdApk->currentText();
if(strApkName.isEmpty()) {
@ -269,15 +268,15 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
}
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;
int cnt = table->topLevelItemCount();
for(int i=0; i<cnt; i++) if(table->item(i)->checkState("id") == Qt::Checked) {
auto item = (UpdateApkItem *) table->topLevelItem(i);
for(int i=0; i<cnt; i++) if(table->topLevelItem(i)->checkState(0) == Qt::Checked) {
auto item = static_cast<wUpgradeApkItem *>(table->topLevelItem(i));
item->setResult(tr("Uninstalling")+" ...");
QJsonObject 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] {
auto reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, this, [reply, item, strApkName] {
QString err = checkReplyForJson(reply, "error");
if(! err.isEmpty()) {
item->setResult(tr("Uninstall error")+": "+err, Qt::red);
@ -290,20 +289,22 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
hBox->addWidget(btnUninstall);
auto btnCheck = new QPushButton(tr("check running state"));
btnCheck->setMinimumSize(QSize(140, 30));
btnCheck->setProperty("ssType", "progManageTool");
connect(btnCheck, &QPushButton::clicked, this, [this, fdApk] {
QString strApkName = fdApk->currentText();
int cnt = table->topLevelItemCount();
for(int i=0; i<cnt; i++) if(table->item(i)->checkState("id") == Qt::Checked) {
auto item = (UpdateApkItem *) table->topLevelItem(i);
for(int i=0; i<cnt; i++) if(table->topLevelItem(i)->checkState(0) == Qt::Checked) {
auto item = static_cast<wUpgradeApkItem *>(table->topLevelItem(i));
item->setResult(tr("Check apk running status"));
QJsonObject json;
json.insert("_id", "IsSoftwareRunning");
json.insert("_type", "IsSoftwareRunning");
json.insert("packageName", strApkName);
auto reply = NetReq("http://"+item->text("ip")+":2016/settings").timeout(60000).post(json);
ConnReply(reply, item) [reply, item, strApkName] {
auto reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, this, [reply, item, strApkName] {
QJsonDocument json;
auto err = errStrWithData(reply, &json);
QString err = errStrWithData(reply, &json);
if(! err.isEmpty()) {
item->setResult(tr("Check error")+": "+err, Qt::red);
return;
@ -323,258 +324,323 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
hBox->addStretch();
auto btnRefresh = new QPushButton(tr("Refresh"));
connect(btnRefresh, &QPushButton::clicked, this, [=] {
btnRefresh->setMinimumSize(QSize(0, 30));
btnRefresh->setProperty("ssType", "progManageTool");
connect(btnRefresh, &QPushButton::clicked, this, [this, label] {
table->clear();
table->fdCheckAll->setCheckState(Qt::Unchecked);
table->onCheckAll(false);
int cnt = gDevicePanel->mDeviceTable->topLevelItemCount();
for(int cc=0; cc<cnt; cc++) {
auto card = ((DeviceItem*) gDevicePanel->mDeviceTable->topLevelItem(cc))->mCard;
int cnt = table->topLevelItemCount();
UpdateApkItem* item;
for(int rr=0; rr<cnt; rr++) if((item = (UpdateApkItem*) table->topLevelItem(rr))->text("id") == card.id) goto end;
item = new UpdateApkItem(table);
item->setFlags(item->flags() & ~Qt::ItemIsUserCheckable);
item->setCheckState("id", Qt::Unchecked);
item->setText("id", card.id);
{
item->fdOnline = new QLabel;
item->fdOnline->setScaledContents(true);
item->fdOnline->setFixedSize(24, 24);
auto wgt = new QWidget;
auto hhh = new HBox(wgt);
hhh->setContentsMargins(0,0,0,0);
hhh->addWidget(item->fdOnline);
item->setCellWidget("online", wgt);
}
item->fdProgress = new QProgressBar;
item->fdProgress->setAlignment(Qt::AlignCenter);
item->fdProgress->setStyleSheet("QProgressBar {margin-top: 6px; margin-bottom: 6px;}");
item->setCellWidget("progress", item->fdProgress);
end:
item->setText("ip", card.ip);
item->setText("alias", card.alias);
item->fdOnline->setPixmap({card.isOnline ? ":/res/online.png" : ":/res/offline.png"});
item->OnCheckSoftVersions();
item->OnCheckFpgaVersions();
if(! card.hasPassword) {
item->isLocked = false;
item->setCellWidget("encrypt", item->btnUnlock = 0);
} else {
item->isLocked = card.isLocked;
if(item->btnUnlock==0) {
item->btnUnlock = new QPushButton;
item->btnUnlock->setMaximumHeight(36);
item->setCellWidget("encrypt", item->btnUnlock);
connect(item->btnUnlock, &QPushButton::clicked, item, [=] {
if(! item->isLocked) return;
bool ok;
auto pwd = QInputDialog::getText(this, tr("Input password"), tr("Input password"), QLineEdit::Password, QString(), &ok);
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")+" ...");
waitingDlg->show();
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json);
ConnReply(reply, waitingDlg) [=] {
QJsonDocument json;
auto err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
waitingDlg->close();
QMessageBox::critical(this, tr("Error"), err);
return;
}
if(! json["result"].toBool()) {
waitingDlg->close();
QMessageBox::warning(this, tr("Tip Info"), tr("password is wrong"));
return;
}
waitingDlg->success();
item->isLocked = false;
item->btnUnlock->setIcon(QIcon(":/res/UnLock.png"));
auto item = findItem(card.id);
if(item) {
item->mCard.isLocked = false;
item->btnUnlock->setIcon(QIcon(":/res/UnLock.png"));
}
});
});
}
item->btnUnlock->setIcon(QIcon(card.isLocked ? ":/res/Lock.png" : ":/res/UnLock.png")); //已验证显示绿色 没验证蓝色
}
}
label->setText(tr("All")+": "+QString::number(cnt));
for(int i=0; i<cnt; i++) onAddLedCard(static_cast<DeviceItem*>(gDevicePanel->mDeviceTable->topLevelItem(i))->mCard);
label->setText(tr("All")+":"+QString::number(cnt));
});
hBox->addWidget(btnRefresh);
auto fdSearch = new QLineEdit;
fdSearch->setClearButtonEnabled(true);
fdSearch->setMaximumWidth(160);
fdSearch->addAction(new QAction(QIcon(":/res/program/bnSearch.png"), ""), QLineEdit::LeadingPosition);
connect(fdSearch, &QLineEdit::textChanged, this, [this](const QString &text) {
auto cnt = table->topLevelItemCount();
if(text.isEmpty()) {
for(int rr=0; rr<cnt; rr++) table->item(rr)->setHidden(false);
return;
}
bool isEmpty = true;
for(int rr=0; rr<cnt; rr++) {
auto item = table->item(rr);
bool contain = item->text("id").contains(text) || item->text("alias").contains(text) || item->text("remarks").contains(text) || item->text("ip").contains(text);
item->setHidden(! contain);
if(contain) isEmpty = false;
}
if(isEmpty) for(int rr=0; rr<cnt; rr++) {
auto item = table->item(rr);
item->setHidden(! (item->text("playerVer").contains(text)
|| item->text("cardsystem").contains(text)
|| item->text("starter").contains(text)
|| item->text("taxiapp").contains(text)
|| item->text("displayer").contains(text)
|| item->text("fpga").contains(text)
|| item->text("connection").contains(text)
|| item->text("update").contains(text)
));
}
});
hBox->addWidget(fdSearch);
auto txtSearch = new QLineEdit();
txtSearch->setClearButtonEnabled(true);
txtSearch->setMaximumWidth(200);
txtSearch->addAction(new QAction(QIcon(":/res/program/bnSearch.png"), ""), QLineEdit::LeadingPosition);
connect(txtSearch,SIGNAL(textChanged(const QString &)),this,SLOT(FilterProgram(const QString &)));
hBox->addWidget(txtSearch);
table = new LoQTreeWidget;
table->addCol("#", "", 20);
table->addCol("id", "ID", 125).margin(4);
table->addCol("online", tr("Online"), 40);
table->addCol("ip", "IP", 95);
table->addCol("alias", tr("Alias"), 80);
table->addCol("encrypt", tr("Security"), 40);
table->addCol("progress", tr("Progress"), 100);
table->addCol("remarks", tr("State"), 200, QHeaderView::Stretch);
table->addCol("playerVer", "XixunPlayer", 70);
table->addCol("cardsystem", "cardsystem", 70);
table->addCol("starter", "starter", 70);
table->addCol("taxiapp", "taxiapp", 70);
table->addCol("displayer", "displayer", 70);
table->addCol("fpga", "FPGA", 70);
table->addCol("connection", "connection", 70);
table->addCol("update", "update", 40);
table->setDefs()->setHeaderAlignC();
table->addFd();
table->setSelectionMode(QAbstractItemView::NoSelection);
table->setSortingEnabled(true);
table = new LoQTreeWidget();
table->setProperty("ssType", "topList");
vBox->addWidget(table);
auto sortField = gDevicePanel->mDeviceTable->sortField();
if(sortField=="id" || sortField=="ip" || sortField=="alias") table->sortItems(sortField, gDevicePanel->mDeviceTable->header()->sortIndicatorOrder());
else table->sortItems("id");
hBox = new HBox(vBox);
hBox->addStretch();
setAttribute(Qt::WA_DeleteOnClose);
setModal(true);
show();
auto pushButtonCancel = new QPushButton(tr("Cancel"));
pushButtonCancel->setMinimumSize(QSize(0, 30));
pushButtonCancel->setProperty("ssType", "progManageTool");
connect(pushButtonCancel, &QPushButton::clicked, this, &UpgradeApkDialog::reject);
hBox->addWidget(pushButtonCancel);
emit btnRefresh->clicked();
int ccs[]{"taxiapp"**table, "fpga"**table};
for(auto cc : ccs) {
auto size = table->sizeHintForColumn(cc);
if(size==0) {
int cnt = 8;
do {
wait(50);
size = table->sizeHintForColumn(cc);
} while(size==0 && --cnt);
}
if(size>table->header()->sectionSize(cc)) table->header()->resizeSection(cc, size);
m_headerItem = new QTreeWidgetItem();
for(int i=1; i<Upgrade_END; i++) if(i!=Upgrade_Remark) m_headerItem->setTextAlignment(i, Qt::AlignCenter);
m_headerItem->setText(Upgrade_Check, "");
m_headerItem->setText(Upgrade_SCREEN_ID, tr("Screen ID"));
m_headerItem->setText(Upgrade_ONLINE, tr("Online"));
m_headerItem->setText(Upgrade_SCREEN_IP, tr("Screen IP"));
m_headerItem->setText(Upgrade_ENCRYPT, tr("Security"));
m_headerItem->setText(Upgrade_REMARK_NAME, tr("Alias"));
m_headerItem->setText(Upgrade_PROGRESS, tr("Progress"));
m_headerItem->setText(Upgrade_Remark, tr("State"));
m_headerItem->setText(Upgrade_XIXUNPLAYER_VERSION, tr("xixunplayer"));
m_headerItem->setText(Upgrade_CARDSYSTEM_VERSION, tr("cardsystem"));
m_headerItem->setText(Upgrade_STARTER_VERSION, tr("starter"));
m_headerItem->setText(Upgrade_TAXIAPP_VERSION, tr("taxiapp"));
m_headerItem->setText(Upgrade_DISPLAYER_VERSION, tr("displayer"));
m_headerItem->setText(Upgrade_FPAG_VERSION, tr("FPGA"));
m_headerItem->setText(Upgrade_CONNECTION_VERSION, tr("connection"));
m_headerItem->setText(Upgrade_UPDATE_VERSION, tr("update"));
table->setHeaderItem(m_headerItem);
table->header()->setSectionResizeMode(Upgrade_Check, QHeaderView::Fixed);
table->setColumnWidth(Upgrade_Check, 40);
table->header()->setSectionResizeMode(Upgrade_SCREEN_ID, QHeaderView::ResizeToContents);
table->header()->setSectionResizeMode(Upgrade_ONLINE, QHeaderView::Fixed);
table->setColumnWidth(Upgrade_ONLINE, 40);
table->header()->setSectionResizeMode(Upgrade_SCREEN_IP, QHeaderView::ResizeToContents);
table->header()->setSectionResizeMode(Upgrade_ENCRYPT, QHeaderView::Fixed);
table->setColumnWidth(Upgrade_ENCRYPT, 40);
table->header()->setSectionResizeMode(Upgrade_PROGRESS, QHeaderView::Fixed);
table->setColumnWidth(Upgrade_PROGRESS, 100);
table->header()->setSectionResizeMode(Upgrade_XIXUNPLAYER_VERSION, QHeaderView::ResizeToContents);
table->header()->setSectionResizeMode(Upgrade_CARDSYSTEM_VERSION, QHeaderView::ResizeToContents);
table->header()->setSectionResizeMode(Upgrade_STARTER_VERSION, QHeaderView::ResizeToContents);
table->header()->setSectionResizeMode(Upgrade_TAXIAPP_VERSION, QHeaderView::ResizeToContents);
table->header()->setSectionResizeMode(Upgrade_DISPLAYER_VERSION, QHeaderView::ResizeToContents);
table->header()->setSectionResizeMode(Upgrade_FPAG_VERSION, QHeaderView::Fixed);
table->setColumnWidth(Upgrade_FPAG_VERSION, 100);
table->header()->setSectionResizeMode(Upgrade_Remark, QHeaderView::Stretch);
table->header()->setSectionResizeMode(Upgrade_REMARK_NAME, QHeaderView::ResizeToContents);
table->header()->setSectionResizeMode(Upgrade_CONNECTION_VERSION, QHeaderView::ResizeToContents);
table->header()->setSectionResizeMode(Upgrade_UPDATE_VERSION, QHeaderView::ResizeToContents);
int cnt = gDevicePanel->mDeviceTable->topLevelItemCount();
for(int i=0; i<cnt; i++) onAddLedCard(static_cast<DeviceItem*>(gDevicePanel->mDeviceTable->topLevelItem(i))->mCard);
label->setText(tr("All")+":"+QString::number(cnt));
}
void UpgradeApkDialog::onAddLedCard(LedCard card) {
int iExistFlg=0;
int cnt = table->topLevelItemCount();
for(int i=0; i<cnt; i++) {
QString strTempCardId=static_cast<wUpgradeApkItem*>(table->topLevelItem(i))->mCard.id;
if(strTempCardId == card.id) {
iExistFlg=1;
static_cast<wUpgradeApkItem*>(table->topLevelItem(i))->SetItemParam(card);
break;
}
}
if(iExistFlg) return;
new wUpgradeApkItem(card, table);
}
void UpgradeApkDialog::keyPressEvent(QKeyEvent *ev) {
if(ev->key() == Qt::Key_F3) {
QMessageBox::warning(this, "Tip", tr("The encrypted control card can be upgraded directly"));
int cnt = table->topLevelItemCount();
for(int i=0; i<cnt; i++) static_cast<wUpgradeApkItem *>(table->topLevelItem(i))->m_lockFlag = false;
}
}
void UpgradeApkDialog::FilterProgram(const QString &strtemp)
{
if (strtemp.isEmpty()) //显示全部
{
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false);
}
}
else
{
QList<QTreeWidgetItem*> resultList = table->findItems(strtemp, Qt::MatchContains,Upgrade_SCREEN_ID); //搜索结果
if (resultList.size() > 0)
{
//QMessageBox::warning(this, "Export", QString(resultList.size()));
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
if (resultList.contains(topItem))
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
void UpgradeApkDialog::sendProgress(UpdateApkItem *item) {
QJsonObject json;
json.insert("_id", "GetFpgaUpdateProgress");
json.insert("_type", "GetFpgaUpdateProgress");
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);
if(! err.isEmpty()) {
item->isUpdating = false;
item->setResult("GetFpgaUpdateProgress "+tr("Error")+": "+err, Qt::red);
return;
QList<QTreeWidgetItem*> resultList6 = table->findItems(strtemp, Qt::MatchContains,Upgrade_REMARK_NAME); //搜索结果
if (resultList6.size() > 0)
{
//QMessageBox::warning(this, "Export", QString(resultList.size()));
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
if (resultList6.contains(topItem))
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
//QMessageBox::warning(this, "Export", "FilterProgram");
QList<QTreeWidgetItem*> resultList1 = table->findItems(strtemp, Qt::MatchContains,Upgrade_XIXUNPLAYER_VERSION); //搜索结果
if (resultList1.size() > 0)
{
//QMessageBox::warning(this, "Export", QString(resultList.size()));
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
if (resultList1.contains(topItem))
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
QList<QTreeWidgetItem*> resultList2 = table->findItems(strtemp, Qt::MatchContains,Upgrade_SCREEN_IP); //搜索结果
if (resultList2.size() > 0)
{
//QMessageBox::warning(this, "Export", QString(resultList.size()));
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
if (resultList2.contains(topItem))
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
QList<QTreeWidgetItem*> resultList2 = table->findItems(strtemp, Qt::MatchContains,Upgrade_XIXUNPLAYER_VERSION); //搜索结果
if (resultList2.size() > 0)
{
//QMessageBox::warning(this, "Export", QString(resultList.size()));
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
if (resultList2.contains(topItem))
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
QList<QTreeWidgetItem*> resultList2 = table->findItems(strtemp, Qt::MatchContains,Upgrade_CARDSYSTEM_VERSION); //搜索结果
if (resultList2.size() > 0)
{
//QMessageBox::warning(this, "Export", QString(resultList.size()));
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
if (resultList2.contains(topItem))
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
QList<QTreeWidgetItem*> resultList2 = table->findItems(strtemp, Qt::MatchContains,Upgrade_TAXIAPP_VERSION); //搜索结果
if (resultList2.size() > 0)
{
//QMessageBox::warning(this, "Export", QString(resultList.size()));
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
if (resultList2.contains(topItem))
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
QList<QTreeWidgetItem*> resultList2 = table->findItems(strtemp, Qt::MatchContains,Upgrade_DISPLAYER_VERSION); //搜索结果
if (resultList2.size() > 0)
{
//QMessageBox::warning(this, "Export", QString(resultList.size()));
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
if (resultList2.contains(topItem))
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
QList<QTreeWidgetItem*> resultList2 = table->findItems(strtemp, Qt::MatchContains,Upgrade_STARTER_VERSION); //搜索结果
if (resultList2.size() > 0)
{
//QMessageBox::warning(this, "Export", QString(resultList.size()));
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
if (resultList2.contains(topItem))
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
QList<QTreeWidgetItem*> resultList2 = table->findItems(strtemp, Qt::MatchContains,Upgrade_CONNECTION_VERSION); //搜索结果
if (resultList2.size() > 0)
{
//QMessageBox::warning(this, "Export", QString(resultList.size()));
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
if (resultList2.contains(topItem))
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
QList<QTreeWidgetItem*> resultList2 = table->findItems(strtemp, Qt::MatchContains,Upgrade_UPDATE_VERSION); //搜索结果
if (resultList2.size() > 0)
{
//QMessageBox::warning(this, "Export", QString(resultList.size()));
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
if (resultList2.contains(topItem))
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
QList<QTreeWidgetItem*> resultList2 = table->findItems(strtemp, Qt::MatchContains,Upgrade_FPAG_VERSION); //搜索结果
if (resultList2.size() > 0)
{
//QMessageBox::warning(this, "Export", QString(resultList.size()));
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
if (resultList2.contains(topItem))
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
QList<QTreeWidgetItem*> resultList2 = table->findItems(strtemp, Qt::MatchContains,Upgrade_Remark); //搜索结果
if (resultList2.size() > 0)
{
//QMessageBox::warning(this, "Export", QString(resultList.size()));
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
if (resultList2.contains(topItem))
table->setRowHidden(i,table->indexFromItem(topItem->parent()),false); //显示匹配的结果
else
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
else {
for (int i = 0; i< table->topLevelItemCount(); ++i)
{
QTreeWidgetItem* topItem = table->topLevelItem(i);
table->setRowHidden(i,table->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果
}
}
}
}
}
}
}
}
}
}
}
}
}
}
auto progre = json["progress"].toInt();
if(progre >= 100) {
item->isUpdating = false;
item->fdProgress->setValue(100);
item->setResult("FPGA "+tr("Install Success"), Qt::darkGreen);
item->OnCheckFpgaVersions();
} else if(progre == -1) {
item->isUpdating = false;
item->fdProgress->setValue(100);
item->setResult(tr("Same version, needn't update"), Qt::darkGreen);
} else if(progre == -2) {
item->isUpdating = false;
item->setResult(tr("Install Failed")+" (-2)", Qt::red);
} else {
item->fdProgress->setValue(progre);
wait(250);
sendProgress(item);
}
});
}
void UpgradeApkDialog::keyPressEvent(QKeyEvent *event) {
if(event->key() == Qt::Key_F3) {
QMessageBox::warning(this, "Tip", tr("The encrypted control card can be upgraded directly"));
auto cnt = table->topLevelItemCount();
for(int i=0; i<cnt; i++) ((UpdateApkItem*) table->topLevelItem(i))->isLocked = false;
}
}
void UpdateApkItem::OnCheckFpgaVersions() {
QJsonObject json;
json.insert("_id", "CheckHardwareVersions");
json.insert("_type", "CheckHardwareVersions");
auto reply = NetReq("http://"+text("ip")+":2016/settings").timeout(60000).post(json);
ConnReply(reply, fdProgress) [=] {
if(treeWidget()==0) return;
JValue json;
auto err = errStrWithJson(reply, &json);
if(! err.isEmpty()) return;
QString strBuf;
auto vers = json["versions"];
for(auto &ver : vers) {
if(! strBuf.isEmpty()) strBuf += ", ";
strBuf += ver.toStr();
}
setText("fpga", strBuf);
auto item = findItem(text("id"));
if(item) item->mCard.HardVersion = strBuf;
});
}
void UpdateApkItem::OnCheckSoftVersions(int repeat) {
QJsonObject json;
json.insert("_id", "CheckSoftVersions");
json.insert("_type", "CheckSoftVersions");
auto reply = NetReq("http://"+text("ip")+":2016/settings").timeout(60000).post(json);
ConnReply(reply, fdProgress) [=] {
if(treeWidget()==0) return;
JValue json;
auto err = errStrWithJson(reply, &json);
if(! err.isEmpty()) return;
QString playerVer;
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=="com.xixun.joey.cardsystem") setText("cardsystem", app["versionName"].toStr());
else if(packageName=="net.sysolution.starter") setText("starter", app["versionName"].toStr());
else if(packageName=="net.sysolution.taxiapp") setText("taxiapp", app["versionName"].toStr());
else if(packageName=="com.xixun.display") setText("displayer", app["versionName"].toStr());
else if(packageName=="com.xixun.xy.conn") setText("connection", app["versionName"].toStr());
else if(packageName=="com.xixun.xy.update") setText("update", app["versionName"].toStr());
}
setText("playerVer", playerVer);
auto item = findItem(text("id"));
if(item) item->mCard.playerVer = playerVer;
if(playerVer.isEmpty() && repeat) OnCheckSoftVersions(repeat-1);
});
}

View File

@ -1,40 +1,25 @@
#ifndef UPGRADEAPKDIALOG_H
#define UPGRADEAPKDIALOG_H
#include "base/loqtreewidget.h"
#include <QDialog>
#include <QProgressBar>
#include <QTreeWidgetItem>
#include "wupgradeapkitem.h"
class UpdateApkItem;
class UpgradeApkDialog : public QDialog {
Q_OBJECT
public:
explicit UpgradeApkDialog(QWidget *parent = nullptr);
void sendProgress(UpdateApkItem *item);
QString filePath, fileId;
protected:
virtual void keyPressEvent(QKeyEvent *ev);
protected slots:
void FilterProgram(const QString &strtemp);
private:
void onAddLedCard(LedCard p);
LoQTreeWidget *table;
};
class UpdateApkItem : public TreeWidgetItem, public QObject {
public:
using TreeWidgetItem::TreeWidgetItem;
void setResult(QString tip, QColor color = Qt::blue) {
auto remarks = "remarks"**treeWidget();
setText(remarks, tip);
setToolTip(remarks, tip);
setForeground(remarks, color);
}
void OnCheckSoftVersions(int = 0);
void OnCheckFpgaVersions();
QLabel *fdOnline;
QProgressBar *fdProgress;
QPushButton *btnUnlock = 0;
bool isUpdating = false;
bool isLocked = true;
QTreeWidgetItem *m_headerItem=nullptr;
};
#endif // UpgradeApkDialog_H

View File

@ -0,0 +1,143 @@
#include "wupgradeapkitem.h"
#include "base/waitingdlg.h"
#include "deviceitem.h"
#include "gutil/qgui.h"
#include "gutil/qnetwork.h"
#include <QMessageBox>
#include <QJsonArray>
#include <QJsonDocument>
#include <QProgressBar>
#include <globaldefine.h>
#include <QMessageBox>
#include <QInputDialog>
wUpgradeApkItem::wUpgradeApkItem(LedCard pLedCard, LoQTreeWidget *parent) : QTreeWidgetItem(UserType), mCard(pLedCard), m_parent(parent) {
setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
setCheckState(0, Qt::Unchecked);
m_parent->addTopLevelItem(this);
m_ImageOnline = new QLabel();
m_ImageOnline->setAlignment(Qt::AlignCenter);
m_parent->setItemWidget(this, Upgrade_ONLINE, m_ImageOnline);
for(int i=1; i<Upgrade_END; i++) setTextAlignment(i, Qt::AlignCenter);
mProgress = new QProgressBar;
mProgress->setAlignment(Qt::AlignCenter);
mProgress->setStyleSheet("margin-top:8px; margin-bottom:8px; ");
m_parent->setItemWidget(this, Upgrade_PROGRESS, mProgress);
btnUnlock = new QPushButton;
btnUnlock->setMaximumHeight(40);
auto wgt = new QWidget;
auto vBox = new VBox(wgt);
vBox->setContentsMargins(0,0,0,0);
vBox->addWidget(btnUnlock);
m_parent->setItemWidget(this, Upgrade_ENCRYPT, wgt);
QObject::connect(btnUnlock, &QPushButton::clicked, mProgress, [this] {
if(! mCard.isLocked) return;
bool ok;
auto pwd = QInputDialog::getText(treeWidget(), QObject::tr("Input password"), QObject::tr("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(treeWidget(), QObject::tr("VerifyPassword")+" ...");
waitingDlg->show();
auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json);
waitingDlg->connAbort(reply);
QObject::connect(reply, &QNetworkReply::finished, mProgress, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
waitingDlg->close();
QMessageBox::critical(treeWidget(), QObject::tr("Error"), err);
return;
}
if(! json["result"].toBool()) {
waitingDlg->close();
QMessageBox::critical(treeWidget(), QObject::tr("Tip Info"), QObject::tr("password is wrong"));
return;
}
waitingDlg->success();
mCard.isLocked = false;
btnUnlock->setIcon(QIcon(":/res/UnLock.png"));
auto item = findItem(mCard.id);
if(item) {
item->mCard.isLocked = false;
item->btnUnlock->setIcon(QIcon(":/res/UnLock.png"));
}
});
});
SetItemParam(mCard);
}
void wUpgradeApkItem::OnCheckFpgaVersions() {
QJsonObject json;
json.insert("_id", "CheckHardwareVersions");
json.insert("_type", "CheckHardwareVersions");
auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json);
QObject::connect(reply, &QNetworkReply::finished, mProgress, [reply, this] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
return;
}
QString strBuf;
auto vers = json["versions"].toArray();
for(int i=0; i<vers.size(); i++) {
if(i) strBuf += "\n";
strBuf += "["+QString::number(i)+"]:"+vers[i].toString();
}
setData(Upgrade_FPAG_VERSION, 0, strBuf);
auto item = findItem(mCard.id);
if(item) {
item->mCard.HardVersion = strBuf;
}
});
}
void wUpgradeApkItem::OnCheckSoftVersions() {
QJsonObject json;
json.insert("_id", "CheckSoftVersions");
json.insert("_type", "CheckSoftVersions");
auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json);
QObject::connect(reply, &QNetworkReply::finished, mProgress, [reply, this] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
return;
}
auto apps = json["apps"].toArray();
foreach(QJsonValue app, apps) {
QString packageName = app["packageName"].toString();
QString verName = app["versionName"].toString();
if(packageName=="com.xixun.xixunplayer") setData(Upgrade_XIXUNPLAYER_VERSION, 0, verName);
else if(packageName=="com.xixun.joey.cardsystem") setData(Upgrade_CARDSYSTEM_VERSION, 0, verName);
else if(packageName=="net.sysolution.starter") setData(Upgrade_STARTER_VERSION, 0, verName);
else if(packageName=="net.sysolution.taxiapp") setData(Upgrade_TAXIAPP_VERSION, 0, verName);
else if(packageName=="com.xixun.display") setData(Upgrade_DISPLAYER_VERSION, 0, verName);
else if(packageName=="com.xixun.xy.conn") setData(Upgrade_CONNECTION_VERSION, 0, verName);
else if(packageName=="com.xixun.xy.update") setData(Upgrade_UPDATE_VERSION, 0, verName);
}
});
}
void wUpgradeApkItem::setResult(QString tip, QColor color) {
setText(Upgrade_Remark, tip);
setToolTip(Upgrade_Remark, tip);
setForeground(Upgrade_Remark, color);
}
void wUpgradeApkItem::SetItemParam(LedCard card) {
mCard.id = card.id;
mCard.ip = card.ip;
mCard.isOnline = card.isOnline;
setData(Upgrade_SCREEN_ID, 0, card.id);
setData(Upgrade_SCREEN_IP, 0, card.ip);
setData(Upgrade_REMARK_NAME, 0, card.alias);
m_ImageOnline->setPixmap(QPixmap(mCard.isOnline ? ":/res/O_Online.png" : ":/res/O_Offline.png"));
OnCheckSoftVersions();
OnCheckFpgaVersions();
if(! card.hasPassword) btnUnlock->hide();
else {
if(! btnUnlock->isVisible()) btnUnlock->show();
btnUnlock->setIcon(QIcon(card.isLocked ? ":/res/Lock.png" : ":/res/UnLock.png")); //如果已经验证通过密码显示绿色图标 没有验证显示蓝色锁图标
}
}

View File

@ -0,0 +1,55 @@
#ifndef WUPGRADEAPKITEM_H
#define WUPGRADEAPKITEM_H
#include "globaldefine.h"
#include <QDir>
#include <QDateTime>
#include <QJsonObject>
#include <QJsonDocument>
#include <QPushButton>
#include <base/loqtreewidget.h>
#include <QProgressBar>
#include <QLabel>
class wUpgradeApkItem : public QTreeWidgetItem {
public:
explicit wUpgradeApkItem(LedCard card, LoQTreeWidget *parent);
void SetItemParam(LedCard p);
void setResult(QString, QColor cr = Qt::blue);
LedCard mCard;
bool isUpdating{false};
bool m_lockFlag=true;
QLabel *m_ImageOnline=nullptr;
LoQTreeWidget *m_parent = nullptr;
QProgressBar *mProgress=nullptr;
QPushButton *btnUnlock = nullptr;
void OnCheckSoftVersions();
void OnCheckFpgaVersions();
private:
void postFileTask(const QString& strUrl, const QString& strFilePath);//需要的数据
};
enum ENUM_DEVICE_PUBLISH_HEADERITEM {
Upgrade_Check=0,
Upgrade_SCREEN_ID,
Upgrade_ONLINE,
Upgrade_SCREEN_IP,
Upgrade_ENCRYPT,
Upgrade_REMARK_NAME,
Upgrade_PROGRESS,
Upgrade_Remark,
Upgrade_XIXUNPLAYER_VERSION,
Upgrade_CARDSYSTEM_VERSION,
Upgrade_STARTER_VERSION,
Upgrade_TAXIAPP_VERSION,
Upgrade_DISPLAYER_VERSION,
Upgrade_FPAG_VERSION,
Upgrade_CONNECTION_VERSION,
Upgrade_UPDATE_VERSION,
Upgrade_END,
};
#endif // WPROGRAMPUBLISHITEM_H

View File

@ -1,7 +1,6 @@
#include "deviceitem.h"
#include "devicepanel.h"
#include "globaldefine.h"
#include "gutil/qwaitingdlg.h"
#include "base/waitingdlg.h"
#include "gutil/qgui.h"
#include "gutil/qnetwork.h"
#include <QMessageBox>
@ -9,73 +8,86 @@
#include <QInputDialog>
#include <QJsonObject>
DeviceItem::DeviceItem(LoQTreeWidget *parent) : TreeWidgetItem(parent) {
setFlags(flags() & ~Qt::ItemIsUserCheckable);
setCheckState("check", Qt::Unchecked);
auto ft = treeWidget()->font();
ft.setPixelSize(14);
for(int i=2; i<treeWidget()->columnCount()-2; i++) setFont(i, ft);
DeviceItem::DeviceItem(LoQTreeWidget *parent) : QObject(parent), QTreeWidgetItem(UserType), m_parent(parent) {
setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
setCheckState(0, Qt::Unchecked);
m_parent->addTopLevelItem(this);
auto btnGetCapture = new QPushButton;
btnGetCapture->setCursor(QCursor(Qt::PointingHandCursor));
btnGetCapture->setIcon(QIcon(":/res/deviceReadbackPic.png"));
btnGetCapture->setIconSize({28, 28});
QObject::connect(btnGetCapture, &QPushButton::clicked, btnGetCapture, [=] {
m_bnCardDetailInfo = new QPushButton();
m_bnCardDetailInfo->setToolTip(tr("GetScreenDetailInfo"));
m_bnCardDetailInfo->setCursor(QCursor(Qt::PointingHandCursor));
m_bnCardDetailInfo->setStyleSheet(R"rrr(
QPushButton {
border-radius: 4px;
image: url(:/res/bnDetail.png);
}
QPushButton:hover{background-color: #ccc;}
)rrr");
m_parent->setItemWidget(this, DeviceTable_Info, m_bnCardDetailInfo);
m_bnReadbackPic = new QPushButton();
m_bnReadbackPic->setToolTip(tr("ReadbackPic"));
m_bnReadbackPic->setCursor(QCursor(Qt::PointingHandCursor));
m_bnReadbackPic->setStyleSheet(R"rrr(
QPushButton {
border-radius: 4px;
image: url(:/res/deviceReadbackPic.png);
}
QPushButton:hover{background-color: #ccc;}
)rrr");
connect(m_bnReadbackPic, &QPushButton::clicked, this, [this] {
QJsonObject json;
json.insert("_id", "GetScreenshotFull");
json.insert("_type", "GetScreenshotFull");
auto waitingDlg = new WaitingDlg(btnGetCapture, DevicePanel::tr("Getting ")+DevicePanel::tr("Screenshot")+" ...");
auto waitingDlg = new WaitingDlg(treeWidget(), tr("GetScreenshotFull")+" ...");
waitingDlg->show();
auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json);
ConnReply(reply, waitingDlg) [=] {
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
waitingDlg->close();
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
QMessageBox::critical(treeWidget(), DevicePanel::tr("Error"), err);
QMessageBox::critical(treeWidget(), tr("Error"), err);
return;
}
ImgDlg dlg(QByteArray::fromBase64(json["data"].toString().toLatin1()), treeWidget());
dlg.exec();
});
});
setCellWidget("screenshot", btnGetCapture);
m_parent->setItemWidget(this, DeviceTable_Screenshot, m_bnReadbackPic);
fdOnline = new QLabel;
fdOnline->setPixmap({":/res/online.png"});
fdOnline->setScaledContents(true);
fdOnline->setFixedSize(24, 24);
auto wgt = new QWidget;
auto hhh = new HBox(wgt);
hhh->setContentsMargins(0,0,0,0);
hhh->addWidget(fdOnline);
setCellWidget("online", wgt);
m_ImageOnline = new QLabel;
m_ImageOnline->setPixmap(QPixmap(":/res/O_Online.png"));
m_ImageOnline->setAlignment(Qt::AlignCenter);
m_parent->setItemWidget(this, DeviceTable_Online, m_ImageOnline);
btnUnlock = new QPushButton;
btnUnlock->setMaximumHeight(40);
QObject::connect(btnUnlock, &QPushButton::clicked, btnUnlock, [this] {
connect(btnUnlock, &QPushButton::clicked, this, [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(), tr("Input password"), tr("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(btnUnlock, DevicePanel::tr("VerifyPassword")+" ...");
auto waitingDlg = new WaitingDlg(treeWidget(), tr("VerifyPassword")+" ...");
waitingDlg->show();
auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(60000).post(json);
ConnReply(reply, waitingDlg) [=] {
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
waitingDlg->close();
QMessageBox::critical(treeWidget(), DevicePanel::tr("Error"), err);
QMessageBox::critical(treeWidget(), tr("Error"), err);
return;
}
if(! json["result"].toBool()) {
waitingDlg->close();
QMessageBox::critical(treeWidget(), DevicePanel::tr("Tip Info"), DevicePanel::tr("password is wrong"));
QMessageBox::critical(treeWidget(), tr("Tip Info"), tr("password is wrong"));
return;
}
waitingDlg->success();
@ -83,17 +95,122 @@ DeviceItem::DeviceItem(LoQTreeWidget *parent) : TreeWidgetItem(parent) {
btnUnlock->setIcon(QIcon(":/res/UnLock.png"));
});
});
wgt = new QWidget;
hhh = new HBox(wgt);
hhh->setContentsMargins(0,0,0,0);
hhh->addWidget(btnUnlock);
setCellWidget("password", wgt);
auto wgt = new QWidget;
auto hBox = new HBox(wgt);
hBox->setContentsMargins(0,0,0,0);
hBox->addWidget(btnUnlock);
m_parent->setItemWidget(this, DeviceTable_Password, wgt);
auto ft = font(0);
ft.setPixelSize(14);
for(int i=1; i<DeviceTable_Screenshot; i++) {
setFont(i, ft);
setTextAlignment(i, Qt::AlignCenter);
}
}
void DeviceItem::init() {
setText("id", mCard.id);
setText("ip", mCard.ip);
setText("screenSize", QString("%1 x %2").arg(mCard.mWidth).arg(mCard.mHeight));
setData(DeviceTable_ID, 0, mCard.id);
setData(DeviceTable_IP, 0, mCard.ip);
setData(DeviceTable_ScreenSize, 0, QString("%1 x %2").arg(mCard.mWidth).arg(mCard.mHeight));
if(mCard.hasPassword) btnUnlock->setIcon(QIcon(mCard.isLocked ? ":/res/Lock.png" : ":/res/UnLock.png"));
else btnUnlock->hide();
}
void DeviceItem::DeviceItemHttpPost() {
QJsonObject json;
json.insert("_id", "GetBuildInformation");
json.insert("_type", "GetBuildInformation");
auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, this, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
mCard.BrightnessLevel = json["BrightnessLevel"].toInt();
mCard.FirmwareVersion = json["FirmwareVersion"].toString();
mCard.HardVersion = json["HardVersion"].toString();
mCard.ScreenResolution = json["ScreenResolution"].toString();
mCard.IMEI = json["IMEI"].toString();
auto androidVersion = json["AndroidVersion"].toString();
if(! androidVersion.isEmpty()) mCard.androidVersion = androidVersion;
});
if(mCard.mWidth==0 || mCard.mHeight==0) {
json = QJsonObject();
json.insert("_id", "GetScreenSize");
json.insert("_type", "GetScreenSize");
reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, this, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
mCard.mWidth = json["width"].toInt();
mCard.mHeight = json["height"].toInt();
setData(DeviceTable_ScreenSize, 0, QString("%1 x %2").arg(mCard.mWidth).arg(mCard.mHeight));
});
}
json = QJsonObject();
json.insert("_id", "GetBrightness");
json.insert("_type", "GetBrightness");
reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, this, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
mCard.bright = json["brightnessPercentage"].toInt(-1);
if(mCard.bright==-1) mCard.bright = qRound(json["brightness"].toInt() * 100.0 / mCard.BrightnessLevel);
setData(DeviceTable_Brightness, 0, QString::number(mCard.bright)+"%");
});
json = QJsonObject();
json.insert("_id", "IsScreenOn");
json.insert("_type", "IsScreenOn");
reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, this, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
mCard.isScreenOn = json["on"].toBool();
setForeground(DeviceTable_Power, mCard.isScreenOn ? Qt::green : Qt::red);
setData(DeviceTable_Power, 0, mCard.isScreenOn ? tr("On") : tr("Off"));
});
json = QJsonObject();
json.insert("_id", "GetCardAlias");
json.insert("_type", "GetCardAlias");
reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, this, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
mCard.alias = QString::fromUtf8(QByteArray::fromBase64(json["alias"].toString().toLatin1()));
setData(DeviceTable_Remark, 0, mCard.alias);
});
json = QJsonObject();
json.insert("_id", "HasControllerPassword");
json.insert("_type", "HasControllerPassword");
reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, this, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
mCard.hasPassword = json["result"].toBool();
if(mCard.hasPassword) {//加过密
btnUnlock->show();
btnUnlock->setIcon(QIcon(mCard.isLocked ? ":/res/Lock.png" : ":/res/UnLock.png"));
} else btnUnlock->hide();
});
}
ImgDlg::ImgDlg(const QByteArray &data, QWidget *parent) : QDialog(parent) {
setWindowFlag(Qt::WindowContextHelpButtonHint, 0);
setWindowTitle(tr("Screenshot"));
mImg.loadFromData(data);
auto www = mImg.width();
auto hhh = mImg.height();
if(www <= 1600 && hhh <= 900) resize(www, hhh);
else if(www > hhh) resize(900 * www / hhh, 900);
else resize(1600, 1600 * hhh / www);
}
void ImgDlg::paintEvent(QPaintEvent *) {
QPainter painter(this);
painter.drawImage(rect(), mImg);
}

View File

@ -1,18 +1,49 @@
#ifndef DEVICEITEM_H
#define DEVICEITEM_H
#include "base/loqtreewidget.h"
#include <QPushButton>
#include <base/loqtreewidget.h>
#include "globaldefine.h"
#include <QLabel>
#include <QPushButton>
#include <QDialog>
class DeviceItem : public TreeWidgetItem, public QObject {
public:
explicit DeviceItem(LoQTreeWidget *);
void init();
LedCard mCard;
QLabel *fdOnline;
QPushButton *btnUnlock = 0;
enum DeviceTableField {
DeviceTable_Check = 0,
DeviceTable_ID,
DeviceTable_Online,
DeviceTable_IP,
DeviceTable_ScreenSize,
DeviceTable_Remark,
DeviceTable_Brightness,
DeviceTable_Power,
DeviceTable_Password,
DeviceTable_Info,
DeviceTable_Screenshot,
DeviceTable_End,
};
class DeviceItem : public QObject, public QTreeWidgetItem {
friend class DevicePanel;
Q_OBJECT
public:
explicit DeviceItem(LoQTreeWidget *parent);
void init();
void DeviceItemHttpPost();
LedCard mCard;
QPushButton *btnUnlock = nullptr;
private:
QPushButton *m_bnCardDetailInfo = nullptr;
QPushButton *m_bnReadbackPic = nullptr;
QLabel *m_ImageOnline=nullptr;
LoQTreeWidget *m_parent = nullptr;
};
class ImgDlg : public QDialog {
Q_OBJECT
public:
explicit ImgDlg(const QByteArray &, QWidget *parent = 0);
QImage mImg;
public:
void paintEvent(QPaintEvent *) override;
};
#endif // DEVICEITEM_H

View File

@ -19,7 +19,6 @@
#include <QJsonArray>
#include <QStyledItemDelegate>
#include <QToolButton>
#include <QPainter>
DevicePanel *gDevicePanel;
QTextEdit *gFdResInfo;
@ -58,27 +57,21 @@ DevicePanel::DevicePanel(QSettings &settings, QWidget *parent) : QWidget(parent)
label_3 = new QLabel(tr("All"));
hBox->addWidget(label_3);
nDeviceNum = new QLabel;
nDeviceNum = new QLabel();
nDeviceNum->setFixedSize(40, 20);
hBox->addWidget(nDeviceNum);
auto fdSearch = new QLineEdit;
auto fdSearch = new QLineEdit();
fdSearch->setClearButtonEnabled(true);
fdSearch->setFixedSize(220, 30);
fdSearch->addAction(new QAction(QIcon(":/res/program/bnSearch.png"), QString()), QLineEdit::LeadingPosition);
fdSearch->setStyleSheet("border: 1px solid #aaaaaa;");
connect(fdSearch, &QLineEdit::textChanged, this, [=](const QString &text) {
connect(fdSearch, &QLineEdit::textChanged, this, [this](const QString &search) {
auto cnt = mDeviceTable->topLevelItemCount();
int sel = 0, unsel = 0;
for(int i=0; i<cnt; i++) {
auto item = mDeviceTable->item(i);
item->setHidden(! (text.isEmpty() || item->text("id").contains(text) || item->text("alias").contains(text) || item->text("ip").contains(text)));
if(item->isHidden()) item->setCheckState("check", Qt::Unchecked);
else (item->checkState("check")==Qt::Checked ? sel : unsel)++;
mDeviceTable->fdCheckAll->blockSignals(true);
mDeviceTable->fdCheckAll->setCheckState(sel==0 ? Qt::Unchecked : unsel ? Qt::PartiallyChecked : Qt::Checked);
mDeviceTable->fdCheckAll->blockSignals(false);
emit mDeviceTable->selChanged();
if(search.isEmpty()) for(int i=0; i<cnt; i++) mDeviceTable->topLevelItem(i)->setHidden(false);
else for(int i=0; i<cnt; i++) {
auto item = mDeviceTable->topLevelItem(i);
item->setHidden(! (item->text(DeviceTable_ID).contains(search) || item->text(DeviceTable_Remark).contains(search) || item->text(DeviceTable_IP).contains(search)));
}
});
hBox->addWidget(fdSearch);
@ -123,8 +116,8 @@ QComboBox QAbstractItemView::item:selected {background-color: #09c;}
btnRefresh = new QPushButton(tr("Refresh"), areaFlash);
btnRefresh->setGeometry(0, 0, 75, areaFlash->height());
connect(btnRefresh, &QPushButton::clicked, this, [this] {
mDeviceTable->onCheckAll(false);
mDeviceTable->clear();
mDeviceTable->fdCheckAll->setCheckState(Qt::Unchecked);
nDeviceNum->setText("0");
sendGetInfo();
});
@ -139,37 +132,48 @@ QPushButton:hover {background-color: #08b;}
hBox->addWidget(areaFlash);
mHBox = new HBox(vBox);
mHBox = new QHBoxLayout();
auto table = new LoQTreeWidget;
table->addCol("#", "", 20);
table->addCol("check", "", 28).margin(2);
table->addCol("id", "ID", 130, QHeaderView::Stretch).alignC();
table->addCol("online", "", 40);
table->addCol("ip", "IP", 130, QHeaderView::Stretch).alignC();
table->addCol("screenSize", "", 100, QHeaderView::Stretch).alignC();
table->addCol("alias", "", 130, QHeaderView::Stretch).alignC();
table->addCol("brightness", "", 80).alignC();
table->addCol("power", "", 80).alignC();
table->addCol("password", "", 72);
table->addCol("info", "", 72);
table->addCol("screenshot", "", 72);
table->setDefs()->setHeaderAlignC();
table->addFd();
table->setSelectionMode(QAbstractItemView::NoSelection);
table->minRowHeight = 36;
table->setSortingEnabled(true);
mDeviceTable = new LoQTreeWidget(this);
mDeviceTable->setSelectionMode(QAbstractItemView::NoSelection);
mDeviceTable->setIndentation(0);
mDeviceTable->setSortingEnabled(true);
mHBox->addWidget(mDeviceTable);
table->hideColumn("check");
table->fdCheckAll->hide();
table->sortItems("id", Qt::AscendingOrder);
connect(table, &LoQTreeWidget::selChanged, table, [=] {
vBox->addLayout(mHBox);
m_headerItem = new QTreeWidgetItem();
for(int i=1; i<DeviceTable_End; i++) m_headerItem->setTextAlignment(i, Qt::AlignCenter);
mDeviceTable->setHeaderItem(m_headerItem);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Check, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Check, 36);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Online, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Online, 48);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_ID, QHeaderView::Stretch);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_IP, QHeaderView::Stretch);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_ScreenSize, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_ScreenSize, 108);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Remark, QHeaderView::Stretch);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Brightness, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Brightness, 108);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Power, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Power, 84);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Password, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Password, 72);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Info, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Info, 72);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Screenshot, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Screenshot, 72);
connect(mDeviceTable, &LoQTreeWidget::sigCheckStateChanged, this, [=] {
gSelCards.clear();
int cnt = table->topLevelItemCount();
for(int i=0; i<cnt; i++) if(table->item(i)->checkState("check") == Qt::Checked) gSelCards.append(static_cast<DeviceItem*>(table->topLevelItem(i))->mCard);
int cnt = mDeviceTable->topLevelItemCount();
for(int i=0; i<cnt; i++) if(mDeviceTable->topLevelItem(i)->checkState(0) == Qt::Checked) gSelCards.append(static_cast<DeviceItem*>(mDeviceTable->topLevelItem(i))->mCard);
emit sigSelectedDeviceList();
});
mHBox->addWidget(mDeviceTable = table);
mDeviceTable->hideColumn(0);
mDeviceTable->fdIsSelAll->hide();
mDeviceTable->sortItems(DeviceTable_ID, Qt::AscendingOrder);
connect(&mUdpTimer, &QTimer::timeout, this, &DevicePanel::sendGetInfo);
connect(&mUdpSocket, &QUdpSocket::readyRead, this, [this] {
@ -214,58 +218,54 @@ QPushButton:hover {background-color: #08b;}
item->mCard.id = packet->serialCode;
item->mCard.ip = addr;
}
item->init();
{
auto btn = new QPushButton;
btn->setCursor(QCursor(Qt::PointingHandCursor));
btn->setIcon(QIcon(":/res/info.png"));
btn->setIconSize({26, 26});
item->setCellWidget("info", btn);
connect(btn, &QPushButton::clicked, btn, [=] {
QString msgpre;
msgpre.append(tr("Current Brightness")).append(": ").append(QString::number(item->mCard.bright)).append("%").append("\n");
msgpre.append(tr("Brightness Level")).append(": ").append(QString::number(item->mCard.BrightnessLevel)).append("\n");
msgpre.append(tr("Android OS Resolution")).append(": ").append(item->mCard.ScreenResolution).append("\n");
msgpre.append(tr("Android Version")).append(": ").append(item->mCard.androidVersion).append("\n");
msgpre.append(tr("FPGA Version")).append(": ").append(item->mCard.HardVersion).append("\n");
msgpre.append(tr("Firmware Version")).append(": ").append(item->mCard.FirmwareVersion).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")+" ...");
QJsonObject json;
json.insert("_id", "CheckSoftVersions");
json.insert("_type", "CheckSoftVersions");
auto card = item->mCard;
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
ConnReply(reply, &msgBox) [=, &msgBox] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
msgBox.setText(msgpre + tr("Player Version")+": "+err);
connect(item->m_bnCardDetailInfo, &QPushButton::clicked, item, [=] {
QString msgpre;
msgpre.append(tr("Current Brightness")).append(": ").append(QString::number(item->mCard.bright)).append("%").append("\n");
msgpre.append(tr("Brightness Level")).append(": ").append(QString::number(item->mCard.BrightnessLevel)).append("\n");
msgpre.append(tr("Android OS Resolution")).append(": ").append(item->mCard.ScreenResolution).append("\n");
msgpre.append(tr("Android Version")).append(": ").append(item->mCard.androidVersion).append("\n");
msgpre.append(tr("FPGA Version")).append(": ").append(item->mCard.HardVersion).append("\n");
msgpre.append(tr("Firmware Version")).append(": ").append(item->mCard.FirmwareVersion).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")+" ...");
QJsonObject json;
json.insert("_id", "CheckSoftVersions");
json.insert("_type", "CheckSoftVersions");
auto card = item->mCard;
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
connect(&msgBox, &QMessageBox::finished, reply, [reply] {
abortSilence(reply);
});
connect(reply, &QNetworkReply::finished, &msgBox, [=, &msgBox] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
msgBox.setText(msgpre + tr("Player Version")+": "+err);
return;
}
auto apps = json["apps"].toArray();
foreach(QJsonValue value, apps) {
QJsonObject app = value.toObject();
if(app["packageName"].toString().contains("xixunplayer")) {
msgBox.setText(msgpre + tr("Player Version")+": "+app["versionName"].toString());
return;
}
auto apps = json["apps"].toArray();
foreach(QJsonValue value, apps) {
QJsonObject app = value.toObject();
if(app["packageName"].toString().contains("xixunplayer")) {
msgBox.setText(msgpre + tr("Player Version")+": "+app["versionName"].toString());
return;
}
}
msgBox.setText(msgpre + tr("Player Version")+":");
});
msgBox.exec();
}
msgBox.setText(msgpre + tr("Player Version")+":");
});
}
init(item);
msgBox.exec();
});
item->init();
item->DeviceItemHttpPost();
nDeviceNum->setText(QString::number(mDeviceTable->topLevelItemCount()));
// {
// QJsonObject json;
// json.insert("_id", "SyncTime");
// json.insert("_type", "SyncTime");
// json.insert("time", QDateTime::currentDateTime().toMSecsSinceEpoch());
// auto reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(60000).post(json);
// connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
// }
{
QJsonObject json;
json.insert("_id", "SyncTime");
json.insert("_type", "SyncTime");
json.insert("time", QDateTime::currentDateTime().toMSecsSinceEpoch());
auto reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(60000).post(json);
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
}
end:;
}
});
@ -291,7 +291,7 @@ QPushButton:hover {background-color: #08b;}
hBox->addStretch();
auto bnSearch = new QPushButton(tr("Search"));
connect(bnSearch, &QPushButton::clicked, fdIP, [this] {
connect(bnSearch, &QPushButton::clicked, this, [this] {
QString ipsStr = fdIP->toPlainText();
if(ipsStr.isEmpty()) {
QMessageBox::warning(this, tr("Attention"), tr("Please input IP address!"));
@ -359,20 +359,21 @@ void DevicePanel::transUi() {
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("alias", tr("Alias"));
mDeviceTable->setHeaderText("brightness", tr("Screen Brightness"));
mDeviceTable->setHeaderText("power", tr("Power Status"));
mDeviceTable->setHeaderText("password", tr("Security"));
mDeviceTable->setHeaderText("info", tr("More Info"));
mDeviceTable->setHeaderText("screenshot", tr("Screenshot"));
m_headerItem->setText(DeviceTable_Online, tr("Online"));
m_headerItem->setText(DeviceTable_ID, tr("Screen ID"));
m_headerItem->setText(DeviceTable_IP, tr("Screen IP"));
m_headerItem->setText(DeviceTable_ScreenSize, tr("Screen Size"));
m_headerItem->setText(DeviceTable_Remark, tr("Alias"));
m_headerItem->setText(DeviceTable_Screenshot, tr("readback pic"));
m_headerItem->setText(DeviceTable_Brightness, tr("Screen Brightness"));
m_headerItem->setText(DeviceTable_Power, tr("Power Status"));
m_headerItem->setText(DeviceTable_Password, tr("Security"));
m_headerItem->setText(DeviceTable_Info, tr("More Info"));
auto cnt = mDeviceTable->topLevelItemCount();
for(int i=0; i<cnt; i++) {
auto item = (DeviceItem*) mDeviceTable->item(i);
item->setText("power", item->mCard.isScreenOn ? tr("On") : tr("Off"));
auto item = (DeviceItem*) mDeviceTable->topLevelItem(i);
item->setData(DeviceTable_Power, 0, item->mCard.isScreenOn ? tr("On") : tr("Off"));
}
transCtrl();
}
@ -451,18 +452,15 @@ void DevicePanel::newCtrl() {
line->setFrameShadow(QFrame::Sunken);
vBox->addWidget(line);
hBox = new QHBoxLayout;
hBox = new QHBoxLayout();
scrollArea = new QScrollArea;
scrollArea = new QScrollArea();
scrollArea->setWidgetResizable(true);
hBox->addWidget(scrollArea);
auto vBox2 = new QVBoxLayout();
fdInfo = new QTextEdit;
auto ft = fdInfo->font();
ft.setFamily("Consolas");
fdInfo->setFont(ft);
fdInfo = new QTextEdit();
gFdResInfo = fdInfo;
fdInfo->setReadOnly(true);
fdInfo->setMaximumWidth(360);
@ -481,7 +479,7 @@ void DevicePanel::newCtrl() {
fdInfo->hide();
btnClear->hide();
connect(this, &DevicePanel::sigSelectedDeviceList, fdInfo, [this] {
connect(this, &DevicePanel::sigSelectedDeviceList, this, [this] {
if(gSelCards.count() < 2) {
if(gSelCards.count()==1) fdCardNumInfo->setText(tr("Current Screen")+": "+gSelCards[0].id);
else fdCardNumInfo->setText(tr("Current Screen")+": "+tr("none"));
@ -499,118 +497,3 @@ void DevicePanel::newCtrl() {
transCtrl();
}
void DevicePanel::init(DeviceItem *item) {
QJsonObject json;
json.insert("_id", "GetBuildInformation");
json.insert("_type", "GetBuildInformation");
auto reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json);
ConnReply(reply, item) [=] {
JValue json;
auto err = errStrWithJson(reply, &json);
if(! err.isEmpty()) return;
item->mCard.BrightnessLevel = json["BrightnessLevel"].toInt();
item->mCard.FirmwareVersion = json["FirmwareVersion"].toStr();
item->mCard.HardVersion = json["HardVersion"].toStr();
item->mCard.ScreenResolution = json["ScreenResolution"].toStr();
item->mCard.IMEI = json["IMEI"].toStr();
auto androidVersion = json["AndroidVersion"].toStr();
if(! androidVersion.isEmpty()) item->mCard.androidVersion = androidVersion;
});
if(item->mCard.mWidth==0 || item->mCard.mHeight==0) {
json = QJsonObject();
json.insert("_id", "GetScreenSize");
json.insert("_type", "GetScreenSize");
reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json);
ConnReply(reply, item) [=] {
JValue json;
auto err = errStrWithJson(reply, &json);
if(! err.isEmpty()) return;
item->mCard.mWidth = json["width"].toInt();
item->mCard.mHeight = json["height"].toInt();
item->setText("screenSize", QString("%1 x %2").arg(item->mCard.mWidth).arg(item->mCard.mHeight));
});
}
json = QJsonObject();
json.insert("_id", "GetBrightness");
json.insert("_type", "GetBrightness");
reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json);
ConnReply(reply, item) [=] {
JValue json;
auto err = errStrWithJson(reply, &json);
if(! err.isEmpty()) return;
item->mCard.bright = json["brightnessPercentage"].toInt(-1);
if(item->mCard.bright==-1) item->mCard.bright = qRound(json["brightness"].toInt() * 100.0 / item->mCard.BrightnessLevel);
item->setText("brightness", QString::number(item->mCard.bright)+"%");
});
json = QJsonObject();
json.insert("_id", "IsScreenOn");
json.insert("_type", "IsScreenOn");
reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json);
ConnReply(reply, item) [=] {
JValue json;
auto err = errStrWithJson(reply, &json);
if(! err.isEmpty()) return;
item->mCard.isScreenOn = json["on"].toBool();
item->setForeground("power"**mDeviceTable, item->mCard.isScreenOn ? Qt::green : Qt::red);
item->setText("power", item->mCard.isScreenOn ? tr("On") : tr("Off"));
});
json = QJsonObject();
json.insert("_id", "GetCardAlias");
json.insert("_type", "GetCardAlias");
reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json);
ConnReply(reply, item) [=] {
JValue json;
auto err = errStrWithJson(reply, &json);
if(! err.isEmpty()) return;
item->mCard.alias = QString::fromUtf8(QByteArray::fromBase64(json["alias"].toStr().toLatin1()));
item->setText("alias", item->mCard.alias);
});
json = QJsonObject();
json.insert("_id", "HasControllerPassword");
json.insert("_type", "HasControllerPassword");
reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json);
ConnReply(reply, item) [=] {
JValue json;
auto err = errStrWithJson(reply, &json);
if(! err.isEmpty()) return;
item->mCard.hasPassword = json["result"].toBool();
if(item->mCard.hasPassword) {//加过密
item->btnUnlock->show();
item->btnUnlock->setIcon(QIcon(item->mCard.isLocked ? ":/res/Lock.png" : ":/res/UnLock.png"));
} else item->btnUnlock->hide();
});
json = QJsonObject();
json.insert("_id", "CheckSoftVersions");
json.insert("_type", "CheckSoftVersions");
reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(120000).post(json);
ConnReply(reply, item) [=] {
JValue json;
auto err = errStrWithJson(reply, &json);
if(! err.isEmpty()) return;
auto apps = json["apps"];
for(auto &app : apps) if(app["packageName"].toStr().contains("xixunplayer")) {
item->mCard.playerVer = app["versionName"].toStr();
return;
}
});
}
ImgDlg::ImgDlg(const QByteArray &data, QWidget *parent) : QDialog(parent) {
setWindowFlag(Qt::WindowContextHelpButtonHint, 0);
setWindowTitle(tr("Screenshot"));
mImg.loadFromData(data);
auto www = mImg.width();
auto hhh = mImg.height();
if(www <= 1600 && hhh <= 900) resize(www, hhh);
else if(www > hhh) resize(900 * www / hhh, 900);
else resize(1600, 1600 * hhh / www);
}
void ImgDlg::paintEvent(QPaintEvent *) {
QPainter painter(this);
painter.drawImage(rect(), mImg);
}

View File

@ -3,7 +3,7 @@
#include "base/loqtreewidget.h"
#include "globaldefine.h"
#include "gutil/qgui.h"
#include <QLabel>
#include <QTimer>
#include <QPushButton>
#include <QUdpSocket>
@ -12,6 +12,7 @@
#include <QTextEdit>
#include <QScrollArea>
#include <QSettings>
#include <QHBoxLayout>
class DevicePanel : public QWidget {
Q_OBJECT
@ -21,7 +22,6 @@ public:
void sendGetInfo();
void newCtrl();
void init(DeviceItem *item);
QLabel *fdCardNumInfo;
LoQTreeWidget *mDeviceTable;
@ -34,7 +34,8 @@ public:
QLabel *label_3, *nDeviceNum;
QComboBox *bnSpecifyIP;
QPushButton *btnRefresh;
HBox *mHBox{0};
QTreeWidgetItem *m_headerItem;
QHBoxLayout *mHBox{0};
QTextEdit *fdInfo;
QButtonGroup *mBtnGrp;
@ -50,15 +51,6 @@ signals:
void sigSelectedDeviceList();
};
class ImgDlg : public QDialog {
Q_OBJECT
public:
explicit ImgDlg(const QByteArray &, QWidget *parent = 0);
QImage mImg;
public:
void paintEvent(QPaintEvent *) override;
};
struct UDPPacket {
unsigned char SyncHead[3];
unsigned char ucCommType;

View File

@ -122,18 +122,18 @@ AVFmt::AVFmt(QByteArray url) {
#endif
sink = new QAudioSink(audioDevice, audioFmt);
sinkWriter = sink->start();
if(sinkWriter==0) {
if(sinkWriter==nullptr) {
au.idx = -1;
qCritical()<<"Couldn't Start Audio Output"<<sink->error();
} else {
const AVCodec *decoder = avcodec_find_decoder(codecpar->codec_id);
if(decoder==0) {
if(decoder==nullptr) {
au.idx = -1;
qWarning()<<"Couldn't found Audio Decoder";
} else {
au.ctx = avcodec_alloc_context3(decoder);
avcodec_parameters_to_context(au.ctx, codecpar);
if(avcodec_open2(au.ctx, decoder, 0) < 0) {
if(avcodec_open2(au.ctx, decoder, nullptr) < 0) {
au.idx = -1;
qWarning()<<"Couldn't open aCodecCtx";
} else {
@ -171,18 +171,18 @@ AVFmt::AVFmt(QByteArray url) {
if(vi.idx > -1) vi.thd = new thread(&AVFmt::mainViDecode, this);
}
AVFmt::~AVFmt() {
if(read_thd) {
acts.lockAddNtf(new Act{0, 0, 'Q'});
if(read_thd!=nullptr) {
acts.lockAddNtf(new Act{0, nullptr, 'Q'});
read_thd->join();
delete read_thd;
qInfo() << "~ read thread";
}
if(au.thd) {
if(au.thd!=nullptr) {
au.thd->join();
delete au.thd;
qInfo() << "~ au thread";
}
if(vi.thd) {
if(vi.thd!=nullptr) {
vi.thd->join();
delete vi.thd;
qInfo() << "~ vi thread";
@ -199,7 +199,7 @@ void AVFmt::mainRead() {
int res = 0;
while(true) {
auto act = wait==0 ? acts.lockPoll() : acts.take(wait);
while(act) {
while(act!=nullptr) {
if(act->act=='S') {
if(au.idx!=-1) {
unique_lock<mutex> lock(au.pkts.mtx);
@ -616,12 +616,12 @@ void FFPlayer::updFrame() {
}
auto now_epoch = chrono::duration_cast<chrono::microseconds>(chrono::steady_clock::now().time_since_epoch()).count();
dur = now_epoch - last_epoch;
last_epoch = now_epoch;
if(dur>100000) return;
if(dur<4000) {
qWarning()<<"FFPlayer UpdFrame Fail: dur"<<dur;
return;
}
last_epoch = now_epoch;
if(dur>100000) return;
ctx->checkAndUpd(this, now_epoch);
viSize = ctx->vi_frms.size;
auSize = ctx->au_frms.size;

View File

@ -25,18 +25,18 @@ public:
delAll();
}
void add(T *node) {
if(node==0) {
if(node==nullptr) {
throw std::invalid_argument("node is null");
return;
}
if(last) last->next = node;
if(last!=nullptr) last->next = node;
else first = node;
last = node;
size++;
}
void remove() {
if(first==0) return;
if(first==last) first = last = 0;
if(first==nullptr) return;
if(first==last) first = last = nullptr;
else first = first->next;
size--;
}
@ -54,7 +54,7 @@ public:
return first;
}
void delAll() {
while(first) delete poll();
while(first!=nullptr) delete poll();
}
T *volatile first{0};
@ -154,6 +154,7 @@ public:
avcodec_free_context(&ctx);
}
};
class FFPlayer;
class AVFmt {
friend class FFPlayer;
public:

View File

@ -11,13 +11,12 @@
QString gFileHome;
QString gApkHome;
QList<LedCard> gSelCards;
bool gVideoCompress = false;
bool gVideoTranscoding = false;
bool gVideoCompress = true;
bool gVideoTranscoding = true;
bool gTextAntialiasing = false;
bool gWidthSplit = false;
int gSendBatch = 5;
bool gHideDetect = false;
bool gShowAlias = false;
bool gShowLora = false;
DeviceItem *findItem(QString id) {
@ -45,21 +44,6 @@ QString checkReply(QNetworkReply *reply, QJsonDocument *outJson) {
}
return "";
}
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 "";
}
QString checkReplyForJson(QNetworkReply *reply, QJsonDocument *outJson, QByteArray *outData) {
auto err = errStr(reply);
auto data = reply->readAll();

View File

@ -1,22 +1,20 @@
#ifndef GLOBALDEFINE_H
#define GLOBALDEFINE_H
#include "gutil/qjson.h"
#include <QJsonDocument>
#include <QNetworkReply>
struct LedCard {
QString id;
QString ip;
int mWidth = 0;
int mHeight = 0;
int bright = 100;
int BrightnessLevel = 255;
int mWidth{0};
int mHeight{0};
int bright{100};
int BrightnessLevel{255};
QString FirmwareVersion;
QString HardVersion = "0000";
QString ScreenResolution;
QString androidVersion;
QString playerVer;
QString alias;
QString IMEI;
bool hasPassword{false};
@ -53,7 +51,6 @@ extern bool gTextAntialiasing;
extern bool gWidthSplit;
extern int gSendBatch;
extern bool gHideDetect;
extern bool gShowAlias;
extern bool gShowLora;
extern quint64 dirFileSize(const QString &path);
@ -89,7 +86,6 @@ inline int verCompare(const QString& a, const QString& b) {
}
QString checkReply(QNetworkReply *, QJsonDocument * = 0);
QString errStrWithJson(QNetworkReply *, JValue * = 0, QByteArray * = 0);
QString checkReplyForJson(QNetworkReply *, QJsonDocument * = 0, QByteArray * = 0);
QString checkReplyForJson(QNetworkReply *, QString errField);
@ -97,7 +93,7 @@ QString checkReplyForJson(QNetworkReply *, QString errField);
waitingDlg->show();\
auto card = gSelCards[0];\
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);\
connect(waitingDlg, &WaitingDlg::rejected, reply, &QNetworkReply::deleteLater);
waitingDlg->connAbort(reply);
#define Def_CtrlSetReqAfter \
QString err = checkReplyForJson(reply);\

View File

@ -2,18 +2,19 @@
#define CPP_H
#include <chrono>
#include <memory>
#include <unordered_map>
inline int64_t steady_milli() {
inline long long steady_milli() {
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}
inline int64_t system_milli() {
inline long long system_milli() {
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}
inline int64_t steady_micro() {
inline long long steady_micro() {
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}
inline int64_t system_micro() {
inline long long system_micro() {
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}
@ -46,7 +47,7 @@ public:
}
SharedPtr &operator=(SharedPtr &&other) noexcept {
auto aaa = ptr;
ptr = other.ptr;
ptr = other._pri;
other.ptr = aaa;
return *this;
}
@ -194,7 +195,7 @@ public:
LinkedMap() {}
LinkedMap(std::initializer_list<std::pair<K, V>> pairs) : _pri{new LinkedMapPri<K, V>} {
for(auto &pair : pairs) insert(pair.first, pair.second);
for(auto pair : pairs) insert(pair.first, pair.second);
}
LinkedMap(std::unordered_map<K, Node*> &&map) : _pri{new LinkedMapPri<K, V>{0, 0, map}} {
_pri->next = _pri->prev = _pri;
@ -268,20 +269,6 @@ public:
} 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);

View File

@ -27,10 +27,10 @@ inline QString gUrlSuffix(const QString &url, int size, bool withDot = false) {
}
inline QString byteSizeStr(double size) {
const char *units[]{"B", "KB", "MB", "GB", "TB", "PB", "EB"};
const char *units[]{"B", "KB", "MB", "GB", "TB", "PB"};
auto i = 0;
for(; size >= 1024 && i < 7; i++) size /= 1024;
return (size > 99 ? QString::number(size, 'f', 0) : QString::number(size, 'g', 3))+" "+units[i];
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) {

View File

@ -6,7 +6,7 @@
const Qt::Alignment AlignRight = Qt::AlignRight | Qt::AlignVCenter;
ColItem TreeWidget::addCol(const QString& field, const QString& text, int width, QHeaderView::ResizeMode resizeMode) {
int i = (int) fdmap.size();
int i = fdmap.size();
auto item = headerItem();
item->setText(i, text);
item->setData(i, FieldRole, field);
@ -36,13 +36,12 @@ bool TreeWidget::eventFilter(QObject *watched, QEvent *event) {
if(event->type()==QEvent::Resize) {
auto eve = (QResizeEvent *) event;
if(eve->size().width() != eve->oldSize().width()) adjSections(-1, 0);
return true;
} else if(isSectionResized && event->type()==QEvent::Leave) {
isSectionResized = false;
auto item = headerItem();
for(int cc=0; cc<columnCount(); cc++) if(item->data(cc, WidthRole).isValid()) item->setData(cc, WidthRole, header()->sectionSize(cc));
return true;
}
return true;
}
return QTreeWidget::eventFilter(watched, event);
}
@ -107,40 +106,8 @@ bool TreeWidget::adjSections(int index, int size) {
class TreeItemMarginStyle : public QProxyStyle {
public:
TreeItemMarginStyle(TreeWidget *wgt) : QProxyStyle(wgt->style()), _wgt(wgt) {}
#if(QT_VERSION_MAJOR > 5)
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override { //draw big indicator and cell focus mask
if(option && option->type==QStyleOption::SO_ViewItem && ((QStyleOptionViewItem*) option)->features & QStyleOptionViewItem::HasCheckIndicator && widget==_wgt) { //PE_PanelItemViewItem PE_IndicatorItemViewItemCheck
auto opt = (QStyleOptionViewItem*) option;
auto add = _wgt->headerItem()->data(opt->index.column(), MarginRole).toInt();
if(add) {
if(element==PE_IndicatorItemViewItemCheck) opt->rect.translate(add, 0); //move big indicator
else if((opt->features & QStyleOptionViewItem::HasDisplay)==0) opt->rect.setLeft(opt->rect.right() + 1); //remove cell focus mask
else {
opt->rect.setLeft(opt->rect.x() + (add << 1)); //move cell focus mask
if(opt->rect.width() < 0) opt->rect.setWidth(0);
}
}
}
QProxyStyle::drawPrimitive(element, option, painter, widget);
}
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override { //draw text, small indicator and focus mask around text
if(option && widget==_wgt) {
auto opt = (QStyleOptionViewItem*) option;
opt->state &= ~State_HasFocus; //remove focus mask around text
if(element==CE_ItemViewItem && option->type==QStyleOption::SO_ViewItem) {
auto add = _wgt->headerItem()->data(opt->index.column(), MarginRole).toInt();
if(add) { //move text and small indicator
if(opt->displayAlignment & Qt::AlignRight) opt->rect.setRight(opt->rect.right() - add);
if(opt->features & QStyleOptionViewItem::HasCheckIndicator) opt->rect.setLeft(opt->rect.x() + (add<<1));
else if((opt->displayAlignment & (Qt::AlignHCenter | Qt::AlignRight))==0) opt->rect.setLeft(opt->rect.x() + add);
if(opt->rect.width() < 0) opt->rect.setWidth(0);
}
}
}
QProxyStyle::drawControl(element, option, painter, widget);
}
#else
using QProxyStyle::QProxyStyle;
TreeItemMarginStyle(QWidget *wgt) : QProxyStyle(wgt->style()), _wgt(wgt) {}
QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const override {
auto res = QProxyStyle::subElementRect(element, option, widget);
auto width = res.width();
@ -158,11 +125,9 @@ public:
}
}
} else if(((QStyleOptionViewItem*)option)->features & QStyleOptionViewItem::HasCheckIndicator) {
auto index = ((QStyleOptionViewItem*)option)->index;
auto add = ((TreeWidget*)widget)->headerItem()->data(index.column(), MarginRole).toInt();
auto add = ((TreeWidget*)widget)->headerItem()->data(((QStyleOptionViewItem*)option)->index.column(), MarginRole).toInt();
if(add) {
if(width < (add+3)<<1) add = width;
else add += add>>1;
add += add>>1;
res.setLeft(res.x() + add);
if(width < add) res.setWidth(0);
}
@ -175,8 +140,7 @@ public:
if(metric==PM_FocusFrameHMargin && option && option->type==QStyleOption::SO_ViewItem && ((QStyleOptionViewItem*)option)->features & QStyleOptionViewItem::HasCheckIndicator && widget==_wgt) res += ((TreeWidget*)widget)->headerItem()->data(((QStyleOptionViewItem*)option)->index.column(), MarginRole).toInt();
return res;
}
#endif
TreeWidget *_wgt = 0;
QWidget *_wgt = 0;
};
ColItem &ColItem::margin(int margin) {
@ -215,13 +179,12 @@ bool TableWidget::eventFilter(QObject *watched, QEvent *event) {
if(event->type()==QEvent::Resize) {
auto eve = (QResizeEvent *) event;
if(eve->size().width() != eve->oldSize().width()) adjSections(-1, 0);
return true;
} else if(isSectionResized && event->type()==QEvent::Leave) {
isSectionResized = false;
QTableWidgetItem *item;
for(int cc=0; cc<columnCount(); cc++) if((item = horizontalHeaderItem(cc)) && item->data(WidthRole).isValid()) item->setData(WidthRole, horizontalHeader()->sectionSize(cc));
return true;
}
return true;
}
return QTableWidget::eventFilter(watched, event);
}

View File

@ -147,9 +147,9 @@ public:
Grid(QSplitter *splitter) : QGridLayout(new QWidget) {
splitter->addWidget(parentWidget());
};
QLabel *addLabel(const QString& text, int row, int column, Qt::Alignment align = Qt::Alignment()) {
QLabel *addLabel(const QString& text) {
auto lb = new QLabel(text);
addWidget(lb, row, column, align);
addWidget(lb);
return lb;
}
};
@ -274,7 +274,6 @@ public:
int sizeHintForColumn(int column) const override {
return QTreeWidget::sizeHintForColumn(column);
}
bool adjSections(int index, int size);
signals:
void updGeos();
protected:
@ -286,6 +285,7 @@ protected:
void rowsInserted(const QModelIndex &parent, int start, int end) override;
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 noMargin = true;
bool isSectionResized = false;
@ -293,11 +293,11 @@ protected:
};
inline int operator*(const QString& key, QTreeView &table) {
if((size_t)&table==0) return -1;
if((size_t)&table==0) return 0;
return ((TreeWidget&)table).fdmap.at(key);
}
inline int operator*(const char *key, QTreeView &table) {
if((size_t)&table==0) return -1;
if((size_t)&table==0) return 0;
return ((TreeWidget&)table).fdmap.at(key);
}

View File

@ -8,6 +8,11 @@ QDebug operator<<(QDebug debug, const JValue &val) {
return debug;
}
inline QChar readOne(QTextStream &in) {
QChar ch;
in >> ch;
return ch;
}
JValue JParser::readValue() {
if(ch=='{') {
JObj obj;
@ -16,15 +21,15 @@ JValue JParser::readValue() {
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";
if(ch == '"') key = readStr();
else if(ch!='n' || in.read(3)!="ull") throw QString("Unexpected char ")+ch+" (code "+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";
if(ch != ':') throw QString("Unexpected char ")+ch+" (code "+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!=',') throw QString("Unexpected char ")+ch+"' (code "+ch+"): was expecting } to end Object or comma to separate Object entries";
}
}
if(ch=='[') {
@ -36,15 +41,15 @@ JValue JParser::readValue() {
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!=',') throw QString("Unexpected char ")+ch+" (code "+ch+"): was expecting ] to end Array or comma to separate Array entries";
}
}
if(ch=='"') return readStr();
if((ch>='0' && ch<='9') || ch=='-') {
QByteArray buf;
QString buf;
buf += ch;
bool isInt = true;
while(readOne()) {
while(0 != (ch = readOne(in))) {
if((ch>'*' && ch<':' && ch!=',' && ch!='/') || ch=='e' || ch=='E') {
buf.append(ch);
if(isInt && ch=='.') isInt = false;
@ -65,34 +70,26 @@ JValue JParser::readValue() {
}
}
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(in.read(3)=="ull") return JValue();
else throw "Unexpected char n: expected 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(in.read(3)=="rue") return true;
else throw "Unexpected char t: expected 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";
if(in.read(4)=="alse") return false;
else throw "Unexpected char f: expected 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;
throw QString("Unexpected char ")+ch+" (code "+ch+"): expected {}, [], \"string\", number, null, true or false";
}
QString JParser::readStr() {
QByteArray buf;
while(readOne() != '"') {
QString buf;
while((ch = readOne(in)) != '"') {
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";
in>>ch;
if(ch==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');
@ -100,50 +97,24 @@ QString JParser::readStr() {
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 '\\'";
auto hex = in.read(4);
if(hex.size()<4) throw "Unexpected end-of-input in char escape sequence";
bool ok;
buf.append(hex.toUShort(&ok, 16));
if(! ok) throw "Illegal hex-digits in char escape sequence: \\u"+hex;
} else throw QString("Unrecognized char-escape ")+ch+" (code "+ch+")";
} else buf.append(ch);
}
return QString::fromUtf8(buf);
return 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)+")";
if(bk.unicode()) {
bk = QChar::Null;
if(! ch.isSpace()) return;
}
in.skipWhiteSpace();
in >> ch;
if(ch==0) throw "Unexpected end-of-input";
}
void JOut::write(const JValue &value) {

View File

@ -3,18 +3,15 @@
#include "cpp.h"
#include "QtCore/qhashfunctions.h"
#include <QDataStream>
#include <QTextStream>
class JValue;
using JObj = LinkedMap<QString, JValue>;
using JArray = Vector<JValue>;
QDebug operator<<(QDebug debug, const JValue &val);
class JValue {
public:
int64_t data = 0;
long long data = 0;
enum Type {
Null, Long, Ulong, Double, Bool, Obj, Array, Str
};
@ -120,28 +117,16 @@ public:
const JValue operator[](const QString &key) const {
return type==Obj ? (*(const JObj*) &data)[key] : JValue();
}
const JValue operator[](uint64_t i) const {
const JValue operator[](int 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();
@ -172,32 +157,31 @@ private:
JValue(const void *) = delete; // avoid implicit conversions from char * to bool
};
QDebug operator<<(QDebug debug, const JValue &val);
class JParser {
public:
JParser(QDataStream &in) : in(in) {}
JParser(QTextStream &in) : in(in) {
#if(QT_VERSION_MAJOR < 6)
in.setCodec("UTF-8");
#endif
}
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();
inline JValue read() {
skipSpace();
return readValue();
}
protected:
JValue readValue();
QString readStr();
void skipSpace();
unsigned char readOne() {
in >> ch;
return ch;
}
QDataStream &in;
unsigned char ch{0}, bk{0};
QTextStream &in;
QChar ch{0}, bk{0};
};
inline JValue JFrom(const QByteArray &json, QString *err = 0) {
QDataStream in(json);
QTextStream in(json);
try {
return JParser(in).read();
} catch (QString anerr) {
@ -210,7 +194,7 @@ inline JValue JFrom(const QByteArray &json, QString *err = 0) {
return JValue();
}
inline JValue JFrom(QIODevice *device, QString *err = 0) {
QDataStream in(device);
QTextStream in(device);
try {
return JParser(in).read();
} catch (QString anerr) {

View File

@ -22,22 +22,6 @@ QString errStr(QNetworkReply *reply) {
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()) {

View File

@ -93,23 +93,20 @@ public:
};
QString errStr(QNetworkReply *);
QString errStrWithData(QNetworkReply *, JValue * = 0);
QString errStrWithData(QNetworkReply *, QJsonDocument *);
QString errStrWithData(QNetworkReply *, QJsonDocument * = 0);
inline int waitFinished(QNetworkReply *reply, QObject *context, bool excludeUser = false) {
inline int waitFinished(QNetworkReply *reply, 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,
inline void abortSilence(QNetworkReply *reply) {
reply->blockSignals(true);
reply->abort();
reply->blockSignals(false);
reply->deleteLater();
}
const char* socketErrKey(int value);

View File

@ -25,6 +25,14 @@ class WaitingDlg : public QDialog {
public:
explicit WaitingDlg(QWidget *parent = nullptr, QString text = 0, QString sucText = 0);
inline void connAbort(QNetworkReply *reply) {
connect(this, &WaitingDlg::rejected, reply, [reply] {
reply->blockSignals(true);
reply->abort();
reply->blockSignals(false);
reply->deleteLater();
});
}
QLabel *fdText;
QString sucText;
WaitingIndicator *mIndicator;

View File

@ -0,0 +1,14 @@
#include "importbninprogramdlg.h"
#include "ui_importbninprogramdlg.h"
ImportBnInProgramDlg::ImportBnInProgramDlg(QWidget *parent) :
LoQDialog(parent),
ui(new Ui::ImportBnInProgramDlg)
{
ui->setupUi(this);
}
ImportBnInProgramDlg::~ImportBnInProgramDlg()
{
delete ui;
}

View File

@ -0,0 +1,22 @@
#ifndef IMPORTBNINPROGRAMDLG_H
#define IMPORTBNINPROGRAMDLG_H
#include <LoQClass/loqdialog.h>
namespace Ui {
class ImportBnInProgramDlg;
}
class ImportBnInProgramDlg : public LoQDialog
{
Q_OBJECT
public:
explicit ImportBnInProgramDlg(QWidget *parent = nullptr);
~ImportBnInProgramDlg();
private:
Ui::ImportBnInProgramDlg *ui;
};
#endif // IMPORTBNINPROGRAMDLG_H

View File

@ -0,0 +1,68 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>ImportBnInProgramDlg</class>
<widget class="QDialog" name="ImportBnInProgramDlg">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>638</width>
<height>296</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>10</x>
<y>210</y>
<width>621</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ImportBnInProgramDlg</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>ImportBnInProgramDlg</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

80
LedOK/importprogramdlg.ui Normal file
View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="windowModality">
<enum>Qt::NonModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>320</width>
<height>240</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>320</width>
<height>240</height>
</size>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="sizeGripEnabled">
<bool>false</bool>
</property>
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>10</x>
<y>200</y>
<width>301</width>
<height>32</height>
</rect>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>buttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -4,9 +4,6 @@
#include <QMessageBox>
#include <QSplashScreen>
#include <QStandardPaths>
#if(QT_VERSION_MAJOR > 5)
#include <QImageReader>
#endif
#ifdef _MSC_VER //MSVC编译器
#include <Windows.h>
@ -30,15 +27,12 @@ LONG WINAPI handleException(_EXCEPTION_POINTERS *excep) {
}
#endif
QString css;
int main(int argc, char *argv[]) {
#if(QT_VERSION_MAJOR > 5)
QImageReader::setAllocationLimit(0);
#else
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
QApplication::setHighDpiScaleFactorRoundingPolicy(Qt::HighDpiScaleFactorRoundingPolicy::PassThrough);
#endif
QApplication::setOrganizationName("Sysolution");
QApplication::setOrganizationName("Shanghai Xixun Electronic Technology Co., Ltd.");
QApplication::setOrganizationDomain("www.ledok.cn");
QApplication::setApplicationName("LedOK Express");
QApplication::setStyle("Fusion");
@ -50,7 +44,7 @@ int main(int argc, char *argv[]) {
QFile file(":/css.css");
if(file.exists() && file.open(QFile::ReadOnly)) {
a.setStyleSheet(file.readAll());
a.setStyleSheet(css = file.readAll());
file.close();
}
QFont font;

View File

@ -98,16 +98,6 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
});
QSettings settings;
auto MainGeo = settings.value("MainGeo");
if(! MainGeo.isValid()) {
QSettings old("Shanghai Xixun Electronic Technology Co., Ltd.", "LedOK Express");
MainGeo = old.value("MainGeo");
if(MainGeo.isValid()) {
auto keys = old.allKeys();
for(auto &key : keys) settings.setValue(key, old.value(key));
old.remove("");
}
}
QString langName = settings.value("Language").toString();
QAction *actLan = 0;
if(! langName.isEmpty()) {
@ -130,7 +120,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
emit menuLang->triggered(actLan);
QCoreApplication::installTranslator(&translator);
auto geo = MainGeo.toRect();
auto geo = settings.value("MainGeo").toRect();
if(geo.width()>=800 && geo.height()>=500 && geo.x()>=-600 && geo.x()<=1280 && geo.y()>=-200 && geo.y()<=800) setGeometry(geo);
else resize(1280, 800);
if(settings.value("MainIsMax", false).toBool()) setWindowState(Qt::WindowMaximized);
@ -146,12 +136,16 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
setPalette(plt);
//项目保存的文档路径
auto dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
if(! dataDir.isEmpty()) {
QDir dataQDir(dataDir);
if(! dataQDir.exists()) dataQDir.mkpath(dataDir);
QString doc_path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
if(!doc_path.isEmpty()) {
QDir app_dir = QDir(doc_path + "/" + QCoreApplication::applicationName());
if(!app_dir.exists()) {
QDir doc_dir(doc_path);
doc_dir.mkdir(QCoreApplication::applicationName());
}
}
//创建一个垂直布局
auto vBox = new VBox(center);
vBox->setContentsMargins(0, 0, 0, 0);
vBox->setSpacing(0);
@ -213,7 +207,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
fdAntiTip->setWordWrap(true);
hBox->addWidget(fdAntiTip, 1);
auto fdWidthSplit = new QCheckBox(tr("Ultra-Long Screen Split"));
auto fdWidthSplit = new QCheckBox(tr("Width Split"));
fdWidthSplit->setChecked(gWidthSplit);
vBox->addWidget(fdWidthSplit);
@ -229,10 +223,6 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
fdHideDetect->setChecked(gHideDetect);
vBox->addWidget(fdHideDetect);
auto fdShowAlias = new QCheckBox(tr("Show Alias in Terminal Control"));
fdShowAlias->setChecked(gShowAlias);
vBox->addWidget(fdShowAlias);
auto fdShowLora = new QCheckBox(tr("Show Lora Screen"));
fdShowLora->setChecked(gShowLora);
vBox->addWidget(fdShowLora);
@ -248,7 +238,6 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
settings.setValue("WidthSplit", gWidthSplit = fdWidthSplit->isChecked());
settings.setValue("SendBatch", gSendBatch = fdSendBatch->value());
settings.setValue("HideDetect", gHideDetect = fdHideDetect->isChecked());
settings.setValue("ShowAlias", gShowAlias = fdShowAlias->isChecked());
settings.setValue("GuangYingPin", gShowLora = fdShowLora->isChecked());
dlg.accept();
});
@ -256,16 +245,6 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
dlg.exec();
fdDetectCard->setVisible(! gHideDetect);
if(mDevicePanel->mDeviceTable->isColumnHidden(mDevicePanel->mDeviceTable->columnCount()-1)) {
if(gShowAlias) {
mDevicePanel->mDeviceTable->showColumn("alias");
mDevicePanel->mDeviceTable->hideColumn("ip");
} else {
mDevicePanel->mDeviceTable->hideColumn("alias");
mDevicePanel->mDeviceTable->showColumn("ip");
}
mDevicePanel->mDeviceTable->adjSections(-1, 0);
}
mBtnGrp->button(MainPage_LoraScreen)->setVisible(gShowLora);
});
menu_setting->addAction(actPreferences);
@ -299,7 +278,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
vBox->addWidget(fdUpdLog);
auto reply = NetReq(updates["changelog_zh_CN"].toString()).timeout(60000).get();
ConnReply(reply, fdUpdLog) [=] {
connect(reply, &QNetworkReply::finished, this, [=] {
auto err = errStr(reply);
if(! err.isEmpty()) {
qCritical()<<"Check Updates"<<err;
@ -322,7 +301,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
auto filePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/ledok-express-updater";
auto url = updates["url"].toString();
auto idx = url.lastIndexOf('.');
if(idx!=-1) filePath += url.mid(idx);
if(idx!=-1) filePath += url.midRef(idx);
qDebug()<<"filePath"<<filePath;
QFile qFile(filePath);
if(! qFile.open(QFile::WriteOnly)) {
@ -334,8 +313,15 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
msgBox.setWindowTitle(tr("Downloading updates"));
msgBox.setText(tr("Downloading updates")+": 0% ");
auto reply = NetReq(url).timeout(60000).get();
auto pfile = &qFile;
ConnReply(reply, &msgBox) [=, &msgBox] {
connect(&msgBox, &QMessageBox::rejected, reply, [reply] {
abortSilence(reply);
});
connect(reply, &QNetworkReply::downloadProgress, &msgBox, [&, reply](qint64 bytesReceived, qint64 bytesTotal) {
if(bytesTotal==0) return;
msgBox.setText(tr("Downloading updates")+": "+QString::number(bytesReceived*100/bytesTotal)+"% ");
qFile.write(reply->readAll());
});
connect(reply, &QNetworkReply::finished, &msgBox, [&, reply] {
auto err = errStr(reply);
if(! err.isEmpty()) {
msgBox.setIcon(QMessageBox::Critical);
@ -344,11 +330,6 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
}
msgBox.accept();
});
connect(reply, &QNetworkReply::downloadProgress, &msgBox, [=, &msgBox](qint64 bytesReceived, qint64 bytesTotal) {
if(bytesTotal==0) return;
msgBox.setText(tr("Downloading updates")+": "+QString::number(bytesReceived*100/bytesTotal)+"% ");
pfile->write(reply->readAll());
});
auto res = msgBox.exec();
qFile.close();
if(res != QDialog::Accepted) return;
@ -358,7 +339,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
menu_setting->addAction(act_update);
auto reply = NetReq(UpdVerUrl).timeout(60000).get();
ConnReply(reply, this) [=] {
connect(reply, &QNetworkReply::finished, this, [=] {
auto err = errStr(reply);
if(! err.isEmpty()) {
qCritical()<<"Check Updates"<<err;
@ -372,11 +353,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
return;
}
#ifdef Q_OS_WIN
#if(QT_VERSION_MAJOR > 5)
updates = json["win-64"].toObject();
#else
updates = json["win"].toObject();
#endif
#endif
#ifdef Q_OS_MAC
updates = json["mac"].toObject();
@ -495,7 +472,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
mDevicePanel->mDeviceTable->fdCheckAll->hide();
mDevicePanel->fdCardNumInfo->hide();
if(mDevicePanel->mDeviceCtrlPanel) {
for(int j="id"**mDevicePanel->mDeviceTable+1; j<mDevicePanel->mDeviceTable->columnCount(); j++) mDevicePanel->mDeviceTable->showColumn(j);
for(int j="screenSize"**mDevicePanel->mDeviceTable; j<mDevicePanel->mDeviceTable->columnCount(); j++) mDevicePanel->mDeviceTable->showColumn(j);
mDevicePanel->mDeviceTable->setMaximumWidth(0xffffff);
mDevicePanel->mDeviceCtrlPanel->hide();
}
@ -503,11 +480,10 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
mDevicePanel->mDeviceTable->showColumn("check");
mDevicePanel->mDeviceTable->fdCheckAll->show();
mDevicePanel->fdCardNumInfo->show();
auto specialIdx = (gShowAlias ? "alias" : "ip")**mDevicePanel->mDeviceTable;
for(int j="id"**mDevicePanel->mDeviceTable+1; j<mDevicePanel->mDeviceTable->columnCount(); j++) if(j!=specialIdx) mDevicePanel->mDeviceTable->hideColumn(j);
for(int j="screenSize"**mDevicePanel->mDeviceTable; j<mDevicePanel->mDeviceTable->columnCount(); j++) mDevicePanel->mDeviceTable->hideColumn(j);
if(mDevicePanel->mDeviceCtrlPanel) mDevicePanel->mDeviceCtrlPanel->show();
else mDevicePanel->newCtrl();
mDevicePanel->mDeviceTable->setMaximumWidth(300);
mDevicePanel->mDeviceTable->setMaximumWidth(340);
}
});
@ -553,27 +529,18 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
}
});
hBox->addWidget(fdDetectCard);
// auto btn = new QPushButton("Test");
// connect(btn, &QPushButton::clicked, this, [=] {
// auto www = new TTTWgt;
// www->show();
// });
// hBox->addWidget(btn);
hBox->addStretch();
hBox->addLabel("V" APP_VERSION" - " __DATE__);
gApkHome = settings.value("ApkHome").toString();
gVideoCompress = settings.value("VideoCompress").toBool();
gVideoTranscoding = settings.value("VideoTranscoding").toBool();
gTextAntialiasing = settings.value("TextAntialiasing").toBool();
gWidthSplit = settings.value("WidthSplit").toBool();
gVideoCompress = settings.value("VideoCompress", true).toBool();
gVideoTranscoding = settings.value("VideoTranscoding", true).toBool();
gTextAntialiasing = settings.value("TextAntialiasing", false).toBool();
gWidthSplit = settings.value("WidthSplit", false).toBool();
gSendBatch = settings.value("SendBatch", 5).toInt();
gHideDetect = settings.value("HideDetect").toBool();
gShowAlias = settings.value("ShowAlias").toBool();
gShowLora = settings.value("GuangYingPin").toBool();
gHideDetect = settings.value("HideDetect", false).toBool();
gShowLora = settings.value("GuangYingPin", false).toBool();
if(gHideDetect) fdDetectCard->hide();
if(! gShowLora) mBtnGrp->button(MainPage_LoraScreen)->hide();

View File

@ -9,7 +9,6 @@
#include "progpanel.h"
#include <QTranslator>
#include <QActionGroup>
#include <QJsonObject>
class MainWindow : public BaseWin {
Q_OBJECT

View File

@ -0,0 +1,153 @@
/**
* @author :
* @date : 201704
* @version: 1.0
* @note : Apache 2.0 ;
* 使
* @remarks:
* http://www.apache.org/licenses/LICENSE-2.0
*
*
*
*
*
*
* https://git.oschina.net/Mr_ChenLuYong/screenshot
*
*
*
*
*
*
* http://blog.csdn.net/csnd_ayo
*
* http://blog.csdn.net/csnd_ayo/article/details/70197915
*
* BugIssues
*
*/
#include "oeamplifier.h"
#include <QPixmap>
#include <QPainter>
#ifndef QT_NO_DEBUG
#include <QDebug>
#endif
#include "oecommonhelper.h"
OEAmplifier::OEAmplifier(std::shared_ptr<QPixmap> originPainting, QWidget *parent) :
QWidget(parent), originPainting_(originPainting) {
/// 设置成无边框对话框
setWindowFlags(Qt::FramelessWindowHint|Qt::WindowSystemMenuHint);
/// 开启鼠标实时追踪
setMouseTracking(true);
/// 设置默认大小
sideLength_ = 122 * OECommonHelper::getWindowHeightMultiplyingPower();
imageHeight_ = 90 * OECommonHelper::getWindowHeightMultiplyingPower();
setFixedSize(sideLength_,sideLength_);
/// 默认隐藏
hide();
}
void OEAmplifier::onSizeChange(int w, int h) {
screenSize_ = QSize(w, h);
}
void OEAmplifier::onPostionChange(int x, int y) {
cursorPoint_ = QPoint(x, y);
raise();
int dest_x = x + 4;
int dest_y = y + 26;
/// 超出屏幕检测
const QSize& parent_size = parentWidget()->size();
if (dest_y + height() > parent_size.height()) {
dest_y = y - 26 - height();
}
if (dest_x + width() > parent_size.width()) {
dest_x = x - 4 - width();
}
move(dest_x, dest_y);
}
/// 绘制鼠标拖拽时选区矩形的右下顶点的放大图;
void OEAmplifier::paintEvent(QPaintEvent *) {
QPainter painter(this);
/// 绘制背景
painter.fillRect(rect(), QColor(0, 0, 0, 160));
QPixmap endPointImage;
/// 绘制放大图;
const QSize& parent_size = parentWidget()->size();
/**
* @bug :
* QQ截图的采取方式是一致的
*
* @marker:
*
* @note :
*/
if ((cursorPoint_.x() + 15 < parent_size.width() && cursorPoint_.x() - 15 > 0)
&& (cursorPoint_.y() + 11 < parent_size.height() && cursorPoint_.y() - 11 > 0)) {
endPointImage = originPainting_->
copy(QRect(cursorPoint_.x() - 15,
cursorPoint_.y() - 11, 30, 22))
.scaled(sideLength_, imageHeight_);
painter.drawPixmap(0,0, endPointImage);
}
else {
endPointImage = originPainting_->
copy(QRect(cursorPoint_.x() - 15,
cursorPoint_.y() - 11, 30, 22));
}
/// 绘制十字
painter.setPen(QPen(QColor(0, 180, 255 , 180), 4));
// 竖线;
painter.drawLine(QPoint(sideLength_ >> 1, 0),
QPoint(sideLength_ >> 1,
imageHeight_ - 4));
// 横线;
painter.drawLine(QPoint(0, imageHeight_ >> 1),
QPoint(sideLength_,
imageHeight_ >> 1));
/// 绘制大图内边框
painter.setPen(QPen(Qt::white, 2));
painter.drawRect(2,2,width()-4, imageHeight_-4);
/// 绘制外边框
painter.setPen(QPen(Qt::black, 1));
painter.drawRect(0,0,width()-1,height()-1);
/// 当前选中矩形的宽高信息;
QString select_screen_info = QString("%1×%2")
.arg(screenSize_.width()).arg(screenSize_.height());
/// 当前鼠标像素值的RGB信息
QImage image = originPainting_->toImage();
QColor cursor_pixel = image.pixel(cursorPoint_);
QString select_pt_rgb = QString("RGB:(%1,%2,%3)")
.arg(cursor_pixel.red())
.arg(cursor_pixel.green())
.arg(cursor_pixel.blue());
/// 绘制坐标轴相关数据
painter.setPen(Qt::white);
painter.drawText(QPoint(6, imageHeight_+14),select_screen_info);
painter.drawText(QPoint(6, imageHeight_+27),select_pt_rgb);
}

View File

@ -0,0 +1,93 @@
/**
* @author :
* @date : 201704
* @version: 1.0
* @note : Apache 2.0 ;
* 使
* @remarks:
* http://www.apache.org/licenses/LICENSE-2.0
*
*
*
*
*
*
* https://git.oschina.net/Mr_ChenLuYong/screenshot
*
*
*
*
*
*
* http://blog.csdn.net/csnd_ayo
*
* http://blog.csdn.net/csnd_ayo/article/details/70197915
*
* BugIssues
*
*/
#ifndef OEAMPLIFIER_H
#define OEAMPLIFIER_H
#include <memory>
#include <QWidget>
/**
* @class : OEAmplifier
* @brief :
* @note :
*/
class OEAmplifier : public QWidget
{
Q_OBJECT
public:
explicit OEAmplifier(std::shared_ptr<QPixmap> originPainting, QWidget *parent = 0);
signals:
public slots:
/**
* @brief :
* @param : w
* @param : h
* @date : 2017429
*/
void onSizeChange(int w, int h);
/**
* @brief :
* @param : w
* @param : h
* @date : 2017429
*/
void onPostionChange(int x, int y);
protected:
/**
* @brief :
* @date : 2017429
*/
virtual void paintEvent(QPaintEvent *);
private:
/// 外部组件的大小信息
QSize screenSize_;
/// 鼠标的位置
QPoint cursorPoint_;
/// 取色放大器的边长
int sideLength_;
/// 放大区的高度
int imageHeight_;
/// 屏幕原画
std::shared_ptr<QPixmap> originPainting_;
};
#endif /// OEAMPLIFIER_H

View File

@ -0,0 +1,141 @@
/**
* @author :
* @date : 201704
* @version: 1.0
* @note : Apache 2.0 ;
* 使
* @remarks:
* http://www.apache.org/licenses/LICENSE-2.0
*
*
*
*
*
*
* https://git.oschina.net/Mr_ChenLuYong/screenshot
*
*
*
*
*
*
* http://blog.csdn.net/csnd_ayo
*
* http://blog.csdn.net/csnd_ayo/article/details/70197915
*
* BugIssues
*
*/
#include "oecommonhelper.h"
#include <QFile>
#include <QTranslator>
#include <QApplication>
#include <QWidget>
#include <QDesktopWidget>
#include <windows.h>
#ifndef QT_NO_DEBUG
#include <QDebug>
#endif
#define WINDOW_BASESIZE_WIDTH (1920)
#define WINDOW_BASESIZE_HEIGHT (1080)
float OECommonHelper::widthMultiplyingPower_ = 0;
float OECommonHelper::heightMultiplyingPower_ = 0;
void OECommonHelper::setStyle(const QString &style) {
QFile qss(style);
qss.open(QFile::ReadOnly);
qApp->setStyleSheet(qss.readAll());
qss.close();
}
void OECommonHelper::setLanguagePack(const QString &language) {
// 加载中文包
QTranslator translator;
translator.load(language);
qApp->installTranslator(&translator);
}
void OECommonHelper::moveCenter(QWidget *widget, QRect parentRect) {
if (parentRect.isEmpty()) {
parentRect = QApplication::desktop()->rect();
}
widget->move (((parentRect.width() - widget->width()) >> 1),
((parentRect.height() - widget->height()) >> 1));
}
const float &OECommonHelper::getWindowWidthMultiplyingPower() {
if (widthMultiplyingPower_ == 0) {
upWindowSizeMultiplyingPower();
}
return widthMultiplyingPower_;
}
const float & OECommonHelper::getWindowHeightMultiplyingPower() {
if (heightMultiplyingPower_ == 0) {
upWindowSizeMultiplyingPower();
}
return heightMultiplyingPower_;
}
void OECommonHelper::upWindowSizeMultiplyingPower() {
QSize temp_size = QApplication::desktop()->size();
widthMultiplyingPower_ = (float)temp_size.width()
/ (float)WINDOW_BASESIZE_WIDTH;
heightMultiplyingPower_ = (float)temp_size.height()
/ (float)WINDOW_BASESIZE_HEIGHT;
}
bool OECommonHelper::getSmallestWindowFromCursor(QRect& out_rect) {
HWND hwnd;
POINT pt;
// 获得当前鼠标位置
::GetCursorPos(&pt);
// 获得当前位置桌面上的子窗口
hwnd = ::ChildWindowFromPointEx(::GetDesktopWindow(), pt, CWP_SKIPDISABLED | CWP_SKIPINVISIBLE);
if (hwnd != NULL) {
HWND temp_hwnd;
temp_hwnd = hwnd;
while (true) {
::GetCursorPos(&pt);
::ScreenToClient(temp_hwnd, &pt);
temp_hwnd = ::ChildWindowFromPointEx(temp_hwnd, pt, CWP_SKIPINVISIBLE);
if (temp_hwnd == NULL || temp_hwnd == hwnd)
break;
hwnd = temp_hwnd;
}
RECT temp_window;
::GetWindowRect(hwnd, &temp_window);
out_rect.setRect(temp_window.left,temp_window.top,
temp_window.right - temp_window.left,
temp_window.bottom - temp_window.top);
return true;
}
return false;
}
bool OECommonHelper::getCurrentWindowFromCursor(QRect &out_rect)
{
HWND hwnd;
POINT pt;
// 获得当前鼠标位置
::GetCursorPos(&pt);
// 获得当前位置桌面上的子窗口
hwnd = ::ChildWindowFromPointEx(::GetDesktopWindow(), pt, CWP_SKIPDISABLED | CWP_SKIPINVISIBLE);
if (hwnd != NULL) {
RECT temp_window;
::GetWindowRect(hwnd, &temp_window);
out_rect.setRect(temp_window.left, temp_window.top,
temp_window.right - temp_window.left,
temp_window.bottom - temp_window.top);
return true;
}
return false;
}

View File

@ -0,0 +1,128 @@
/**
* @author :
* @date : 201704
* @version: 1.0
* @note : Apache 2.0 ;
* 使
* @remarks:
* http://www.apache.org/licenses/LICENSE-2.0
*
*
*
*
*
*
* https://git.oschina.net/Mr_ChenLuYong/screenshot
*
*
*
*
*
*
* http://blog.csdn.net/csnd_ayo
*
* http://blog.csdn.net/csnd_ayo/article/details/70197915
*
* BugIssues
*
*/
#ifndef COMMONHELPER_H
#define COMMONHELPER_H
#include <QString>
#include <QRect>
class QWidget;
/**
* @class : OECommonHelper
* @brief :
* @note :
*/
class OECommonHelper
{
public:
/**
* @brief : QSS文件
* @param : style
* @author:
* @date : 20170410
* @remark: qrc路径 qrc:/
**/
static void setStyle(const QString &style);
/**
* @brief :
* @param : language
* @author:
* @date : 20170410
**/
static void setLanguagePack(const QString& language);
/**
* @brief :
* @param : widget
* @param : parentRect
* @author:
* @date : 20170410
**/
static void moveCenter(QWidget* widget, QRect parentRect = {});
/**
* @brief :
* @return: float
* @author:
* @date : 20170410
**/
static const float& getWindowWidthMultiplyingPower(void);
/**
* @brief :
* @return: float
* @author:
* @date : 20170410
**/
static const float& getWindowHeightMultiplyingPower(void);
/**
* @brief :
* @param : out_rect ()
* @return: :true
* @author:
* @date : 20170410
**/
static bool getSmallestWindowFromCursor(QRect &out_rect);
/**
* @brief :
* @param : out_rect ()
* @return: :true
* @author:
* @date : 20170410
**/
static bool getCurrentWindowFromCursor(QRect &out_rect);
protected:
/**
* @brief :
* @author:
* @date : 20170410
**/
static void upWindowSizeMultiplyingPower(void);
private:
/// 窗口横向倍率
static float widthMultiplyingPower_;
/// 窗口纵向倍率
static float heightMultiplyingPower_;
};
#endif /// COMMONHELPER_H

View File

@ -0,0 +1,86 @@
#include "oemodelview.h"
#include <QPen>
#include <QPainter>
#include <QPoint>
#include <QDebug>
#include <QtMath>
/// @test : 测试变量
QPoint startPoint_;
QPoint endPoint_;
OEModelView::OEModelView(MODEL model,
QWidget *parent) : QWidget(parent),
color_(Qt::red) {
/// 确定画图样式
switch (model) {
case MODEL::Arrows:
{
drawFunc_ = &OEModelView::drawArrows;
break;
}
default:
{
drawFunc_ = &OEModelView::drawArrows;
}
}
}
void OEModelView::paintEvent(QPaintEvent *) {
QPainter paiter(this);
/// @test : 测试变量
startPoint_ = QPoint(width(),height());
endPoint_ = {};
/// 绘制图形
(this->*drawFunc_)(startPoint_, endPoint_, paiter);
}
void OEModelView::drawArrows(const QPoint& startPoint,
const QPoint& endPoint,
QPainter &paiter) {
/// 消锯齿
paiter.setRenderHint(QPainter::Antialiasing, true);
/// 创建画笔,设置画刷
QPen pen;
pen.setColor(color_);
pen.setWidth(1);
paiter.setPen(pen);
paiter.setBrush(color_);
/// 箭头部分三角形的腰长
double par = 15.0;
double slopy = atan2((endPoint.y() - startPoint.y()),
(endPoint.x() - startPoint.x()));
double cos_y = cos(slopy);
double sin_y = sin(slopy);
QPoint head_point1 = QPoint(endPoint.x() + int(-par*cos_y - (par / 2.0 * sin_y)),
endPoint.y() + int(-par*sin_y + (par / 2.0 * cos_y)));
QPoint head_point2 = QPoint(endPoint.x() + int(-par*cos_y + (par / 2.0 * sin_y)),
endPoint.y() - int(par / 2.0*cos_y + par * sin_y));
QPoint head_points[3] = { endPoint, head_point1, head_point2 };
/// 绘制箭头部分
paiter.drawPolygon(head_points, 3);
/// 计算箭身部分
int offset_x = int(par*sin_y / 3);
int offset_y = int(par*cos_y / 3);
QPoint body_point1, body_point2;
body_point1 = QPoint(endPoint.x() + int(-par*cos_y - (par / 2.0*sin_y)) +
offset_x, endPoint.y() + int(-par*sin_y + (par / 2.0*cos_y)) - offset_y);
body_point2 = QPoint(endPoint.x() + int(-par*cos_y + (par / 2.0*sin_y) - offset_x),
endPoint.y() - int(par / 2.0*cos_y + par*sin_y) + offset_y);
QPoint body_points[3] = { startPoint, body_point1, body_point2 };
/// 绘制箭身部分
paiter.drawPolygon(body_points, 3);
}
void OEModelView::onColor(const QColor &color) {
color_ = color;
}

View File

@ -0,0 +1,61 @@
#ifndef OEMODELVIEW_H
#define OEMODELVIEW_H
#include <QWidget>
#include <QMap>
#include <QColor>
#include <QPoint>
class OEModelView : public QWidget
{
Q_OBJECT
public:
/**
* @brief :
*/
enum MODEL{
Arrows = 0, /// 箭头
Rectangle = 1, /// 矩形
Roundness /// 圆形
};
private:
typedef void (OEModelView::*PDRAWFUNC)
(const QPoint &,const QPoint &, QPainter&);
signals:
public:
explicit OEModelView(MODEL model = MODEL::Arrows,
QWidget *parent = 0);
protected:
/**
* @brief :
*/
virtual void paintEvent(QPaintEvent *);
private:
void drawArrows(const QPoint &startPoint,
const QPoint &endPoint,
QPainter& paiter);
public slots:
void onColor(const QColor &color);
private:
QColor color_;
PDRAWFUNC drawFunc_;
/// @bug : 莫名,开启此处变量的声明,程序就会崩溃。
// QPoint ssPoint331_;
// QPoint esoint233_;
};
#endif // OEMODELVIEW_H

View File

@ -0,0 +1,768 @@
/**
* @author :
* @date : 201704
* @version: 1.0
* @note : Apache 2.0 ;
* 使
* @remarks:
* http://www.apache.org/licenses/LICENSE-2.0
*
*
*
*
*
*
* https://git.oschina.net/Mr_ChenLuYong/screenshot
*
*
*
*
*
*
* http://blog.csdn.net/csnd_ayo
*
* http://blog.csdn.net/csnd_ayo/article/details/70197915
*
* BugIssues
*
*/
#include "oescreenshot.h"
#include <QDesktopWidget>
#include <QApplication>
#include <QMouseEvent>
#include <QFileDialog>
#include <QClipboard>
#include <QDateTime>
#include <QPainter>
#include <QScreen>
#include <QCursor>
#include <QMutex>
#include <QMenu>
#include <QPen>
#ifndef QT_NO_DEBUG
#include <QDebug>
#endif
#include <windows.h>
#include "oeamplifier.h"
#include "oecommonhelper.h"
/// 鼠标按钮图片的十六进制数据
static const unsigned char uc_mouse_image[] = {
0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52
,0x00, 0x00, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x2D, 0x08, 0x06, 0x00, 0x00, 0x00, 0x52, 0xE9, 0x60
,0xA2, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0B, 0x13, 0x00, 0x00, 0x0B
,0x13, 0x01, 0x00, 0x9A, 0x9C, 0x18, 0x00, 0x00, 0x01, 0x40, 0x49, 0x44, 0x41, 0x54, 0x58, 0x85
,0xED, 0xD5, 0x21, 0x6E, 0xC3, 0x30, 0x14, 0xC6, 0xF1, 0xFF, 0x9B, 0xC6, 0x36, 0x30, 0x38, 0xA9
,0x05, 0x01, 0x05, 0x81, 0x05, 0x03, 0x39, 0xCA, 0x60, 0x8F, 0xD2, 0x03, 0xEC, 0x10, 0x3B, 0x46
,0xC1, 0xC0, 0xC6, 0x0A, 0x3B, 0x96, 0xB1, 0x80, 0x82, 0xC1, 0x56, 0x2A, 0xFF, 0x06, 0xE2, 0x36
,0x75, 0x9A, 0xB4, 0xCA, 0xEC, 0x4E, 0x9A, 0xE4, 0x2F, 0xB2, 0x42, 0x22, 0xFF, 0xF2, 0xFC, 0x9C
,0x18, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52, 0xFE, 0x55, 0xE4, 0xC6, 0xA0
,0xDC, 0xC4, 0x71, 0x87, 0xC1, 0xC1, 0x68, 0x01, 0xCC, 0x06, 0xC2, 0x51, 0xD0, 0x29, 0xB0, 0x18
,0x00, 0xDF, 0xC6, 0x40, 0x33, 0x37, 0x84, 0x30, 0x4C, 0x80, 0x85, 0xCE, 0x7B, 0x2E, 0x2A, 0x91
,0x84, 0x24, 0xBE, 0x25, 0xDE, 0x25, 0x5E, 0x2F, 0x6E, 0xAE, 0xD0, 0x37, 0x92, 0x10, 0xF0, 0x09
,0x54, 0x40, 0xE9, 0xEE, 0x15, 0xC6, 0xA2, 0x77, 0xFE, 0xE0, 0xE5, 0x85, 0x8F, 0x16, 0x58, 0xDF
,0x35, 0x06, 0x5B, 0xD3, 0xB9, 0xD4, 0x11, 0xD0, 0xA5, 0x8F, 0xDE, 0x57, 0x75, 0x83, 0x73, 0x50
,0x06, 0xF6, 0x72, 0x0A, 0x47, 0x40, 0x57, 0x0D, 0x38, 0xDE, 0xC0, 0x04, 0x6F, 0x68, 0x05, 0x36
,0xF5, 0xE1, 0x08, 0x3D, 0xCD, 0xEA, 0xEA, 0x5A, 0xD8, 0xBE, 0x5A, 0x46, 0xB0, 0x05, 0x1E, 0xAC
,0xF1, 0xC2, 0xD1, 0xCC, 0x01, 0x6D, 0x74, 0x02, 0xDB, 0x3B, 0xBF, 0xD3, 0x73, 0x07, 0x87, 0x2F
,0xEF, 0x53, 0x07, 0x38, 0x82, 0x2F, 0xF6, 0xFB, 0xB8, 0x81, 0x73, 0x41, 0x69, 0x28, 0x3A, 0x7A
,0x5C, 0xDD, 0x73, 0xCF, 0x3A, 0x86, 0xA3, 0x05, 0x87, 0xEA, 0xCC, 0x60, 0xA1, 0x06, 0x75, 0x89
,0xFE, 0x77, 0x92, 0x76, 0x68, 0x23, 0xEF, 0x88, 0xD3, 0x4C, 0xA8, 0x10, 0x7A, 0xD4, 0xEF, 0x8E
,0xBE, 0x8B, 0x68, 0x79, 0x3A, 0xB1, 0x72, 0xE1, 0xAE, 0xBC, 0x13, 0x0D, 0xDE, 0xBD, 0x3D, 0xF3
,0x08, 0x15, 0xD4, 0xDF, 0x4C, 0x06, 0x36, 0xF7, 0x9E, 0x09, 0xED, 0xE9, 0x99, 0x97, 0x3E, 0x42
,0xFF, 0x30, 0x42, 0x4B, 0xA1, 0x8D, 0xD8, 0xE9, 0x2A, 0xBD, 0xED, 0x41, 0x25, 0x2A, 0x89, 0x37
,0x1F, 0xBD, 0xEA, 0x61, 0x8B, 0x5F, 0xDD, 0xC1, 0xFA, 0x01, 0xD8, 0xA3, 0x8F, 0xFB, 0xCA, 0x70
,0x16, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
};
OEScreenshot * OEScreenshot::self_ = nullptr;
bool OEScreenshot::isActivity_ = false;
bool OEScreen::isInit_ = false;
OEScreenshot::OEScreenshot(QWidget *parent) : QWidget(parent),
isLeftPressed_ (false), backgroundScreen_(nullptr),
originPainting_(nullptr), screenTool_(nullptr) {
/// 初始化鼠标
initCursor();
/// 截取屏幕信息
initGlobalScreen();
/// 初始化鼠标放大器
initAmplifier();
/// 初始化大小感知器
initMeasureWidget();
/// 全屏窗口
showFullScreen();
/// 窗口与显示屏对齐
setGeometry(getScreenRect());
/// 霸道置顶
onEgoistic();
/// 开启鼠标实时追踪
setMouseTracking(true);
/// 更新鼠标的位置
emit cursorPosChange(cursor().pos().x(), cursor().pos().y());
/// 更新鼠标区域窗口
updateMouse();
/// 展示窗口
show();
}
OEScreenshot::~OEScreenshot(void) {
}
/**
* @brief
* @returnOEScreenshot
*/
OEScreenshot *OEScreenshot::Instance(void) {
if (!isActivity_ && self_) {
destroy();
}
static QMutex mutex;
if (!self_) {
QMutexLocker locker(&mutex);
if (!self_) {
isActivity_ = true;
self_ = new OEScreenshot;
}
}
return self_;
}
void OEScreenshot::destroy(void) {
if (!isActivity_ && self_) {
delete self_;
self_ = nullptr;
}
}
void OEScreenshot::hideEvent(QHideEvent *) {
isActivity_ = false;
}
void OEScreenshot::closeEvent(QCloseEvent *) {
isActivity_ = false;
}
void OEScreenshot::mouseDoubleClickEvent(QMouseEvent *) {
emit doubleClick();
}
/**
* ()
*/
void OEScreenshot::initAmplifier(std::shared_ptr<QPixmap> originPainting) {
std::shared_ptr<QPixmap> temp_pm = originPainting;
if (temp_pm == nullptr) {
temp_pm = originPainting_;
}
amplifierTool_.reset(new OEAmplifier(temp_pm, this));
connect(this,SIGNAL(cursorPosChange(int,int)),
amplifierTool_.get(), SLOT(onPostionChange(int,int)));
amplifierTool_->show();
amplifierTool_->raise();
}
void OEScreenshot::initMeasureWidget(void)
{
rectTool_.reset(new OERect(this));
rectTool_->raise();
}
/**
*
*/
const QRect &OEScreenshot::getScreenRect(void) {
if (!desktopRect_.isEmpty()) {
return desktopRect_;
}
/// 获得屏幕个数
int temp_screen_num = QApplication::screens().size();
/// 获得屏幕大小
desktopRect_ = QApplication::desktop()->rect();
if (temp_screen_num != 1) {
/// 多屏幕策略
const int& temp = desktopRect_.width() -
(desktopRect_.width() / temp_screen_num);
/// 重新设置矩形
desktopRect_ = QRect(-temp, 0,
desktopRect_.width(), desktopRect_.height());
}
return desktopRect_;
}
std::shared_ptr<QPixmap> OEScreenshot::initGlobalScreen(void) {
if (backgroundScreen_.get() != nullptr) {
return backgroundScreen_;
}
/// 获得屏幕原画
std::shared_ptr<QPixmap> temp_screen = getGlobalScreen();
/// 制作暗色屏幕背景
QPixmap temp_dim_pix(temp_screen->width(), temp_screen->height());
temp_dim_pix.fill((QColor(0, 0, 0, 160)));
backgroundScreen_.reset(new QPixmap(*temp_screen));
QPainter p(backgroundScreen_.get());
p.drawPixmap(0, 0, temp_dim_pix);
return backgroundScreen_;
}
/*
*
* QPixmap*
*/
std::shared_ptr<QPixmap> OEScreenshot::getGlobalScreen(void) {
if (originPainting_.get() == nullptr) {
/// 截取当前桌面,作为截屏的背景图
QScreen *screen = QGuiApplication::primaryScreen();
const QRect& temp_rect = getScreenRect();
originPainting_.reset(new QPixmap(screen->grabWindow(0, temp_rect.x(),
temp_rect.y(), temp_rect.width(),
temp_rect.height())));
}
return originPainting_;
}
void OEScreenshot::onEgoistic(void)
{
/// 窗口置顶
#ifdef Q_OS_WIN32
// SetWindowPos(HWND)this->winId(),HWND_TOPMOST,this->pos().x(),this->pos().y(),this->width(),this->height(),SWP_SHOWWINDOW);
#else
Qt::WindowFlags flags = windowFlags();
flags |= Qt::WindowStaysOnTopHint;
setWindowFlags(flags);
#endif
}
/*
*
* _ico
*/
void OEScreenshot::initCursor(const QString& ico) {
QPixmap pixmap;
if (ico.isEmpty()) {
pixmap.loadFromData(uc_mouse_image, sizeof(uc_mouse_image));
}
else {
pixmap.load(ico);
}
QCursor cursor;
cursor = QCursor(pixmap, 15, 23);
setCursor(cursor);
}
std::shared_ptr<OEScreen> OEScreenshot::createScreen(const QPoint &pos) {
if (screenTool_.get() == nullptr) {
/// 创建截图器
screenTool_.reset(new OEScreen(originPainting_, pos, this));
/// 建立信号连接
connect (this, SIGNAL(cursorPosChange(int,int)),
screenTool_.get(),SLOT(onMouseChange(int,int)));
/// 建立主界面双击保存信号关联
connect (this, SIGNAL(doubleClick()),
screenTool_.get(),SLOT(onSaveScreen()));
/// 建立截图器大小关联
connect(screenTool_.get(), SIGNAL(sizeChange(int,int)),
rectTool_.get(), SLOT(onSizeChange(int,int)));
connect(screenTool_.get(), SIGNAL(sizeChange(int,int)),
amplifierTool_.get(), SLOT(onSizeChange(int,int)));
/// 建立截图器与感知器的位置关联
connect(screenTool_.get(), SIGNAL(postionChange(int,int)),
rectTool_.get(), SLOT(onPostionChange(int,int)));
/// 获得截图器当前起始位置
startPoint_ = pos;
isLeftPressed_ = true;
}
return screenTool_;
}
void OEScreenshot::destroyScreen() {
if (screenTool_.get() != nullptr) {
/// 断开信号资源
disconnect (this, SIGNAL(doubleClick()),
screenTool_.get(),SLOT(onSaveScreen()));
disconnect(screenTool_.get(), SIGNAL(sizeChange(int,int)),
rectTool_.get(), SLOT(onSizeChange(int,int)));
disconnect(screenTool_.get(), SIGNAL(postionChange(int,int)),
rectTool_.get(), SLOT(onPostionChange(int,int)));
/// 清理工具
screenTool_.reset();
screenTool_ = nullptr;
isLeftPressed_ = false;
update();
return;
}
}
void OEScreenshot::mousePressEvent(QMouseEvent *e) {
if (e->button() == Qt::LeftButton) {
createScreen(e->pos());
return ;
}
}
void OEScreenshot::mouseReleaseEvent(QMouseEvent *e) {
if (e->button() == Qt::RightButton) {
if (screenTool_.get() != nullptr) {
rectTool_->hide();
amplifierTool_->onPostionChange(e->x(), e->y());
amplifierTool_->show();
return destroyScreen();
}
close();
return ;
}
else if (isLeftPressed_ == true
&& e->button() == Qt::LeftButton) {
/// 选择窗口选区
if (startPoint_ == e->pos()
&& !windowRect_.isEmpty()) {
screenTool_->setGeometry(windowRect_);
screenTool_->show();
windowRect_ = {};
}
/// 断开鼠标移动的信号
disconnect (this, SIGNAL(cursorPosChange(int,int)),
screenTool_.get(),SLOT(onMouseChange(int,int)));
/// 隐藏放大器
amplifierTool_->hide();
/// 断开截图器的大小修改信号
disconnect (screenTool_.get(), SIGNAL(sizeChange(int,int)),
amplifierTool_.get(),SLOT(onSizeChange(int,int)));
isLeftPressed_ = false;
}
QWidget::mouseReleaseEvent(e);
}
void OEScreenshot::mouseMoveEvent(QMouseEvent *e) {
emit cursorPosChange(e->x(), e->y());
if (isLeftPressed_) {
amplifierTool_->raise();
windowRect_ = {};
update();
}
else if (isLeftPressed_ == false
&& false == OEScreen::state()){
/// 霸道置顶
onEgoistic();
/// 更新当前鼠标选中的窗口
updateMouse();
}
QWidget::mouseMoveEvent(e);
}
void OEScreenshot::paintEvent(QPaintEvent *) {
QPainter painter(this);
/// 画全屏图
painter.drawPixmap(0,0,desktopRect_.width(),
desktopRect_.height(), *backgroundScreen_);
if (!windowRect_.isEmpty()) {
/// 绘制选区
QPen pen = painter.pen();
pen.setColor(QColor(0,175,255));
pen.setWidth(2);
painter.setPen(pen);
painter.drawRect(windowRect_.x(),windowRect_.y(),
windowRect_.width(),windowRect_.height());
painter.drawPixmap(QPoint(windowRect_.x(),windowRect_.y()),
*originPainting_, windowRect_);
}
}
void OEScreenshot::updateMouse(void) {
/// 获取当前鼠标选中的窗口
::EnableWindow((HWND)winId(), FALSE);
OECommonHelper::getSmallestWindowFromCursor(windowRect_);
QPoint temp_pt = mapFromGlobal(QPoint(windowRect_.x(), windowRect_.y()));
windowRect_ = QRect(temp_pt.x(), temp_pt.y(),
windowRect_.width(), windowRect_.height());
::EnableWindow((HWND)winId(), TRUE);
amplifierTool_->onSizeChange(windowRect_.width(),windowRect_.height());
emit findChildWind(windowRect_);
update();
}
void OEScreenshot::keyPressEvent(QKeyEvent *e) {
/// Esc 键退出截图;
if (e->key() == Qt::Key_Escape) {
close();
}
else {
e->ignore();
}
}
///////////////////////////////////////////////////////////
OERect::OERect(QWidget *parent) : QWidget(parent) {
/// 设置感知器默认大小
setFixedSize(95 * OECommonHelper::getWindowHeightMultiplyingPower(),
20 * OECommonHelper::getWindowHeightMultiplyingPower());
/// 填充默认背景
backgroundPixmap_.reset(new QPixmap(width(),height()));
backgroundPixmap_->fill((QColor(8, 8, 8, 160)));
/// 默认隐藏
hide();
}
void OERect::paintEvent(QPaintEvent *) {
QPainter painter(this);
painter.drawPixmap(rect(),*backgroundPixmap_);
painter.setPen(QPen(QColor(Qt::white)));
painter.drawText(rect(), Qt::AlignCenter, info_);
}
void OERect::onPostionChange(int x, int y) {
if (x < 0) x = 0;
if (y < 0) y = 0;
const int& ry = y - height() - 1;
if (ry < 0) {
this->raise();
}
move(x, ((ry < 0) ? y : ry));
show();
}
void OERect::onSizeChange(int w, int h) {
info_ = QString("%1 × %2").arg(w).arg(h);
}
///////////////////////////////////////////////////////////
OEScreen::OEScreen(std::shared_ptr<QPixmap> originPainting, QPoint pos, QWidget *parent)
: QWidget(parent), direction_(NONE), originPoint_(pos),
isPressed_(false), originPainting_(originPainting) {
menu_ = new QMenu(this);
menu_->addAction("完成截图", this, SLOT(onSaveScreen()));
menu_->addAction("保存", this, SLOT(onSaveScreenOther()));
menu_->addSeparator();
menu_->addAction("退出截图", this, SLOT(quitScreenshot()));
/// 双击即完成
connect(this, SIGNAL(doubleClick()),
this, SLOT(onSaveScreen()));
/// 开启鼠标实时追踪
setMouseTracking(true);
/// 默认隐藏
hide();
}
OEScreen::DIRECTION OEScreen::getRegion(const QPoint &cursor) {
if (!isInit_) {
return NONE;
}
OEScreen::DIRECTION ret_dir = NONE;
// left upper
QPoint pt_lu = mapToParent(rect().topLeft());
// right lower
QPoint pt_rl = mapToParent(rect().bottomRight());
int x = cursor.x();
int y = cursor.y();
/// 获得鼠标当前所处窗口的边界方向
if(pt_lu.x() + PADDING_ >= x
&& pt_lu.x() <= x
&& pt_lu.y() + PADDING_ >= y
&& pt_lu.y() <= y) {
// 左上角
ret_dir = LEFTUPPER;
this->setCursor(QCursor(Qt::SizeFDiagCursor));
} else if(x >= pt_rl.x() - PADDING_
&& x <= pt_rl.x()
&& y >= pt_rl.y() - PADDING_
&& y <= pt_rl.y()) {
// 右下角
ret_dir = RIGHTLOWER;
this->setCursor(QCursor(Qt::SizeFDiagCursor));
} else if(x <= pt_lu.x() + PADDING_
&& x >= pt_lu.x()
&& y >= pt_rl.y() - PADDING_
&& y <= pt_rl.y()) {
// 左下角
ret_dir = LEFTLOWER;
this->setCursor(QCursor(Qt::SizeBDiagCursor));
} else if(x <= pt_rl.x()
&& x >= pt_rl.x() - PADDING_
&& y >= pt_lu.y()
&& y <= pt_lu.y() + PADDING_) {
// 右上角
ret_dir = RIGHTUPPER;
this->setCursor(QCursor(Qt::SizeBDiagCursor));
} else if(x <= pt_lu.x() + PADDING_
&& x >= pt_lu.x()) {
// 左边
ret_dir = LEFT;
this->setCursor(QCursor(Qt::SizeHorCursor));
} else if( x <= pt_rl.x()
&& x >= pt_rl.x() - PADDING_) {
// 右边
ret_dir = RIGHT;
this->setCursor(QCursor(Qt::SizeHorCursor));
}else if(y >= pt_lu.y()
&& y <= pt_lu.y() + PADDING_){
// 上边
ret_dir = UPPER;
this->setCursor(QCursor(Qt::SizeVerCursor));
} else if(y <= pt_rl.y()
&& y >= pt_rl.y() - PADDING_) {
// 下边
ret_dir = LOWER;
this->setCursor(QCursor(Qt::SizeVerCursor));
}else {
// 默认
ret_dir = NONE;
this->setCursor(QCursor(Qt::SizeAllCursor));
}
return ret_dir;
}
void OEScreen::contextMenuEvent(QContextMenuEvent *) {
/// 在鼠标位置弹射出菜单栏
menu_->exec(cursor().pos());
}
void OEScreen::mouseDoubleClickEvent(QMouseEvent *e) {
if (e->button() == Qt::LeftButton) {
emit doubleClick();
e->accept();
}
}
void OEScreen::mousePressEvent(QMouseEvent *e) {
if (e->button() == Qt::LeftButton) {
isPressed_ = true;
if(direction_ != NONE) {
this->mouseGrabber();
}
/// @bug :这里可能存在问题, 不应当使用globalPos
movePos_ = e->globalPos() - pos();
}
}
void OEScreen::mouseReleaseEvent(QMouseEvent * e) {
if (e->button() == Qt::LeftButton) {
isPressed_ = false;
if(direction_ != NONE) {
setCursor(QCursor(Qt::SizeAllCursor));
}
}
}
void OEScreen::mouseMoveEvent(QMouseEvent * e) {
QPoint gloPoint = mapToParent(e->pos());
// left upper
QPoint pt_lu = mapToParent(rect().topLeft());
// left lower
QPoint pt_ll = mapToParent(rect().bottomLeft());
// right lower
QPoint pt_rl = mapToParent(rect().bottomRight());
// right upper
QPoint pt_ru = mapToParent(rect().topRight());
if(!isPressed_) {
/// 检查鼠标鼠标方向
direction_ = getRegion(gloPoint);
/// 根据方位判断拖拉对应支点
switch(direction_) {
case NONE:
case RIGHT:
case RIGHTLOWER:
originPoint_ = pt_lu;
break;
case RIGHTUPPER:
originPoint_ = pt_ll;
break;
case LEFT:
case LEFTLOWER:
originPoint_ = pt_ru;
break;
case LEFTUPPER:
case UPPER:
originPoint_ = pt_rl;
break;
case LOWER:
originPoint_ = pt_lu;
break;
}
}
else {
if(direction_ != NONE) {
const int& global_x = gloPoint.x();
/// 鼠标进行拖拉拽
switch(direction_) {
case LEFT:
return onMouseChange(global_x, pt_ll.y() + 1);
case RIGHT:
return onMouseChange(global_x, pt_rl.y() + 1);
case UPPER:
return onMouseChange(pt_lu.x(), gloPoint.y());
case LOWER:
return onMouseChange(pt_rl.x() + 1, gloPoint.y());
case LEFTUPPER:
case RIGHTUPPER:
case LEFTLOWER:
case RIGHTLOWER:
return onMouseChange(global_x, gloPoint.y());
default:
break;
}
}
else {
/// 窗口的移动
/// @bug :这里可能存在问题, 不应当使用globalPos
move(e->globalPos() - movePos_);
movePos_ = e->globalPos() - pos();
e->accept();
}
}
currentRect_ = geometry();
}
void OEScreen::moveEvent(QMoveEvent *) {
emit postionChange(x(), y());
}
void OEScreen::resizeEvent(QResizeEvent *) {
listMarker_.clear();
/// 重新计算八个锚点
// 角点
listMarker_.push_back(QPoint(0, 0));
listMarker_.push_back(QPoint(width(), 0));
listMarker_.push_back(QPoint(0, height()));
listMarker_.push_back(QPoint(width(), height()));
// 中点
listMarker_.push_back(QPoint((width() >> 1), 0));
listMarker_.push_back(QPoint((width() >> 1), height()));
listMarker_.push_back(QPoint(0, (height() >> 1)));
listMarker_.push_back(QPoint(width(), (height() >> 1)));
emit sizeChange(width(), height());
}
void OEScreen::showEvent(QShowEvent *) {
isInit_ = true;
}
void OEScreen::hideEvent(QHideEvent *) {
currentRect_ = {};
movePos_ = {};
originPoint_ = {};
isInit_ = false;
}
void OEScreen::enterEvent(QEvent *e) {
setCursor(Qt::SizeAllCursor);
QWidget::enterEvent(e);
}
void OEScreen::leaveEvent(QEvent *e) {
setCursor(Qt::ArrowCursor);
QWidget::leaveEvent(e);
}
void OEScreen::closeEvent(QCloseEvent *)
{
isInit_ = false;
}
void OEScreen::paintEvent(QPaintEvent *) {
QPainter painter(this);
/// 绘制截屏编辑窗口
painter.drawPixmap(QPoint(0,0),
*originPainting_, currentRect_);
/// 绘制边框线
QPen pen(QColor(0,174,255),2);
painter.setPen(pen);
painter.drawRect(rect());
/// 绘制八个点
//改变点的宽度
pen.setWidth(4);
pen.setColor(Qt::red);
painter.setPen(pen);
painter.drawPoints(listMarker_);
}
const QString OEScreen::getFileName(void) {
QString file_name = QDateTime::currentDateTime().toString("CSDN博客_瓯裔_yyyy-MM-dd-HH-mm-ss");
return file_name;
}
void OEScreen::onSaveScreenOther(void) {
QString fileName = QFileDialog::getSaveFileName(this, "保存图片", getFileName(), "JPEG Files (*.jpg)");
if (fileName.length() > 0) {
originPainting_->copy(currentRect_).save(fileName, "jpg");
quitScreenshot();
}
}
void OEScreen::onSaveScreen(void) {
/// 把图片放入剪切板
QClipboard *board = QApplication::clipboard();
board->setPixmap(originPainting_->copy(currentRect_));
/// 退出当前截图工具
quitScreenshot();
}
void OEScreen::quitScreenshot(void) {
close();
parentWidget()->close();
}
void OEScreen::onMouseChange(int x, int y) {
show();
if (x < 0 || y < 0) {
return;
}
const int& rx = (x >= originPoint_.x()) ? originPoint_.x() : x;
const int& ry = (y >= originPoint_.y()) ? originPoint_.y() : y;
const int& rw = abs(x - originPoint_.x());
const int& rh = abs(y - originPoint_.y());
/// 改变大小
currentRect_ = QRect(rx, ry, rw, rh);
this->setGeometry(currentRect_);
/// 改变大小后更新父窗口,防止父窗口未及时刷新而导致的问题
parentWidget()->update();
}

View File

@ -0,0 +1,508 @@
/**
* @author :
* @date : 201704
* @version: 1.0
* @note : Apache 2.0 ;
* 使
* @remarks:
* http://www.apache.org/licenses/LICENSE-2.0
*
*
*
*
*
*
* https://git.oschina.net/Mr_ChenLuYong/screenshot
*
*
*
*
*
*
* http://blog.csdn.net/csnd_ayo
*
* http://blog.csdn.net/csnd_ayo/article/details/70197915
*
* BugIssues
*
*/
#ifndef OESCREENSHOT_H
#define OESCREENSHOT_H
#include <memory>
#include <QRect>
#include <QWidget>
class OEScreen;
class OERect;
class OEAmplifier;
class QTimer;
class QMenu;
/**
* @class : OEScreenshot
* @brief : ,
* ,.
* @remark: ( OEScreenshot::Instance(); )
*/
class OEScreenshot : public QWidget {
Q_OBJECT
signals:
/**
* @brief :
* @param : int x轴的坐标
* @param : int y轴的坐标
* @date : 20170418
*/
void cursorPosChange(int, int);
/**
* @brief :
* @date : 20170418
*/
void doubleClick(void);
/**
* @brief :
* @param : QRect
* @date : 20170418
*/
void findChildWind(QRect);
public:
/**
* @brief :
* @note :
* @date : 20170416
*/
explicit OEScreenshot(QWidget *parent = 0);
~OEScreenshot(void);
/**
* @brief :
* @note :
* @return: OEScreenshot
* @date : 20170415
*/
static OEScreenshot *Instance(void);
/**
* @brief :
* @note :
* @date : 20170430
*/
static void destroy(void);
protected:
/**
* @brief :
*/
virtual void hideEvent(QHideEvent *);
/**
* @brief :
*/
virtual void closeEvent(QCloseEvent *);
/**
* @brief :
*/
virtual void mouseDoubleClickEvent(QMouseEvent*);
/**
* @brief :
*/
virtual void mousePressEvent(QMouseEvent *);
/**
* @brief :
*/
virtual void mouseReleaseEvent(QMouseEvent *e);
/**
* @brief :
*/
virtual void mouseMoveEvent(QMouseEvent *e);
/**
* @brief :
*/
virtual void keyPressEvent(QKeyEvent *e);
/**
* @brief :
*/
virtual void paintEvent(QPaintEvent *);
/**
* @brief :
*/
void updateMouse(void);
private:
/**
* @brief : ()
* @note :
* @param : originPainting originPainting_原画
* @date : 20170415
* @remark: getGlobalScreen
*/
void initAmplifier(std::shared_ptr<QPixmap> originPainting = nullptr);
/**
* @brief : ()
* @date : 20170427
*/
void initMeasureWidget(void);
/**
* @brief :
* @return: QPixmap
* @date : 20170415
*/
std::shared_ptr<QPixmap> initGlobalScreen(void);
/**
* @brief :
* @note :
* @param : ico
* @date : 20170415
* @remark: 使Logo
*/
void initCursor(const QString& ico = "");
/**
* @brief :
* @note :
* @param : pos
* @date : 20170416
* @remark: ()
*/
std::shared_ptr<OEScreen> createScreen(const QPoint &pos);
/**
* @brief :
* @note :
* @date : 20170416
*/
void destroyScreen(void);
/**
* @brief :
* @note : QRect-1920, 0, 3840, 1080
* @return: QRect
* @date : 20170415
*/
const QRect& getScreenRect(void);
/**
* @brief :
* @note :
* @return: QPixmap*
* @date : 20170415
* @remark:
*/
std::shared_ptr<QPixmap> getGlobalScreen(void);
private:
/// 截屏窗口是否已经展示
bool isLeftPressed_;
/// 用于检测误操作
QPoint startPoint_;
/// 当前桌面屏幕的矩形数据
QRect desktopRect_;
/// 屏幕暗色背景图
std::shared_ptr<QPixmap> backgroundScreen_;
/// 屏幕原画
std::shared_ptr<QPixmap> originPainting_;
/// 截图屏幕
std::shared_ptr<OEScreen> screenTool_;
/// 截图器大小感知器
std::shared_ptr<OERect> rectTool_;
/// 放大取色器
std::shared_ptr<OEAmplifier> amplifierTool_;
/// 当前鼠标选区最小的矩形窗口
QRect windowRect_;
/// 截屏实例对象
static OEScreenshot *self_;
/// 置顶定时器
QTimer* egoisticTimer_;
/// 活动窗口
static bool isActivity_;
private slots:
/**
* @brief : Window下霸道置顶
* @date : 20170428
* @remark: 使使BUG
*/
void onEgoistic(void);
};
/**
* @class : OERect
* @brief :
* @note :
*/
class OERect : public QWidget {
Q_OBJECT
signals:
public:
explicit OERect(QWidget *parent = 0);
protected:
/**
* @brief :
*/
void paintEvent(QPaintEvent *);
public slots:
/**
* @brief :
* @note :
* @param : x
* @param : y
* @date : 20170415
*/
void onPostionChange(int x, int y);
/**
* @brief :
* @note :
* @param : w
* @param : h
* @date : 20170415
*/
void onSizeChange(int w, int h);
private:
/// 背景色
std::shared_ptr<QPixmap> backgroundPixmap_;
/// 显示的文字信息
QString info_;
};
/**
* @class : OEScreen
* @brief :
* @note :
*/
class OEScreen : public QWidget {
Q_OBJECT
signals:
/**
* @brief :
* @param : int
* @param : int
* @date : 20170417
*/
void sizeChange(int,int);
/**
* @brief :
* @param : int
* @param : int
* @date : 20170417
*/
void postionChange(int,int);
/**
* @brief :
* @date : 20170417
*/
void doubleClick(void);
protected:
/// 内边距,决定拖拽的触发。
const int PADDING_ = 6;
/// 方位枚举
enum DIRECTION {
UPPER=0,
LOWER=1,
LEFT,
RIGHT,
LEFTUPPER,
LEFTLOWER,
RIGHTLOWER,
RIGHTUPPER,
NONE
};
public:
explicit OEScreen(std::shared_ptr<QPixmap> originPainting, QPoint pos, QWidget *parent = 0);
~OEScreen() { isInit_ = false; }
/**
* @brief :
* @return: true :
* @date : 20170417
*/
static bool state(void) { return isInit_; }
protected:
/**
* @brief :
* @param : cursor
* @return: DIRECTION
* @date : 20170417
*/
DIRECTION getRegion(const QPoint &cursor);
/**
* @brief :
*/
virtual void contextMenuEvent(QContextMenuEvent *);
/**
* @brief :
*/
virtual void mouseDoubleClickEvent(QMouseEvent *e);
/**
* @brief :
*/
virtual void mousePressEvent(QMouseEvent *e);
/**
* @brief :
*/
virtual void mouseReleaseEvent(QMouseEvent *e);
/**
* @brief :
*/
virtual void mouseMoveEvent(QMouseEvent *e);
/**
* @brief :
*/
virtual void moveEvent(QMoveEvent *);
/**
* @brief :
*/
virtual void resizeEvent(QResizeEvent *);
/**
* @brief :
*/
virtual void showEvent(QShowEvent *);
/**
* @brief :
*/
virtual void hideEvent(QHideEvent *);
/**
* @brief :
*/
virtual void enterEvent(QEvent *e);
/**
* @brief :
*/
virtual void leaveEvent(QEvent *e);
/**
* @brief :
*/
virtual void closeEvent(QCloseEvent *);
/**
* @brief :
*/
virtual void paintEvent(QPaintEvent *);
private:
/**
* @brief :
* @return: QString
* @date : 20170416
*/
virtual const QString getFileName(void);
public slots:
/**
* @brief :
* @param : x
* @param : y
* @date : 20170416
*/
void onMouseChange(int x,int y);
/**
* @brief :
* @date : 20170416
*/
void onSaveScreen(void);
protected slots:
/**
* @brief :
* @note :
* @date : 20170416
*/
void onSaveScreenOther(void);
/**
* @brief : 退
* @date : 20170416
*/
void quitScreenshot(void);
private:
/// 是否已经设置初始大小
static bool isInit_;
/// 窗口大小改变时,记录改变方向
DIRECTION direction_;
/// 起点
QPoint originPoint_;
/// 鼠标是否按下
bool isPressed_;
/// 拖动的距离
QPoint movePos_;
/// 标记锚点
QPolygon listMarker_;
/// 屏幕原画
std::shared_ptr<QPixmap> originPainting_;
/// 当前窗口几何数据 用于绘制截图区域
QRect currentRect_;
/// 右键菜单对象
QMenu *menu_;
};
#endif /// OESCREENSHOT_H

239
LedOK/player/digiclock.cpp Normal file
View File

@ -0,0 +1,239 @@
#include "digiclock.h"
#include "gutil/qgui.h"
#include <QJsonObject>
#include <QJsonArray>
DigiClock::DigiClock(QString prefix, const QJsonObject &layer, QWidget *parent) : QWidget{parent} {
timeZone = QTimeZone(layer["timezone"].toString().toUtf8());
auto spaceWidth = layer["spaceWidth"].toDouble();
auto pics = layer["arrayPics"].toArray();
foreach(QJsonValue pic, pics) imgs.insert(pic["name"].toString(), QPixmap(prefix+pic["id"].toString()));
int dateStyle = layer["dateStyle"].toInt();
isSingleMonth = dateStyle==1||dateStyle==2||dateStyle==4||dateStyle==6||dateStyle==8||dateStyle==10||dateStyle==12;
QPixmap& timeSep = imgs["maohao"];
weekly = layer["weekly"].toBool();
bool hour12 = layer["hour12"].toBool();
bool AmPm = hour12 ? layer["AmPm"].toBool() : false;
timeptn = hour12 ? "hhmmssa" : "HHmmss";
bool hour = layer["hour"].toBool();
bool min = layer["min"].toBool();
bool sec = layer["sec"].toBool();
multiline = layer["multiline"].toBool();
if(multiline) {
QVBoxLayout *vBox = new QVBoxLayout(this);
vBox->setAlignment(Qt::AlignCenter);
vBox->setContentsMargins(0,0,0,0);
vBox->setSpacing(0);
vBox->addStretch();
QHBoxLayout *hBox = new QHBoxLayout();
vBox->addLayout(hBox);
hBox->addStretch();
addDate(dateStyle, layer, hBox);
hBox->addStretch();
if(weekly) {
hBox = new QHBoxLayout();
vBox->addLayout(hBox);
hBox->addStretch();
hBox->addWidget((QWidget*)weekComp);
hBox->addStretch();
}
hBox = new QHBoxLayout();
vBox->addLayout(hBox);
hBox->addStretch();
if(AmPm) {
hBox->addWidget((QWidget*)ampmComp);
hBox->addSpacing(spaceWidth);
}
if(hour) {
hBox->addWidget((QWidget*)hourComps[0]);
hBox->addWidget((QWidget*)hourComps[1]);
}
if(hour&&min) hBox->addWidget((QWidget*)new ImgWgt(timeSep));
if(min) {
hBox->addWidget((QWidget*)minComps[0]);
hBox->addWidget((QWidget*)minComps[1]);
}
if(min&&sec) hBox->addWidget((QWidget*)new ImgWgt(timeSep));
if(sec) {
hBox->addWidget((QWidget*)secComps[0]);
hBox->addWidget((QWidget*)secComps[1]);
}
hBox->addStretch();
vBox->addStretch();
} else {
QHBoxLayout *hBox = new QHBoxLayout(this);
hBox->setContentsMargins(0,0,0,0);
hBox->setSpacing(0);
hBox->addStretch();
addDate(dateStyle, layer, hBox);
if(hBox->count()>1) hBox->addSpacing(spaceWidth*2);
if(weekly) {
hBox->addWidget((QWidget*)weekComp);
hBox->addSpacing(spaceWidth*2);
}
if(AmPm) {
hBox->addWidget((QWidget*)ampmComp);
hBox->addSpacing(spaceWidth);
}
if(hour) {
hBox->addWidget((QWidget*)hourComps[0]);
hBox->addWidget((QWidget*)hourComps[1]);
}
if(hour&&min) hBox->addWidget((QWidget*)new ImgWgt(timeSep));
if(min) {
hBox->addWidget((QWidget*)minComps[0]);
hBox->addWidget((QWidget*)minComps[1]);
}
if(min&&sec) hBox->addWidget((QWidget*)new ImgWgt(timeSep));
if(sec) {
hBox->addWidget((QWidget*)secComps[0]);
hBox->addWidget((QWidget*)secComps[1]);
}
hBox->addStretch();
}
}
void DigiClock::addDate(int dateStyle, QJsonObject layer, QHBoxLayout* tar) {
if(dateStyle==0 || dateStyle==1) {
addYear(layer, tar, imgs["YEAR"]);
if(layer["month"].toBool()) {
tar->addWidget((QWidget*)monthComps[0]);
tar->addWidget((QWidget*)monthComps[1]);
tar->addWidget((QWidget*)new ImgWgt(imgs["MONTH"]));
}
if(layer["day"].toBool()) {
tar->addWidget((QWidget*)dayComps[0]);
tar->addWidget((QWidget*)dayComps[1]);
tar->addWidget((QWidget*)new ImgWgt(imgs["DAY"]));
}
} else if(dateStyle==2 || dateStyle==3) {
QPixmap sep = imgs["xiegang"];
if(layer["month"].toBool()) {
tar->addWidget((QWidget*)monthComps[0]);
tar->addWidget((QWidget*)monthComps[1]);
tar->addWidget((QWidget*)new ImgWgt(sep));
}
if(layer["day"].toBool()) {
tar->addWidget((QWidget*)dayComps[0]);
tar->addWidget((QWidget*)dayComps[1]);
tar->addWidget((QWidget*)new ImgWgt(sep));
}
addYear(layer, tar, QPixmap());
} else if(dateStyle==4 || dateStyle==5) {
QPixmap sep = imgs["xiegang"];
if(layer["day"].toBool()) {
tar->addWidget((QWidget*)dayComps[0]);
tar->addWidget((QWidget*)dayComps[1]);
tar->addWidget((QWidget*)new ImgWgt(sep));
}
if(layer["month"].toBool()) {
tar->addWidget((QWidget*)monthComps[0]);
tar->addWidget((QWidget*)monthComps[1]);
tar->addWidget((QWidget*)new ImgWgt(sep));
}
addYear(layer, tar, QPixmap());
} else if(dateStyle==6 || dateStyle==7) {
QPixmap sep = imgs["xiegang"];
addYear(layer, tar, sep);
if(layer["month"].toBool()) {
tar->addWidget((QWidget*)monthComps[0]);
tar->addWidget((QWidget*)monthComps[1]);
tar->addWidget((QWidget*)new ImgWgt(sep));
}
if(layer["day"].toBool()) {
tar->addWidget((QWidget*)dayComps[0]);
tar->addWidget((QWidget*)dayComps[1]);
}
} else if(dateStyle==8 || dateStyle==9) {
QPixmap sep = imgs["hengxian"];
if(layer["month"].toBool()) {
tar->addWidget((QWidget*)monthComps[0]);
tar->addWidget((QWidget*)monthComps[1]);
tar->addWidget((QWidget*)new ImgWgt(sep));
}
if(layer["day"].toBool()) {
tar->addWidget((QWidget*)dayComps[0]);
tar->addWidget((QWidget*)dayComps[1]);
tar->addWidget((QWidget*)new ImgWgt(sep));
}
addYear(layer, tar, QPixmap());
} else if(dateStyle==10 || dateStyle==11) {
QPixmap sep = imgs["hengxian"];
if(layer["day"].toBool()) {
tar->addWidget((QWidget*)dayComps[0]);
tar->addWidget((QWidget*)dayComps[1]);
tar->addWidget((QWidget*)new ImgWgt(sep));
}
if(layer["month"].toBool()) {
tar->addWidget((QWidget*)monthComps[0]);
tar->addWidget((QWidget*)monthComps[1]);
tar->addWidget((QWidget*)new ImgWgt(sep));
}
addYear(layer, tar, QPixmap());
} else if(dateStyle==12 || dateStyle==13) {
QPixmap sep = imgs["hengxian"];
addYear(layer, tar, sep);
if(layer["month"].toBool()) {
tar->addWidget((QWidget*)monthComps[0]);
tar->addWidget((QWidget*)monthComps[1]);
tar->addWidget((QWidget*)new ImgWgt(sep));
}
if(layer["day"].toBool()) {
tar->addWidget((QWidget*)dayComps[0]);
tar->addWidget((QWidget*)dayComps[1]);
}
}
}
void DigiClock::addYear(QJsonObject layer, QHBoxLayout* tar, QPixmap sep) {
if(layer["year"].toBool()) {
if(layer["fullYear"].toBool()) {
tar->addWidget((QWidget*)yearComps[0]);
tar->addWidget((QWidget*)yearComps[1]);
}
tar->addWidget((QWidget*)yearComps[2]);
tar->addWidget((QWidget*)yearComps[3]);
if(!sep.isNull()) tar->addWidget((QWidget*)new ImgWgt(sep));
}
}
void DigiClock::cal() {
QDateTime dt = QDateTime::currentDateTime().toTimeZone(timeZone);
QTime time = dt.time();
QString hms = time.toString(timeptn);
*ampmComp = imgs[time.hour()<12?"AM":"PM"];
*hourComps[0] = imgs[hms.mid(0,1)];
*hourComps[1] = imgs[hms.mid(1,1)];
*minComps[0] = imgs[hms.mid(2,1)];
*minComps[1] = imgs[hms.mid(3,1)];
*secComps[0] = imgs[hms.mid(4,1)];
*secComps[1] = imgs[hms.mid(5,1)];
if(yearComps[0]->img.isNull() || (time.hour()==0 && time.second()==0)) {
QDate date = dt.date();
if(weekly) *weekComp = imgs[weeks[date.dayOfWeek()-1]];
QString ymd = date.toString("yyyyMMdd");
*yearComps[0] = imgs[ymd.mid(0,1)];
*yearComps[1] = imgs[ymd.mid(1,1)];
*yearComps[2] = imgs[ymd.mid(2,1)];
*yearComps[3] = imgs[ymd.mid(3,1)];
QChar ch = ymd.at(4);
if(isSingleMonth && ch=='0') *monthComps[0] = QPixmap();
else *monthComps[0] = imgs[ymd.mid(4,1)];
*monthComps[1] = imgs[ymd.mid(5,1)];
*dayComps[0] = imgs[ymd.mid(6,1)];
*dayComps[1] = imgs[ymd.mid(7,1)];
}
}
void DigiClock::showEvent(QShowEvent *) {
if(timerId==0) {
timerId = startTimer(1000, Qt::PreciseTimer);
cal();
}
}
void DigiClock::timerEvent(QTimerEvent *) {
if(isVisible()) {
cal();
update();
} else if(timerId!=0) {
killTimer(timerId);
timerId = 0;
}
}

View File

@ -1,67 +1,67 @@
#ifndef ELEDIGICLOCK_H
#define ELEDIGICLOCK_H
#include "gutil/qjson.h"
#include "gutil/qgui.h"
#include <QTimeZone>
#include <QPainter>
class ImgWgt : public QWidget {
public:
ImgWgt(QWidget *parent = nullptr) : QWidget{parent} {}
ImgWgt(const QPixmap &img) :img(img){
setFixedSize(this->img.size());
}
ImgWgt(QPixmap &&img) {
this->img = std::move(img);
setFixedSize(this->img.size());
}
ImgWgt &operator=(const QPixmap &img) {
this->img = img;
setFixedSize(this->img.size());
return *this;
}
ImgWgt &operator=(QPixmap &&img) {
this->img = std::move(img);
setFixedSize(this->img.size());
return *this;
}
QPixmap img;
protected:
virtual void paintEvent(QPaintEvent *) override {
if(img.isNull()) return;
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform);
painter.drawPixmap(0, 0, width(), height(), img);
}
};
const QString weeks[7]{"MON","TUE","WED","THU","FRI","SAT","SUN"};
class EleDigiClock : public QWidget {
Q_OBJECT
public:
EleDigiClock(QString path, const JValue &layer, QWidget *parent = nullptr);
void cal();
void addDate(int, const JValue &, HBox*);
void addYear(const JValue &layer, HBox* tar, const QPixmap &sep);
QTimeZone timeZone;
ImgWgt *yearComps[4] {new ImgWgt(), new ImgWgt(), new ImgWgt(), new ImgWgt()};
ImgWgt *monthComps[2] {new ImgWgt(), new ImgWgt()};
ImgWgt *dayComps[2] {new ImgWgt(), new ImgWgt()};
ImgWgt *weekComp = new ImgWgt(), *ampmComp = new ImgWgt();
ImgWgt *hourComps[2] {new ImgWgt(), new ImgWgt()};
ImgWgt *minComps[2] {new ImgWgt(), new ImgWgt()};
ImgWgt *secComps[2] {new ImgWgt(), new ImgWgt()};
QMap<QString, QPixmap> imgs;
QString timeptn;
bool multiline, weekly, isSingleMonth;
int timerId = 0;
protected:
void timerEvent(QTimerEvent *) override;
void showEvent(QShowEvent *) override;
};
#endif // ELEDIGICLOCK_H
#ifndef DIGICLOCK_H
#define DIGICLOCK_H
#include <QWidget>
#include <QTimeZone>
#include <QPainter>
#include <QHBoxLayout>
class ImgWgt : public QWidget {
public:
ImgWgt(QWidget *parent = nullptr) : QWidget{parent} {}
ImgWgt(const QPixmap &img) :img(img){
setFixedSize(this->img.size());
}
ImgWgt(QPixmap &&img) {
this->img = std::move(img);
setFixedSize(this->img.size());
}
ImgWgt &operator=(const QPixmap &img) {
this->img = img;
setFixedSize(this->img.size());
return *this;
}
ImgWgt &operator=(QPixmap &&img) {
this->img = std::move(img);
setFixedSize(this->img.size());
return *this;
}
QPixmap img;
protected:
virtual void paintEvent(QPaintEvent *) override {
if(img.isNull()) return;
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform);
painter.drawPixmap(0, 0, width(), height(), img);
}
};
const QString weeks[7]{"MON","TUE","WED","THU","FRI","SAT","SUN"};
class DigiClock : public QWidget {
Q_OBJECT
public:
DigiClock(QString path, const QJsonObject &layer, QWidget *parent = nullptr);
void cal();
void addDate(int, QJsonObject, QHBoxLayout*);
void addYear(QJsonObject layer, QHBoxLayout* tar, QPixmap sep);
QTimeZone timeZone;
ImgWgt *yearComps[4] {new ImgWgt(), new ImgWgt(), new ImgWgt(), new ImgWgt()};
ImgWgt *monthComps[2] {new ImgWgt(), new ImgWgt()};
ImgWgt *dayComps[2] {new ImgWgt(), new ImgWgt()};
ImgWgt *weekComp = new ImgWgt(), *ampmComp = new ImgWgt();
ImgWgt *hourComps[2] {new ImgWgt(), new ImgWgt()};
ImgWgt *minComps[2] {new ImgWgt(), new ImgWgt()};
ImgWgt *secComps[2] {new ImgWgt(), new ImgWgt()};
QMap<QString, QPixmap> imgs;
QString timeptn;
bool multiline, weekly, isSingleMonth;
int timerId = 0;
protected:
void timerEvent(QTimerEvent *) override;
void showEvent(QShowEvent *) override;
};
#endif // DIGICLOCK_H

View File

@ -1,8 +1,9 @@
#include "eleanaclock.h"
#include <QJsonObject>
#include <QPainter>
EleAnaClock::EleAnaClock(double w, double h, QString path, const JValue &layer, QWidget *parent) : QWidget{parent} {
timeZone = QTimeZone(layer["timeZone"].toString().toUtf8());
EleAnaClock::EleAnaClock(double w, double h, QString path, const QJsonObject &layer, QWidget *parent) : QWidget{parent} {
timeZone = QTimeZone(layer["timezone"].toString().toUtf8());
img.load(path);
pinHourColor = layer["pinHourColor"].toString();
pinMinColor = layer["pinMinColor"].toString();

View File

@ -1,7 +1,6 @@
#ifndef ELEANACLOCK_H
#define ELEANACLOCK_H
#include "gutil/qjson.h"
#include <QWidget>
#include <QTimeZone>
#include <QPen>
@ -9,7 +8,7 @@
class EleAnaClock : public QWidget {
Q_OBJECT
public:
explicit EleAnaClock(double w, double h, QString path, const JValue &layer, QWidget *parent);
explicit EleAnaClock(double w, double h, QString path, const QJsonObject &layer, QWidget *parent = nullptr);
void cal();
QTimeZone timeZone;
QPixmap img;

1
LedOK/player/elebase.cpp Normal file
View File

@ -0,0 +1 @@
//#include "elebase.h"

20
LedOK/player/elebase.h Normal file
View File

@ -0,0 +1,20 @@
#ifndef ELEBASE_H
#define ELEBASE_H
#include <QWidget>
class EleBase {
public:
QString id;
QString type;
int x;
int y;
int w;
int h;
int startTime;
int endTime;
bool repeat;
QWidget *wgt{0};
};
#endif // ELEBASE_H

View File

@ -1,231 +0,0 @@
#include "eledigiclock.h"
EleDigiClock::EleDigiClock(QString prefix, const JValue &layer, QWidget *parent) : QWidget{parent} {
timeZone = QTimeZone(layer["timeZone"].toString().toUtf8());
auto spaceWidth = layer["spaceWidth"].toDouble();
auto pics = layer["arrayPics"];
for(auto &pic : pics) imgs[pic["name"].toString()] = QPixmap(prefix+pic["id"].toString());
int dateStyle = layer["dateStyle"].toInt();
isSingleMonth = dateStyle==1||dateStyle==2||dateStyle==4||dateStyle==6||dateStyle==8||dateStyle==10||dateStyle==12;
auto& timeSep = imgs["maohao"];
weekly = layer["weekly"].toBool();
auto hour12 = layer["hour12"].toBool();
auto AmPm = hour12 ? layer["AmPm"].toBool() : false;
timeptn = hour12 ? "hhmmssa" : "HHmmss";
auto hour = layer["hour"].toBool();
auto min = layer["min"].toBool();
auto sec = layer["sec"].toBool();
multiline = layer["multiline"].toBool();
if(multiline) {
auto vBox = new VBox(this);
vBox->setAlignment(Qt::AlignCenter);
vBox->setContentsMargins(0,0,0,0);
vBox->setSpacing(0);
vBox->addStretch();
auto hBox = new HBox(vBox);
hBox->addStretch();
addDate(dateStyle, layer, hBox);
hBox->addStretch();
if(weekly) {
hBox = new HBox(vBox);
hBox->addStretch();
hBox->addWidget(weekComp);
hBox->addStretch();
}
hBox = new HBox(vBox);
hBox->addStretch();
if(AmPm) {
hBox->addWidget(ampmComp);
hBox->addSpacing(spaceWidth);
}
if(hour) {
hBox->addWidget(hourComps[0]);
hBox->addWidget(hourComps[1]);
}
if(hour&&min) hBox->addWidget(new ImgWgt(timeSep));
if(min) {
hBox->addWidget(minComps[0]);
hBox->addWidget(minComps[1]);
}
if(min&&sec) hBox->addWidget(new ImgWgt(timeSep));
if(sec) {
hBox->addWidget(secComps[0]);
hBox->addWidget(secComps[1]);
}
hBox->addStretch();
vBox->addStretch();
} else {
auto hBox = new HBox(this);
hBox->setContentsMargins(0,0,0,0);
hBox->setSpacing(0);
hBox->addStretch();
addDate(dateStyle, layer, hBox);
if(hBox->count()>1) hBox->addSpacing(spaceWidth*2);
if(weekly) {
hBox->addWidget(weekComp);
hBox->addSpacing(spaceWidth*2);
}
if(AmPm) {
hBox->addWidget(ampmComp);
hBox->addSpacing(spaceWidth);
}
if(hour) {
hBox->addWidget(hourComps[0]);
hBox->addWidget(hourComps[1]);
}
if(hour&&min) hBox->addWidget(new ImgWgt(timeSep));
if(min) {
hBox->addWidget(minComps[0]);
hBox->addWidget(minComps[1]);
}
if(min&&sec) hBox->addWidget(new ImgWgt(timeSep));
if(sec) {
hBox->addWidget(secComps[0]);
hBox->addWidget(secComps[1]);
}
hBox->addStretch();
}
}
void EleDigiClock::addDate(int dateStyle, const JValue &layer, HBox *tar) {
if(dateStyle==0 || dateStyle==1) {
addYear(layer, tar, imgs["YEAR"]);
if(layer["month"].toBool()) {
tar->addWidget(monthComps[0]);
tar->addWidget(monthComps[1]);
tar->addWidget(new ImgWgt(imgs["MONTH"]));
}
if(layer["day"].toBool()) {
tar->addWidget(dayComps[0]);
tar->addWidget(dayComps[1]);
tar->addWidget(new ImgWgt(imgs["DAY"]));
}
} else if(dateStyle==2 || dateStyle==3) {
auto& sep = imgs["xiegang"];
if(layer["month"].toBool()) {
tar->addWidget(monthComps[0]);
tar->addWidget(monthComps[1]);
tar->addWidget(new ImgWgt(sep));
}
if(layer["day"].toBool()) {
tar->addWidget(dayComps[0]);
tar->addWidget(dayComps[1]);
tar->addWidget(new ImgWgt(sep));
}
addYear(layer, tar, QPixmap());
} else if(dateStyle==4 || dateStyle==5) {
auto& sep = imgs["xiegang"];
if(layer["day"].toBool()) {
tar->addWidget(dayComps[0]);
tar->addWidget(dayComps[1]);
tar->addWidget(new ImgWgt(sep));
}
if(layer["month"].toBool()) {
tar->addWidget(monthComps[0]);
tar->addWidget(monthComps[1]);
tar->addWidget(new ImgWgt(sep));
}
addYear(layer, tar, QPixmap());
} else if(dateStyle==6 || dateStyle==7) {
auto& sep = imgs["xiegang"];
addYear(layer, tar, sep);
if(layer["month"].toBool()) {
tar->addWidget(monthComps[0]);
tar->addWidget(monthComps[1]);
tar->addWidget(new ImgWgt(sep));
}
if(layer["day"].toBool()) {
tar->addWidget(dayComps[0]);
tar->addWidget(dayComps[1]);
}
} else if(dateStyle==8 || dateStyle==9) {
auto& sep = imgs["hengxian"];
if(layer["month"].toBool()) {
tar->addWidget(monthComps[0]);
tar->addWidget(monthComps[1]);
tar->addWidget(new ImgWgt(sep));
}
if(layer["day"].toBool()) {
tar->addWidget(dayComps[0]);
tar->addWidget(dayComps[1]);
tar->addWidget(new ImgWgt(sep));
}
addYear(layer, tar, QPixmap());
} else if(dateStyle==10 || dateStyle==11) {
auto& sep = imgs["hengxian"];
if(layer["day"].toBool()) {
tar->addWidget(dayComps[0]);
tar->addWidget(dayComps[1]);
tar->addWidget(new ImgWgt(sep));
}
if(layer["month"].toBool()) {
tar->addWidget(monthComps[0]);
tar->addWidget(monthComps[1]);
tar->addWidget(new ImgWgt(sep));
}
addYear(layer, tar, QPixmap());
} else if(dateStyle==12 || dateStyle==13) {
auto& sep = imgs["hengxian"];
addYear(layer, tar, sep);
if(layer["month"].toBool()) {
tar->addWidget(monthComps[0]);
tar->addWidget(monthComps[1]);
tar->addWidget(new ImgWgt(sep));
}
if(layer["day"].toBool()) {
tar->addWidget(dayComps[0]);
tar->addWidget(dayComps[1]);
}
}
}
void EleDigiClock::addYear(const JValue &layer, HBox *tar, const QPixmap &sep) {
if(layer["year"].toBool()) {
if(layer["fullYear"].toBool()) {
tar->addWidget(yearComps[0]);
tar->addWidget(yearComps[1]);
}
tar->addWidget(yearComps[2]);
tar->addWidget(yearComps[3]);
if(!sep.isNull()) tar->addWidget(new ImgWgt(sep));
}
}
void EleDigiClock::cal() {
auto dt = QDateTime::currentDateTime().toTimeZone(timeZone);
auto time = dt.time();
auto hms = time.toString(timeptn);
*ampmComp = imgs[time.hour()<12?"AM":"PM"];
*hourComps[0] = imgs[hms.mid(0,1)];
*hourComps[1] = imgs[hms.mid(1,1)];
*minComps[0] = imgs[hms.mid(2,1)];
*minComps[1] = imgs[hms.mid(3,1)];
*secComps[0] = imgs[hms.mid(4,1)];
*secComps[1] = imgs[hms.mid(5,1)];
if(yearComps[0]->img.isNull() || (time.hour()==0 && time.second()==0)) {
auto date = dt.date();
if(weekly) *weekComp = imgs[weeks[date.dayOfWeek()-1]];
auto ymd = date.toString("yyyyMMdd");
*yearComps[0] = imgs[ymd.mid(0,1)];
*yearComps[1] = imgs[ymd.mid(1,1)];
*yearComps[2] = imgs[ymd.mid(2,1)];
*yearComps[3] = imgs[ymd.mid(3,1)];
*monthComps[0] = isSingleMonth && ymd.at(4)=='0' ? QPixmap() : imgs[ymd.mid(4,1)];
*monthComps[1] = imgs[ymd.mid(5,1)];
*dayComps[0] = isSingleMonth && ymd.at(6)=='0' ? QPixmap() : imgs[ymd.mid(6,1)];
*dayComps[1] = imgs[ymd.mid(7,1)];
}
}
void EleDigiClock::showEvent(QShowEvent *) {
if(timerId==0) {
timerId = startTimer(1000, Qt::PreciseTimer);
cal();
}
}
void EleDigiClock::timerEvent(QTimerEvent *) {
if(isVisible()) {
cal();
update();
} else if(timerId) {
killTimer(timerId);
timerId = 0;
}
}

View File

@ -10,10 +10,10 @@ EleGif::EleGif(QString path, QWidget *parent) : QWidget{parent} {
void EleGif::paintEvent(QPaintEvent *){
QPainter painter(this);
if(movie) {
if(movie!=nullptr) {
painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform);
painter.drawPixmap(0, 0, width(), height(), movie->currentPixmap());
if(timer==0) {
if(timer==nullptr) {
timer = new SyncTimer(movie->nextFrameDelay());
connect(timer, &SyncTimer::timeout, this, &EleGif::sltNext, Qt::BlockingQueuedConnection);
timer->start();
@ -25,8 +25,8 @@ void EleGif::sltNext(){
movie->jumpToNextFrame();
timer->inter = movie->nextFrameDelay();
update();
} else if(timer) {
} else if(timer!=nullptr) {
timer->stop();
timer = 0;
timer = nullptr;
}
}

14
LedOK/player/eleimg.cpp Normal file
View File

@ -0,0 +1,14 @@
#include "eleimg.h"
#include <QJsonObject>
#include <QPainter>
EleImg::EleImg(QString path, QWidget *parent) : QWidget{parent} {
img.load(path);
}
void EleImg::paintEvent(QPaintEvent *){
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform);
if(! img.isNull()) painter.drawPixmap(0, 0, width(), height(), img);
}

15
LedOK/player/eleimg.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef ELEIMG_H
#define ELEIMG_H
#include <QWidget>
class EleImg : public QWidget {
Q_OBJECT
public:
explicit EleImg(QString, QWidget *parent = nullptr);
QPixmap img;
protected:
void paintEvent(QPaintEvent *) override;
};
#endif // ELEIMG_H

View File

@ -0,0 +1,104 @@
#include "elemultipng.h"
#include <QJsonObject>
#include <QJsonArray>
#include <QPainter>
#include <QTimerEvent>
const QChar effTypes[] = {'l', 't', 'r', 'b'};
EleMultiPng::EleMultiPng(QString dirPre, QJsonArray maps, QWidget *parent) : QWidget{parent} {
QJsonObject map = maps[0].toObject();
picDur = map["picDuration"].toInt()*1000;
if(picDur==0) return;
EffDur = map["effectSpeed"].toInt()*1000;
foreach(QJsonValue map, maps) imgs.append(QPixmap(dirPre+map["id"].toString()));
QString effStr = map["effect"].toString();
if(effStr.isEmpty() || effStr=="no") EffDur = 0;
else if(effStr.endsWith("left")) effType = 'l';
else if(effStr.endsWith("top")) effType = 't';
else if(effStr.endsWith("right")) effType = 'r';
else if(effStr.endsWith("bottom")) effType = 'b';
else if(effStr == "random") needRand = true;
else EffDur = 0;
}
void EleMultiPng::startMove() {
if(EffDur==0) return;
if(needRand) effType = effTypes[rand.generate() % 4];
double effDurD = EffDur;
if(effType=='l') {
imgx = width();
imgy = 0;
effDurD /= width();
} else if(effType=='r') {
imgx = -width();
imgy = 0;
effDurD /= width();
} else if(effType=='t') {
imgx = 0;
imgy = height();
effDurD /= height();
} else if(effType=='b') {
imgx = 0;
imgy = -height();
effDurD /= height();
} else return;
movePx = ceil(17/effDurD);
moveInter = effDurD*movePx;
moveTimerId = startTimer(moveInter, Qt::PreciseTimer);
}
void EleMultiPng::paintEvent(QPaintEvent *) {
if(timerId==0 && (EffDur!=0 || imgs.size()>1)) {
timerId = startTimer(picDur, Qt::PreciseTimer);
startMove();
}
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform);
painter.drawPixmap(imgx, imgy, imgs[imgc]);
}
void EleMultiPng::timerEvent(QTimerEvent *e) {
if(isVisible()) {
int id = e->timerId();
if(id==timerId){
if(imgc+2 > imgs.size()) imgc = 0;
else imgc++;
startMove();
} else if(id==moveTimerId){
if(effType=='l') {
imgx -= movePx;
if(imgx < 0) imgx = 0;
} else if(effType=='t') {
imgy -= movePx;
if(imgy < 0) imgy = 0;
} else if(effType=='r') {
imgx += movePx;
if(imgx > 0) imgx = 0;
} else if(effType=='b') {
imgy += movePx;
if(imgy > 0) imgy = 0;
}
if(imgx==0 && imgy==0) {
killTimer(moveTimerId);
moveTimerId = 0;
}
}
update();
foreach(auto split, splits) split->update();
} else {
if(timerId!=0) {
killTimer(timerId);
timerId = 0;
}
if(moveTimerId!=0) {
killTimer(moveTimerId);
moveTimerId = 0;
}
}
}
void EleSplitPng::paintEvent(QPaintEvent *) {
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform);
painter.drawPixmap(multiPng->imgx, multiPng->imgy, multiPng->imgs[multiPng->imgc]);
}

View File

@ -0,0 +1,37 @@
#ifndef ELEMULTIPNG_H
#define ELEMULTIPNG_H
#include <QWidget>
#include <QRandomGenerator>
class EleSplitPng;
class EleMultiPng : public QWidget {
Q_OBJECT
public:
explicit EleMultiPng(QString, QJsonArray, QWidget *parent = nullptr);
void startMove();
QVector<QPixmap> imgs;
int timerId = 0, moveTimerId = 0;
int picDur = 0, EffDur = 0, moveInter = 0, movePx = 0, imgc = 0, imgx = 0, imgy = 0;
QChar effType{0};
QRandomGenerator rand;
bool needRand = false;
QList<EleSplitPng*> splits;
protected:
void paintEvent(QPaintEvent *) override;
void timerEvent(QTimerEvent *) override;
};
class EleSplitPng : public QWidget {
Q_OBJECT
public:
explicit EleSplitPng(EleMultiPng *multiPng, QWidget *parent) : QWidget{parent}, multiPng(multiPng) {}
protected:
void paintEvent(QPaintEvent *) override;
EleMultiPng *multiPng;
};
#endif // ELEMULTIPNG_H

View File

@ -1,98 +1,80 @@
#include "elescroll.h"
#include "playwin.h"
#include <QOpenGLWidget>
#include <QJsonObject>
#include <QPainter>
#include <QPaintEvent>
#include <complex>
EleScroll::EleScroll(QWidget *parent, QString dirPre, const JValue &json, int w, int h) : QWidget{parent}, w(w), h(h) {
img.load(dirPre + json["id"].toString());
auto effStr = json["effect"].toString();
if(effStr.isEmpty() || effStr=="no") return;
auto scrollSpeed = json["scrollSpeed"].toDouble();
if(scrollSpeed==0) {
auto scrollDur = json["effectSpeed"].toDouble();
if(scrollDur==0) return;
scrollSpeed = 1000 / scrollDur;
}
interval = step = 1;
if(scrollSpeed > 60) step = (int) round(scrollSpeed/60);
else if(scrollSpeed < 60) interval = (int) round(60/scrollSpeed);
EleScroll::EleScroll(QWidget *parent, QString dirPre, QJsonObject map) : QWidget{parent} {
img.load(dirPre + map["id"].toString());
QString effStr = map["effect"].toString();
if(effStr.isNull() || effStr=="no") return;
double effDurD = map["effectSpeed"].toInt()/2;
if(effDurD==0) return;
int idx = effStr.lastIndexOf(' ');
if(idx > -1) {
effect = effStr.at(idx+1).toLatin1();
if(effect=='l') end = -(img.width()-step);
else if(effect=='r') end = img.width()-step;
else if(effect=='t') end = -(img.height()-step);
else if(effect=='b') end = img.height()-step;
if(effect=='l') end = -(img.width()-1);
else if(effect=='r') end = img.width()-1;
else if(effect=='t') end = -(img.height()-1);
else if(effect=='b') end = img.height()-1;
}
interval = ceil(effDurD/16.666666)*16.666666;
curAdd = ceil(interval/effDurD);
}
EleScroll::EleScroll(QWidget *parent, QString imgPath, char effect, double scrollSpeed) : QWidget{parent}, effect(effect) {
EleScroll::EleScroll(QWidget *parent, QString imgPath, char effect, double effDur) : QWidget{parent}, effect(effect) {
img.load(imgPath);
if(effect==0) return;
if(scrollSpeed==0) return;
interval = step = 1;
if(scrollSpeed > 60) step = (int) round(scrollSpeed/60);
else if(scrollSpeed < 60) interval = (int) round(60/scrollSpeed);
if(effect=='l') end = -(img.width()-step);
else if(effect=='r') end = img.width()-step;
else if(effect=='t') end = -(img.height()-step);
else if(effect=='b') end = img.height()-step;
if(effDur==0) return;
if(effect=='l') end = -(img.width()-1);
else if(effect=='r') end = img.width()-1;
else if(effect=='t') end = -(img.height()-1);
else if(effect=='b') end = img.height()-1;
interval = ceil(effDur/16.666666)*16.666666;
curAdd = ceil(interval/effDur);
}
void EleScroll::paintEvent(QPaintEvent *e) {
void EleScroll::paintEvent(QPaintEvent *) {
paint(this);
}
void EleScroll::paint(QPaintDevice *that) {
if(img.isNull()) return;
auto rect = e->rect();
QPainter painter(this);
if(timerId==0 && effect!=0 && interval!=0) {
cur = 0;
timerId = startTimer(interval, Qt::PreciseTimer);
}
QPainter painter(that);
painter.setRenderHints(QPainter::Antialiasing|QPainter::SmoothPixmapTransform);
if(effect=='l') {
int x = cur;
do {
if(x > rect.left()-img.width() && x < rect.right()+1) painter.drawPixmap(x, 0, img);
x += img.width();
} while(x < rect.right()+1);
painter.drawPixmap(cur, 0, img);
painter.drawPixmap(cur+img.width(), 0, img);
} else if(effect=='r') {
int x = cur + w;
boolean con1;
do {
x -= img.width();
con1 = x > rect.left()-img.width();
if(con1 && x < rect.right()+1) painter.drawPixmap(x, 0, img);
} while(con1);
painter.drawPixmap(cur, 0, img);
painter.drawPixmap(cur-img.width(), 0, img);
} else if(effect=='t') {
int y = cur;
do {
if(y > rect.top()-img.height() && y < rect.bottom()+1) painter.drawPixmap(0, y, img);
y += img.height();
} while(y < rect.bottom()+1);
painter.drawPixmap(0, cur, img);
painter.drawPixmap(0, cur+img.height(), img);
} else if(effect=='b') {
int y = cur + h;
boolean con1;
do {
y -= img.height();
con1 = y > rect.top()-img.height();
if(con1 && y < rect.bottom()+1) painter.drawPixmap(0, y, img);
} while(con1);
painter.drawPixmap(0, cur, img);
painter.drawPixmap(0, cur-img.height(), img);
} else painter.drawPixmap(0, 0, img);
if(freshCnt==0 && effect!=0 && interval!=0) connect(PlayWin::self->gl, &QOpenGLWidget::frameSwapped, this, &EleScroll::doFrame, Qt::UniqueConnection);
}
void EleScroll::doFrame() {
if(! isVisible()) {
freshCnt = cur = 0;
disconnect(PlayWin::self->gl, &QOpenGLWidget::frameSwapped, this, &EleScroll::doFrame);
return;
}
if(freshCnt < interval) freshCnt++;
else {
freshCnt = 1;
void EleScroll::timerEvent(QTimerEvent *) {
if(isVisible()) {
if(effect=='t' || effect=='l') {
if(cur <= end) cur -= end;
else cur -= step;
if(cur <= end) cur = 0;
else cur-=curAdd;
} else if(effect=='b' || effect=='r') {
if(cur >= end) cur -= end;
else cur += step;
if(cur >= end) cur = 0;
else cur+=curAdd;
}
update();
foreach(auto split, splits) split->update();
} else if(timerId!=0) {
killTimer(timerId);
timerId = 0;
}
}
void EleSplitScroll::paintEvent(QPaintEvent *) {
scroll->paint(this);
}

View File

@ -1,22 +1,31 @@
#ifndef ELESCROLL_H
#define ELESCROLL_H
#include "gutil/qjson.h"
#include <QWidget>
class EleSplitScroll;
class EleScroll : public QWidget {
Q_OBJECT
public:
explicit EleScroll(QWidget *, QString, const JValue &, int, int);
explicit EleScroll(QWidget *, QString, QJsonObject);
explicit EleScroll(QWidget *, QString, char effect = 0, double effDur = 0.0);
int w = 0, h = 0;
QPixmap img;
char effect = 0;
int interval = 0, freshCnt = 0, cur = 0, end = 0, step = 1;
bool noUpdate = false;
void doFrame();
int interval = 0, timerId = 0, cur = 0, end = 0, curAdd = 1;
QList<EleSplitScroll*> splits;
void paint(QPaintDevice *);
protected:
void paintEvent(QPaintEvent *) override;
void timerEvent(QTimerEvent *) override;
};
class EleSplitScroll : public QWidget {
Q_OBJECT
public:
explicit EleSplitScroll(QWidget *parent, EleScroll *scroll) : QWidget{parent}, scroll(scroll) {};
protected:
void paintEvent(QPaintEvent *) override;
EleScroll *scroll;
};
#endif // ELESCROLL_H

View File

@ -2,15 +2,16 @@
#include "tools.h"
#include "globaldefine.h"
#include <QPainter>
#include <QJsonObject>
EleTimer::EleTimer(const JValue &json, QWidget *parent) : QWidget{parent} {
EleTimer::EleTimer(const QJsonObject &json, QWidget *parent) : QWidget{parent} {
isDown = json["isDown"].toBool();
targetTime = QDateTime::fromString(json["targetTime"].toString(), "yyyy-MM-dd HH:mm:ss");
hasDay = json["hasDay"].toBool();
hasHour = json["hasHour"].toBool();
hasMin = json["hasMin"].toBool();
hasSec = json["hasSec"].toBool();
title = json["text"].toString();
text = json["text"].toString();
isMultiline = json["isMultiline"].toBool();
font = QFont(json["font"].toString());
font.setPixelSize(json["fontSize"].toInt());
@ -32,8 +33,12 @@ EleTimer::EleTimer(const JValue &json, QWidget *parent) : QWidget{parent} {
}
void EleTimer::paintEvent(QPaintEvent *){
auto text = this->title;
if(! text.isEmpty()) text += isMultiline ? '\n' : ' ';
QString text;
if(! this->text.isEmpty()) {
text += this->text;
if(isMultiline) text += '\n';
else text += " ";
}
int secs = this->secs;
if(hasDay) {
text.append(QString::number(secs/86400)).append(" ").append(tr("day")).append(" ");

View File

@ -1,25 +1,24 @@
#ifndef ELETIMER_H
#define ELETIMER_H
#include "gutil/qjson.h"
#include <QWidget>
#include <QDateTime>
class EleTimer : public QWidget {
Q_OBJECT
public:
explicit EleTimer(const JValue &, QWidget *parent = 0);
explicit EleTimer(const QJsonObject&, QWidget *parent = 0);
QDateTime targetTime;
QString title;
QColor textColor;
QColor backColor;
QString text;
QColor textColor;
QColor backColor;
QFont font;
bool isDown;
bool isMultiline;
bool hasDay;
bool hasHour;
bool hasMin;
bool hasSec;
bool isDown;
bool isMultiline;
bool hasDay;
bool hasHour;
bool hasMin;
bool hasSec;
int secs = 0;
protected:
void paintEvent(QPaintEvent *) override;

View File

@ -1,184 +1,176 @@
#include "playwin.h"
#include "eledigiclock.h"
#include "digiclock.h"
#include "eleanaclock.h"
#include "eleborder.h"
#include "elegif.h"
#include "eleimg.h"
#include "elemultipng.h"
#include "elescroll.h"
#include "eletimer.h"
#include "elevideo.h"
#include "srccopy.h"
#include "posdlg.h"
#include <QFileInfo>
#include <QJsonArray>
#include <QJsonObject>
#include <QLabel>
#include <QMouseEvent>
#include <QMovie>
#include <QThread>
#include <QWebEngineView>
#include <QGuiApplication>
#include <QOpenGLWidget>
PlayWin* PlayWin::self = 0;
QPoint gPlayPos{0, 0};
PlayWin *PlayWin::newIns(int width, int height, QString dir, const JValue &aprog, QWidget *parent) {
Page::Page(QWidget *parent) : QWidget{parent} {
}
PlayWin *PlayWin::newIns(int width, int height, QString dir, const QJsonObject &aprog, QWidget *parent) {
if(! gPlayPos.isNull() && QGuiApplication::screenAt(QPoint(gPlayPos.x()+width/2, gPlayPos.y()+height/2))==0) gPlayPos = QPoint();
return new PlayWin(gPlayPos.x(), gPlayPos.y(), width, height, dir, aprog, parent);
}
PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const JValue &aprog, QWidget *parent) : QWidget(parent) {
self = this;
PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const QJsonObject &aprog, QWidget *parent) : QWidget(parent) {
setAttribute(Qt::WA_DeleteOnClose);
setAttribute(Qt::WA_QuitOnClose, false);
setWindowFlag(Qt::FramelessWindowHint);
setWindowFlag(Qt::WindowStaysOnTopHint);
setGeometry(x, y, width, height+1);
auto plt = palette();
plt.setColor(QPalette::Window, Qt::black);
setGeometry(x, y, width, height);
QPalette plt = palette();
plt.setColor(QPalette::Window, QColor(0,0,0));
setPalette(plt);
gl = new QOpenGLWidget(this);
gl->setGeometry(0, height, width, 1);
connect(gl, &QOpenGLWidget::frameSwapped, gl, (void(QOpenGLWidget::*)())&QOpenGLWidget::update);
auto task = aprog["task"];
auto jpages = task["items"];
connect(this, &PlayWin::sigSetVisible, this, &PlayWin::sltSetVisible);
auto partLengths = task["partLengths"];
auto isVertical = task["isVertical"].toBool();
QWidget *box = this;
if(partLengths.size() > 1) {
box = new QWidget(this);
auto width = task["width"].toInt();
auto height = task["height"].toInt();
box->setGeometry(0, 0, width, height);
auto mask = new QWidget(this);
mask->setAutoFillBackground(true);
auto pal = mask->palette();
pal.setColor(QPalette::Window, Qt::black);
mask->setPalette(pal);
auto len0 = partLengths[0].toInt();
isVertical ? mask->setGeometry(0, len0, width, height - len0) : mask->setGeometry(len0, 0, width - len0, height);
int x = 0, y = 0;
for(int i=1; i<(int)partLengths.size(); i++) {
auto part = new SrcCopy(this, box);
if(isVertical) {
y -= partLengths[i-1].toInt();
x += width;
part->setGeometry(x, y, width, partLengths[i].toInt() - y);
} else {
x -= partLengths[i-1].toInt();
y += height;
part->setGeometry(x, y, partLengths[i].toInt() - x, height);
}
}
}
for(auto &pageMap : jpages) {
auto _program = pageMap["_program"];
auto layers = _program["layers"];
if(layers.empty()) continue;
Page page;
page.repeatTimes = pageMap["repeatTimes"].toInt();
for(int ll=(int)layers.size()-1; ll>=0; ll--) {
Layer layer;
layer.isLoop = layers[ll]["repeat"].toBool();
auto sources = layers[ll]["sources"];
auto border = layers[ll]["border"];
const auto pageMaps = aprog["task"]["items"].toArray();
int pageCnt = pageMaps.size();
EleBase ele; Page *page;
for(int p=0; p<pageCnt; p++) {
auto _program = pageMaps[p]["_program"].toObject();
auto layers = _program["layers"].toArray();
if(layers.isEmpty()) continue;
auto splitWidths = _program["splitWidths"].toArray();
page = new Page(this);
page->setGeometry(0, 0, width, height);
page->setVisible(false);
for(int ll=layers.size()-1; ll>=0; ll--) {
auto layer = layers[ll].toObject();
auto repeat = layer["repeat"].toBool();
auto srcMaps = layer["sources"].toArray();
QJsonValue border = layer["border"];
EleBorder *bdEle = 0;
int bdWidth = 0, bdStart = 0xffff, bdEnd = 0;
if(! border.isNull()) {
bdEle = new EleBorder(dir+"/"+border["img"].toString(), border["eff"].toString(), border["speed"].toInt(), box);
bdEle = new EleBorder(dir+"/"+border["img"].toString(), border["eff"].toString(), border["speed"].toInt(), page);
bdWidth = bdEle->img.height();
}
Source src;
for(auto &source : sources) {
src.type = source["_type"].toString();
if(src.type.isEmpty()) continue;
auto timeSpan = source["timeSpan"].toInt()*1000;
foreach(QJsonValue srcMap, srcMaps) {
ele.type = srcMap["_type"].toString();
if(ele.type.isEmpty()) continue;
auto timeSpan = srcMap["timeSpan"].toInt()*1000;
if(timeSpan==0) continue;
auto x = source["left"].toInt()+bdWidth;
auto y = source["top"].toInt()+bdWidth;
auto w = source["width"].toInt()-bdWidth-bdWidth;
auto h = source["height"].toInt()-bdWidth-bdWidth;
bool notAudio = src.type!="Audio";
if((w<=0 || h<=0) && notAudio) continue;
src.startTime = source["playTime"].toInt()*1000;
if(bdStart > src.startTime) bdStart = src.startTime;
src.endTime = src.startTime + timeSpan;
if(bdEnd < src.endTime) bdEnd = src.endTime;
if(layer.dur < src.endTime) layer.dur = src.endTime;
if(notAudio) {
if(page.sDur < src.endTime) page.sDur = src.endTime;
} else if(page.audioDur < src.endTime) page.audioDur = src.endTime;
if(src.exitDur!=0) src.exitStart = timeSpan*60/1000 - src.exitDur;
auto id = source["id"].toString();
src.view = 0;
if(src.type=="Image") {
if(source["fileExt"].toString()=="gif") src.view = new EleGif(dir+"/"+id, box);
else {
auto lb = new QLabel(box);
lb->setPixmap(QPixmap(dir+"/"+id));
lb->setScaledContents(true);
src.view = lb;
}
} else if(src.type.startsWith("Environ")) {
auto arrayPics = source["arrayPics"];
for(int i=(int)arrayPics.size()-1; i>=0; i--) if(arrayPics[i]["name"].toString() == "previewTmp") {
if(source["bSingleScroll"].toBool()) src.view = new EleScroll(box, dir+"/" + arrayPics[i]["id"].toString(), 'l', source["iScrollSpeed"].toDouble());
else src.view = new EleScroll(box, dir+"/"+arrayPics[i]["id"].toString());
ele.x = srcMap["left"].toInt()+bdWidth;
ele.y = srcMap["top"].toInt()+bdWidth;
ele.w = srcMap["width"].toInt()-bdWidth-bdWidth;
ele.h = srcMap["height"].toInt()-bdWidth-bdWidth;
bool notAudio = ele.type!="Audio";
if((ele.w<=0 || ele.h<=0) && notAudio) continue;
ele.repeat = repeat;
ele.startTime = srcMap["playTime"].toInt()*1000;
if(bdStart > ele.startTime) bdStart = ele.startTime;
ele.endTime = ele.startTime + timeSpan;
if(bdEnd < ele.endTime) bdEnd = ele.endTime;
if(page->timeSpan < ele.endTime && notAudio) page->timeSpan = ele.endTime;
ele.id = srcMap["id"].toString();
ele.wgt = 0;
if(ele.type=="Image") {
if(srcMap["mime"].toString().endsWith("gif")) ele.wgt = new EleGif(dir+"/"+ele.id, page);
else ele.wgt = new EleImg(dir+"/"+ele.id, page);
} else if(ele.type.startsWith("Environ")) {
QJsonValue arrayPics = srcMap["arrayPics"];
for(int i=arrayPics.toArray().size()-1; i>=0; i--) if(arrayPics[i]["name"].toString() == "previewTmp") {
if(srcMap["bSingleScroll"].toBool()) ele.wgt = new EleScroll(page, dir+"/" + arrayPics[i]["id"].toString(), 'l', srcMap["iScrollSpeed"].toDouble());
else ele.wgt = new EleScroll(page, dir+"/"+arrayPics[i]["id"].toString());
break;
}
} else if(src.type=="MultiPng" || src.type=="SplitText") {
auto imgs = source["arrayPics"];
if(! imgs.empty()) src.view = new EleScroll(box, dir+"/", imgs[0], w, h);
} else if(src.type=="DigitalClockNew") src.view = new EleDigiClock(dir+"/", source, box);
else if(src.type=="AnalogClock") src.view = new EleAnaClock(w, h, dir+"/"+id, source, box);
else if(src.type=="Video" || src.type=="Audio") {
auto video = new EleVideo(dir+"/"+id, box);
auto vol = source["vol"].toInt(100);
if(vol<100) video->player->setVol(vol/100.0);
src.view = video;
} else if(src.type=="WebURL") {
auto web = new QWebEngineView(box);
web->load(QUrl(source["url"].toString()));
src.view = web;
}
else if(src.type=="Timer") src.view = new EleTimer(source, box);
else continue;
if(src.view==0) continue;
src.view->setVisible(false);
if(w) src.view->setGeometry(x, y, w, h);
layer.srcs.push_back(src);
}
if(bdEle && ! sources.empty()) {
auto geometry = border["geometry"];
src.startTime = bdStart;
src.endTime = bdEnd;
src.view = bdEle;
src.view->setVisible(false);
src.view->setGeometry(geometry[0].toInt(), geometry[1].toInt(), geometry[2].toInt(), geometry[3].toInt());
layer.srcs.push_back(src);
}
if(! layer.srcs.empty()) page.layers.emplace_back(std::move(layer));
}
if(page.sDur==0) {
if(page.audioDur > 0) page.sDur = page.audioDur;
else continue;
}
page.tDur = page.sDur * page.repeatTimes;
for(auto layer=page.layers.begin(); layer<page.layers.end(); ++layer) {
for(auto src=layer->srcs.begin(); src<layer->srcs.end(); ++src) {
if(src->startTime >= page.sDur) {
if(layer->srcs.size() > 1) layer->srcs.erase(src--);
else {
page.layers.erase(layer--);
goto conti_layer;
} else if(ele.type=="MultiPng") {
QJsonArray imgs = srcMap["arrayPics"].toArray();
if(imgs.isEmpty()) continue;
if(imgs.size()==1 && imgs.at(0)["picDuration"].toInt()==0) ele.wgt = new EleScroll(page, dir+"/", imgs[0].toObject());
else ele.wgt = new EleMultiPng(dir+"/", imgs, page);
} else if(ele.type=="SplitText") {
QJsonArray imgs = srcMap["arrayPics"].toArray();
if(imgs.isEmpty()) continue;
ele.wgt = new QWidget(page);
ele.wgt->setGeometry(0, 0, width, height);
auto height = _program["height"].toInt();
if(imgs.size()==1 && imgs.at(0)["picDuration"].toInt()==0) {
auto wgt = new EleScroll(ele.wgt, dir+"/", imgs[0].toObject());
wgt->setGeometry(ele.x, ele.y, ele.w, ele.h);
for(int i=1; i<splitWidths.size(); i++) {
ele.x -= splitWidths[i-1].toInt();
ele.y += height;
auto split = new EleSplitScroll(ele.wgt, wgt);
split->setGeometry(ele.x, ele.y, splitWidths[i].toInt()-ele.x, ele.h);
wgt->splits.append(split);
}
} else {
auto wgt = new EleMultiPng(dir+"/", imgs, ele.wgt);
wgt->setGeometry(ele.x, ele.y, ele.w, ele.h);
for(int i=1; i<splitWidths.size(); i++) {
ele.x -= splitWidths[i-1].toInt();
ele.y += height;
auto split = new EleSplitPng(wgt, ele.wgt);
split->setGeometry(ele.x, ele.y, splitWidths[i].toInt()-ele.x, ele.h);
wgt->splits.append(split);
}
}
} else if(src->endTime > page.sDur) src->endTime = page.sDur;
ele.w = 0;
} else if(ele.type=="DigitalClockNew") ele.wgt = new DigiClock(dir+"/", srcMap.toObject(), page);
else if(ele.type=="AnalogClock") ele.wgt = new EleAnaClock(ele.w, ele.h, dir+"/"+ele.id, srcMap.toObject(), page);
else if(ele.type=="Video" || ele.type=="Audio") {
auto video = new EleVideo(dir+"/"+ele.id, page);
auto vol = srcMap["vol"].toInt(100);
if(vol<100) video->player->setVol(vol/100.0);
ele.wgt = video;
} else if(ele.type=="WebURL") {
auto web = new QWebEngineView(page);
web->load(QUrl(srcMap["url"].toString()));
ele.wgt = web;
}
else if(ele.type=="Timer") ele.wgt = new EleTimer(srcMap.toObject(), page);
else continue;
if(ele.wgt==0) continue;
if(ele.startTime>0) ele.wgt->setVisible(false);
if(ele.w) ele.wgt->setGeometry(ele.x, ele.y, ele.w, ele.h);
page->eles.append(ele);
}
if(bdEle && ! srcMaps.isEmpty()) {
QJsonArray geometry = border["geometry"].toArray();
ele.x = geometry[0].toInt();
ele.y = geometry[1].toInt();
ele.w = geometry[2].toInt();
ele.h = geometry[3].toInt();
ele.startTime = bdStart;
ele.endTime = bdEnd;
ele.wgt = bdEle;
if(ele.startTime>0) ele.wgt->setVisible(false);
ele.wgt->setGeometry(ele.x, ele.y, ele.w, ele.h);
page->eles.append(ele);
}
if(layer->dur > page.sDur) layer->dur = page.sDur;
if(layer->dur == page.sDur) layer->isLoop = false;
conti_layer:;
}
pages.emplace_back(std::move(page));
if(page->timeSpan==0) continue;
for(int i=0; i<page->eles.size(); i++) if(page->eles[i].repeat) page->eles[i].endTime = page->timeSpan;
pages.append(page);
}
setVisible(true);
if(! pages.isEmpty()) {
Page* page0 = pages[0];
EleBase* eleptr;
for(int ee=0; ee<page0->eles.size(); ee++) if((eleptr = &page0->eles[ee])->startTime > 0 || eleptr->endTime < page0->timeSpan) {
if(eleptr->startTime > 0) timerMap.insert(startTimer(eleptr->startTime), TimerValue(eleptr->wgt, true));
timerMap.insert(startTimer(eleptr->endTime), TimerValue(eleptr->wgt, false));
}
}
menu = new QMenu(this);
@ -196,52 +188,48 @@ PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const JValue
if(self==this) self = nullptr;
close();
});
setVisible(true);
if(pages.empty()) return;
pages[0].setMillis((std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() + 999)/1000*1000);
connect(gl, &QOpenGLWidget::frameSwapped, this, &PlayWin::doFrame, Qt::UniqueConnection);
}
void PlayWin::doFrame() {
if(! isVisible()) return;
auto milli = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
auto& lastPage = pages[curAva];
if(milli >= lastPage.endMilli) {
lastPage.hide();
if(curTimes < lastPage.repeatTimes) curTimes++;
else {
curTimes = 1;
curAva++;
if(curAva >= (int)pages.size()) {
curAva = 0;
auto isDiff = milli-lastPage.endMilli>=1000;
pages[curAva].setMillis(isDiff ? milli : lastPage.endMilli);
return;
}
}
pages[curAva].setMillis(lastPage.endMilli);
} else {
for(auto &layer : lastPage.layers) {
for(auto &src : layer.srcs) {
if(src.view->isVisible()) {
if(milli >= src.endMilli) src.hide();
else src.doEff();
} else if(milli < src.endMilli && milli >= src.startMilli) src.show();
}
if(milli >= layer.endMilli) {
layer.endMilli += layer.dur;
for(auto &src : layer.srcs) {
src.endMilli += layer.dur;
src.startMilli += layer.dur;
if(src.startTime > 0) src.hide();
else src.show();
}
}
void PlayWin::sltNext() {
if(isVisible()) {
pages[cur]->setVisible(false);
if(cur+2 > pages.size()) cur = 0;
else cur++;
Page* page = pages[cur];
if(timer) timer->inter = page->timeSpan;
EleBase* ele;
for(int ee=0; ee<page->eles.size(); ee++) if((ele = &page->eles[ee])->startTime > 0 || ele->endTime < page->timeSpan) {
if(ele->startTime > 0) timerMap.insert(startTimer(ele->startTime), TimerValue(ele->wgt, true));
else ele->wgt->setVisible(true);
timerMap.insert(startTimer(ele->endTime), TimerValue(ele->wgt, false));
}
page->setVisible(true);
} else if(timer) {
timer->stop();
timer = 0;
}
}
void PlayWin::timerEvent(QTimerEvent *e){
int id = e->timerId();
killTimer(id);
TimerValue value = timerMap[id];
if(value.ele) {
timerMap.remove(id);
value.ele->setVisible(value.visible);
}
}
void PlayWin::paintEvent(QPaintEvent *e){
if(timer==0 && isVisible() && ! pages.isEmpty()) {
if(cur!=0) {
pages[cur]->setVisible(false);
cur = 0;
}
pages[cur]->setVisible(true);
timer = new SyncTimer(pages[cur]->timeSpan);
connect(timer, &SyncTimer::timeout, this, &PlayWin::sltNext, Qt::BlockingQueuedConnection);
timer->start();
}
QWidget::paintEvent(e);
}
void PlayWin::mousePressEvent(QMouseEvent *e) {
if(e->button() == Qt::LeftButton) {

View File

@ -1,225 +1,50 @@
#ifndef PLAYWIN_H
#define PLAYWIN_H
#include "gutil/qjson.h"
#include "elebase.h"
#include "synctimer.h"
#include <QWidget>
#include <QMenu>
#include <QVector>
#include <QMap>
enum Effect {
EXPAND_HOR, EXPAND_VER, EXPAND_LEFT, EXPAND_TOP, EXPAND_RIGHT, EXPAND_BOTTOM,
ZOOM, ZOOM_TL, ZOOM_TR, ZOOM_BR, ZOOM_BL,
ROTATE, ROTATE_R,
FADE,
MOVE_LEFT, MOVE_TOP, MOVE_RIGHT, MOVE_BOTTOM,
End
};
class Source {
class Page : public QWidget {
public:
QWidget *view = 0;
int64_t startMilli = 0, endMilli = LLONG_MAX;
int startTime = 0, entryDur = 0, exitStart = INT_MAX, exitDur = 0, endTime = 0, ff = 0;
Effect entryEff, exitEff;
QString type;
bool isEntryRand = 0, isExitRand = 0;
void show() {
if(view->isVisible()) return;
view->setVisible(true);
ff = 0;
if(isEntryRand) entryEff = (Effect) (rand() % Effect::End);
if(isExitRand) exitEff = (Effect) (rand() % Effect::End);
resetEff();
doEff();
}
void hide() {
if(! view->isVisible()) return;
view->setVisible(false);
}
void doEff() {
// auto w = view->width();
// auto h = view->height();
// if(ff < entryDur) {
// if(entryEff == Effect::EXPAND_HOR) view.setScaleX(ff / (float) entryDur);
// else if(entryEff == Effect::EXPAND_VER) view.setScaleY(ff / (float) entryDur);
// else if(entryEff == Effect::EXPAND_LEFT) {
// view.setScaleX(ff / (float) entryDur);
// view.setTranslationX((1 - view.getScaleX()) * w / 2);
// } else if(entryEff == Effect::EXPAND_TOP) {
// view.setScaleY(ff / (float) entryDur);
// view.setTranslationY((1 - view.getScaleY()) * h / 2);
// } else if(entryEff == Effect::EXPAND_RIGHT) {
// view.setScaleX(ff / (float) entryDur);
// view.setTranslationX((view.getScaleX() - 1) * w / 2);
// } else if(entryEff == Effect::EXPAND_BOTTOM) {
// view.setScaleY(ff / (float) entryDur);
// view.setTranslationY((view.getScaleY() - 1) * h / 2);
// }
// else if(entryEff == Effect::MOVE_LEFT) view.setTranslationX(w - ff*w/(float) entryDur);
// else if(entryEff == Effect::MOVE_TOP) view.setTranslationY(h - ff*h/(float) entryDur);
// else if(entryEff == Effect::MOVE_RIGHT) view.setTranslationX(ff*w/(float) entryDur - w);
// else if(entryEff == Effect::MOVE_BOTTOM) view.setTranslationY(ff*h/(float) entryDur - h);
// else if(entryEff == Effect::FADE) view.setAlpha(ff / (float) entryDur);
// else if(entryEff == Effect::ZOOM) {
// view.setScaleX(ff / (float) entryDur);
// view.setScaleY(view.getScaleX());
// } else if(entryEff == Effect::ZOOM_TL) {
// var rate = ff / (float) entryDur;
// view.setTranslationX((rate - 1) * w / 2);
// view.setTranslationY((rate - 1) * h / 2);
// view.setScaleX(rate);
// view.setScaleY(rate);
// } else if(entryEff == Effect::ZOOM_BR) {
// var rate = ff / (float) entryDur;
// view.setTranslationX((1 - rate) * w / 2);
// view.setTranslationY((1 - rate) * h / 2);
// view.setScaleX(rate);
// view.setScaleY(rate);
// } else if(entryEff == Effect::ZOOM_TR) {
// var rate = ff / (float) entryDur;
// view.setTranslationX((1 - rate) * w / 2);
// view.setTranslationY((rate - 1) * h / 2);
// view.setScaleX(rate);
// view.setScaleY(rate);
// } else if(entryEff == Effect::ZOOM_BL) {
// var rate = ff / (float) entryDur;
// view.setTranslationX((rate - 1) * w / 2);
// view.setTranslationY((1 - rate) * h / 2);
// view.setScaleX(rate);
// view.setScaleY(rate);
// } else if(entryEff == Effect::ROTATE) {
// view.setScaleX(ff / (float) entryDur);
// view.setScaleY(view.getScaleX());
// view.setRotation(view.getScaleX() * 360);
// } else if(entryEff == Effect::ROTATE_R) {
// view.setScaleX(ff / (float) entryDur);
// view.setScaleY(view.getScaleX());
// view.setRotation(- view.getScaleX() * 360);
// }
// } else if(ff>=exitStart) {
// var fff = ff - exitStart;
// if(fff > exitDur) fff = exitDur;
// if(exitEff == Effect::EXPAND_HOR) view.setScaleX(1 - fff / (float) exitDur);
// else if(exitEff == Effect::EXPAND_VER) view.setScaleY(1 - fff / (float) exitDur);
// else if(exitEff == Effect::EXPAND_LEFT) {
// var rate = fff / (float) exitDur;
// view.setScaleX(1 - rate);
// view.setTranslationX(rate * w / 2);
// } else if(exitEff == Effect::EXPAND_TOP) {
// var rate = fff / (float) exitDur;
// view.setScaleY(1 - rate);
// view.setTranslationY(rate * h / 2);
// } else if(exitEff == Effect::EXPAND_RIGHT) {
// var rate = fff / (float) exitDur;
// view.setScaleX(1 - rate);
// view.setTranslationX(- rate * w / 2);
// } else if(exitEff == Effect::EXPAND_BOTTOM) {
// var rate = fff / (float) exitDur;
// view.setScaleY(1 - rate);
// view.setTranslationY(- rate * h / 2);
// }
// else if(exitEff == Effect::MOVE_LEFT) view.setTranslationX(- fff*w / (float) exitDur);
// else if(exitEff == Effect::MOVE_RIGHT) view.setTranslationX(fff*w / (float) exitDur);
// else if(exitEff == Effect::MOVE_TOP) view.setTranslationY(- fff*h / (float) exitDur);
// else if(exitEff == Effect::MOVE_BOTTOM) view.setTranslationY(fff*h / (float) exitDur);
// else if(exitEff == Effect::FADE) view.setAlpha(1 - fff / (float) exitDur);
// else if(exitEff == Effect::ZOOM) {
// view.setScaleX(1 - fff / (float) exitDur);
// view.setScaleY(view.getScaleX());
// } else if(exitEff == Effect::ZOOM_TL) {
// var rate = fff / (float) exitDur;
// view.setTranslationX(- rate * w / 2);
// view.setTranslationY(- rate * h / 2);
// view.setScaleX(1 - rate);
// view.setScaleY(1 - rate);
// } else if(exitEff == Effect::ZOOM_BR) {
// var rate = fff / (float) exitDur;
// view.setTranslationX(rate * w / 2);
// view.setTranslationY(rate * h / 2);
// view.setScaleX(1 - rate);
// view.setScaleY(1 - rate);
// } else if(exitEff == Effect::ZOOM_TR) {
// var rate = fff / (float) exitDur;
// view.setTranslationX(rate * w / 2);
// view.setTranslationY(- rate * h / 2);
// view.setScaleX(1 - rate);
// view.setScaleY(1 - rate);
// } else if(exitEff == Effect::ZOOM_BL) {
// var rate = fff / (float) exitDur;
// view.setTranslationX(- rate * w / 2);
// view.setTranslationY(rate * h / 2);
// view.setScaleX(1 - rate);
// view.setScaleY(1 - rate);
// } else if(exitEff == Effect::ROTATE) {
// var rate = fff / (float) exitDur;
// view.setScaleX(1 - rate);
// view.setScaleY(view.getScaleX());
// view.setRotation(rate * 360);
// } else if(exitEff == Effect::ROTATE_R) {
// var rate = fff / (float) exitDur;
// view.setScaleX(1 - rate);
// view.setScaleY(view.getScaleX());
// view.setRotation(- rate * 360);
// }
// } else resetEff();
ff++;
}
void resetEff() {
// view.setTranslationX(0);
// view.setTranslationY(0);
// view.setAlpha(1);
// view.setScaleX(1);
// view.setScaleY(1);
// view.setRotation(0);
}
};
struct Layer {
std::vector<Source> srcs;
int64_t endMilli = LLONG_MAX;
int dur = 0;
bool isLoop = 0;
explicit Page(QWidget *parent = nullptr);
int timeSpan{0};
QVector<EleBase> eles;
};
struct Page {
std::vector<Layer> layers;
int64_t endMilli = LLONG_MAX;
int sDur = 0, tDur = 0, repeatTimes = 0, audioDur = 0;
void hide() {
for(auto &layer : layers) for(auto &src : layer.srcs) src.hide();
}
void setMillis(int64_t milli) {
endMilli = milli + sDur;
for(auto &layer : layers) {
if(layer.isLoop) layer.endMilli = milli + layer.dur;
for(auto &src : layer.srcs) {
src.endMilli = milli + src.endTime;
src.startMilli = milli + src.startTime;
if(src.startTime == 0) src.show();
}
}
}
class TimerValue{
public:
TimerValue(QWidget *ele = nullptr, bool visible = false): ele(ele), visible(visible){}
QWidget* ele;
bool visible;
};
class PlayWin : public QWidget {
Q_OBJECT
public:
static PlayWin *self;
static PlayWin *newIns(int width, int height, QString dir, const JValue &prog, QWidget *parent = nullptr);
PlayWin(int x, int y, int width, int height, QString dir, const JValue &prog, QWidget *parent = nullptr);
static PlayWin *newIns(int width, int height, QString dir, const QJsonObject &prog, QWidget *parent = nullptr);
PlayWin(int x, int y, int width, int height, QString dir, const QJsonObject &prog, QWidget *parent = nullptr);
QOpenGLWidget *gl;
SyncTimer* timer = 0;
int cur = 0;
std::vector<Page> pages;
std::vector<Page> avas;
int curAva = 0, curTimes = 1;
QVector<Page*> pages;
QMap<int,TimerValue> timerMap;
QPoint mPressRel;
QMenu *menu;
void doFrame();
public slots:
void sltNext();
void sltSetVisible(QWidget *wgt, bool visible){
wgt->setVisible(visible);
}
signals:
void sigSetVisible(QWidget *, bool);
protected:
void paintEvent(QPaintEvent *) override;
void timerEvent(QTimerEvent *) override;
void mousePressEvent(QMouseEvent *) override;
void mouseReleaseEvent(QMouseEvent *) override;
void mouseMoveEvent(QMouseEvent *) override;

View File

@ -1,11 +0,0 @@
#include "srccopy.h"
#include "playwin.h"
#include <QOpenGLWidget>
#include <QBackingStore>
SrcCopy::SrcCopy(QWidget *parent, QWidget *master) : QWidget{parent}, master(master) {
connect(PlayWin::self->gl, &QOpenGLWidget::frameSwapped, this, (void(SrcCopy::*)())&SrcCopy::update);
}
void SrcCopy::paintEvent(QPaintEvent *) {
master->render(backingStore()->paintDevice(), pos(), QRegion(), DrawChildren|IgnoreMask);
}

View File

@ -1,16 +0,0 @@
#ifndef SRCCOPY_H
#define SRCCOPY_H
#include <QWidget>
class SrcCopy : public QWidget {
public:
SrcCopy(QWidget *parent, QWidget *master);
protected:
void paintEvent(QPaintEvent *) override;
QWidget *master;
};
#endif // SRCCOPY_H

View File

@ -1,5 +1,4 @@
#include "progpanel.h"
#include "program/progitem.h"
#include "globaldefine.h"
#include "gutil/qgui.h"
#include "cfg.h"
@ -7,6 +6,7 @@
#include "program/progeditorwin.h"
#include "program/copydirthread.h"
#include <QApplication>
#include <QHeaderView>
#include <QMessageBox>
#include <QStandardPaths>
#include <QProgressBar>
@ -33,38 +33,30 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) {
bnNew->setProperty("ssType", "progManageTool");
hBox->addWidget(bnNew);
connect(bnNew, &QPushButton::clicked, this, [this] {
ProgCreateDlg dlg("", 512, 256, "", "", false, this);
ProgCreateDlg dlg("", 512, 256, "", "", this);
if(dlg.exec() != QDialog::Accepted) return;
if(checkIfNameRepeated(dlg.fdName->text())) return;
std::vector<int> widths;
int max = 0;
auto width = dlg.fdVer->isChecked() ? dlg.fdHeight->value() : dlg.fdWidth->value();
if(dlg.fdIsUltraLong->isChecked()) {
auto partLengths = dlg.fdSplitWidths->text().split(" ", Qt::SkipEmptyParts);
int ttl = 0;
for(auto &partLength : partLengths) {
int val = partLength.toInt();
if(val==0) continue;
if(max < val) max = val;
ttl += val;
widths.emplace_back(val);
if(ttl>=width) break;
}
if(max) {
while(ttl < width) {
ttl += max;
widths.emplace_back(max);
}
if(ttl > width) widths.back() -= ttl - width;
}
auto splitWidths = dlg.fdSplitWidths->text().split(" ", Qt::SkipEmptyParts);
QList<int> widths; int max = 0, ttl = 0;
auto width = dlg.fdWidth->value();
foreach(auto splitWidth, splitWidths) {
int val = splitWidth.toInt();
if(val==0) continue;
if(max < val) max = val;
widths.append(val);
ttl += val;
if(ttl>=width) break;
}
auto item = new ProgItem(mProgsDir, dlg.fdName->text(), dlg.fdWidth->value(), dlg.fdHeight->value(), dlg.fdRemark->toPlainText(), widths, max, dlg.fdVer->isChecked(), mProgTree);
if(max) {
while(ttl < width) {
widths.append(max);
ttl += max;
}
if(ttl > width) widths.last() -= ttl - width;
}
auto item = new ProgItem(mProgsDir, dlg.fdName->text(), width, dlg.fdHeight->value(), dlg.fdRemark->toPlainText(), widths, max, mProgTree);
item->save();//保存pro.json
if(mProgTree->fdCheckAll->checkState()==Qt::Checked) {
mProgTree->fdCheckAll->blockSignals(true);
mProgTree->fdCheckAll->setCheckState(Qt::PartiallyChecked);
mProgTree->fdCheckAll->blockSignals(false);
}
if(mProgTree->fdCheckAll->checkState()==Qt::Checked) mProgTree->fdCheckAll->setCheckState(Qt::PartiallyChecked);
auto editor = new ProgEditorWin(item, this);
editor->show();
});
@ -130,7 +122,14 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) {
mProgTree->clear();
QStringList progNames = QDir(mProgsDir).entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
for(auto &pro_name : progNames) addProFile(mProgsDir + "/" + pro_name + "/pro.json");
foreach(QString pro_name, progNames) {
QFile jFile(mProgsDir + "/" + pro_name + "/pro.json");
if(! jFile.exists()) continue;
if(! jFile.open(QIODevice::ReadOnly)) continue;
auto data = jFile.readAll();
jFile.close();
m_pwPorgramItemList.append(new ProgItem(mProgsDir, QJsonDocument::fromJson(data).object(), mProgTree));
}
});
bnExport = new QPushButton(tr("Export"));
@ -186,16 +185,16 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) {
int cnt = mProgTree->topLevelItemCount();
for(int i=0; i<cnt; i++) if(mProgTree->item(i)->checkState("check") == Qt::Checked) {
auto item = (ProgItem*) mProgTree->topLevelItem(i);
auto dir = mProgsDir+"/"+item->mName+"_tmp";
QString dir = mProgsDir+"/"+item->mName+"_tmp";
QFile file(dir+"/program");
if(! file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
auto value = file.readAll();
QString value = file.readAll();
file.close();
QString jsErr;
auto prog = JFrom(value, &jsErr);
if(! jsErr.isEmpty()) return;
if(item->partLens.empty()) PlayWin::self = PlayWin::newIns(item->mWidth, item->mHeight, dir, prog);
else PlayWin::self = item->isVer ? PlayWin::newIns(item->mWidth * item->partLens.size(), item->maxLen, dir, prog) : PlayWin::newIns(item->maxLen, item->mHeight * item->partLens.size(), dir, prog);
QJsonParseError jsErr;
QJsonObject prog = QJsonDocument::fromJson(value.toUtf8(), &jsErr).object();
if(jsErr.error) return;
if(item->mSplitWidths.isEmpty()) PlayWin::self = PlayWin::newIns(item->mWidth, item->mHeight, dir, prog);
else PlayWin::self = PlayWin::newIns(item->mMaxWidth, item->mHeight * item->mSplitWidths.size(), dir, prog);
break;
}
}
@ -243,29 +242,28 @@ ProgPanel::ProgPanel(QWidget *parent) : QWidget(parent) {
});
vBox->addWidget(mProgTree = table);
auto dataDir = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
if(! dataDir.isEmpty()) {
mProgsDir = dataDir + "/programs";
if(! QFileInfo::exists(mProgsDir)) {
qDebug()<<"mkdir programs"<<QDir(dataDir).mkdir("programs");
auto oldProgsDir = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation)+"/"+QApplication::applicationName()+"/NPrograms";
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();
oldProgsQDir.removeRecursively();
}
}
QString doc_path = QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
if(!doc_path.isEmpty()) {
QString app_path = doc_path + "/" + QApplication::applicationName();
mProgsDir = app_path + "/NPrograms";
if(!QFileInfo::exists(mProgsDir)) QDir(app_path).mkdir("NPrograms");
}
//connect(search, SIGNAL(triggered(bool)), this, SLOT(FilterProgram()));
//查找根路径下的项目文件夹查找文件夹下的节目pro.json信息包括节目名称大小像素备注等信息
if(! mProgsDir.isEmpty()) {
if(!mProgsDir.isEmpty()) {
QDir root_dir(mProgsDir);
auto pro_list = root_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
for(auto &pro_name : pro_list) addProFile(mProgsDir + "/" + pro_name + "/pro.json");
QStringList pro_list = root_dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::NoSymLinks);
foreach(QString pro_name, pro_list) {
QDir pro_dir(mProgsDir + "/" + pro_name);
if(pro_dir.exists("pro.json")) {
QFile fPro(pro_dir.path() + "/pro.json");
fPro.open(QIODevice::ReadOnly);
QJsonDocument pro = QJsonDocument::fromJson(fPro.readAll());
fPro.close();
m_pwPorgramItemList.append(new ProgItem(mProgsDir, pro.object(), mProgTree));
}
}
}
QSettings settings;
if(settings.value("ProgramListSortOrder").toInt()==0) mProgTree->sortByColumn(settings.value("ProgramListSortColumn").toInt(),Qt::SortOrder::AscendingOrder);
@ -294,35 +292,6 @@ void ProgPanel::transUi() {
btnPlay->setText(tr("Play")+"/"+tr("Stop"));
}
void ProgPanel::addProFile(const QString &file) {
QFile qFile(file);
if(! qFile.exists()) return;
if(! qFile.open(QIODevice::ReadOnly)) return;
auto data = qFile.readAll();
qFile.close();
QString error;
auto json = JFrom(data, &error);
if(! error.isEmpty()) return;
auto item = new ProgItem(mProgTree);
item->mProgsDir = mProgsDir;
item->mName = json["name"].toString();
item->mWidth = json["resolution"]["w"].toInt();
item->mHeight = json["resolution"]["h"].toInt();
item->mRemark = json["remarks"].toString();
item->isVer = json["isVer"].toBool();
auto partLengths = json["splitWidths"].toArray();
for(auto &partLength : partLengths) {
auto len = partLength.toInt();
if(item->maxLen < len) item->maxLen = len;
item->partLens.emplace_back(len);
}
item->m_fsize = json["file_size"].toDouble();
item->mProgDir = item->mProgsDir + "/" + item->mName;
item->m_orgName = item->mName;
item->setText("lasttime", QFileInfo(file).lastModified().toString("yyyy-MM-dd hh:mm:ss"));
item->init();
}
void ProgPanel::onEditClicked(bool){
int cnt = mProgTree->topLevelItemCount();
for(int i=0; i<cnt; i++) {
@ -347,10 +316,20 @@ bool ProgPanel::checkIfNameRepeated(const QString &name, QTreeWidgetItem *skip){
}
return false;
}
void ProgPanel::onCreateNewProgramOnOpenEditProgramWidget(QString name, QSize res, QString remarks, QList<int> &splitWidths, int max)
{
if(checkIfNameRepeated(name)) return;
auto item = new ProgItem(mProgsDir, name, res.width(), res.height(), remarks, splitWidths, max, mProgTree);
item->save();//保存pro.json
if(mProgTree->fdCheckAll->checkState()==Qt::Checked) mProgTree->fdCheckAll->setCheckState(Qt::PartiallyChecked);
auto editor = new ProgEditorWin(item, this);
editor->show();
}
void ProgPanel::onDeleteClicked(bool){
auto res = QMessageBox::information(this, tr("Tip Info"), tr("You will delete the selected solution(s),are you sure?"), QMessageBox::Ok, QMessageBox::Cancel);
if(res == QMessageBox::Ok) {
for(int i=0; i<mProgTree->topLevelItemCount(); i++) if(mProgTree->item(i)->checkState("check") == Qt::Checked) {
int cnt = mProgTree->topLevelItemCount();
for(int i=0; i<cnt; i++) if(mProgTree->item(i)->checkState("check") == Qt::Checked) {
auto item = (ProgItem*) mProgTree->topLevelItem(i--);
item->del();
delete item;

View File

@ -2,6 +2,7 @@
#define PROGPANEL_H
#include "base/loqtreewidget.h"
#include "program/progitem.h"
#include <QPushButton>
#include <QSettings>
#include <QTableWidget>
@ -17,14 +18,15 @@ protected:
void changeEvent(QEvent *) override;
void transUi();
bool checkIfNameRepeated(const QString &name, QTreeWidgetItem *skip = nullptr);
void addProFile(const QString &);
public slots:
void onEditClicked(bool f);
void onDeleteClicked(bool f);
void onCreateNewProgramOnOpenEditProgramWidget(QString name, QSize res, QString remarks, QList<int> &, int);
private:
QString mProgsDir;
QList<ProgItem *> m_pwPorgramItemList;
QPushButton *bnNew;
QPushButton *bnEdit;
QPushButton *bnDelete;

View File

@ -16,7 +16,7 @@ bool CopyDirThread::copyDir(const QString &fromDir, const QString &toDir, bool c
QDir targetDir(toDir);
if(! targetDir.exists() && ! targetDir.mkdir(toDir)) return false;
QFileInfoList fileInfos = QDir(fromDir).entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);
for(auto &fileInfo : fileInfos) {
foreach(QFileInfo fileInfo, fileInfos) {
if(fileInfo.isDir()) { //< 当为目录时递归的进行copy
if(! copyDir(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName()), coverIfExist)) return false;
} else { //当允许覆盖操作时,将旧文件进行删除操作
@ -30,29 +30,3 @@ bool CopyDirThread::copyDir(const QString &fromDir, const QString &toDir, bool c
}
return true;
}
void CopyDirThread::move() {
for(; i<dirSrcs.size(); i++) {
copiedSize = 0;
moveDir(dirSrcs[i], dirDst+"/"+QFileInfo(dirSrcs[i]).fileName());
}
}
bool CopyDirThread::moveDir(const QString &fromDir, const QString &toDir) {
QDir targetDir(toDir);
if(! targetDir.exists() && ! targetDir.mkdir(toDir)) return false;
QFileInfoList fileInfos = QDir(fromDir).entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot);
foreach(QFileInfo fileInfo, fileInfos) {
if(fileInfo.isDir()) { //< 当为目录时递归的进行copy
if(! moveDir(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName()))) return false;
} else { //当允许覆盖操作时,将旧文件进行删除操作
if(! QFile::rename(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName()))) return false;
else {
copiedSize += fileInfo.size();
emit sigProgress(i, copiedSize);
}
}
}
return true;
}

View File

@ -9,11 +9,9 @@ public:
CopyDirThread();
QStringList dirSrcs;
QString dirDst;
void run();
void move();
protected:
void run();
bool copyDir(const QString &fromDir, const QString &toDir, bool coverFileIfExist);
bool moveDir(const QString &fromDir, const QString &toDir);
int i{0};
int copiedSize = 0;

View File

@ -23,28 +23,27 @@ EAClock::EAClock(EBase *multiWin) : EBase(multiWin) {
m_attr.textColor = Qt::red;
}
EAClock::EAClock(const JObj &json, EBase *multiWin) : EBase(multiWin) {
EAClock::EAClock(const QJsonObject &json, EBase *multiWin) : EBase(multiWin) {
mType = EBase::AClock;
setBaseAttr(json);
auto widget = json["widget"];
if(widget.isNull()) widget = json;
m_attr.timeZone = QTimeZone(widget["timeZone"].toString().toUtf8());
m_attr.hourMark = widget["hourMark"].toInt();
m_attr.hourMarkSize = widget["hourMarkSize"].toInt();
auto color = widget["hourMarkColor"];
m_attr.hourMarkColor = color.isStr() ? QColor(color.toString()) : Tools::int2Color(color.toInt());
m_attr.hourMarkColor = color.isString() ? QColor(color.toString()) : Tools::int2Color(color.toInt());
m_attr.minMark = widget["minMark"].toInt();
m_attr.minMarkSize = widget["minMarkSize"].toInt();
color = widget["minMarkColor"];
m_attr.minMarkColor = color.isStr() ? QColor(color.toString()) : Tools::int2Color(color.toInt());
m_attr.minMarkColor = color.isString() ? QColor(color.toString()) : Tools::int2Color(color.toInt());
color = widget["hourHandColor"];
m_attr.hourHandColor = color.isStr() ? QColor(color.toString()) : Tools::int2Color(color.toInt());
m_attr.hourHandColor = color.isString() ? QColor(color.toString()) : Tools::int2Color(color.toInt());
color = widget["minHandColor"];
m_attr.minHandColor = color.isStr() ? QColor(color.toString()) : Tools::int2Color(color.toInt());
m_attr.minHandColor = color.isString() ? QColor(color.toString()) : Tools::int2Color(color.toInt());
color = widget["secHandColor"];
m_attr.secHandColor = color.isStr() ? QColor(color.toString()) : Tools::int2Color(color.toInt());
m_attr.secHandColor = color.isString() ? QColor(color.toString()) : Tools::int2Color(color.toInt());
color = widget["textColor"];
m_attr.textColor = color.isStr() ? QColor(color.toString()) : Tools::int2Color(color.toInt());
m_attr.textColor = color.isString() ? QColor(color.toString()) : Tools::int2Color(color.toInt());
m_attr.text = widget["text"].toString();
m_attr.textFont = QFont(widget["textFontFamily"].toString());
m_attr.textFont.setPixelSize(widget["textFontSize"].toInt());
@ -58,10 +57,14 @@ EAClock::EAClock(const JObj &json, EBase *multiWin) : EBase(multiWin) {
m_attr.mhWidth = widget["mhWidth"].toInt(m_attr.mhWidth);
m_attr.shWidth = widget["shWidth"].toInt(m_attr.shWidth);
m_attr.showSecHand = widget["showSecHand"].toBool(true);
m_attr.playDuration = json["play"]["duration"].toInt();
m_attr.path = widget["path"].toString();
m_attr.name = widget["name"].toString();
m_attr.selfCreateDialName= widget["selfCreateDialName"].toString();
m_attr.hasDialImg = widget["bCustomDial"].toBool();
if(m_attr.hasDialImg) dial_img.load(m_attr.path+"/"+m_attr.name);
if(! m_attr.hasDialImg) m_attr.selfCreateDialName = QString("%1%2%3%4%5.png").arg((int)zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight);
else dial_img.load(m_attr.path+"/"+m_attr.name);
}
void EAClock::timerEvent(QTimerEvent *) {
@ -82,24 +85,62 @@ void EAClock::cal() {
void EAClock::paintDial(QPainter *painter) {
if(! m_attr.hasDialImg || dial_img.isNull()) {
auto inner = innerRect();
auto r = (qMin(inner.width(), inner.height()) - qMax(m_attr.minMarkSize, m_attr.hourMarkSize)) / 2;
auto cx = inner.width() / 2;
auto cy = inner.height() / 2;
painter->translate(cx, cy);
qreal r = radius();
qreal cx = inner.width() / 2;
qreal cy = inner.height() / 2;
QVector<QPointF> plist;
qreal x, y, ox, oy;
qreal k;
qreal a = 0;
const qreal s = 6;
for(int i=0; i<60; i++) {
auto k = i * M_PI / 30;
auto x = sin(k) * r;
auto y = -cos(k) * r;
if(i % 5) {
if(m_attr.minMark==0) drawMarkCircular(painter, {x, y}, m_attr.minMarkColor, m_attr.minMarkSize);
else if(m_attr.minMark==1) drawMarkRectangle(painter, {x, y}, m_attr.minMarkColor, m_attr.minMarkSize, i*6);
if (a < 90) {
k = a * M_PI / 180;
ox = sin(k) * r;
oy = cos(k) * r;
x = cx + ox;
y = cy - oy;
} else if (a < 180) {
k = (a - 90) * M_PI / 180;
ox = cos(k) * r;
oy = sin(k) * r;
x = cx + ox;
y = cy + oy;
} else if (a < 270) {
k = (a - 180) * M_PI / 180;
ox = sin(k) * r;
oy = cos(k) * r;
x = cx - ox;
y = cy + oy;
} else {
if(m_attr.hourMark==0) drawMarkCircular(painter, {x, y}, m_attr.hourMarkColor, m_attr.hourMarkSize);
else if(m_attr.hourMark==1) drawMarkRectangle(painter, {x, y}, m_attr.hourMarkColor, m_attr.hourMarkSize, i*6);
else if(m_attr.hourMark==2) drawMarkNumber(painter, {x, y}, m_attr.hourMarkColor, m_attr.hourMarkSize, i/5);
k = (a - 270) * M_PI / 180;
ox = cos(k) * r;
oy = sin(k) * r;
x = cx - ox;
y = cy - oy;
}
a += s;
plist.push_back(QPointF(x, y));
}
a = 0;
for(int i=0; i<60; i++) {
if(i % 5) {
switch (m_attr.minMark) {
case 0: drawMarkCircular (painter, plist.at(i), m_attr.minMarkColor, m_attr.minMarkSize); break;
case 1: drawMarkRectangle(painter, plist.at(i), m_attr.minMarkColor, m_attr.minMarkSize, a); break;
default: break;
}
} else {
switch (m_attr.hourMark) {
case 0: drawMarkCircular (painter, plist.at(i), m_attr.hourMarkColor, m_attr.hourMarkSize); break;
case 1: drawMarkRectangle(painter, plist.at(i), m_attr.hourMarkColor, m_attr.hourMarkSize, a); break;
case 2: drawMarkNumber (painter, plist.at(i), m_attr.hourMarkColor, m_attr.hourMarkSize, i/5); break;
default: break;
}
}
a += s;
}
painter->translate(-cx, -cy);
} else {
auto inner = innerRect();
int wid, hei;
@ -111,30 +152,45 @@ void EAClock::paintDial(QPainter *painter) {
}
void EAClock::drawMarkCircular(QPainter *painter, const QPointF &pos, const QColor &color, qreal diameter) {
auto r = diameter / 2;
QPointF cp(pos.x(), pos.y());
qreal r = diameter / 2;
painter->save();
painter->setBrush(color);
painter->setPen(color);
painter->drawEllipse(pos, r, r);
painter->setRenderHint(QPainter::Antialiasing);
painter->drawEllipse(cp, r, r);
painter->restore();
}
void EAClock::drawMarkRectangle(QPainter *painter, const QPointF &pos, const QColor &color, qreal len, qreal angle) {
void EAClock::drawMarkRectangle(QPainter *painter, const QPointF &pos, const QColor &color, qreal len, qreal angle)
{
QPointF cp(pos.x(), pos.y());
QRectF rect(-len/2, -len/2, len, len);
painter->save();
painter->setBrush(color);
painter->setPen(color);
painter->translate(pos);
painter->translate(cp);
painter->rotate(angle);
painter->setRenderHint(QPainter::Antialiasing);
painter->drawRect(rect);
painter->restore();
}
void EAClock::drawMarkNumber(QPainter *painter, const QPointF &pos, const QColor &color, qreal len, int num) {
void EAClock::drawMarkNumber(QPainter *painter, const QPointF &pos, const QColor &color, qreal len, int num)
{
QRectF rect(pos.x()-len/2, pos.y()-len/2, len, len);
QFont font("Arial");
font.setPixelSize(round(len));
painter->setFont(font);
QTextOption opt;
opt.setAlignment(Qt::AlignCenter);
painter->save();
painter->setPen(color);
painter->drawText(rect, QString::number(num==0 ? 12 : num), QTextOption(Qt::AlignCenter));
painter->setFont(font);
painter->setRenderHint(QPainter::Antialiasing);
if(num==0)
num=12;
painter->drawText(rect, QString("%1").arg(num), opt);
painter->restore();
}
void EAClock::paintText(QPainter *painter){
@ -543,6 +599,32 @@ QWidget* EAClock::attrWgt() {
update();
});
hBox->addWidget(fdTextColor);
hBox->addStretch();
hBox = new HBox(vBox);
hBox->addWidget(new QLabel(tr("Play Properties")));
line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
hBox = new HBox(vBox);
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Play Duration")));
auto fdDuration = new QSpinBox();
fdDuration->setRange(1, 99999);
fdDuration->setValue(m_attr.playDuration);
connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
m_attr.playDuration = value;
});
hBox->addWidget(fdDuration);
hBox->addWidget(new QLabel(tr("s")));
hBox->addStretch();
vBox->addStretch();
@ -551,59 +633,70 @@ QWidget* EAClock::attrWgt() {
bool EAClock::save(const QString &pRoot){
if(m_attr.hasDialImg) {
auto old_file = m_attr.path + PAGEDEL_SUFFIX + "/" + m_attr.name;
if(! QFileInfo::exists(old_file)) {
old_file = m_attr.path + "/" + m_attr.name;
if(! QFileInfo::exists(old_file)) return false; //自己画点,不用背景表盘
QString file0 = m_attr.path + PAGEDEL_SUFFIX + "/" + m_attr.name;
QString file1 = m_attr.path + "/" + m_attr.name;
QFile f0(file0);
QFile f1(file1);
QString old_file;
QString new_file = pRoot + "/" + m_attr.name;
if(f0.exists()) {
old_file = file0;
} else if(f1.exists()) {
old_file = file1;
} else {//自己画点,不用背景表盘
return false;
}
auto new_file = pRoot + "/" + m_attr.name;
if(! QFileInfo::exists(new_file)) QFile(old_file).copy(new_file);
} else {
auto filename = QString("%1-%2-%3-%4-%5.png").arg((int)zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight);
m_attr.path = pRoot;
QRectF inner = innerRect();
QImage img(inner.width(), inner.height(), QImage::Format_ARGB32);
img.fill(Qt::transparent);
{
QPainter painter(&img);
paintDial(&painter);
paintText(&painter);
}
img.save(pRoot+"/"+filename, "PNG");
QFile old_f(old_file);
QFile new_f(new_file);
if(!new_f.exists()) old_f.copy(new_file);
}
m_attr.selfCreateDialName = QString("%1%2%3%4%5.png").arg((int)zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight);
m_attr.path = pRoot;
QRectF inner = innerRect();
QImage img(inner.width(), inner.height(), QImage::Format_ARGB32);
img.fill(Qt::transparent);
{
QPainter painter(&img);
paintDial(&painter);
paintText(&painter);
}
img.save(pRoot+"/"+m_attr.selfCreateDialName, "PNG");
return true;
}
JObj EAClock::attrJson() const {
JObj json;
json["elementType"] = "AClock";
json["timeZone"] = QString::fromUtf8(m_attr.timeZone.id());
json["hourMark"] = m_attr.hourMark;
json["hourMarkSize"] = m_attr.hourMarkSize;
json["hourMarkColor"] = m_attr.hourMarkColor.name();
json["minMark"] = m_attr.minMark;
json["minMarkSize"] = m_attr.minMarkSize;
json["minMarkColor"] = m_attr.minMarkColor.name();
json["hourHandColor"] = m_attr.hourHandColor.name();
json["minHandColor"] = m_attr.minHandColor.name();
json["secHandColor"] = m_attr.secHandColor.name();
json["text"] = m_attr.text;
json["textFontFamily"] = m_attr.textFont.family();
json["textFontSize"] = m_attr.textFont.pixelSize();
json["textFontBold"] = m_attr.textFont.bold();
json["textFontItalics"] = m_attr.textFont.italic();
json["textFontUnderline"] = m_attr.textFont.underline();
json["textColor"] = m_attr.textColor.name();
json["hhLen"] = m_attr.hhLen;
json["mhLen"] = m_attr.mhLen;
json["shLen"] = m_attr.shLen;
json["hhWidth"] = m_attr.hhWidth;
json["mhWidth"] = m_attr.mhWidth;
json["shWidth"] = m_attr.shWidth;
json["showSecHand"] = m_attr.showSecHand;
json["path"] = m_attr.path;
json["name"] = m_attr.name;
json["selfCreateDialName"] = QString("%1-%2-%3-%4-%5.png").arg((int)zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight);
json["bCustomDial"] = m_attr.hasDialImg;
QJsonObject EAClock::attrJson() const {
QJsonObject json;
addBaseAttr(json);
json["elementType"] = "AClock";
QJsonObject widget;
widget["timeZone"] = QString::fromUtf8(m_attr.timeZone.id());
widget["hourMark"] = m_attr.hourMark;
widget["hourMarkSize"] = m_attr.hourMarkSize;
widget["hourMarkColor"] = m_attr.hourMarkColor.name();
widget["minMark"] = m_attr.minMark;
widget["minMarkSize"] = m_attr.minMarkSize;
widget["minMarkColor"] = m_attr.minMarkColor.name();
widget["hourHandColor"] = m_attr.hourHandColor.name();
widget["minHandColor"] = m_attr.minHandColor.name();
widget["secHandColor"] = m_attr.secHandColor.name();
widget["text"] = m_attr.text;
widget["textFontFamily"] = m_attr.textFont.family();
widget["textFontSize"] = m_attr.textFont.pixelSize();
widget["textFontBold"] = m_attr.textFont.bold();
widget["textFontItalics"] = m_attr.textFont.italic();
widget["textFontUnderline"] = m_attr.textFont.underline();
widget["textColor"] = m_attr.textColor.name();
widget["hhLen"] = m_attr.hhLen;
widget["mhLen"] = m_attr.mhLen;
widget["shLen"] = m_attr.shLen;
widget["hhWidth"] = m_attr.hhWidth;
widget["mhWidth"] = m_attr.mhWidth;
widget["shWidth"] = m_attr.shWidth;
widget["showSecHand"] = m_attr.showSecHand;
widget["path"] = m_attr.path;
widget["name"] = m_attr.name;
widget["selfCreateDialName"] = m_attr.selfCreateDialName;
widget["bCustomDial"] = m_attr.hasDialImg;
json["widget"] = widget;
json["play"] = QJsonObject{{"duration", m_attr.playDuration}};
return json;
}

View File

@ -21,23 +21,28 @@ public:
QColor secHandColor;//秒针颜色
int hhLen{50}, mhLen{75}, shLen{100};
int hhWidth{15}, mhWidth{10}, shWidth{5};
// r/2, r / 20
// r*3/4, r / 30
// r, r / 40
QString text;//标题
QFont textFont = qfont("Arial", 12);//标题字体
QColor textColor;//标题字体颜色
int playDuration{10};//
QString path;
QString name;
QString selfCreateDialName;
bool hasDialImg{false};
bool showSecHand{true};
};
explicit EAClock(EBase *multiWin = nullptr);
explicit EAClock(const JObj &json, EBase *multiWin = nullptr);
explicit EAClock(const QJsonObject &json, EBase *multiWin = nullptr);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
int type() const override { return EBase::AClock; }
QWidget* attrWgt() override;
bool save(const QString &pRoot) override;
JObj attrJson() const override;
QJsonObject attrJson() const override;
protected:
void timerEvent(QTimerEvent *) override;
@ -47,6 +52,10 @@ protected:
void paintDial(QPainter *painter);
void paintText(QPainter *painter);
qreal radius() const {
return (qMin(rect().width(), rect().height()) - qMax(m_attr.minMarkSize, m_attr.hourMarkSize)) / 2;
}
void cal();
Data m_attr;

View File

@ -33,7 +33,7 @@ struct Initer {
};
EBase::EBase(EBase *multiWin) : mMultiWin(multiWin) {
static struct Initer aaa;
if(mMultiWin == 0) {
if(mMultiWin == nullptr) {
setFlag(ItemIsMovable);
setFlag(ItemIsSelectable);
}
@ -41,54 +41,50 @@ EBase::EBase(EBase *multiWin) : mMultiWin(multiWin) {
mSidePen.setDashPattern(QVector<qreal>{1,3});
}
void EBase::setBaseAttr(const JObj &json) {
void EBase::setBaseAttr(const QJsonObject &json) {
mStartTime = json["startTime"].toInt();
mDuration = json["duration"].toInt();
if(mDuration==0) {
mDuration = json["play"]["playDuration"].toInt();
if(mDuration==0) mDuration = json["play"]["duration"].toInt(10);
}
mEntryEffect = json["entryEffect"].toStr();
mExitEffect = json["exitEffect"].toStr();
mEntryDur = json["entryDur"].toInt();
mExitDur = json["exitDur"].toInt();
auto geometry = json["geometry"];
auto geometry = json["geometry"].toObject();
setPos(geometry["x"].toInt(), geometry["y"].toInt());
setSize(geometry["w"].toInt(), geometry["h"].toInt());
setZValue(geometry["order"].toInt());
auto bdName = json["border"].toString();
QString bdName = json["border"].toString();
if(! bdName.isEmpty()) {
for(int i=0; i<borderImgs.size(); i++) if(borderImgs[i].name==bdName) {bdImgIdx = i; break;}
bdEff = json["borderEff"].toString();
bdSpeed = json["borderSpeed"].toInt(2);
} else {
bdName = geometry["border"].toString();
if(! bdName.isEmpty()) {
for(int i=0; i<borderImgs.size(); i++) if(borderImgs[i].name==bdName) {bdImgIdx = i; break;}
bdEff = geometry["border_eff"].toString();
bdSpeed = geometry["border_speed"].toInt(2);
}
}
}
void EBase::addBaseAttr(JObj &obj) const {
auto ele = mMultiWin ? mMultiWin : this;
void EBase::addBaseAttr(QJsonObject &obj) const {
auto ele = mMultiWin!=nullptr ? mMultiWin : this;
int bdWidth = ele->bdImgIdx > -1 ? borderImgs[ele->bdImgIdx].img.height() : 0;
JObj geometry;
obj.insert("startTime", mStartTime);
obj.insert("innerX", ((int)ele->x())+bdWidth);
obj.insert("innerY", ((int)ele->y())+bdWidth);
obj.insert("innerW", ((int)ele->mWidth)-bdWidth-bdWidth);
obj.insert("innerH", ((int)ele->mHeight)-bdWidth-bdWidth);
QJsonObject geometry;
geometry["order"] = zValue();
geometry["x"] = (int)ele->x();
geometry["y"] = (int)ele->y();
geometry["w"] = (int)ele->mWidth;
geometry["h"] = (int)ele->mHeight;
obj.insert("geometry", geometry);
obj.insert("innerX", ((int)ele->x())+bdWidth);
obj.insert("innerY", ((int)ele->y())+bdWidth);
obj.insert("innerW", ((int)ele->mWidth)-bdWidth-bdWidth);
obj.insert("innerH", ((int)ele->mHeight)-bdWidth-bdWidth);
obj.insert("startTime", mStartTime);
obj.insert("duration", mDuration);
obj.insert("entryEffect", mEntryEffect);
obj.insert("exitEffect", mExitEffect);
obj.insert("entryDur", mEntryDur);
obj.insert("exitDur", mExitDur);
if(bdImgIdx>-1) {
obj["border"] = borderImgs[bdImgIdx].name;
obj["borderSize"] = JArray{borderImgs[bdImgIdx].img.width(), borderImgs[bdImgIdx].img.height()};
obj["borderEff"] = bdEff.isEmpty() ? JValue() : bdEff;
obj["borderSize"] = QJsonArray{borderImgs[bdImgIdx].img.width(), borderImgs[bdImgIdx].img.height()};
obj["borderEff"] = bdEff.isEmpty() ? QJsonValue() : bdEff;
obj["borderSpeed"] = bdSpeed;
// geometry["border"] = borderImgs[bdImgIdx].name;
// geometry["border_eff"] = bdEff.isEmpty() ? QJsonValue() : bdEff;
// geometry["border_speed"] = bdSpeed;
}
obj.insert("geometry", geometry);
}
QRectF EBase::innerRect() const {
@ -523,338 +519,185 @@ void EBase::clearSnap() {
}
void EBase::addBaseAttrWgt(QBoxLayout *vBox) {
if(mMultiWin!=nullptr) return;
auto hBox = new QHBoxLayout();
hBox->addWidget(new QLabel(tr("Area")));
auto line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line,1);
vBox->addLayout(hBox);
auto spacing = vBox->spacing();
if(spacing < 0) spacing = 0;
if(mMultiWin==0) {
auto hBox = new HBox(vBox);
hBox->addLabel(tr("Area"));
vBox->addSpacing(-spacing-2);
auto line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
hBox = new QHBoxLayout();
hBox->addStretch();
hBox->addWidget(new QLabel(tr("X")+": "));
vBox->addSpacing(-spacing-2);
hBox = new HBox(vBox);
hBox->addStretch();
hBox->addLabel(tr("X")+": ");
auto fdX = new QSpinBox;
fdX->setRange(0, 999999);
fdX->setValue(x());
connect(fdX, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdX](int value) {
int max = gProgItem->mWidth - mWidth;
if(value > max) {
value = max;
fdX->blockSignals(true);
fdX->setValue(value);
fdX->blockSignals(false);
}
setX(value);
});
hBox->addWidget(fdX);
hBox->addSpacing(10);
hBox->addLabel(tr("Y")+": ");
auto fdY = new QSpinBox;
fdY->setRange(0, 999999);
fdY->setValue(y());
connect(fdY, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdY](int value) {
int max = gProgItem->mHeight - mHeight;
if(value > max) {
value = max;
fdY->blockSignals(true);
fdY->setValue(value);
fdY->blockSignals(false);
}
setY(value);
});
hBox->addWidget(fdY);
hBox->addStretch();
hBox = new HBox(vBox);
hBox->addStretch();
hBox->addLabel(tr("W")+": ");
auto fdW = new QSpinBox;
fdW->setRange(6, 999999);
fdW->setValue(mWidth);
connect(fdW, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdW](int value) {
int max = gProgItem->mWidth - x();
if(value > max) {
value = max;
fdW->blockSignals(true);
fdW->setValue(value);
fdW->blockSignals(false);
}
setSize(value, mHeight);
});
hBox->addWidget(fdW);
hBox->addSpacing(10);
hBox->addLabel(tr("H")+": ");
auto fdH = new QSpinBox;
fdH->setRange(6, 999999);
fdH->setValue(mHeight);
connect(fdH, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdH](int value) {
int max = gProgItem->mHeight - y();
if(value > max) {
value = max;
fdH->blockSignals(true);
fdH->setValue(value);
fdH->blockSignals(false);
}
setSize(mWidth, value);
});
hBox->addWidget(fdH);
hBox->addStretch();
vBox->addSpacing(-spacing);
connect(this, &EBase::xChanged, fdX, [this, fdX] {
auto fdX = new QSpinBox();
fdX->setRange(0, 9999);
fdX->setValue(x());
connect(fdX, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdX](int value) {
int max = gProgItem->mWidth - mWidth;
if(value > max) {
value = max;
fdX->blockSignals(true);
fdX->setValue(x());
fdX->setValue(value);
fdX->blockSignals(false);
});
connect(this, &EBase::yChanged, fdY, [this, fdY] {
fdY->blockSignals(true);
fdY->setValue(y());
fdY->blockSignals(false);
});
connect(this, &EBase::sizeChanged, fdW, [this, fdW, fdH] {
fdW->blockSignals(true);
fdW->setValue(mWidth);
fdW->blockSignals(false);
fdH->blockSignals(true);
fdH->setValue(mHeight);
fdH->blockSignals(false);
});
hBox = new HBox(vBox);
hBox->addLabel(tr("Border"));
line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
vBox->addSpacing(-spacing-2);
hBox = new HBox(vBox);
hBox->setSpacing(2);
hBox->addStretch();
auto borderFd = new QComboBox;
borderFd->addItem(tr("None"));
for(int i=0; i<borderImgs.size(); i++) borderFd->addItem(QIcon(borderImgs[i].img), QString::number(borderImgs[i].img.height()), borderImgs[i].name);
borderFd->setIconSize(QSize(borderImgMaxWidth, borderImgMaxHeight));
if(bdImgIdx>-1) borderFd->setCurrentIndex(bdImgIdx+1);
connect(borderFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int idx){
bdImgIdx = idx-1;
if(bdImgIdx==-1 && bdTimerId>0) {
killTimer(bdTimerId);
bdTimerId = 0;
}
bdOff = 0;
update();
emit sizeChanged();
});
hBox->addWidget(borderFd);
hBox->addStretch();
hBox->addLabel(tr("Effect"));
auto borderEffFd = new QComboBox;
borderEffFd->addItem(tr("Rotate"), "rotate");
borderEffFd->addItem(tr("Blink"), "blink");
borderEffFd->addItem(tr("None"), "");
if(bdImgIdx>-1) SetCurData(borderEffFd, bdEff);
connect(borderEffFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, borderEffFd] {
bdEff = borderEffFd->currentData().toString();
if(bdTimerId>0) {
killTimer(bdTimerId);
bdTimerId = 0;
}
bdOff = 0;
update();
});
hBox->addWidget(borderEffFd);
hBox->addStretch();
hBox->addLabel(tr("Speed"));
auto borderSpeedFd = new QComboBox;
borderSpeedFd->addItem(tr("Slow"), 1);
borderSpeedFd->addItem(tr("Moderate"), 2);
borderSpeedFd->addItem(tr("Fast"), 3);
if(bdImgIdx>-1) SetCurData(borderSpeedFd, bdSpeed);
connect(borderSpeedFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, borderSpeedFd] {
bdSpeed = borderSpeedFd->currentData().toInt();
if(bdTimerId>0) {
killTimer(bdTimerId);
bdTimerId = 0;
}
update();
});
hBox->addWidget(borderSpeedFd);
hBox->addStretch();
}
if(mType!=Window) {
auto hBox = new HBox(vBox);
hBox->addLabel(tr("Play Time"));
auto line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
vBox->addSpacing(-spacing-2);
hBox = new HBox(vBox);
hBox->setSpacing(4);
hBox->addStretch();
if(mMultiWin==0) {
hBox->addLabel(tr("Start"));
auto fdStart = new QSpinBox;
fdStart->setRange(0, 9999);
fdStart->setValue(mStartTime);
hBox->addWidget(fdStart);
hBox->addLabel(tr("s"));
hBox->addStretch();
}
setX(value);
});
hBox->addWidget(fdX);
hBox->addLabel(tr("Duration"));
hBox->addSpacing(10);
fdDuration = new QSpinBox;
fdDuration->setRange(1, 9999);
fdDuration->setValue(mDuration);
hBox->addWidget(fdDuration);
hBox->addLabel(tr("s"));
hBox->addStretch();
hBox->addWidget(new QLabel(tr("Y")+": "));
auto fdY = new QSpinBox();
fdY->setRange(0, 9999);
fdY->setValue(y());
connect(fdY, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdY](int value) {
int max = gProgItem->mHeight - mHeight;
if(value > max) {
value = max;
fdY->blockSignals(true);
fdY->setValue(value);
fdY->blockSignals(false);
}
setY(value);
});
hBox->addWidget(fdY);
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new HBox(vBox);
hBox->addLabel(tr("Effect"));
hBox = new QHBoxLayout();
hBox->addStretch();
hBox->addWidget(new QLabel(tr("W")+": "));
auto fdW = new QSpinBox();
fdW->setRange(6, 9999);
fdW->setValue(mWidth);
connect(fdW, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdW](int value) {
int max = gProgItem->mWidth - x();
if(value > max) {
value = max;
fdW->blockSignals(true);
fdW->setValue(value);
fdW->blockSignals(false);
}
setSize(value, mHeight);
});
hBox->addWidget(fdW);
line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
hBox->addSpacing(10);
hBox->addWidget(new QLabel(tr("H")+": "));
auto fdH = new QSpinBox();
fdH->setRange(6, 9999);
fdH->setValue(mHeight);
connect(fdH, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdH](int value) {
int max = gProgItem->mHeight - y();
if(value > max) {
value = max;
fdH->blockSignals(true);
fdH->setValue(value);
fdH->blockSignals(false);
}
setSize(mWidth, value);
});
hBox->addWidget(fdH);
hBox->addStretch();
vBox->addSpacing(-spacing-2);
vBox->addLayout(hBox);
vBox->addSpacing(-spacing);
auto grid = new Grid(vBox);
grid->setSpacing(4);
int ccc = 0;
grid->setColumnStretch(ccc++, 1);
grid->addLabel(tr("Entry"), 0, ccc++, Qt::AlignRight|Qt::AlignVCenter);
connect(this, &EBase::xChanged, fdX, [this, fdX] {
fdX->blockSignals(true);
fdX->setValue(x());
fdX->blockSignals(false);
});
connect(this, &EBase::yChanged, fdY, [this, fdY] {
fdY->blockSignals(true);
fdY->setValue(y());
fdY->blockSignals(false);
});
connect(this, &EBase::sizeChanged, fdW, [this, fdW, fdH] {
fdW->blockSignals(true);
fdW->setValue(mWidth);
fdW->blockSignals(false);
fdH->blockSignals(true);
fdH->setValue(mHeight);
fdH->blockSignals(false);
});
auto fdEntryEff = new QComboBox;
fdEntryEff->addItem(tr("None"), "");
fdEntryEff->addItem(tr("Random"), "Random");
fdEntryEff->addItem(tr("Expand horizontal"), "EXPAND_HOR");
fdEntryEff->addItem(tr("Expand vertical"), "EXPAND_VER");
fdEntryEff->addItem(tr("Expand to left"), "EXPAND_LEFT");
fdEntryEff->addItem(tr("Expand to top"), "EXPAND_TOP");
fdEntryEff->addItem(tr("Expand to right"), "EXPAND_RIGHT");
fdEntryEff->addItem(tr("Expand to bottom"), "EXPAND_BOTTOM");
fdEntryEff->addItem(tr("Zoom in"), "ZOOM");
fdEntryEff->addItem(tr("Zoom in from left-top"), "ZOOM_TL");
fdEntryEff->addItem(tr("Zoom in from right-top"), "ZOOM_TR");
fdEntryEff->addItem(tr("Zoom in from right-bottom"), "ZOOM_BR");
fdEntryEff->addItem(tr("Zoom in from left-bottom"), "ZOOM_BL");
fdEntryEff->addItem(tr("Rotate zoom"), "ROTATE");
fdEntryEff->addItem(tr("Rotate zoom reverse"), "ROTATE_R");
fdEntryEff->addItem(tr("Fade in"), "FADE");
fdEntryEff->addItem(tr("Move to left"), "MOVE_LEFT");
fdEntryEff->addItem(tr("Move to top"), "MOVE_TOP");
fdEntryEff->addItem(tr("Move to right"), "MOVE_RIGHT");
fdEntryEff->addItem(tr("Move to bottom"), "MOVE_BOTTOM");
SetCurData(fdEntryEff, mEntryEffect);
connect(fdEntryEff, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] {
mEntryEffect = fdEntryEff->currentData().toString();
});
grid->addWidget(fdEntryEff, 0, ccc++);
grid->setColumnStretch(ccc++, 1);
hBox = new QHBoxLayout();
hBox->addWidget(new QLabel(tr("Border")));
grid->addLabel(tr("Dur"), 0, ccc++, Qt::AlignRight|Qt::AlignVCenter);
line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
auto fdEntryDur = new QSpinBox;
fdEntryDur->setRange(1, 99);
fdEntryDur->setValue(mEntryDur);
connect(fdEntryDur, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) {
mEntryDur = value;
if(mDuration < value) {
mDuration = value;
fdDuration->setValue(value);
}
});
grid->addWidget(fdEntryDur, 0, ccc++);
grid->addLabel(tr("s"), 0, ccc++);
grid->setColumnStretch(ccc, 1);
vBox->addLayout(hBox);
vBox->addSpacing(-spacing-2);
ccc = 1;
grid->addLabel(tr("Exit"), 1, ccc++, Qt::AlignRight|Qt::AlignVCenter);
hBox = new QHBoxLayout();
hBox->setSpacing(0);
auto fdExitEff = new QComboBox;
fdExitEff->addItem(tr("None"), "");
fdExitEff->addItem(tr("Random"), "Random");
fdExitEff->addItem(tr("Expand horizontal"), "EXPAND_HOR");
fdExitEff->addItem(tr("Expand vertical"), "EXPAND_VER");
fdExitEff->addItem(tr("Expand to left"), "EXPAND_LEFT");
fdExitEff->addItem(tr("Expand to top"), "EXPAND_TOP");
fdExitEff->addItem(tr("Expand to right"), "EXPAND_RIGHT");
fdExitEff->addItem(tr("Expand to bottom"), "EXPAND_BOTTOM");
fdExitEff->addItem(tr("Zoom out"), "ZOOM");
fdExitEff->addItem(tr("Zoom out to left-top"), "ZOOM_TL");
fdExitEff->addItem(tr("Zoom out to right-top"), "ZOOM_TR");
fdExitEff->addItem(tr("Zoom out to right-bottom"), "ZOOM_BR");
fdExitEff->addItem(tr("Zoom out to left-bottom"), "ZOOM_BL");
fdExitEff->addItem(tr("Rotate zoom"), "ROTATE");
fdExitEff->addItem(tr("Rotate zoom reverse"), "ROTATE_R");
fdExitEff->addItem(tr("Fade out"), "FADE");
fdExitEff->addItem(tr("Move to left"), "MOVE_LEFT");
fdExitEff->addItem(tr("Move to top"), "MOVE_TOP");
fdExitEff->addItem(tr("Move to right"), "MOVE_RIGHT");
fdExitEff->addItem(tr("Move to bottom"), "MOVE_BOTTOM");
SetCurData(fdExitEff, mExitEffect);
connect(fdExitEff, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] {
mExitEffect = fdExitEff->currentData().toString();
});
grid->addWidget(fdExitEff, 1, ccc++);
ccc++;
hBox->addStretch();
auto borderFd = new QComboBox;
borderFd->addItem(tr("None"));
for(int i=0; i<borderImgs.size(); i++) borderFd->addItem(QIcon(borderImgs[i].img), QString::number(borderImgs[i].img.height()), borderImgs[i].name);
borderFd->setIconSize(QSize(borderImgMaxWidth, borderImgMaxHeight));
if(bdImgIdx>-1) borderFd->setCurrentIndex(bdImgIdx+1);
connect(borderFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int idx){
bdImgIdx = idx-1;
if(bdImgIdx==-1 && bdTimerId>0) {
killTimer(bdTimerId);
bdTimerId = 0;
}
bdOff = 0;
update();
emit sizeChanged();
});
hBox->addWidget(borderFd);
grid->addLabel(tr("Dur"), 1, ccc++, Qt::AlignRight|Qt::AlignVCenter);
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Effect")+":"));
auto borderEffFd = new QComboBox();
borderEffFd->addItem(tr("Rotate"), "rotate");
borderEffFd->addItem(tr("Blink"), "blink");
borderEffFd->addItem(tr("None"), "");
if(bdImgIdx>-1) setCurrentData(borderEffFd, bdEff);
connect(borderEffFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, borderEffFd] {
bdEff = borderEffFd->currentData().toString();
if(bdTimerId>0) {
killTimer(bdTimerId);
bdTimerId = 0;
}
bdOff = 0;
update();
});
hBox->addWidget(borderEffFd);
auto fdExitDur = new QSpinBox;
fdExitDur->setRange(1, 99);
fdExitDur->setValue(mExitDur);
connect(fdExitDur, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) {
mExitDur = value;
if(mDuration < value) {
mDuration = value;
fdDuration->setValue(value);
}
});
grid->addWidget(fdExitDur, 1, ccc++);
grid->addLabel(tr("s"), 1, ccc++);
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Speed")+":"));
auto borderSpeedFd = new QComboBox();
borderSpeedFd->addItem(tr("Slow"), 1);
borderSpeedFd->addItem(tr("Moderate"), 2);
borderSpeedFd->addItem(tr("Fast"), 3);
if(bdImgIdx>-1) setCurrentData(borderSpeedFd, bdSpeed);
connect(borderSpeedFd, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, borderSpeedFd] {
bdSpeed = borderSpeedFd->currentData().toInt();
if(bdTimerId>0) {
killTimer(bdTimerId);
bdTimerId = 0;
}
update();
});
hBox->addWidget(borderSpeedFd);
hBox->addStretch();
connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) {
mDuration = value;
if(mEntryDur > value) {
mEntryDur = value;
fdEntryDur->setValue(value);
}
if(mExitDur > value) {
mExitDur = value;
fdExitDur->setValue(value);
}
});
}
vBox->addLayout(hBox);
}

View File

@ -2,9 +2,7 @@
#define EBASE_H
#include <QGraphicsObject>
#include "gutil/qjson.h"
#include <QVBoxLayout>
#include <QSpinBox>
#include <QPen>
#include <float.h>
#define m_handleLen 10
@ -14,20 +12,20 @@ class EBase : public QGraphicsObject {
public:
enum ElementType {
Text = QGraphicsItem::UserType + 1,
Image, Video, Gif, Audio,
Photo, Video, Gif, Audio,
DClock, AClock, Timer, Environ, Window, Web
};
Q_ENUM(ElementType)
explicit EBase(EBase *multiWin = nullptr);
void setBaseAttr(const JObj &);
void addBaseAttr(JObj &) const;
void setBaseAttr(const QJsonObject &);
void addBaseAttr(QJsonObject &) const;
QRectF boundingRect() const override;
void paint(QPainter *, const QStyleOptionGraphicsItem *, QWidget *) override;
virtual JObj attrJson() const = 0;
virtual QJsonObject attrJson() const = 0;
virtual void loadFiles() {}
virtual void freeFiles() {}
virtual bool save(const QString &) {return true;}
@ -44,13 +42,10 @@ public:
QRectF innerRect() const;
QRectF rect() const { return innerRect(); }
int mType = -1;
EBase *mMultiWin = 0;
qreal mWidth = 0, mHeight = 0;
QSpinBox *fdDuration = 0;
int mStartTime = 0, mDuration = 10;
QString mEntryEffect, mExitEffect;
int mEntryDur = 1, mExitDur = 1;
int mType{-1};
EBase *mMultiWin{nullptr};
qreal mWidth{0.0}, mHeight{0.0};
int mStartTime{0};
signals:
void sizeChanged();

View File

@ -30,7 +30,7 @@ EDClock::EDClock(EBase *multiWin) : EBase(multiWin) {
init();
}
EDClock::EDClock(const JObj &json, EBase *multiWin) : EBase(multiWin) {
EDClock::EDClock(const QJsonObject &json, EBase *multiWin) : EBase(multiWin) {
mType = EBase::DClock;
setBaseAttr(json);
auto widget = json["widget"];
@ -52,6 +52,7 @@ EDClock::EDClock(const JObj &json, EBase *multiWin) : EBase(multiWin) {
m_attr.dateStyle = widget["dateStyle"].toInt();
m_attr.timeStyle = widget["timeStyle"].toInt();
m_attr.multiline = widget["multiline"].toBool();
m_attr.playDuration = json["play"]["duration"].toInt();
isSingleMD = m_attr.dateStyle==1||m_attr.dateStyle==2||m_attr.dateStyle==4||m_attr.dateStyle==6||m_attr.dateStyle==8||m_attr.dateStyle==10||m_attr.dateStyle==12;
init();
}
@ -418,14 +419,41 @@ QWidget* EDClock::attrWgt() {
});
hBox->addWidget(fdColor);
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addWidget(new QLabel(tr("Play Properties")));
line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Play Duration")));
auto fdDuration = new QSpinBox();
fdDuration->setRange(1, 99999);
fdDuration->setValue(m_attr.playDuration);
connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
m_attr.playDuration = value;
});
hBox->addWidget(fdDuration);
hBox->addWidget(new QLabel(tr("s")));
hBox->addStretch();
vBox->addLayout(hBox);
vBox->addStretch();
return wgtAttr;
}
JObj EDClock::attrJson() const{
JObj oWidget;
QJsonObject EDClock::attrJson() const{
QJsonObject oWidget;
oWidget["timeZone"] = QString::fromUtf8(m_attr.timeZoneId);
oWidget["year"] = m_attr.year;
oWidget["month"] = m_attr.month;
@ -440,7 +468,7 @@ JObj EDClock::attrJson() const{
oWidget["dateStyle"] = m_attr.dateStyle;
oWidget["timeStyle"] = m_attr.timeStyle;
oWidget["multiline"] = m_attr.multiline;
oWidget["font"] = JObj{
oWidget["font"] = QJsonObject{
{"family", m_attr.font.family()},
{"size", m_attr.font.pixelSize()},
{"bold", m_attr.font.bold()},
@ -448,9 +476,10 @@ JObj EDClock::attrJson() const{
{"underline", m_attr.font.underline()},
{"color", Tools::color2Int(m_attr.textColor)}
};
JObj oRoot;
QJsonObject oRoot;
addBaseAttr(oRoot);
oRoot["elementType"] = "DClock";
oRoot["widget"] = oWidget;
oRoot["play"] = QJsonObject{{"duration", m_attr.playDuration}};
return oRoot;
}

View File

@ -29,15 +29,16 @@ public:
bool multiline;
int dateStyle;
int timeStyle;
int playDuration = 10;
};
explicit EDClock(EBase *multiWin = nullptr);
explicit EDClock(const JObj &json, EBase *multiWin = nullptr);
explicit EDClock(const QJsonObject &json, EBase *multiWin = nullptr);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
int type() const override { return EBase::DClock; }
QWidget* attrWgt() override;
JObj attrJson() const override;
QJsonObject attrJson() const override;
private:
void init();

File diff suppressed because it is too large Load Diff

View File

@ -3,63 +3,55 @@
#include "ebase.h"
#include "gutil/qgui.h"
struct EnvironItem {
QString text;
QString unit;
QString label;
bool has = true;
};
class EEnviron : public EBase {
Q_OBJECT
public:
static LinkedMap<QString, EnvironItem> genItemMap() {
return LinkedMap<QString, EnvironItem> {
{"temperature", {tr("Temperature"), ""}},
{"humidity", {tr("Humidity"), "%"}},
{"noise", {tr("Noise"), "dB"}},
{"windSpeed", {tr("Wind Speed"), "m/s"}},
{"windDirection", {tr("Wind Direction")}},
{"pm2.5", {"PM2.5", "μg/m³"}},
{"pm10", {"PM10", "μg/m³"}},
{"SO2", {"SO₂", "ppb"}},
{"NO2", {"NO₂", "ppb"}},
{"CO", {"CO", "ppb"}},
{"O3", {"O₃", "ppb"}},
{"pressure", {tr("Pressure"), "hPa"}},
{"rainfall", {tr("Rainfall"), "mm"}},
{"radiation", {tr("Radiation"), "W/m²"}},
{"beam", {tr("Beam"), "lux"}},
{"CO2", {"CO₂", "ppm"}}
};
}
LinkedMap<QString, EnvironItem> itemMap = genItemMap();
QString title;
QColor textColor = Qt::red;
QColor backColor = Qt::transparent;
QFont font = qfont("Arial", 12);
int tempCompen = 0;
int align = 0;
int scrollSpeed = 30;
bool useFahrenheit = false;
bool isSingleLine = false;
struct Data {
QString title;
QString labelTemp;
QString labelHum;
QString labelNoise;
QString labelWindSpeed;
QString labelWindDirectiton;
QString labelPm25;
QString labelPm10;
int tempType = 0;
int compensation = 0;
static JObj genProg(const JValue &, const QString &, const QString &);
QFont font = qfont("Arial", 12);
QColor textColor = Qt::red;
QColor backColor = Qt::transparent;
int align = 0;
int playRefresh = 1;
int playDuration = 10;
int scrollSpeed = 33;
bool isSingleLine = false;
bool hasTemp = true;
bool hasHum = true;
bool hasNoise = true;
bool hasWindSpeed = true;
bool hasWindDirection = true;
bool hasPM25 = true;
bool hasPM10 = true;
};
static QJsonObject genProg(const QJsonObject &, const QString &, const QString &);
explicit EEnviron(EBase *multiWin = nullptr);
explicit EEnviron(const JObj &json, EBase *multiWin = nullptr);
explicit EEnviron(const QJsonObject &json, EBase *multiWin = nullptr);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
void timerEvent(QTimerEvent *) override;
int type() const override { return EBase::Environ; }
QWidget* attrWgt() override;
bool save(const QString &pRoot) override;
JObj attrJson() const override;
QJsonObject attrJson() const override;
private:
void init();
void drawText(QPainter*, QRectF&);
void calAttr();
Data m_attr;
int scroll_width;
QString scroll_txt;
int item_cnt = 0;

View File

@ -1,7 +1,6 @@
#include "egif.h"
#include "cfg.h"
#include "tools.h"
#include "globaldefine.h"
#include <QBoxLayout>
#include <QDir>
#include <QLabel>
@ -24,7 +23,7 @@ EGif *EGif::create(const QString &file, PageListItem *pageItem, EBase *multiWin)
QFileInfo info(file);
return new EGif(movie, info.absolutePath(), info.fileName(), pageItem, multiWin);
}
EGif *EGif::create(const JObj &json, PageListItem *pageItem, EBase *multiWin) {
EGif *EGif::create(const QJsonObject &json, PageListItem *pageItem, EBase *multiWin) {
auto widget = json["widget"];
auto dir = widget["path"].toString();
auto name = widget["file"].toString();
@ -42,6 +41,9 @@ EGif *EGif::create(const JObj &json, PageListItem *pageItem, EBase *multiWin) {
movie->jumpToFrame(0);
auto ins = new EGif(movie, dir, name, pageItem, multiWin);
ins->setBaseAttr(json);
auto play = json["play"];
ins->mDuration = play["playDuration"].toInt();
ins->mPlayTimes = play["playTimes"].toInt();
return ins;
}
@ -141,6 +143,46 @@ QWidget* EGif::attrWgt() {
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addWidget(new QLabel(tr("Play Properties")));
line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Play Duration")));
auto wPlayDuration = new QSpinBox();
wPlayDuration->setRange(1, 99999);
wPlayDuration->setValue(mDuration);
connect(wPlayDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
mDuration = value;
});
hBox->addWidget(wPlayDuration);
hBox->addWidget(new QLabel(tr("s")));
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Play Times")));
auto wPlayTimes = new QSpinBox();
wPlayTimes->setRange(1, 99999);
wPlayTimes->setValue(mPlayTimes);
connect(wPlayTimes, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
mPlayTimes = value;
});
hBox->addWidget(wPlayTimes);
hBox->addStretch();
vBox->addLayout(hBox);
vBox->addStretch();
return wgtAttr;
}
@ -155,13 +197,17 @@ bool EGif::save(const QString &pageDir) {
return true;
}
JObj EGif::attrJson() const {
JObj oRoot;
QJsonObject EGif::attrJson() const {
QJsonObject oRoot;
addBaseAttr(oRoot);
oRoot["elementType"] = "Gif";
oRoot["widget"] = JObj{
oRoot["widget"] = QJsonObject{
{"file", mName},
{"path", mDir}
};
oRoot["play"] = QJsonObject{
{"playDuration", mDuration},
{"playTimes", mPlayTimes}
};
return oRoot;
}

View File

@ -9,7 +9,7 @@ class EGif : public EBase {
public:
static QString filters() { return "Gif(*.gif)"; }
static EGif *create(const QString &file, PageListItem *pageItem, EBase *multiWin = nullptr);
static EGif *create(const JObj &, PageListItem *pageItem, EBase *multiWin = nullptr);
static EGif *create(const QJsonObject &, PageListItem *pageItem, EBase *multiWin = nullptr);
explicit EGif(QMovie*, const QString &dir, const QString &name, PageListItem *pageItem, EBase *multiWin = nullptr);
~EGif();
@ -17,7 +17,7 @@ public:
void paint(QPainter*, const QStyleOptionGraphicsItem *, QWidget *) override;
QWidget* attrWgt() override;
bool save(const QString &pRoot) override;
JObj attrJson() const override;
QJsonObject attrJson() const override;
void loadFiles() override;
void freeFiles() override;
@ -29,7 +29,9 @@ public slots:
protected:
PageListItem *mPageItem;
SyncTimer* timer = 0;
int mDuration = 10;
int mPlayTimes = 1;
SyncTimer* timer = nullptr;
};
#endif // EGIF_H

View File

@ -1,5 +1,5 @@
#include "emultiwin.h"
#include "globaldefine.h"
#include "tools.h"
#include "base/extendedgroupbox.h"
#include "ebase.h"
#include "etext.h"
@ -16,37 +16,36 @@
#include <QMenu>
#include <QMessageBox>
#include <QGraphicsScene>
#include <QFileDialog>
EMultiWin::EMultiWin(PageListItem *pageItem) : mPageItem(pageItem) {
mType = EBase::Window;
}
EMultiWin::EMultiWin(const JObj &json, PageListItem *pageItem) : mPageItem(pageItem) {
EMultiWin::EMultiWin(const QJsonObject &json, PageListItem *pageItem) : mPageItem(pageItem) {
mType = EBase::Window;
setBaseAttr(json);
auto elements = json["elements"].toArray();
index = json["index"].toInt();
for(auto &element : elements) {
foreach(QJsonValue element, elements) {
QString type = element["elementType"].toString();
EBase *inner = nullptr;
if(type=="Text") inner = new EText(element.toObj(), this);
else if(type=="Image"||type=="Photo") inner = EPhoto::create(element.toObj(), pageItem, this);
else if(type=="Gif") inner = EGif::create(element.toObj(), pageItem, this);
else if(type=="Video"||type=="Movie") inner = EVideo::create(element.toObj(), pageItem, this);
else if(type=="DClock") inner = new EDClock(element.toObj(), this);
else if(type=="AClock") inner = new EAClock(element.toObj(), this);
else if(type=="Temp") inner = new EEnviron(element.toObj(), this);
else if(type=="Web") inner = new EWeb(element.toObj(), this);
else if(type=="Timer") inner = new ETimer(element.toObj(), this);
if(type=="Text") inner = new EText(element.toObject(), this);
else if(type=="Photo") inner = EPhoto::create(element.toObject(), pageItem, this);
else if(type=="Gif") inner = EGif::create(element.toObject(), pageItem, this);
else if(type=="Movie") inner = EVideo::create(element.toObject(), pageItem, this);
else if(type=="DClock") inner = new EDClock(element.toObject(), this);
else if(type=="AClock") inner = new EAClock(element.toObject(), this);
else if(type=="Temp") inner = new EEnviron(element.toObject(), this);
else if(type=="Web") inner = new EWeb(element.toObject(), this);
else if(type=="Timer") inner = new ETimer(element.toObject(), this);
if(inner==0) continue;
inner->setPos(0, 0);
inner->setFlag(QGraphicsItem::ItemStacksBehindParent);
if(index != inners.size()) inner->freeFiles();
inners.emplace_back(inner);
inners.append(inner);
}
if(inners.empty()) return;
if(index < 0 || index >= (int)inners.size()) index = (int)inners.size()-1;
if(inners.isEmpty()) return;
if(index < 0 || index >= inners.size()) index = inners.size()-1;
setCur(inners[index]);
}
EMultiWin::~EMultiWin() {
@ -54,7 +53,7 @@ EMultiWin::~EMultiWin() {
}
void EMultiWin::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
if(inners.empty()) {
if(inners.isEmpty()) {
QTextOption opt(Qt::AlignCenter);
painter->save();
painter->fillRect(rect(),QColor(0, 0, 0));
@ -71,10 +70,10 @@ bool EMultiWin::save(const QString &pageDir) {
return true;
}
JObj EMultiWin::attrJson() const{
JArray eles;
for(auto inner : inners) eles.append(inner->attrJson());
JObj oRoot;
QJsonObject EMultiWin::attrJson() const{
QJsonArray eles;
foreach(auto inner, inners) eles.append(inner->attrJson());
QJsonObject oRoot;
addBaseAttr(oRoot);
oRoot["elementType"] = "Window";
oRoot["index"] = index;
@ -127,7 +126,7 @@ QWidget* EMultiWin::attrWgt() {
auto menu = new QMenu();
menu->addAction(QIcon(":/res/program/Text.png"), tr("Text"))->setData(EBase::Text);
menu->addAction(QIcon(":/res/program/Photo.png"), tr("Photo"))->setData(EBase::Image);
menu->addAction(QIcon(":/res/program/Photo.png"), tr("Photo"))->setData(EBase::Photo);
menu->addAction(QIcon(":/res/program/Movie.png"), tr("Video"))->setData(EBase::Video);
menu->addAction(QIcon(":/res/program/Gif.png"), tr("Gif"))->setData(EBase::Gif);
menu->addAction(QIcon(":/res/program/DClock.png"), tr("DClock"))->setData(EBase::DClock);
@ -138,7 +137,7 @@ QWidget* EMultiWin::attrWgt() {
int order = listWgt->count();
EBase *ele = 0;
QListWidgetItem *item = 0;
if(type==EBase::Image) {
if(type==EBase::Photo) {
auto files = QFileDialog::getOpenFileNames(wgtAttr, tr("Select File"), gFileHome, EPhoto::filters());
for(int i=0; i<files.count(); i++) {
auto ePhoto = EPhoto::create(files[i], mPageItem, this);
@ -146,7 +145,7 @@ QWidget* EMultiWin::attrWgt() {
ePhoto->setSize(mWidth, mHeight);
ePhoto->setZValue(order++);
ePhoto->setFlag(QGraphicsItem::ItemStacksBehindParent);
inners.emplace_back(ePhoto);
inners.append(ePhoto);
auto item = new QListWidgetItem(QIcon(":/res/program/Photo.png"), tr("Photo")+" "+ePhoto->mName);
item->setData(Qt::UserRole, QVariant::fromValue((void*) ePhoto));
listWgt->addItem(item);
@ -163,7 +162,7 @@ QWidget* EMultiWin::attrWgt() {
eGif->setSize(mWidth, mHeight);
eGif->setZValue(order++);
eGif->setFlag(QGraphicsItem::ItemStacksBehindParent);
inners.emplace_back(eGif);
inners.append(eGif);
auto item = new QListWidgetItem(QIcon(":/res/program/Gif.png"), tr("Gif")+" "+eGif->mName);
item->setData(Qt::UserRole, QVariant::fromValue((void*) eGif));
listWgt->addItem(item);
@ -201,7 +200,7 @@ QWidget* EMultiWin::attrWgt() {
ele->setSize(mWidth, mHeight);
ele->setZValue(order);
ele->setFlag(QGraphicsItem::ItemStacksBehindParent);
inners.emplace_back(ele);
inners.append(ele);
item->setData(Qt::UserRole, QVariant::fromValue((void*)ele));
listWgt->addItem(item);
listWgt->setCurrentItem(item);
@ -220,7 +219,7 @@ QWidget* EMultiWin::attrWgt() {
if(listWgt->count() > 0) listWgt->setCurrentRow(0);
auto ele = static_cast<EBase*>(item->data(Qt::UserRole).value<void*>());
delete item;
for(auto i=inners.begin(); i < inners.end(); ++i) if(*i==ele) inners.erase(i);
inners.removeOne(ele);
delete ele;
int n = listWgt->count();
for(int i=0; i<n; i++) static_cast<EBase*>(listWgt->item(i)->data(Qt::UserRole).value<void*>())->setZValue(i);
@ -247,9 +246,7 @@ QWidget* EMultiWin::attrWgt() {
listWgt->setCurrentRow(row-1);
int n = listWgt->count();
for(int i=0; i<n; i++) static_cast<EBase*>(listWgt->item(i)->data(Qt::UserRole).value<void*>())->setZValue(i);
auto aaa = inners[row];
inners[row] = inners[row-1];
inners[row-1] = aaa;
inners.swapItemsAt(row, row-1);
});
hBox->addWidget(btnGoUp);
@ -263,9 +260,7 @@ QWidget* EMultiWin::attrWgt() {
listWgt->setCurrentRow(row+1);
int n = listWgt->count();
for(int i=0; i<n; i++) static_cast<EBase*>(listWgt->item(i)->data(Qt::UserRole).value<void*>())->setZValue(i);
auto aaa = inners[row];
inners[row] = inners[row+1];
inners[row+1] = aaa;
inners.swapItemsAt(row, row+1);
});
hBox->addWidget(btnGoDown);
@ -277,7 +272,7 @@ QWidget* EMultiWin::attrWgt() {
QListWidgetItem *item = 0;
int type = inner->type();
if(type==EBase::Text) item = new QListWidgetItem(QIcon(":/res/program/Text.png"), tr("Text"));
else if(type==EBase::Image) item = new QListWidgetItem(QIcon(":/res/program/Photo.png"), tr("Photo")+" "+static_cast<EPhoto*>(inner)->mName);
else if(type==EBase::Photo) item = new QListWidgetItem(QIcon(":/res/program/Photo.png"), tr("Photo")+" "+static_cast<EPhoto*>(inner)->mName);
else if(type==EBase::Video) item = new QListWidgetItem(QIcon(":/res/program/Movie.png"), tr("Video")+" "+static_cast<EVideo*>(inner)->mRawName);
else if(type==EBase::Gif) item = new QListWidgetItem(QIcon(":/res/program/Gif.png"), tr("Gif")+" "+static_cast<EGif*>(inner)->mName);
else if(type==EBase::DClock) item = new QListWidgetItem(QIcon(":/res/program/DClock.png"), tr("DClock"));

View File

@ -8,19 +8,19 @@ class EMultiWin : public EBase {
Q_OBJECT
public:
explicit EMultiWin(PageListItem *pageItem);
explicit EMultiWin(const JObj &json, PageListItem *pageItem);
explicit EMultiWin(const QJsonObject &json, PageListItem *pageItem);
~EMultiWin();
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
int type() const override { return EBase::Window; }
QWidget* attrWgt() override;
bool save(const QString &) override;
JObj attrJson() const override;
QJsonObject attrJson() const override;
void setCur(EBase *);
PageListItem *mPageItem = 0;
std::vector<EBase*> inners;
PageListItem *mPageItem{nullptr};
QList<EBase*> inners;
int index{-1};
};

View File

@ -1,7 +1,6 @@
#include "ephoto.h"
#include "cfg.h"
#include "tools.h"
#include "globaldefine.h"
#include <QComboBox>
#include <QFileDialog>
#include <QImageReader>
@ -20,10 +19,10 @@ EPhoto *EPhoto::create(const QString &file, PageListItem *pageItem, EBase *multi
QFileInfo info(file);
return new EPhoto(img, info.absolutePath(), info.fileName(), pageItem, multiWin);
}
EPhoto *EPhoto::create(const JObj &json, PageListItem *pageItem, EBase *multiWin) {
EPhoto *EPhoto::create(const QJsonObject &json, PageListItem *pageItem, EBase *multiWin) {
auto widget = json["widget"];
auto dir = (widget.isNull() ? json["dir"] : widget["path"]).toString();
auto name = (widget.isNull() ? json["name"] : widget["file"]).toString();
auto dir = widget["path"].toString();
auto name = widget["file"].toString();
if(! QFileInfo(dir).isDir()) dir = pageItem->mPageDir;
QString file = dir + "/" + name;
QFileInfo fileInfo(file);
@ -35,23 +34,35 @@ EPhoto *EPhoto::create(const JObj &json, PageListItem *pageItem, EBase *multiWin
else return nullptr;
}
auto img = QImage(file);
if(img.isNull()) return 0;
if(img.isNull()) return nullptr;
auto ins = new EPhoto(img, dir, name, pageItem, multiWin);
ins->setBaseAttr(json);
auto play = json["play"];
ins->mDuration = play["playDuration"].toInt();
ins->mEnterStyle = play["enterStyle"].toInt();
ins->mEnterDuration = play["enterDuration"].toInt();
return ins;
}
EPhoto::EPhoto(const QImage &img, const QString &dir, const QString &name, PageListItem *pageItem, EBase *multiWin) : EBase(multiWin), img(img), mDir(dir), mName(name), mPageItem(pageItem) {
mType = EBase::Image;
mType = EBase::Photo;
scaleImgIfNeed();
}
JObj EPhoto::attrJson() const {
JObj json;
addBaseAttr(json);
json["elementType"] = "Image";
json["dir"] = mDir;
json["name"] = mName;
return json;
QJsonObject EPhoto::attrJson() const {
QJsonObject oRoot;
addBaseAttr(oRoot);
oRoot["elementType"] = "Photo";
oRoot["widget"] = QJsonObject{
{"path", mDir},
{"file", mName}
};
oRoot["play"] = QJsonObject{
{"playDuration", mDuration},
{"playTimes", 1},
{"enterStyle", mEnterStyle},
{"enterDuration", mEnterDuration}
};
return oRoot;
}
void EPhoto::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {
painter->drawImage(innerRect(), img);
@ -83,14 +94,14 @@ bool EPhoto::save(const QString &pageDir) {
}
QWidget* EPhoto::attrWgt() {
auto wgtAttr = new QWidget;
auto vBox = new VBox(wgtAttr);
auto wgtAttr = new QWidget();
auto vBox = new QVBoxLayout(wgtAttr);
vBox->setContentsMargins(6, 0, 6, 0);
if(mMultiWin) vBox->setSpacing(3);
addBaseAttrWgt(vBox);
auto hBox = new HBox(vBox);
auto hBox = new QHBoxLayout();
hBox->addWidget(new QLabel(tr("Basic Properties")));
auto line = new QFrame();
@ -98,7 +109,9 @@ QWidget* EPhoto::attrWgt() {
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
hBox = new HBox(vBox);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("File")));
@ -129,98 +142,86 @@ QWidget* EPhoto::attrWgt() {
});
hBox->addWidget(bnSelectFile);
// hBox = new HBox(vBox);
// hBox->addWidget(new QLabel(tr("Play Properties")));
vBox->addLayout(hBox);
// line = new QFrame();
// line->setFrameShape(QFrame::HLine);
// line->setFrameShadow(QFrame::Sunken);
// hBox->addWidget(line, 1);
hBox = new QHBoxLayout();
hBox->addWidget(new QLabel(tr("Play Properties")));
// hBox = new HBox(vBox);
// hBox->setSpacing(2);
// hBox->addSpacing(6);
// hBox->addWidget(new QLabel(tr("Entry Effect")));
line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
// auto fdEntryEff = new QComboBox;
// fdEntryEff->addItem(tr("None"), "");
// fdEntryEff->addItem(tr("Move to left"), "moving_left");
// fdEntryEff->addItem(tr("Move to top"), "moving_top");
// fdEntryEff->addItem(tr("Move to right"), "moving_right");
// fdEntryEff->addItem(tr("Move to bottom"), "moving_bottom");
// fdEntryEff->addItem(tr("Alpha in"), "alpha_in");
// fdEntryEff->addItem(tr("Zoom in"), "zoom_in");
// fdEntryEff->addItem(tr("Zoom in from left-top"), "zoom_in_left_top");
// fdEntryEff->addItem(tr("Zoom in from right-top"), "zoom_in_right_top");
// fdEntryEff->addItem(tr("Zoom in from right-bottom"), "zoom_in_right_bottom");
// fdEntryEff->addItem(tr("Zoom in from left-bottom"), "zoom_in_left_bottom");
// fdEntryEff->addItem(tr("Rotate to right"), "rotate_right");
// fdEntryEff->addItem(tr("Rotate to left"), "rotate_left");
// fdEntryEff->addItem(tr("Random"), "Random");
// SetCurData(fdEntryEff, mEntryEffect);
// connect(fdEntryEff, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] {
// mEntryEffect = fdEntryEff->currentData().toString();
// });
// hBox->addWidget(fdEntryEff);
// hBox->addStretch();
vBox->addLayout(hBox);
// hBox->addLabel(tr("Dur"));
hBox = new QHBoxLayout();
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Play Duration")));
// auto fdEntryDur = new QSpinBox;
// fdEntryDur->setRange(1, 99);
// fdEntryDur->setValue(mEntryDur);
// connect(fdEntryDur, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) {
// mEntryDur = value;
// if(mDuration < value) {
// mDuration = value;
// fdDuration->setValue(value);
// }
// });
// hBox->addWidget(fdEntryDur);
// hBox->addLabel(tr("s"));
auto fdDuration = new QSpinBox();
fdDuration->setRange(1, 99999);
fdDuration->setValue(mDuration);
hBox->addWidget(fdDuration);
// hBox = new HBox(vBox);
// hBox->setSpacing(2);
// hBox->addSpacing(6);
// hBox->addWidget(new QLabel(tr("Exit Effect")));
hBox->addWidget(new QLabel(tr("s")));
hBox->addStretch();
// auto fdExitEff = new QComboBox;
// fdExitEff->addItem(tr("None"), "");
// fdExitEff->addItem(tr("Move to left"), "moving_left");
// fdExitEff->addItem(tr("Move to top"), "moving_top");
// fdExitEff->addItem(tr("Move to right"), "moving_right");
// fdExitEff->addItem(tr("Move to bottom"), "moving_bottom");
// fdExitEff->addItem(tr("Alpha out"), "alpha_out");
// fdExitEff->addItem(tr("Zoom out"), "zoom_out");
// fdExitEff->addItem(tr("Zoom out to left-top"), "zoom_out_left_top");
// fdExitEff->addItem(tr("Zoom out to right-top"), "zoom_out_right_top");
// fdExitEff->addItem(tr("Zoom out to right-bottom"), "zoom_out_right_bottom");
// fdExitEff->addItem(tr("Zoom out to left-bottom"), "zoom_out_left_bottom");
// fdExitEff->addItem(tr("Rotate to right"), "rotate_right");
// fdExitEff->addItem(tr("Rotate to left"), "rotate_left");
// fdExitEff->addItem(tr("Random"), "Random");
// SetCurData(fdExitEff, mExitEffect);
// connect(fdExitEff, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] {
// mExitEffect = fdExitEff->currentData().toString();
// });
// hBox->addWidget(fdExitEff);
// hBox->addStretch();
vBox->addLayout(hBox);
// hBox->addLabel(tr("Dur"));
hBox = new QHBoxLayout();
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Enter Style")));
// auto fdExitDur = new QSpinBox;
// fdExitDur->setRange(1, 99);
// fdExitDur->setValue(mExitDur);
// connect(fdExitDur, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) {
// mExitDur = value;
// if(mDuration < value) {
// mDuration = value;
// fdDuration->setValue(value);
// }
// });
// hBox->addWidget(fdExitDur);
// hBox->addLabel(tr("s"));
auto wEnterStyle = new QComboBox();
wEnterStyle->addItem(tr("None"));
wEnterStyle->addItem(tr("Alpha_In"));
wEnterStyle->addItem(tr("Moving to left"));
wEnterStyle->addItem(tr("Moving to right"));
wEnterStyle->addItem(tr("Moving to top"));
wEnterStyle->addItem(tr("Move to bottom"));
wEnterStyle->addItem(tr("Zoom in"));
wEnterStyle->addItem(tr("Zoom in to left_bottom"));
wEnterStyle->addItem(tr("Zoom in to left_top"));
wEnterStyle->addItem(tr("Zoom in to right_top"));
wEnterStyle->addItem(tr("Zoom in to right bottom"));
wEnterStyle->addItem(tr("Rotate to right"));
wEnterStyle->addItem(tr("Rotate to left"));
wEnterStyle->setCurrentIndex(mEnterStyle);
connect(wEnterStyle, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int value) {
mEnterStyle = value;
});
hBox->addWidget(wEnterStyle);
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Enter Duration")));
auto fdEnterDuration = new QSpinBox();
fdEnterDuration->setRange(1, 99999);
fdEnterDuration->setValue(mEnterDuration);
connect(fdDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdEnterDuration](int value){
mDuration = value;
if(mEnterDuration > value) {
mEnterDuration = value;
fdEnterDuration->setValue(value);
}
});
connect(fdEnterDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdDuration](int value){
mEnterDuration = value;
if(mDuration < value) {
mDuration = value;
fdDuration->setValue(value);
}
});
hBox->addWidget(fdEnterDuration);
hBox->addWidget(new QLabel(tr("s")));
hBox->addStretch();
vBox->addLayout(hBox);
vBox->addStretch();
return wgtAttr;
}

View File

@ -6,27 +6,41 @@
class EPhoto : public EBase {
Q_OBJECT
public:
enum EnterStyle {
NoneStyle = 0,
Expanding2Left,
Expanding2Right,
Expanding2Top,
Expanding2Bottom,
ExpandingFromCenter
};
public:
static QString filters() { return tr("Images (*.png *.jpg *.jpeg *.bmp)"); }
static EPhoto *create(const QString &file, PageListItem *pageItem, EBase *multiWin = nullptr);
static EPhoto *create(const JObj &, PageListItem *pageItem, EBase *multiWin = nullptr);
static EPhoto *create(const QJsonObject &, PageListItem *pageItem, EBase *multiWin = nullptr);
explicit EPhoto(const QImage&, const QString &dir, const QString &name, PageListItem *pageItem, EBase *multiWin = nullptr);
void scaleImgIfNeed();
int type() const override { return EBase::Image; }
int type() const override { return EBase::Photo; }
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
JObj attrJson() const override;
QJsonObject attrJson() const override;
void freeFiles() override;
void loadFiles() override;
bool save(const QString &pageDir) override;
QWidget* attrWgt() override;
QImage img;
QString mDir, mName;
QString mDir;
QString mName;
protected:
PageListItem *mPageItem;
int mDuration = 10;
int mEnterStyle = 0;
int mEnterDuration = 0;
};
#endif // EPHOTO_H

View File

@ -11,53 +11,48 @@
#include <QSpinBox>
#include <QStackedLayout>
#include <QTextBlock>
#if(QT_VERSION_MAJOR > 5)
#include <QStringConverter>
#else
#include <QTextCodec>
#endif
#include <QTimeEdit>
#include <QToolButton>
#include <QPainter>
#include <QLabel>
static QColor charColors[]{"#fff","#f00","#f00","#f0f","#c0c","#ff0","#f80","#0f0","#0f0","#0a0","#0a0","#7b0","#00f","#00f","#0af","#0ef"};
QString playModes[]{"Flip", "Scroll", "Static"};
EText::EText(EBase *multiWin) : EBase(multiWin) {
mType = EBase::Text;
text = "<body>"+tr("Enter your text")+"</body>";
m_attr.text = "<body>"+tr("Enter your text")+"</body>";
connect(this, &EText::sizeChanged, this, &EText::updImg);
updImg();
}
EText::EText(const JObj &json, EBase *multiWin) : EBase(multiWin) {
EText::EText(const QJsonObject &json, EBase *multiWin) : EBase(multiWin) {
mType = EBase::Text;
setBaseAttr(json);
auto widget = json["widget"];
if(widget.isNull()) widget = json;
text = widget["text"].toString();
align = (Qt::Alignment) widget["align"].toInt();
backColor = widget["backColor"].toString("#00000000");
auto play = json["play"];
if(play.isNull()) {
playMode = json["playMode"].toString();
if(playMode=="Scroll") {
direction = json["direction"].toString();
speed = json["speed"].toInt();
headTailSpacing = json["headTailSpacing"].toInt();
}
} else {
playMode = playModes[play["style"].toInt()];
auto rolling = play["rolling"];
QString ds[]{"left", "top", "right", "bottom"};
direction = ds[rolling["rollingStyle"].toInt()];
speed = 1000/rolling["rollingSpeed"].toInt(33);
headTailSpacing = rolling["headTailSpacing"].toInt();
}
setElement(json, m_attr);
connect(this, &EText::sizeChanged, this, &EText::updImg);
updImg();
}
void EText::setElement(const QJsonObject &json, Data &attr) {
auto widget = json["widget"];
attr.text = widget["text"].toString();
attr.align = static_cast<Qt::Alignment>(widget["align"].toInt());
auto backColor = widget["backColor"].toString();
attr.backColor = backColor.isEmpty() ? QColor(0,0,0,0) : QColor(backColor);
auto play = json["play"];
attr.playMode = play["style"].toInt();
auto turning = play["turning"];
attr.flip.effect = turning["strEffect"].toString();
attr.flip.pageDuration = turning["iEffectTime"].toInt();
attr.flip.effectDuration = turning["iEffectSpeed"].toInt();
auto rolling = play["rolling"];
attr.scroll.effect = rolling["rollingStyle"].toInt();
attr.scroll.effectSpeed = rolling["rollingSpeed"].toInt();
attr.scroll.headTailSpacing = rolling["headTailSpacing"].toInt();
attr.scroll.duration = rolling["playDuration"].toInt();
attr.duration = play["static"]["playDuration"].toInt();
}
class TTextEdit : public QTextEdit {
public:
TTextEdit() {}
@ -196,12 +191,12 @@ QWidget* EText::attrWgt() {
});
hBox->addWidget(fdTextColor);
auto fdBackColor = new LoColorSelector("B", backColor);
auto fdBackColor = new LoColorSelector("B", m_attr.backColor);
fdBackColor->setToolTip(tr("Back Color"));
fdBackColor->setFixedSize(30, 30);
connect(fdBackColor, &LoColorSelector::sColorChanged, this, [this](const QColor &color) {
if(! color.isValid()) return;
backColor = color;
m_attr.backColor = color;
updImg();
});
hBox->addWidget(fdBackColor);
@ -274,12 +269,12 @@ QWidget* EText::attrWgt() {
lb->setToolTip(lb->text());
hBox->addWidget(lb);
auto fdLineSpacing = new QSpinBox;
auto fdLineSpacing = new QSpinBox();
fdLineSpacing->setRange(-99, 999);
connect(fdLineSpacing, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this, fdText](int value) {
QTextBlockFormat fmt;
fmt.setLineHeight(value, QTextBlockFormat::LineDistanceHeight);
auto cursor = fdText->textCursor();
QTextCursor cursor = fdText->textCursor();
if(! cursor.hasSelection()) cursor.select(QTextCursor::WordUnderCursor);
cursor.mergeBlockFormat(fmt);
updImg();
@ -288,11 +283,11 @@ QWidget* EText::attrWgt() {
vBox->addLayout(hBox);
auto fdAlignH = new QButtonGroup(wgtAttr);
fdAlignH->addButton(wTextAlignHL, Qt::AlignLeft);
fdAlignH->addButton(wTextAlignHC, Qt::AlignHCenter);
fdAlignH->addButton(wTextAlignHR, Qt::AlignRight);
connect(fdAlignH, &QButtonGroup::idClicked, this, [this, fdText](int value) {
auto wTextAlignH = new QButtonGroup(wgtAttr);
wTextAlignH->addButton(wTextAlignHL, Qt::AlignLeft);
wTextAlignH->addButton(wTextAlignHC, Qt::AlignHCenter);
wTextAlignH->addButton(wTextAlignHR, Qt::AlignRight);
connect(wTextAlignH, &QButtonGroup::idClicked, this, [this, fdText](int value) {
QTextBlockFormat fmt;
fmt.setAlignment((Qt::Alignment) value);
QTextCursor cursor = fdText->textCursor();
@ -300,16 +295,16 @@ QWidget* EText::attrWgt() {
updImg();
});
auto fdAlignV = new QButtonGroup(wgtAttr);
fdAlignV->addButton(wTextAlignVT, Qt::AlignTop);
fdAlignV->addButton(wTextAlignVC, Qt::AlignVCenter);
fdAlignV->addButton(wTextAlignVB, Qt::AlignBottom);
connect(fdAlignV, &QButtonGroup::idClicked, this, [this](int value) {
align = (Qt::Alignment) value;
auto wTextAlignV = new QButtonGroup(wgtAttr);
wTextAlignV->addButton(wTextAlignVT, Qt::AlignTop);
wTextAlignV->addButton(wTextAlignVC, Qt::AlignVCenter);
wTextAlignV->addButton(wTextAlignVB, Qt::AlignBottom);
connect(wTextAlignV, &QButtonGroup::idClicked, this, [this](int value) {
m_attr.align = (Qt::Alignment) value;
updImg();
});
auto v_align = align & Qt::AlignVertical_Mask;
auto v_align = m_attr.align & Qt::AlignVertical_Mask;
if(v_align==Qt::AlignTop) wTextAlignVT->setChecked(true);
if(v_align==Qt::AlignVCenter) wTextAlignVC->setChecked(true);
if(v_align==Qt::AlignBottom) wTextAlignVB->setChecked(true);
@ -328,33 +323,11 @@ QWidget* EText::attrWgt() {
fdText->setPalette(pal);
fdText->setFrameShape(QFrame::NoFrame);
fdText->setAcceptRichText(false);
fdText->setHtml(text);
fdText->setHtml(m_attr.text);
connect(fdText, &QTextEdit::textChanged, this, [this, fdText] {
text = fdText->toHtml();
m_attr.text = fdText->toHtml();
updImg();
});
connect(fdText, &QTextEdit::currentCharFormatChanged, this, [=](const QTextCharFormat &format) {
fdFontSize->blockSignals(true);
fdFontSize->setValue(format.font().pixelSize());
fdFontSize->blockSignals(false);
auto foreground = format.foreground();
fdTextColor->blockSignals(true);
fdTextColor->setColor(foreground.style()==Qt::NoBrush ? Qt::white : foreground.color());
fdTextColor->blockSignals(false);
fdLetterSpacing->blockSignals(true);
fdLetterSpacing->setValue(format.fontLetterSpacing());
fdLetterSpacing->blockSignals(false);
auto cursor = fdText->textCursor();
auto blockFormat = cursor.blockFormat();
auto btn = fdAlignH->button(blockFormat.alignment() & Qt::AlignHorizontal_Mask);
if(btn) btn->setChecked(true);
fdLineSpacing->blockSignals(true);
fdLineSpacing->setValue(blockFormat.lineHeightType()==QTextBlockFormat::LineDistanceHeight ? blockFormat.lineHeight() : 0);
fdLineSpacing->blockSignals(false);
});
vBox->addWidget(fdText);
hBox = new QHBoxLayout;
@ -395,16 +368,9 @@ QWidget* EText::attrWgt() {
}
auto data = qFile.readAll();
qFile.close();
#if(QT_VERSION_MAJOR > 5)
#include <QStringConverter>
QStringDecoder decoder(QStringDecoder::Utf8);
QString text = decoder(data);
if(decoder.hasError()) text = QStringDecoder(QStringDecoder::System)(data);
#else
QTextCodec::ConverterState state;
auto text = QTextCodec::codecForName("UTF-8")->toUnicode(data.constData(), data.size(), &state);
QString text = QTextCodec::codecForName("UTF-8")->toUnicode(data.constData(), data.size(), &state);
if(state.invalidChars > 0) text = QString::fromLocal8Bit(data);
#endif
fdText->setText(text);
});
hBox->addWidget(btnImport);
@ -439,110 +405,232 @@ QWidget* EText::attrWgt() {
vBox->addLayout(hBox);
auto fdPlayStyle = new QButtonGroup(wgtAttr);
fdPlayStyle->addButton(fdFlip, 0);
fdPlayStyle->addButton(fdScroll, 1);
fdPlayStyle->addButton(fdStatic, 2);
if(playMode=="Flip") fdFlip->setChecked(true);
else if(playMode=="Scroll") fdScroll->setChecked(true);
else if(playMode=="Static") fdStatic->setChecked(true);
fdPlayStyle->addButton(fdFlip, EText::Flip);
fdPlayStyle->addButton(fdScroll, EText::Scroll);
fdPlayStyle->addButton(fdStatic, EText::Static);
if(m_attr.playMode==EText::Flip) fdFlip->setChecked(true);
else if(m_attr.playMode==EText::Scroll) fdScroll->setChecked(true);
else if(m_attr.playMode==EText::Static) fdStatic->setChecked(true);
auto wgtAttrFlip = new QWidget;
auto wgtAttrScroll = new QWidget;
auto wgtAttrFlip = new QWidget();
auto fdDur = new QTimeEdit(QTime::fromMSecsSinceStartOfDay(m_attr.flip.pageDuration * mImgs.size() * 1000));
auto fdPageDur = new QTimeEdit(QTime::fromMSecsSinceStartOfDay(m_attr.flip.pageDuration * 1000));
{
auto vBox = new VBox(wgtAttrScroll);
auto vBox = new QVBoxLayout(wgtAttrFlip);
vBox->setContentsMargins(2, 0, 2, 0);
vBox->setSpacing(3);
auto hBox = new HBox(vBox);
auto label = new QLabel(tr("Head-Tail Spacing"));
hBox = new QHBoxLayout;
auto label = new QLabel(tr("Play Duration"));
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);
fdDur->setReadOnly(true);
fdDur->setButtonSymbols(QAbstractSpinBox::NoButtons);
fdDur->setDisplayFormat("H:mm:ss");
fdDur->setStyleSheet("QTimeEdit{background-color:#ddd;}");
hBox->addWidget(fdDur);
hBox->addStretch();
hBox = new HBox(vBox);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
label = new QLabel(tr("Duration/Page"));
label->setMinimumWidth(100);
hBox->addWidget(label);
fdPageDur->setDisplayFormat("H:mm:ss");
fdPageDur->setCurrentSection(QTimeEdit::SecondSection);
hBox->addWidget(fdPageDur);
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
label = new QLabel(tr("Entrance Effect"));
label->setMinimumWidth(100);
hBox->addWidget(label);
auto fdEff = new QComboBox();
fdEff->addItem(tr("no"), "no");
fdEff->addItem(tr("random"), "random");
fdEff->addItem(tr("right to left"), "right to left");
fdEff->addItem(tr("bottom to top"), "bottom to top");
fdEff->addItem(tr("left to right"), "left to right");
fdEff->addItem(tr("top to bottom"), "top to bottom");
int idx = fdEff->findData(m_attr.flip.effect);
if(idx!=-1) fdEff->setCurrentIndex(idx);
connect(fdEff, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this, fdEff] {
m_attr.flip.effect = fdEff->currentData().toString();
update();
});
hBox->addWidget(fdEff);
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
label = new QLabel(tr("Effect time"));
label->setMinimumWidth(100);
hBox->addWidget(label);
auto wEffectSpeed = new QSpinBox();
wEffectSpeed->setValue(m_attr.flip.effectDuration);
hBox->addWidget(wEffectSpeed);
hBox->addWidget(new QLabel(tr("s")));
hBox->addStretch();
vBox->addLayout(hBox);
vBox->addStretch();
connect(fdPageDur, &QTimeEdit::timeChanged, this, [=](const QTime &time) {
int effDur = wEffectSpeed->value();
int pageDur = time.msecsSinceStartOfDay()/1000;
if(pageDur < effDur) {
QMessageBox::warning(wgtAttr, tr("Tip Info"), tr("Effect time cannot be longer than duration time"));
pageDur = effDur;
fdPageDur->setTime(QTime::fromMSecsSinceStartOfDay(pageDur*1000));
fdPageDur->setFocus();
}
m_attr.flip.pageDuration = pageDur;
fdDur->setTime(QTime::fromMSecsSinceStartOfDay(pageDur * mImgs.size() * 1000));
});
connect(wEffectSpeed, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [=](int value) {
int pageDur = fdPageDur->time().msecsSinceStartOfDay()/1000;
if(value > pageDur) {
QMessageBox::warning(wgtAttr, tr("Tip Info"), tr("Effect time cannot be longer than duration time"));
if(pageDur>1) value = pageDur-1;
else value = 0;
wEffectSpeed->setValue(value);
wEffectSpeed->setFocus();
}
m_attr.flip.effectDuration = value;
});
}
auto wgtAttrScroll = new QWidget();
{
auto vBox = new QVBoxLayout(wgtAttrScroll);
vBox->setContentsMargins(2, 0, 2, 0);
vBox->setSpacing(3);
auto hBox = new QHBoxLayout();
auto label = new QLabel(tr("Play Duration"));
label->setMinimumWidth(100);
hBox->addWidget(label);
auto timeEdit = new QTimeEdit(QTime::fromMSecsSinceStartOfDay(m_attr.scroll.duration*1000));
timeEdit->setDisplayFormat("H:mm:ss");
timeEdit->setCurrentSectionIndex(2);
connect(timeEdit, &QTimeEdit::timeChanged, this, [this](const QTime &time) {
m_attr.scroll.duration = time.msecsSinceStartOfDay()/1000;
});
hBox->addWidget(timeEdit);
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
label = new QLabel(tr("Head-Tail Spacing"));
label->setMinimumWidth(100);
hBox->addWidget(label);
auto wHeadTailSpacing = new QSpinBox;
wHeadTailSpacing->setRange(0, 9999);
wHeadTailSpacing->setValue(m_attr.scroll.headTailSpacing);
connect(wHeadTailSpacing, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
m_attr.scroll.headTailSpacing = value;
});
hBox->addWidget(wHeadTailSpacing);
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
label = new QLabel(tr("Scroll Style"));
label->setMinimumWidth(100);
hBox->addWidget(label);
auto fdDirection = new QComboBox;
fdDirection->addItem(tr("Right -> Left"), "left");
fdDirection->addItem(tr("Bottom -> Top"), "top");
fdDirection->addItem(tr("Left -> Right"), "right");
fdDirection->addItem(tr("Top -> Bottom"), "bottom");
SetCurData(fdDirection, direction);
connect(fdDirection, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [=] {
direction = fdDirection->currentData().toString();
auto wRollingStyle = new QComboBox;
wRollingStyle->addItem(tr("Right -> Left"));
wRollingStyle->addItem(tr("Bottom -> Top"));
wRollingStyle->addItem(tr("Left -> Right"));
wRollingStyle->addItem(tr("Top -> Bottom"));
wRollingStyle->setCurrentIndex(m_attr.scroll.effect);
connect(wRollingStyle, (void(QComboBox::*)(int))&QComboBox::currentIndexChanged, this, [this](int index) {
m_attr.scroll.effect = index;
updImg();
});
hBox->addWidget(fdDirection);
hBox->addWidget(wRollingStyle);
hBox->addStretch();
hBox = new HBox(vBox);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
label = new QLabel(tr("Scroll Speed"));
label->setMinimumWidth(100);
hBox->addWidget(label);
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;
auto wRollingSpeed = new QSpinBox();
wRollingSpeed->setMaximum(9999);
wRollingSpeed->setValue(m_attr.scroll.effectSpeed);
connect(wRollingSpeed, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
m_attr.scroll.effectSpeed = value;
});
hBox->addWidget(fd);
hBox->addLabel("px/s");
hBox->addWidget(wRollingSpeed);
hBox->addStretch();
vBox->addLayout(hBox);
vBox->addStretch();
}
auto wgtAttrStatic = new QWidget();
{
auto vBox = new QVBoxLayout(wgtAttrStatic);
vBox->setContentsMargins(2, 0, 2, 0);
vBox->setSpacing(3);
hBox = new QHBoxLayout();
auto label = new QLabel(tr("Play Duration"));
label->setMinimumWidth(100);
hBox->addWidget(label);
auto timeEdit = new QTimeEdit(QTime::fromMSecsSinceStartOfDay(m_attr.duration*1000));
timeEdit->setDisplayFormat("H:mm:ss");
timeEdit->setCurrentSectionIndex(2);
connect(timeEdit, &QTimeEdit::timeChanged, this, [this](const QTime &time) {
m_attr.duration = time.msecsSinceStartOfDay() / 1000;
});
hBox->addWidget(timeEdit);
hBox->addStretch();
vBox->addLayout(hBox);
vBox->addStretch();
}
auto stackBox = new QStackedLayout;
vBox->addLayout(stackBox);
stackBox->addWidget(wgtAttrFlip);
stackBox->addWidget(wgtAttrScroll);
stackBox->addWidget(new QWidget);
auto idx = std::find(playModes, playModes+3, playMode)-playModes;
if(idx>2) idx = 0;
stackBox->setCurrentIndex(idx);
connect(fdPlayStyle, &QButtonGroup::idToggled, this, [=](int value, bool checked) {
stackBox->addWidget(wgtAttrStatic);
stackBox->setCurrentIndex(m_attr.playMode);
connect(fdPlayStyle, &QButtonGroup::idToggled, this, [this, stackBox, pageInfoWgt](int value, bool checked) {
if(! checked) return;
playMode = playModes[value];
m_attr.playMode = value;
updImg();
stackBox->setCurrentIndex(value);
pageInfoWgt->setVisible(playMode=="Flip");
pageInfoWgt->setVisible(value==Flip);
});
connect(this, &EText::updPageCnt, wgtAttr, [=] {
connect(this, &EText::updPageCnt, wgtAttr, [this, fdPageCnt, fdPageIdx, fdPageDur, fdDur] {
fdPageCnt->setText(QString::number(mImgs.size()));
fdPageIdx->setRange(1, mImgs.size());
fdPageIdx->setValue(1);
fdDur->setTime(QTime::fromMSecsSinceStartOfDay(fdPageDur->time().msecsSinceStartOfDay() * mImgs.size()));
});
return wgtAttr;
}
@ -553,34 +641,44 @@ bool EText::save(const QString &pageDir) {
for(int i=0; i<mImgs.count(); i++) mImgs[i].save(idDir + QString("/text%1.png").arg(i));
return true;
}
JObj EText::attrJson() const {
JArray files;
QJsonObject EText::attrJson() const {
QJsonArray files;
for(int i=0; i<mImgs.count(); i++) files.append(QString("text%1.png").arg(i)); //上下滚动,生成一张纵向长图
JObj obj{
{"elementType", "Text"},
{"playMode", playMode},
{"text", text},
{"align", (int) align},
{"backColor", backColor.name(QColor::HexArgb)},
QJsonObject obj;
addBaseAttr(obj);
obj["elementType"] = "Text";
obj["widget"] = QJsonObject{
{"text", m_attr.text},
{"align", (int) m_attr.align},
{"backColor", m_attr.backColor.name(QColor::HexArgb)},
{"files", files},
{"idDir", QString("%1-%2-%3-%4-%5").arg(zValue()).arg((int)x()).arg((int)y()).arg((int)mWidth).arg((int)mHeight)}
};
addBaseAttr(obj);
if(playMode=="Scroll") {
obj["direction"] = direction;
obj["speed"] = speed;
obj["headTailSpacing"] = headTailSpacing;
}
obj["play"] = QJsonObject{
{"style", m_attr.playMode},
{"turning", QJsonObject{
{"strEffect", m_attr.flip.effect},
{"iEffectTime", m_attr.flip.pageDuration},
{"iEffectSpeed", m_attr.flip.effectDuration}
}},
{"rolling", QJsonObject{
{"rollingStyle", m_attr.scroll.effect},
{"rollingSpeed", m_attr.scroll.effectSpeed},
{"headTailSpacing", m_attr.scroll.headTailSpacing},
{"playDuration", m_attr.scroll.duration}
}},
{"static", QJsonObject{{"playDuration", m_attr.duration}}}
};
return obj;
}
void EText::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
painter->save();
auto rect = innerRect();
if(playMode!="Flip") curIdx = 0;
if(m_attr.playMode!=EText::Flip) curIdx = 0;
else if(curIdx>=mImgs.size()) curIdx = mImgs.size() - 1;
else if(curIdx < 0) curIdx = 0;
if(playMode=="Scroll") painter->drawImage(rect.x(), rect.y(), mImgs[0], 0, 0, rect.width(), rect.height());
if(m_attr.playMode==EText::Scroll) painter->drawImage(rect.x(), rect.y(), mImgs[0], 0, 0, rect.width(), rect.height());
else painter->drawImage(rect.x(), rect.y(), mImgs[curIdx]);
painter->restore();
EBase::paint(painter, option, widget);
@ -599,25 +697,25 @@ void EText::updImg() {
if(! gTextAntialiasing) font.setStyleStrategy(QFont::NoAntialias);
doc.setDefaultFont(font);
doc.setDefaultStyleSheet("body {color: #fff;}");
if(playMode=="Flip") {
doc.setHtml(text);
doc.setHtml(m_attr.text);
if(m_attr.playMode==EText::Flip) {
doc.setPageSize(innerRect.size());
auto pageHeight = height;
auto pageCnt = doc.pageCount();
QImage img(width, pageHeight*pageCnt, QImage::Format_ARGB32);
img.fill(backColor);
img.fill(m_attr.backColor);
{
QPainter painter(&img);
doc.drawContents(&painter);
}
if(pageCnt > 1) {
check:
for(int y=pageHeight-1; y<img.height(); y+=pageHeight) for(int x=0; x<width; x++) if(img.pixelColor(x, y)!=backColor) {
for(int y=pageHeight-1; y<img.height(); y+=pageHeight) for(int x=0; x<width; x++) if(img.pixelColor(x, y)!=m_attr.backColor) {
pageHeight *= 2;
doc.setPageSize(QSizeF(width, pageHeight));
pageCnt = doc.pageCount();
img = QImage(width, pageHeight*pageCnt, QImage::Format_ARGB32);
img.fill(backColor);
img.fill(m_attr.backColor);
{
QPainter painter(&img);
doc.drawContents(&painter);
@ -626,7 +724,7 @@ void EText::updImg() {
else goto forend;
}
if(pageCnt > 1) {
for(int y=img.height()-pageHeight; y<img.height(); y++) for(int x=0; x<width; x++) if(img.pixelColor(x, y)!=backColor) goto forend;
for(int y=img.height()-pageHeight; y<img.height(); y++) for(int x=0; x<width; x++) if(img.pixelColor(x, y)!=m_attr.backColor) goto forend;
pageCnt--;
}
}
@ -640,35 +738,19 @@ void EText::updImg() {
rect.translate(0, pageHeight);
}
emit updPageCnt();
} else if(playMode=="Scroll") {//生成一张大图
if(direction=="left" || direction=="right") {
doc.setHtml(text.replace("<p ", "<span ").replace("</p>", "</span>").replace("<br />", " "));
width = ceil(doc.idealWidth()) + headTailSpacing;
} else {
} else if(m_attr.playMode==EText::Scroll) {//生成一张大图
if(m_attr.scroll.effect==0||m_attr.scroll.effect==2) width = qMax(width, ((int)doc.idealWidth()) + m_attr.scroll.headTailSpacing);
else {
doc.setTextWidth(width);
doc.setHtml(text);
height = doc.size().height() + headTailSpacing;
height = doc.size().height() + m_attr.scroll.headTailSpacing;
}
QImage img(width, height, QImage::Format_ARGB32);
img.fill(backColor);
img.fill(m_attr.backColor);
{
QPainter painter(&img);
doc.drawContents(&painter);
}
if(direction=="left" || direction=="right") {
alignV(img);
if(width < innerRect.width()) {
auto newWidth = width*2;
while(newWidth<innerRect.width()) newWidth += width;
QImage newImg(newWidth, height, QImage::Format_ARGB32);
newImg.fill(Qt::transparent);
{
QPainter painter(&newImg);
for(int x=0; x<newWidth; x+=width) painter.drawImage(x, 0, img);
}
img = newImg;
}
}
if(m_attr.scroll.effect==0||m_attr.scroll.effect==2) alignV(img);
mImgs.clear();
mImgs.append(img);
// if(img.width()<=8192) mImgs.append(img);
@ -683,11 +765,10 @@ void EText::updImg() {
// mImgs.append(imgpart);
// }
// }
} else if(playMode=="Static") {//生成一张图
doc.setHtml(text);
} else if(m_attr.playMode==EText::Static) {//生成一张图
doc.setTextWidth(width);
QImage img(width, height, QImage::Format_ARGB32);
img.fill(backColor);
img.fill(m_attr.backColor);
{
QPainter painter(&img);
doc.drawContents(&painter);
@ -701,26 +782,26 @@ void EText::updImg() {
void EText::alignV(QImage &img, int cutHeight) {
int width = img.width(), height = img.height();
if(cutHeight==0) cutHeight = height;
if(align & Qt::AlignTop) {
if(m_attr.align & Qt::AlignTop) {
int ss = 0;
for(; ss<height; ss++) for(int i=0; i<width; i++) if(img.pixelColor(i, ss)!=backColor) goto l12;
for(; ss<height; ss++) for(int i=0; i<width; i++) if(img.pixelColor(i, ss)!=m_attr.backColor) goto l12;
if(cutHeight==height) return;
ss = 0;
l12:
img = copy(img, 0, ss, width, cutHeight);
} else if(align & Qt::AlignVCenter) {
} else if(m_attr.align & Qt::AlignVCenter) {
int ss = 0, ee = height - 1;
for(; ss<height; ss++) for(int i=0; i<width; i++) if(img.pixelColor(i, ss)!=backColor) goto l2;
for(; ss<height; ss++) for(int i=0; i<width; i++) if(img.pixelColor(i, ss)!=m_attr.backColor) goto l2;
if(cutHeight==height) return;
ss = 0;
goto l3;
l2:
for(; ee>ss; ee--) for(int i=0; i<width; i++) if(img.pixelColor(i, ee)!=backColor) goto l3;
for(; ee>ss; ee--) for(int i=0; i<width; i++) if(img.pixelColor(i, ee)!=m_attr.backColor) goto l3;
l3:
img = copy(img, 0, (ss+ee-cutHeight+2)/2, width, cutHeight);
} else if(align & Qt::AlignBottom) {
} else if(m_attr.align & Qt::AlignBottom) {
int ee = height - 1;
for(; ee>=0; ee--) for(int i=0; i<width; i++) if(img.pixelColor(i, ee)!=backColor) goto l32;
for(; ee>=0; ee--) for(int i=0; i<width; i++) if(img.pixelColor(i, ee)!=m_attr.backColor) goto l32;
if(cutHeight==height) return;
ee = height - 1;
l32:
@ -730,7 +811,7 @@ void EText::alignV(QImage &img, int cutHeight) {
QImage EText::copy(QImage &img, int x, int y, int w, int h) {
QImage imgpart(w, h, QImage::Format_ARGB32);
imgpart.fill(backColor);
imgpart.fill(m_attr.backColor);
{
QPainter painter(&imgpart);
painter.drawImage(-x, -y, img);

View File

@ -6,22 +6,38 @@
class EText : public EBase {
Q_OBJECT
public:
enum PlayMode {Flip, Scroll, Static};
struct Flip {
int pageDuration{10};
QString effect{"no"};
int effectDuration{3};
};
struct Scroll {
int duration{30};
int effect{0};
int effectSpeed{50};
int headTailSpacing{10};
};
struct Data {
QString text;
Qt::Alignment align;
QColor backColor{Qt::transparent};
int playMode{Flip};
int duration{10};
struct Flip flip;
struct Scroll scroll;
};
static void setElement(const QJsonObject &json, Data &attr);
explicit EText(EBase *multiWin = nullptr);
explicit EText(const JObj &json, EBase *multiWin = nullptr);
explicit EText(const QJsonObject &json, EBase *multiWin = nullptr);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
int type() const override { return EBase::Text; }
QWidget* attrWgt() override;
bool save(const QString &pRoot) override;
JObj attrJson() const override;
QString text;
Qt::Alignment align;
QColor backColor{Qt::transparent};
QString playMode = "Flip";
QString direction = "left";
int speed = 60;
int headTailSpacing{10};
QJsonObject attrJson() const override;
public slots:
void updImg();
@ -32,6 +48,7 @@ private:
void alignV(QImage &, int h=0);
QImage copy(QImage &img, int x, int y, int w, int h);
Data m_attr;
QList<QImage> mImgs;
int curIdx{0};
};

Some files were not shown because too many files have changed in this diff Show More