Compare commits

...

10 Commits

Author SHA1 Message Date
Gangphon 332897f9cf ledok增加版本提示 2024-03-29 15:23:12 +08:00
Gangphon 6015d932d3 ledok 2024-03-05 19:02:33 +08:00
Gangphon c311554cee ledok 2024-02-28 11:34:33 +08:00
Gangphon e54f367005 ledok 2024-02-21 18:08:50 +08:00
Gangphon 4411e50aee util 2024-01-28 20:28:02 +08:00
Gangphon 8bf38c468d ledok 2023-10-23 15:08:45 +08:00
Gangphon 3a7eaae7a8 ledok 2023-10-23 14:58:29 +08:00
Gangphon bedfe3c2c7 ledok 2023-10-23 11:44:22 +08:00
Gangphon 4c2a30cbe1 xlsx兼容qt6 2023-10-20 18:43:30 +08:00
Gangphon b3ebcb885d 增加 demo 图片 2023-10-20 18:30:14 +08:00
147 changed files with 11437 additions and 13852 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

View File

@ -1,242 +1,245 @@
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)
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)

View File

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

View File

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

View File

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

View File

@ -1,6 +1,6 @@
#include "ctrladvancedpanel.h"
#include "globaldefine.h"
#include "base/waitingdlg.h"
#include "gutil/qwaitingdlg.h"
#include "base/changepasswordform.h"
#include "tools.h"
#include "gutil/qgui.h"
@ -30,9 +30,14 @@
CtrlAdvancedPanel::CtrlAdvancedPanel() {
setFocusPolicy(Qt::StrongFocus);
auto vBox = new QVBoxLayout(this);
auto vBox = new VBox(this);
vBox->setContentsMargins(6,6,6,0);
lbTitle = new QLabel;
auto ft = lbTitle->font();
ft.setPixelSize(16);
ft.setBold(true);
lbTitle->setFont(ft);
lbTitle->setAlignment(Qt::AlignCenter);
vBox->addWidget(lbTitle);
@ -119,7 +124,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
auto item = findItem(card.id);
if(item) {
item->mCard.alias = alias;
item->setText(DeviceTable_Remark, alias);
item->setText("alias", alias);
}
});
} else {
@ -132,7 +137,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
auto item = findItem(card.id);
if(item) {
item->mCard.alias = alias;
item->setText(DeviceTable_Remark, alias);
item->setText("alias", alias);
}
});
}
@ -172,21 +177,10 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
QString serverAddr = fdWebServerAddr->currentText();
if(serverAddr.isEmpty()) {
QMessageBox::information(this, tr("Tip"),tr("InputWebServerAddressTip"));
fdWebServerAddr->setFocus();
return;
}
auto serverAddr = fdWebServerAddr->currentText();
auto companyId = fdCompanyId->text();
if(companyId.isEmpty()) {
QMessageBox::information(this, tr("Tip"),tr("InputCompanyIdTip"));
fdCompanyId->setFocus();
return;
}
auto res = QMessageBox::question(this, tr("Tip Info"), tr("Do you want to modify webserveraddress and companyId?"));
if(res != QMessageBox::Yes) return;
// auto res = QMessageBox::question(this, tr("Tip Info"), tr("This operation will clear current program.")+"\n"+tr("Do you want to continue?"));
// if(res != QMessageBox::Yes) return;
QJsonObject json;
json.insert("_id", "SetOnlineAddr");
json.insert("_type", "SetOnlineAddr");
@ -209,12 +203,10 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
hBox->addStretch();
hBox = new HBox(vBox);
label = new QLabel;
hBox->addWidget(label);
hBox->addWidget(lbRealtime = new QLabel);
fdRealtimeServer = new QComboBox;
fdRealtimeServer->addItem(tr("www.ledokcloud.com/realtime"));
fdRealtimeServer->addItem("www.ledokcloud.com/realtime");
fdRealtimeServer->setMinimumWidth(260);
fdRealtimeServer->setEditable(true);
hBox->addWidget(fdRealtimeServer);
@ -279,8 +271,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
btnWareUpdate->setMinimumSize(100, 30);
btnWareUpdate->setProperty("ssType", "progManageTool");
connect(btnWareUpdate, &QPushButton::clicked, this, [=] {
UpgradeApkDialog dlg(this);
dlg.exec();
new UpgradeApkDialog(this);
});
hBox->addWidget(btnWareUpdate);
@ -317,7 +308,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
infoDlg->setWindowTitle(tr("Software Version Info"));
auto vBox = new QVBoxLayout(infoDlg);
vBox->setContentsMargins(0, 0, 0, 0);
auto table = new Table{
auto table = new TableWidget{
{"apk", "Apk"},
{"ver", tr("Version")},
{"pkg", tr("Package")}
@ -487,7 +478,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
tcp->connectToHost(card.ip, 3333);
tcp->startTimer(10000);
} else {
foreach(auto card, gSelCards) {
for(auto &card : gSelCards) {
auto tcp = new TcpSocket;
auto cardId = card.id;
connect(tcp, &QTcpSocket::connected, tcp, [=] {
@ -608,28 +599,211 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
waitingDlg->show();
auto card = gSelCards[0];
auto reply = NetReq("http://"+card.ip+":2016/download?file=logs").timeout(120000).get();
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
ConnReply(reply, waitingDlg) [=] {
waitingDlg->close();
QString err = checkReply(reply);
if(! err.isEmpty()) {
QMessageBox::critical(this, tr("Error"), err);
return;
}
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});
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();
});
}
});
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);
@ -703,8 +877,8 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
auto hBox = new HBox(grpY50);
auto fdY50Resolu = new QComboBox;
auto dirs = QDir(QApplication::applicationDirPath()+"/y50 param").entryList(QDir::Dirs | QDir::NoDotAndDotDot);
foreach(auto dir, dirs) fdY50Resolu->addItem(dir);
auto params = QDir(QApplication::applicationDirPath()+"/rk_lcd_parameters").entryList(QDir::Files);
for(auto &param : params) fdY50Resolu->addItem(param);
fdY50Resolu->setMinimumWidth(160);
hBox->addWidget(fdY50Resolu);
@ -715,14 +889,14 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
auto filePath = QApplication::applicationDirPath()+"/y50 param/"+fdY50Resolu->currentText()+"/rk_lcd_parameters";
QFile qFile(filePath);
auto file = QApplication::applicationDirPath()+"/rk_lcd_parameters/"+fdY50Resolu->currentText();
QFile qFile(file);
if(! qFile.exists()) {
QMessageBox::information(this, tr("Tip"), tr("File not exist"));
return;
}
if(! qFile.open(QIODevice::ReadOnly)) {
QMessageBox::information(this, tr("Tip"), tr("Cannot Open File")+": "+qFile.errorString()+"\n"+filePath);
QMessageBox::information(this, tr("Tip"), tr("Cannot Open File")+": "+qFile.errorString()+"\n"+file);
return;
}
auto fileData = qFile.readAll();
@ -738,8 +912,7 @@ 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);
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
ConnReply(reply, waitingDlg) [=] {
QString err = checkReply(reply);
if(! err.isEmpty()) {
waitingDlg->close();
@ -817,7 +990,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
connect(reply, &QNetworkReply::finished, this, [=] {
Def_CtrlSingleGetReply
waitingDlg->success();
setCurrentData(fdDisMode, json["result"].toInt());
SetCurData(fdDisMode, json["result"].toInt());
});
} else {
foreach(auto card, gSelCards) {
@ -924,11 +1097,66 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
btnLedSet->setProperty("ssType", "progManageTool");
connect(btnLedSet, &QPushButton::clicked, btnLedSet, [] {
QFileInfo file("LedSet4.0/LedSet4.0.exe");
if(file.exists()) QProcess::startDetached(file.absoluteFilePath(), QStringList());
if(file.exists()) QProcess::startDetached(file.absoluteFilePath(), QStringList(), file.absolutePath());
});
hBox->addWidget(btnLedSet);
hBox->addStretch();
hBox = new HBox(vBox);
btnReceCardsGet = new QPushButton;
btnReceCardsGet->setProperty("ssType", "progManageTool");
connect(btnReceCardsGet, &QPushButton::clicked, this, [=] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
QJsonObject json;
json.insert("_id", "GetReceCards");
json.insert("_type", "GetReceCards");
if(gSelCards.count() == 1) {
auto waitingDlg = new WaitingDlg(this, btnReceCardsGet->text() + " ...");
Def_CtrlReqPre
connect(reply, &QNetworkReply::finished, this, [=] {
Def_CtrlSingleGetReply
waitingDlg->close();
QMessageBox::information(this, btnReceCardsGet->text(), QString::number(json["receCardNum"].toInt()));
});
} else {
foreach(auto card, gSelCards) {
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
auto cardId = card.id;
connect(reply, &QNetworkReply::finished, this, [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(err.isEmpty()) err = QString::number(json["receCardNum"].toInt());
gFdResInfo->append(cardId+" "+btnReceCardsGet->text()+" "+err);
});
}
}
});
hBox->addWidget(btnReceCardsGet);
// auto btnTool = new QPushButton("本地监控");
// btnTool->setMinimumHeight(30);
// btnTool->setProperty("ssType", "progManageTool");
// connect(btnTool, &QPushButton::clicked, btnTool, [] {
// QFileInfo file("EasyTool/EasyTool.exe");
// if(file.exists()) QProcess::startDetached(file.absoluteFilePath(), QStringList(), file.absolutePath());
// });
// hBox->addWidget(btnTool);
// auto btnVMS = new QPushButton("平台监控");
// btnVMS->setMinimumHeight(30);
// btnVMS->setProperty("ssType", "progManageTool");
// connect(btnVMS, &QPushButton::clicked, btnVMS, [] {
// QFileInfo file("EasyVMS/EasyVMS.exe");
// if(file.exists()) QProcess::startDetached(file.absoluteFilePath(), QStringList(), file.absolutePath());
// });
// hBox->addWidget(btnVMS);
hBox->addStretch();
#ifndef Q_OS_WIN
btnLedSet->setVisible(false);
#endif
@ -973,8 +1201,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
auto waitingDlg = new WaitingDlg(this, tr("InvokeTaxiAppFunction"));
waitingDlg->show();
auto reply = NetReq("http://"+gSelCards[0].ip+":3000").timeout(120000).post(json);
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
ConnReply(reply, waitingDlg) [=] {
QString err = checkReply(reply);
if(! err.isEmpty()) {
waitingDlg->close();
@ -1358,8 +1585,7 @@ 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);
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
ConnReply(reply, waitingDlg) [=] {
QString err = checkReply(reply);
if(! err.isEmpty()) {
waitingDlg->close();
@ -1423,7 +1649,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
QString file = QFileDialog::getOpenFileName(this, tr("Select File"), gFileHome, EPhoto::filters());
auto file = QFileDialog::getOpenFileName(this, tr("Select File"), gFileHome, EPhoto::filters());
if(file.isEmpty()) return;
QFileInfo info(file);
if(! info.isFile()) return;
@ -1560,6 +1786,19 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
fdM80Resolu = new QComboBox;
fdM80Resolu->setMinimumWidth(160);
fdM80Resolu->addItem("480x4096", "550x4500");
fdM80Resolu->addItem("576x3840", "625x3960");
fdM80Resolu->addItem("720x3200", "750x3300");
fdM80Resolu->addItem("864x2672", "900x2750");
fdM80Resolu->addItem("1080x1920", "1125x2200");
fdM80Resolu->addItem("1280x1760", "1320x1850");
fdM80Resolu->addItem("1472x1536", "1500x1650");
fdM80Resolu->addItem("1536x1472", "1650x1500");
fdM80Resolu->addItem("1920x1080", "2200x1125");
fdM80Resolu->addItem("2672x864", "2750x900");
fdM80Resolu->addItem("3200x720", "3300x750");
fdM80Resolu->addItem("3840x576", "3960x625");
fdM80Resolu->addItem("4096x480", "4500x550");
hBox->addWidget(fdM80Resolu);
btnM80Set = new QPushButton();
@ -1653,7 +1892,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
lbRotate = new QLabel;
hBox->addWidget(lbRotate);
hBox->addSpacing(20);
hBox->addSpacing(12);
auto fdDeg0 = new QRadioButton("");
hBox->addWidget(fdDeg0);
@ -1735,6 +1974,42 @@ 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;
@ -1932,10 +2207,54 @@ 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);
@ -1992,7 +2311,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
connect(reply, &QNetworkReply::finished, this, [=] {
Def_CtrlSingleGetReply
waitingDlg->success();
setCurrentData(fdTraficProtocol, json["protocolType"].toInt());
SetCurData(fdTraficProtocol, json["protocolType"].toInt());
});
} else {
foreach(auto card, gSelCards) {
@ -2079,7 +2398,7 @@ CtrlAdvancedPanel::CtrlAdvancedPanel() {
connect(reply, &QNetworkReply::finished, this, [=] {
Def_CtrlSingleGetReply
waitingDlg->success();
setCurrentData(fdServerType, json["serverType"].toInt());
SetCurData(fdServerType, json["serverType"].toInt());
fdPort->setValue(json["port"].toInt());
});
} else {
@ -2106,8 +2425,31 @@ 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();
});
@ -2150,8 +2492,8 @@ void CtrlAdvancedPanel::init() {
vBox->addWidget(btnBox);
connect(btnBox, &QDialogButtonBox::accepted, &dlg, [=, &dlg] {
QString pwdRaw = QSettings().value("advUiPs").toString();
QString password = pwdRaw.isEmpty() ? "888" : QString::fromUtf8(QByteArray::fromBase64(pwdRaw.toLatin1()));
auto pwdVar = QSettings().value("advUiPs");
auto password = pwdVar.isNull() ? "888" : QString::fromUtf8(QByteArray::fromBase64(pwdVar.toString().toLatin1()));
if(fdPassword->text() == password) dlg.accept();
else QMessageBox::critical(&dlg, tr("Tip"),tr("Password is error"));
});
@ -2163,7 +2505,6 @@ void CtrlAdvancedPanel::init() {
bool isSingle = gSelCards.count()==1;
btnApkCheck->setEnabled(isSingle);
btnRestart->setEnabled(isSingle);
btnGetLog->setEnabled(isSingle);
if(! isSingle) {
@ -2178,33 +2519,36 @@ void CtrlAdvancedPanel::init() {
auto isM80 = card.id.startsWith("M8", Qt::CaseInsensitive);
grpM80->setVisible(isM80);
if(isM80) {
QJsonObject json;
json.insert("_id", "GetAllScreenSizeM80");
json.insert("_type", "GetAllScreenSizeM80");
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, this, [this, reply] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
auto sizes = json["result"].toObject();
fdM80Resolu->clear();
auto send = sizes.constEnd();
for(auto size=sizes.constBegin(); 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(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());
// });
// }
auto isY50 = card.id.startsWith("st5", 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);
|| 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);
grpY50->setVisible(isY50);
QJsonObject json;
json.insert("_id", "GetOnlineAddr");
json.insert("_type", "GetOnlineAddr");
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json);
connect(reply, &QNetworkReply::finished, this, [this, reply] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
@ -2216,10 +2560,10 @@ void CtrlAdvancedPanel::init() {
json = QJsonObject();
json.insert("_id", "GetRealtimeServer");
json.insert("_type", "GetRealtimeServer");
reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json);
connect(reply, &QNetworkReply::finished, this, [this, reply] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
auto err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
fdRealtimeServer->setCurrentText(json["server"].toString());
});
@ -2232,6 +2576,7 @@ void CtrlAdvancedPanel::transUi() {
btnBindTaxiIc->setText(tr("Binding *.ic account indentity voucher"));
btnGetTopLevel->setText(tr("Readback"));
btnLedSet->setText(tr("Start LedSet4"));
btnReceCardsGet->setText(tr("Get Receive Card Num"));
grpM80->setTitle("M80 "+tr("Config"));
btnM80Refresh->setText(tr("Refresh"));
@ -2262,6 +2607,7 @@ 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"));
@ -2276,9 +2622,10 @@ 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"));
label->setText(tr("Realtimer Server Address:"));
lbRealtime->setText(tr("Realtime Address:"));
lbTitle->setText(tr("Advanced"));
lbCompanyId->setText(tr("Compant ID:"));
labelWebServer->setText(tr("Web Server Address:"));
@ -2368,22 +2715,11 @@ 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");
resNum = tcp.write(QJsonDocument(req).toJson(QJsonDocument::Compact));
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 'imgFileStart'");
tcp.close();
@ -2425,28 +2761,18 @@ 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 'fileEnd'");
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when write 'imgFileEnd'");
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 'proEnd'");
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when waitForRead 'imgFileEnd'");
tcp.close();
return;
}
auto resp = tcp.readAll();
if(resp.isEmpty()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when read 'proEnd'");
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when read 'imgFileEnd'");
tcp.close();
return;
}

View File

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

View File

@ -1,5 +1,5 @@
#include "ctrlbrightpanel.h"
#include "base/waitingdlg.h"
#include "gutil/qwaitingdlg.h"
#include "gutil/qnetwork.h"
#include "globaldefine.h"
#include "tools.h"
@ -17,16 +17,15 @@
CtrlBrightPanel::CtrlBrightPanel() {
auto vBox = new VBox(this);
vBox->setContentsMargins(0,0,0,0);
vBox->addSpacing(8);
vBox->setContentsMargins(6,6,6,0);
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);
lbTitle = new QLabel;
auto ft = lbTitle->font();
ft.setPixelSize(16);
ft.setBold(true);
lbTitle->setFont(ft);
lbTitle->setAlignment(Qt::AlignCenter);
vBox->addWidget(lbTitle);
vBox->addSpacing(9);
auto hBox = new HBox(vBox);
@ -528,7 +527,7 @@ CtrlBrightPanel::CtrlBrightPanel() {
auto item = findItem(card.id);
if(item) {
item->mCard.bright = bright;
item->setData(DeviceTable_Brightness, 0, QString::number(bright)+"%");
item->setText("brightness", QString::number(bright)+"%");
}
});
} else {
@ -544,7 +543,7 @@ CtrlBrightPanel::CtrlBrightPanel() {
auto item = findItem(card.id);
if(item) {
item->mCard.bright = bright;
item->setData(DeviceTable_Brightness, 0, err);
item->setText("brightness", err);
}
}
gFdResInfo->append(card.id+" "+tr("Brightness")+" "+err);
@ -618,7 +617,6 @@ 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();
@ -719,15 +717,17 @@ CtrlBrightPanel::CtrlBrightPanel() {
hBox->addWidget(btnScheExport);
tableSche = new Table({
tableSche = new TableWidget{
{"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() {
lbBrightCfg->setText(tr("Brightness Configuration"));
lbTitle->setText(tr("Brightness Config"));
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 *lbBrightCfg;
QLabel *lbTitle;
QRadioButton *radioAuto;
QRadioButton *radioManual;
QRadioButton *radioSchedule;
@ -59,7 +59,7 @@ private:
QSlider *fdDefBright;
QPushButton *btnScheImport;
QPushButton *btnScheExport;
Table *tableSche;
TableWidget *tableSche;
QPushButton *btnScheSet;
QPushButton *btnScheGet;
};

View File

@ -3,7 +3,7 @@
#include "gutil/qnetwork.h"
#include "tools.h"
#include "globaldefine.h"
#include "base/waitingdlg.h"
#include "gutil/qwaitingdlg.h"
#include <QMessageBox>
#include <QButtonGroup>
#include <QTimeEdit>
@ -13,16 +13,18 @@
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 line = new QFrame;
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
vBox->addWidget(line);
auto hBox = new QHBoxLayout();
auto hBox = new HBox(vBox);
hBox->addStretch();
fdManual = new QRadioButton;
@ -33,8 +35,6 @@ 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 Table({
tableSche = new TableWidget{
{"start", "", 100},
{"end", "", 100},
{"0", "", 60},
@ -160,9 +160,8 @@ 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));
@ -199,7 +198,7 @@ CtrlHdmiPanel::CtrlHdmiPanel() {
btnScheClear = new QPushButton;
btnScheClear->setMinimumSize(QSize(60, 30));
btnScheClear->setProperty("ssType", "progManageTool");
connect(btnScheClear, &QPushButton::clicked, tableSche, &Table::clearRows);
connect(btnScheClear, &QPushButton::clicked, tableSche, &TableWidget::clearRows);
hBox->addWidget(btnScheClear);
hBox->addStretch();

View File

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

View File

@ -1,5 +1,5 @@
#include "ctrlnetworkpanel.h"
#include "base/waitingdlg.h"
#include "gutil/qwaitingdlg.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, this, [=] {
connect(reply, &QNetworkReply::finished, waitingDlg, [=] {
QString err = checkReplyForJson(reply);
if(! err.isEmpty()) {
waitingDlg->close();
@ -354,8 +354,7 @@ CtrlNetworkPanel::CtrlNetworkPanel() {
return;
}
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json2);
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
ConnReply(reply, waitingDlg) [=] {
Def_CtrlSetReqAfter
});
});

View File

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

View File

@ -34,7 +34,7 @@ private:
QPushButton *pushButtonImport;
QPushButton *pushButtonExport;
QLabel *labelPowerScheduleTip;
Table *tableSche;
TableWidget *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 "base/waitingdlg.h"
#include "gutil/qwaitingdlg.h"
#include "QFileDialog"
#include <QMessageBox>
#include <QJsonObject>
@ -12,7 +12,13 @@
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 "base/waitingdlg.h"
#include "gutil/qwaitingdlg.h"
#include <QFileDialog>
#include <QLineEdit>
#include <QJsonObject>
@ -177,9 +177,9 @@ CtrlTestPanel::CtrlTestPanel() {
hhh = new HBox(vv);
hhh->addStretch();
pushButtonStopTest = new QPushButton;
pushButtonStopTest->setMinimumSize(QSize(60, 30));
hhh->addWidget(pushButtonStopTest);
btnStopTest = new QPushButton;
btnStopTest->setMinimumSize(QSize(60, 30));
hhh->addWidget(btnStopTest);
hhh->addStretch();
vv->addStretch();
@ -192,14 +192,12 @@ CtrlTestPanel::CtrlTestPanel() {
vv = new VBox(hBox);
lineEdit = new QLineEdit;
lineEdit->setMinimumSize(QSize(0, 36));
lineEdit->setMaximumSize(QSize(194, 16777215));
lineEdit->setAutoFillBackground(false);
lineEdit->setStyleSheet(QString::fromUtf8("color: rgb(0, 255, 0);\n"
"background-color: rgb(0, 0, 0);"));
lineEdit->setAlignment(Qt::AlignCenter);
vv->addWidget(lineEdit);
fdAnycast = new QLineEdit;
fdAnycast->setValidator(new QIntValidator(0, 100, this));
fdAnycast->setMinimumHeight(36);
fdAnycast->setStyleSheet("color: #0f0; background: #000;");
fdAnycast->setAlignment(Qt::AlignCenter);
vv->addWidget(fdAnycast);
auto gridLayout = new Grid(vv);
@ -221,20 +219,47 @@ CtrlTestPanel::CtrlTestPanel() {
gridLayout->addWidget(btngrp->button(9), 2, 2);
gridLayout->addWidget(btngrp->button(0), 3, 0);
connect(btngrp, &QButtonGroup::idClicked, this, [=](int id) {
if(lineEdit->text().contains("-")) lineEdit->clear();
lineEdit->setText(lineEdit->text() + QString::number(id));
if(fdAnycast->text().contains("-")) fdAnycast->clear();
fdAnycast->setText(fdAnycast->text() + QString::number(id));
btnAnycast->setEnabled(true);
});
pushButton_11 = new QPushButton;
pushButton_11->setFixedSize(QSize(60, 30));
gridLayout->addWidget(pushButton_11, 3, 1, 1, 1);
btnAnycastClear = new QPushButton;
btnAnycastClear->setFixedSize(60, 30);
btnAnycastClear->setProperty("ssType", "progManageTool");
connect(btnAnycastClear, &QPushButton::clicked, this, [=] {
fdAnycast->clear();
btnAnycast->setEnabled(false);
});
gridLayout->addWidget(btnAnycastClear, 3, 1, 1, 1);
pushButton_12 = new QPushButton;
pushButton_12->setFixedSize(QSize(60, 30));
gridLayout->addWidget(pushButton_12, 3, 2, 1, 1);
btnAnycastReset = new QPushButton;
btnAnycastReset->setFixedSize(60, 30);
btnAnycastReset->setProperty("ssType", "progManageTool");
connect(btnAnycastReset, &QPushButton::clicked, this, [=] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
SendAnycastCmd(0);
fdAnycast->setText("- "+tr("Loop Mode")+" -");
btnAnycast->setEnabled(false);
});
gridLayout->addWidget(btnAnycastReset, 3, 2, 1, 1);
btnAnycast = new QPushButton;
btnAnycast->setEnabled(false);
btnAnycast->setMinimumHeight(36);
btnAnycast->setProperty("ssType", "progManageTool");
connect(btnAnycast, &QPushButton::clicked, this, [=] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
SendAnycastCmd(fdAnycast->text().toInt());
fdAnycast->setText(tr("Anycast")+" - "+fdAnycast->text());
btnAnycast->setEnabled(false);
});
vv->addWidget(btnAnycast);
vv->addStretch();
@ -244,10 +269,7 @@ CtrlTestPanel::CtrlTestPanel() {
pushButtonStartLine->setProperty("ssType", "progManageTool");
pushButtonStartGray->setProperty("ssType", "progManageTool");
pushButtonStartColor->setProperty("ssType", "progManageTool");
pushButtonStopTest->setProperty("ssType", "progManageTool");
pushButton_11->setProperty("ssType", "progManageTool");
pushButton_12->setProperty("ssType", "progManageTool");
btnAnycast->setProperty("ssType", "progManageTool");
btnStopTest->setProperty("ssType", "progManageTool");
spinBoxLineSpeed->setValue(10);
spinBoxLineDistance->setValue(15);
@ -371,7 +393,7 @@ CtrlTestPanel::CtrlTestPanel() {
}
}
});
connect(pushButtonStopTest, &QPushButton::clicked, this, [this] {
connect(btnStopTest, &QPushButton::clicked, this, [this] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
@ -392,38 +414,6 @@ CtrlTestPanel::CtrlTestPanel() {
}
}
});
connect(pushButton_11, &QPushButton::clicked, this, [=] {
lineEdit->clear();
btnAnycast->setEnabled(false);
});
connect(pushButton_12, &QPushButton::clicked, this, [=] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
int iIndex = lineEdit->text().toInt();
if(gSelCards.count()==1) SendAnycastCmd(gSelCards[0], 0, true);
else {
foreach(auto card, gSelCards) SendAnycastCmd(card, iIndex, false);
}
lineEdit->setText("-"+tr("loopback mode")+"-");
btnAnycast->setEnabled(false);
});
connect(btnAnycast, &QPushButton::clicked, this, [=] {
if(gSelCards.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
return;
}
int iIndex = lineEdit->text().toInt();
if(gSelCards.count()==1) SendAnycastCmd(gSelCards[0], iIndex, true);
else foreach(auto card, gSelCards) SendAnycastCmd(card, iIndex, false);
lineEdit->setText(tr("Anycast")+" - "+lineEdit->text());
btnAnycast->setEnabled(false);
});
btnAnycast->setEnabled(false);
lineEdit->setValidator(new QIntValidator(0, 100, this));
transUi();
}
@ -467,43 +457,74 @@ void CtrlTestPanel::transUi() {
radioButton_Green->setText(tr("Green"));
radioButton_Blue->setText(tr("Blue"));
radioButton_White->setText(tr("White"));
pushButtonStopTest->setText(tr("Stop"));
pushButton_11->setText(tr("Clear"));
pushButton_12->setText(tr("Reset"));
btnStopTest->setText(tr("Stop"));
btnAnycastClear->setText(tr("Clear"));
btnAnycastReset->setText(tr("Reset"));
btnAnycast->setText(tr("Anycast"));
}
void CtrlTestPanel::SendAnycastCmd(LedCard card, int iProgramIndex, bool isSingle) {
QTcpSocket *send = new QTcpSocket();
connect(send, SIGNAL(connected()), this, SLOT(connect_sucessful()));
connect(send, SIGNAL(error(QAbstractSocket::SocketError)),this, SLOT(show_error(QAbstractSocket::SocketError)));
send->connectToHost(QHostAddress(card.ip),31299);
void CtrlTestPanel::SendAnycastCmd(int progIdx) {
ST_ANSY_PROGRAM_PACKET tempStreadPakcet;
tempStreadPakcet.ucCommType=0x97;
tempStreadPakcet.iBaoLiu=0;
tempStreadPakcet.iLength=4;
unsigned char uctemp[4]={0};
uctemp[0]=iProgramIndex;
memcpy(tempStreadPakcet.pDataBuffer,uctemp,4);
tempStreadPakcet.pDataBuffer[tempStreadPakcet.iLength]=GetCheckCodeIn8(&tempStreadPakcet.ucCommType,tempStreadPakcet.iLength+sizeof(tempStreadPakcet.iBaoLiu)+sizeof(tempStreadPakcet.ucCommType)+sizeof(tempStreadPakcet.iLength));
int iLenPacket=3*sizeof(unsigned char)+sizeof(char)+sizeof(int)+sizeof(int)+tempStreadPakcet.iLength+sizeof(char);/////除正文外的协议结构大小;
QByteArray databuf = QByteArray(reinterpret_cast<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;
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);
}
}
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,7 +1,6 @@
#ifndef CTRLTESTPANEL_H
#define CTRLTESTPANEL_H
#include "globaldefine.h"
#include <QScrollArea>
#include <QGroupBox>
#include <QRadioButton>
@ -20,7 +19,7 @@ protected:
signals:
void sigSend(QJsonObject &,QString);
private:
void SendAnycastCmd(LedCard, int, bool);
void SendAnycastCmd(int);
QLabel *labelTestScreen;
QGroupBox *groupBox;
@ -58,10 +57,10 @@ private:
QRadioButton *radioButton_Blue;
QRadioButton *radioButton_White;
QPushButton *pushButtonStartColor;
QPushButton *pushButtonStopTest;
QLineEdit *lineEdit;
QPushButton *pushButton_11;
QPushButton *pushButton_12;
QPushButton *btnStopTest;
QLineEdit *fdAnycast;
QPushButton *btnAnycastClear;
QPushButton *btnAnycastReset;
QPushButton *btnAnycast;
};

View File

@ -1,5 +1,5 @@
#include "ctrlverifyclockpanel.h"
#include "base/waitingdlg.h"
#include "gutil/qwaitingdlg.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 "base/waitingdlg.h"
#include "gutil/qwaitingdlg.h"
#include "gutil/qnetwork.h"
#include "tools.h"
#include <QMessageBox>
@ -11,10 +11,16 @@
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();
@ -180,7 +186,6 @@ 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;
@ -234,7 +239,7 @@ CtrlVolumePanel::CtrlVolumePanel() {
});
hBox->addWidget(btnScheExport);
tableSche = new Table({
tableSche = new TableWidget{
{"vol", "", 300},
{"start", "", 100},
{"end", "", 100},
@ -245,9 +250,10 @@ 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;
Table *tableSche;
TableWidget *tableSche;
QPushButton *btnScheSet;
QPushButton *btnScheGet;
};

View File

@ -2,7 +2,7 @@
#include "gutil/qcore.h"
#include "gutil/qgui.h"
#include "gutil/qnetwork.h"
#include "base/waitingdlg.h"
#include "gutil/qwaitingdlg.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 QLabel;
fdFileName->setMinimumSize(200, 30);
fdFileName->setStyleSheet("background-color: #fff;");
auto fdFileName = new QLineEdit;
fdFileName->setReadOnly(true);
fdFileName->setMinimumWidth(200);
hBox->addWidget(fdFileName);
connect(btnSelectApk, &QPushButton::clicked, this, [=] {
filePath = QFileDialog::getOpenFileName(this, "Open file", QString(), "apk package (*.apk *.zip)");
if(filePath.isEmpty()) return;
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());
fileId = "";
fdFileName->setText(QFileInfo(filePath).fileName());
});
connect(btnSelectFpga, &QPushButton::clicked, this, [=] {
filePath = QFileDialog::getOpenFileName(this, "Open File", QString(), "rpd package (*.rpd)");
if(filePath.isEmpty()) return;
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());
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("");
connect(reply, &QNetworkReply::finished, this, [=] {
QJsonDocument json;
ConnReply(reply, this) [=] {
JValue 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.isEmpty()) {
if(files.empty()) {
QMessageBox::critical(this, "Error", tr("No Files"));
return;
}
@ -87,23 +87,24 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
auto vBox = new VBox(&dlg);
vBox->setContentsMargins(0,0,0,0);
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());
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());
}
connect(table, &Table::cellDoubleClicked, &dlg, [=, &dlg](int row) {
fdFileName->setText(table->text(row, "name"));
fileId = table->data(row, 0).toString();
connect(table, &TreeWidget::itemDoubleClicked, &dlg, [=, &dlg](QTreeWidgetItem *itm) {
auto item = (TreeWidgetItem*) itm;
fdFileName->setText(item->text("name"));
fileId = item->data(0).toString();
filePath = "";
dlg.accept();
});
@ -113,14 +114,13 @@ 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 sels = table->selectedRanges();
if(sels.isEmpty()) {
auto item = table->selectedItem();
if(item==0) {
QMessageBox::warning(&dlg, "Warning", tr("Please select a file"));
return;
}
auto row = sels[0].topRow();
fdFileName->setText(table->text(row, "name"));
fileId = table->data(row, 0).toString();
fdFileName->setText(item->text("name"));
fileId = item->data(0).toString();
filePath = "";
dlg.accept();
});
@ -130,25 +130,16 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
});
});
auto btnUpgread = new QPushButton(tr("Upgrade"));
btnUpgread->setMinimumSize(QSize(80, 30));
btnUpgread->setProperty("ssType", "progManageTool");
connect(btnUpgread, &QPushButton::clicked, this, [=] {
auto btnUpdate = new QPushButton(tr("Upgrade"));
connect(btnUpdate, &QPushButton::clicked, this, [=] {
auto fileName = fdFileName->text();
if(fileName.length() < 3) return;
int cnt = table->topLevelItemCount();
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);
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);
}
if(items.isEmpty()) {
QMessageBox::information(this, tr("Tip"), tr("NoSelectedController"));
@ -161,17 +152,19 @@ 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(120000).get();
QEventLoop loop;
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
auto reply = NetReq("https://www.ledokcloud.com/aips4/sys/file/download/"+fileId).timeout(60000).get();
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)+" %");
});
loop.exec(QEventLoop::ExcludeUserInputEvents);
if(waitFinished(reply, waitingDlg)) return;
waitingDlg->close();
auto err = errStr(reply);
fileData = reply->readAll();
@ -184,6 +177,9 @@ 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);
@ -192,25 +188,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);
foreach(auto item, items) {
item->setResult(tr("Uploading")+" ...");
item->mProgress->setValue(0);
for(auto item : items) {
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) {
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) {
if(bytesTotal==0) return;
item->mProgress->setValue(bytesSent*100/bytesTotal);
item->fdProgress->setValue(bytesSent*100/bytesTotal);
});
connect(reply, &QNetworkReply::finished, item->mProgress, [=] {
QString err = errStrWithData(reply);
ConnReply(reply, item) [=] {
auto err = errStrWithData(reply);
if(! err.isEmpty()) {
item->setResult(tr("Upload error")+": "+err, Qt::red);
item->isUpdating = false;
return;
}
item->mProgress->setValue(100);
auto info = tr("Installing")+" ...";
item->fdProgress->setValue(100);
auto info = tr("Upgrading")+" ...";
QJsonObject json;
if(isApk) {
json.insert("_id", "UpgradeSoftware");
@ -218,33 +214,40 @@ 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->mCard.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, item->mProgress, [=] {
item->isUpdating = false;
QString err = errStrWithData(reply);
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);
if(! err.isEmpty()) {
item->isUpdating = false;
item->setResult(tr("Install error")+": "+err, Qt::red);
return;
}
item->setResult(tr("Install success"), Qt::darkGreen);
if(isApk) item->OnCheckSoftVersions();
else item->OnCheckFpgaVersions();
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);
}
});
});
}
});
hBox->addWidget(btnUpgread);
hBox->addWidget(btnUpdate);
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");
@ -258,8 +261,6 @@ 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()) {
@ -268,15 +269,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->topLevelItem(i)->checkState(0) == Qt::Checked) {
auto item = static_cast<wUpgradeApkItem *>(table->topLevelItem(i));
for(int i=0; i<cnt; i++) if(table->item(i)->checkState("id") == Qt::Checked) {
auto item = (UpdateApkItem *) 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->mCard.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, this, [reply, item, strApkName] {
auto reply = NetReq("http://"+item->text("ip")+":2016/settings").timeout(60000).post(json);
ConnReply(reply, item) [reply, item, strApkName] {
QString err = checkReplyForJson(reply, "error");
if(! err.isEmpty()) {
item->setResult(tr("Uninstall error")+": "+err, Qt::red);
@ -289,22 +290,20 @@ 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->topLevelItem(i)->checkState(0) == Qt::Checked) {
auto item = static_cast<wUpgradeApkItem *>(table->topLevelItem(i));
for(int i=0; i<cnt; i++) if(table->item(i)->checkState("id") == Qt::Checked) {
auto item = (UpdateApkItem *) 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->mCard.ip+":2016/settings").timeout(120000).post(json);
connect(reply, &QNetworkReply::finished, this, [reply, item, strApkName] {
auto reply = NetReq("http://"+item->text("ip")+":2016/settings").timeout(60000).post(json);
ConnReply(reply, item) [reply, item, strApkName] {
QJsonDocument json;
QString err = errStrWithData(reply, &json);
auto err = errStrWithData(reply, &json);
if(! err.isEmpty()) {
item->setResult(tr("Check error")+": "+err, Qt::red);
return;
@ -324,323 +323,258 @@ UpgradeApkDialog::UpgradeApkDialog(QWidget *parent) : QDialog(parent) {
hBox->addStretch();
auto btnRefresh = new QPushButton(tr("Refresh"));
btnRefresh->setMinimumSize(QSize(0, 30));
btnRefresh->setProperty("ssType", "progManageTool");
connect(btnRefresh, &QPushButton::clicked, this, [this, label] {
connect(btnRefresh, &QPushButton::clicked, this, [=] {
table->clear();
table->onCheckAll(false);
table->fdCheckAll->setCheckState(Qt::Unchecked);
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));
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));
});
hBox->addWidget(btnRefresh);
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);
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);
table = new LoQTreeWidget();
table->setProperty("ssType", "topList");
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);
vBox->addWidget(table);
hBox = new HBox(vBox);
hBox->addStretch();
auto sortField = gDevicePanel->mDeviceTable->sortField();
if(sortField=="id" || sortField=="ip" || sortField=="alias") table->sortItems(sortField, gDevicePanel->mDeviceTable->header()->sortIndicatorOrder());
else table->sortItems("id");
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);
setAttribute(Qt::WA_DeleteOnClose);
setModal(true);
show();
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;
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);
}
}
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 {
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); //隐藏不匹配的结果
}
}
}
}
}
}
}
}
}
}
}
}
}
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;
}
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,25 +1,40 @@
#ifndef UPGRADEAPKDIALOG_H
#define UPGRADEAPKDIALOG_H
#include "base/loqtreewidget.h"
#include <QDialog>
#include <QTreeWidgetItem>
#include "wupgradeapkitem.h"
#include <QProgressBar>
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;
QTreeWidgetItem *m_headerItem=nullptr;
};
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;
};
#endif // UpgradeApkDialog_H

View File

@ -1,143 +0,0 @@
#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

@ -1,55 +0,0 @@
#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,6 +1,7 @@
#include "deviceitem.h"
#include "devicepanel.h"
#include "globaldefine.h"
#include "base/waitingdlg.h"
#include "gutil/qwaitingdlg.h"
#include "gutil/qgui.h"
#include "gutil/qnetwork.h"
#include <QMessageBox>
@ -8,86 +9,73 @@
#include <QInputDialog>
#include <QJsonObject>
DeviceItem::DeviceItem(LoQTreeWidget *parent) : QObject(parent), QTreeWidgetItem(UserType), m_parent(parent) {
setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
setCheckState(0, Qt::Unchecked);
m_parent->addTopLevelItem(this);
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);
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] {
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, [=] {
QJsonObject json;
json.insert("_id", "GetScreenshotFull");
json.insert("_type", "GetScreenshotFull");
auto waitingDlg = new WaitingDlg(treeWidget(), tr("GetScreenshotFull")+" ...");
auto waitingDlg = new WaitingDlg(btnGetCapture, DevicePanel::tr("Getting ")+DevicePanel::tr("Screenshot")+" ...");
waitingDlg->show();
auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json);
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
ConnReply(reply, waitingDlg) [=] {
waitingDlg->close();
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
QMessageBox::critical(treeWidget(), tr("Error"), err);
QMessageBox::critical(treeWidget(), DevicePanel::tr("Error"), err);
return;
}
ImgDlg dlg(QByteArray::fromBase64(json["data"].toString().toLatin1()), treeWidget());
dlg.exec();
});
});
m_parent->setItemWidget(this, DeviceTable_Screenshot, m_bnReadbackPic);
setCellWidget("screenshot", btnGetCapture);
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);
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);
btnUnlock = new QPushButton;
btnUnlock->setMaximumHeight(40);
connect(btnUnlock, &QPushButton::clicked, this, [this] {
QObject::connect(btnUnlock, &QPushButton::clicked, btnUnlock, [this] {
if(! mCard.isLocked) return;
bool ok;
auto pwd = QInputDialog::getText(treeWidget(), tr("Input password"), tr("Input password"), QLineEdit::Password, QString(), &ok);
auto pwd = QInputDialog::getText(treeWidget(), DevicePanel::tr("Input password"), DevicePanel::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(), tr("VerifyPassword")+" ...");
auto waitingDlg = new WaitingDlg(btnUnlock, DevicePanel::tr("VerifyPassword")+" ...");
waitingDlg->show();
auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(60000).post(json);
waitingDlg->connAbort(reply);
connect(reply, &QNetworkReply::finished, this, [=] {
ConnReply(reply, waitingDlg) [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) {
waitingDlg->close();
QMessageBox::critical(treeWidget(), tr("Error"), err);
QMessageBox::critical(treeWidget(), DevicePanel::tr("Error"), err);
return;
}
if(! json["result"].toBool()) {
waitingDlg->close();
QMessageBox::critical(treeWidget(), tr("Tip Info"), tr("password is wrong"));
QMessageBox::critical(treeWidget(), DevicePanel::tr("Tip Info"), DevicePanel::tr("password is wrong"));
return;
}
waitingDlg->success();
@ -95,122 +83,17 @@ QPushButton:hover{background-color: #ccc;}
btnUnlock->setIcon(QIcon(":/res/UnLock.png"));
});
});
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);
}
wgt = new QWidget;
hhh = new HBox(wgt);
hhh->setContentsMargins(0,0,0,0);
hhh->addWidget(btnUnlock);
setCellWidget("password", wgt);
}
void DeviceItem::init() {
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));
setText("id", mCard.id);
setText("ip", mCard.ip);
setText("screenSize", 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,49 +1,18 @@
#ifndef DEVICEITEM_H
#define DEVICEITEM_H
#include <QPushButton>
#include <base/loqtreewidget.h>
#include "base/loqtreewidget.h"
#include "globaldefine.h"
#include <QLabel>
#include <QDialog>
#include <QPushButton>
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
class DeviceItem : public TreeWidgetItem, public QObject {
public:
explicit DeviceItem(LoQTreeWidget *parent);
explicit DeviceItem(LoQTreeWidget *);
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;
QLabel *fdOnline;
QPushButton *btnUnlock = 0;
};
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,6 +19,7 @@
#include <QJsonArray>
#include <QStyledItemDelegate>
#include <QToolButton>
#include <QPainter>
DevicePanel *gDevicePanel;
QTextEdit *gFdResInfo;
@ -57,21 +58,27 @@ 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, [this](const QString &search) {
connect(fdSearch, &QLineEdit::textChanged, this, [=](const QString &text) {
auto cnt = mDeviceTable->topLevelItemCount();
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)));
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();
}
});
hBox->addWidget(fdSearch);
@ -116,8 +123,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();
});
@ -132,48 +139,37 @@ QPushButton:hover {background-color: #08b;}
hBox->addWidget(areaFlash);
mHBox = new QHBoxLayout();
mHBox = new HBox(vBox);
mDeviceTable = new LoQTreeWidget(this);
mDeviceTable->setSelectionMode(QAbstractItemView::NoSelection);
mDeviceTable->setIndentation(0);
mDeviceTable->setSortingEnabled(true);
mHBox->addWidget(mDeviceTable);
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);
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, [=] {
table->hideColumn("check");
table->fdCheckAll->hide();
table->sortItems("id", Qt::AscendingOrder);
connect(table, &LoQTreeWidget::selChanged, table, [=] {
gSelCards.clear();
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);
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);
emit sigSelectedDeviceList();
});
mDeviceTable->hideColumn(0);
mDeviceTable->fdIsSelAll->hide();
mDeviceTable->sortItems(DeviceTable_ID, Qt::AscendingOrder);
mHBox->addWidget(mDeviceTable = table);
connect(&mUdpTimer, &QTimer::timeout, this, &DevicePanel::sendGetInfo);
connect(&mUdpSocket, &QUdpSocket::readyRead, this, [this] {
@ -218,54 +214,58 @@ QPushButton:hover {background-color: #08b;}
item->mCard.id = packet->serialCode;
item->mCard.ip = addr;
}
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());
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);
return;
}
}
msgBox.setText(msgpre + tr("Player Version")+":");
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.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);
}
init(item);
nDeviceNum->setText(QString::number(mDeviceTable->topLevelItemCount()));
// {
// QJsonObject json;
// json.insert("_id", "SyncTime");
// json.insert("_type", "SyncTime");
// json.insert("time", QDateTime::currentDateTime().toMSecsSinceEpoch());
// auto reply = NetReq("http://"+item->mCard.ip+":2016/settings").timeout(60000).post(json);
// connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
// }
end:;
}
});
@ -291,7 +291,7 @@ QPushButton:hover {background-color: #08b;}
hBox->addStretch();
auto bnSearch = new QPushButton(tr("Search"));
connect(bnSearch, &QPushButton::clicked, this, [this] {
connect(bnSearch, &QPushButton::clicked, fdIP, [this] {
QString ipsStr = fdIP->toPlainText();
if(ipsStr.isEmpty()) {
QMessageBox::warning(this, tr("Attention"), tr("Please input IP address!"));
@ -359,21 +359,20 @@ void DevicePanel::transUi() {
bnSpecifyIP->setItemText(0,tr("Specify IP"));
label_3->setText(tr("All"));
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"));
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"));
auto cnt = mDeviceTable->topLevelItemCount();
for(int i=0; i<cnt; i++) {
auto item = (DeviceItem*) mDeviceTable->topLevelItem(i);
item->setData(DeviceTable_Power, 0, item->mCard.isScreenOn ? tr("On") : tr("Off"));
auto item = (DeviceItem*) mDeviceTable->item(i);
item->setText("power", item->mCard.isScreenOn ? tr("On") : tr("Off"));
}
transCtrl();
}
@ -452,15 +451,18 @@ 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();
fdInfo = new QTextEdit;
auto ft = fdInfo->font();
ft.setFamily("Consolas");
fdInfo->setFont(ft);
gFdResInfo = fdInfo;
fdInfo->setReadOnly(true);
fdInfo->setMaximumWidth(360);
@ -479,7 +481,7 @@ void DevicePanel::newCtrl() {
fdInfo->hide();
btnClear->hide();
connect(this, &DevicePanel::sigSelectedDeviceList, this, [this] {
connect(this, &DevicePanel::sigSelectedDeviceList, fdInfo, [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"));
@ -497,3 +499,118 @@ 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 <QLabel>
#include "gutil/qgui.h"
#include <QTimer>
#include <QPushButton>
#include <QUdpSocket>
@ -12,7 +12,6 @@
#include <QTextEdit>
#include <QScrollArea>
#include <QSettings>
#include <QHBoxLayout>
class DevicePanel : public QWidget {
Q_OBJECT
@ -22,6 +21,7 @@ public:
void sendGetInfo();
void newCtrl();
void init(DeviceItem *item);
QLabel *fdCardNumInfo;
LoQTreeWidget *mDeviceTable;
@ -34,8 +34,7 @@ public:
QLabel *label_3, *nDeviceNum;
QComboBox *bnSpecifyIP;
QPushButton *btnRefresh;
QTreeWidgetItem *m_headerItem;
QHBoxLayout *mHBox{0};
HBox *mHBox{0};
QTextEdit *fdInfo;
QButtonGroup *mBtnGrp;
@ -51,6 +50,15 @@ 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==nullptr) {
if(sinkWriter==0) {
au.idx = -1;
qCritical()<<"Couldn't Start Audio Output"<<sink->error();
} else {
const AVCodec *decoder = avcodec_find_decoder(codecpar->codec_id);
if(decoder==nullptr) {
if(decoder==0) {
au.idx = -1;
qWarning()<<"Couldn't found Audio Decoder";
} else {
au.ctx = avcodec_alloc_context3(decoder);
avcodec_parameters_to_context(au.ctx, codecpar);
if(avcodec_open2(au.ctx, decoder, nullptr) < 0) {
if(avcodec_open2(au.ctx, decoder, 0) < 0) {
au.idx = -1;
qWarning()<<"Couldn't open aCodecCtx";
} else {
@ -171,18 +171,18 @@ AVFmt::AVFmt(QByteArray url) {
if(vi.idx > -1) vi.thd = new thread(&AVFmt::mainViDecode, this);
}
AVFmt::~AVFmt() {
if(read_thd!=nullptr) {
acts.lockAddNtf(new Act{0, nullptr, 'Q'});
if(read_thd) {
acts.lockAddNtf(new Act{0, 0, 'Q'});
read_thd->join();
delete read_thd;
qInfo() << "~ read thread";
}
if(au.thd!=nullptr) {
if(au.thd) {
au.thd->join();
delete au.thd;
qInfo() << "~ au thread";
}
if(vi.thd!=nullptr) {
if(vi.thd) {
vi.thd->join();
delete vi.thd;
qInfo() << "~ vi thread";
@ -199,7 +199,7 @@ void AVFmt::mainRead() {
int res = 0;
while(true) {
auto act = wait==0 ? acts.lockPoll() : acts.take(wait);
while(act!=nullptr) {
while(act) {
if(act->act=='S') {
if(au.idx!=-1) {
unique_lock<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==nullptr) {
if(node==0) {
throw std::invalid_argument("node is null");
return;
}
if(last!=nullptr) last->next = node;
if(last) last->next = node;
else first = node;
last = node;
size++;
}
void remove() {
if(first==nullptr) return;
if(first==last) first = last = nullptr;
if(first==0) return;
if(first==last) first = last = 0;
else first = first->next;
size--;
}
@ -54,7 +54,7 @@ public:
return first;
}
void delAll() {
while(first!=nullptr) delete poll();
while(first) delete poll();
}
T *volatile first{0};
@ -154,7 +154,6 @@ public:
avcodec_free_context(&ctx);
}
};
class FFPlayer;
class AVFmt {
friend class FFPlayer;
public:

View File

@ -11,12 +11,13 @@
QString gFileHome;
QString gApkHome;
QList<LedCard> gSelCards;
bool gVideoCompress = true;
bool gVideoTranscoding = true;
bool gVideoCompress = false;
bool gVideoTranscoding = false;
bool gTextAntialiasing = false;
bool gWidthSplit = false;
int gSendBatch = 5;
bool gHideDetect = false;
bool gShowAlias = false;
bool gShowLora = false;
DeviceItem *findItem(QString id) {
@ -44,6 +45,21 @@ 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,20 +1,22 @@
#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};
@ -51,6 +53,7 @@ extern bool gTextAntialiasing;
extern bool gWidthSplit;
extern int gSendBatch;
extern bool gHideDetect;
extern bool gShowAlias;
extern bool gShowLora;
extern quint64 dirFileSize(const QString &path);
@ -86,6 +89,7 @@ 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);
@ -93,7 +97,7 @@ QString checkReplyForJson(QNetworkReply *, QString errField);
waitingDlg->show();\
auto card = gSelCards[0];\
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);\
waitingDlg->connAbort(reply);
connect(waitingDlg, &WaitingDlg::rejected, reply, &QNetworkReply::deleteLater);
#define Def_CtrlSetReqAfter \
QString err = checkReplyForJson(reply);\

View File

@ -2,19 +2,18 @@
#define CPP_H
#include <chrono>
#include <memory>
#include <unordered_map>
inline long long steady_milli() {
inline int64_t steady_milli() {
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}
inline long long system_milli() {
inline int64_t system_milli() {
return std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}
inline long long steady_micro() {
inline int64_t steady_micro() {
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
}
inline long long system_micro() {
inline int64_t system_micro() {
return std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}
@ -47,7 +46,7 @@ public:
}
SharedPtr &operator=(SharedPtr &&other) noexcept {
auto aaa = ptr;
ptr = other._pri;
ptr = other.ptr;
other.ptr = aaa;
return *this;
}
@ -195,7 +194,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;
@ -269,6 +268,20 @@ 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"};
const char *units[]{"B", "KB", "MB", "GB", "TB", "PB", "EB"};
auto i = 0;
for(; size >= 1024 && i < 5; i++) size /= 1024;
return QString::number(size, 'g', 3)+" "+units[i];
for(; size >= 1024 && i < 7; i++) size /= 1024;
return (size > 99 ? QString::number(size, 'f', 0) : QString::number(size, 'g', 3))+" "+units[i];
}
inline void wait(int msec, QEventLoop::ProcessEventsFlags flags = QEventLoop::AllEvents) {

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 = fdmap.size();
int i = (int) fdmap.size();
auto item = headerItem();
item->setText(i, text);
item->setData(i, FieldRole, field);
@ -36,12 +36,13 @@ 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);
}
@ -106,8 +107,40 @@ bool TreeWidget::adjSections(int index, int size) {
class TreeItemMarginStyle : public QProxyStyle {
public:
using QProxyStyle::QProxyStyle;
TreeItemMarginStyle(QWidget *wgt) : QProxyStyle(wgt->style()), _wgt(wgt) {}
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
QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const override {
auto res = QProxyStyle::subElementRect(element, option, widget);
auto width = res.width();
@ -125,9 +158,11 @@ public:
}
}
} else if(((QStyleOptionViewItem*)option)->features & QStyleOptionViewItem::HasCheckIndicator) {
auto add = ((TreeWidget*)widget)->headerItem()->data(((QStyleOptionViewItem*)option)->index.column(), MarginRole).toInt();
auto index = ((QStyleOptionViewItem*)option)->index;
auto add = ((TreeWidget*)widget)->headerItem()->data(index.column(), MarginRole).toInt();
if(add) {
add += add>>1;
if(width < (add+3)<<1) add = width;
else add += add>>1;
res.setLeft(res.x() + add);
if(width < add) res.setWidth(0);
}
@ -140,7 +175,8 @@ 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;
}
QWidget *_wgt = 0;
#endif
TreeWidget *_wgt = 0;
};
ColItem &ColItem::margin(int margin) {
@ -179,12 +215,13 @@ 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) {
QLabel *addLabel(const QString& text, int row, int column, Qt::Alignment align = Qt::Alignment()) {
auto lb = new QLabel(text);
addWidget(lb);
addWidget(lb, row, column, align);
return lb;
}
};
@ -274,6 +274,7 @@ public:
int sizeHintForColumn(int column) const override {
return QTreeWidget::sizeHintForColumn(column);
}
bool adjSections(int index, int size);
signals:
void updGeos();
protected:
@ -285,7 +286,6 @@ 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 0;
if((size_t)&table==0) return -1;
return ((TreeWidget&)table).fdmap.at(key);
}
inline int operator*(const char *key, QTreeView &table) {
if((size_t)&table==0) return 0;
if((size_t)&table==0) return -1;
return ((TreeWidget&)table).fdmap.at(key);
}

View File

@ -8,11 +8,6 @@ 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;
@ -21,15 +16,15 @@ JValue JParser::readValue() {
while(ch==',');
if(ch=='}') return obj;
QString key;
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";
if(ch=='"') key = readStr();
else if(ch!='n' || readOne()!='u' || readOne()!='l' || readOne()!='l') throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting double-quote to start field name or null";
skipSpace();
if(ch != ':') throw QString("Unexpected char ")+ch+" (code "+ch+"): was expecting a colon to separate field name and value";
if(ch!=':') throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting a colon to separate field name and value";
skipSpace();
obj.insert(key, readValue());
skipSpace(); //ch有两种可能
if(ch=='}') return obj;
if(ch!=',') throw QString("Unexpected char ")+ch+"' (code "+ch+"): was expecting } to end Object or comma to separate Object entries";
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=='[') {
@ -41,15 +36,15 @@ JValue JParser::readValue() {
list->push_back(readValue());
skipSpace(); //ch有两种可能
if(ch==']') return list;
if(ch!=',') throw QString("Unexpected char ")+ch+" (code "+ch+"): was expecting ] to end Array or comma to separate Array entries";
if(ch!=',') throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting ] to end Array or comma to separate Array entries";
}
}
if(ch=='"') return readStr();
if((ch>='0' && ch<='9') || ch=='-') {
QString buf;
QByteArray buf;
buf += ch;
bool isInt = true;
while(0 != (ch = readOne(in))) {
while(readOne()) {
if((ch>'*' && ch<':' && ch!=',' && ch!='/') || ch=='e' || ch=='E') {
buf.append(ch);
if(isInt && ch=='.') isInt = false;
@ -70,26 +65,34 @@ JValue JParser::readValue() {
}
}
if(ch=='n') {
if(in.read(3)=="ull") return JValue();
else throw "Unexpected char n: expected null";
if(readOne()=='u' && readOne()=='l' && readOne()=='l') return JValue();
else throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting null";
}
if(ch=='t') {
if(in.read(3)=="rue") return true;
else throw "Unexpected char t: expected true";
if(readOne()=='r' && readOne()=='u' && readOne()=='e') return true;
else throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting true";
}
if(ch=='f') {
if(in.read(4)=="alse") return false;
else throw "Unexpected char f: expected false";
if(readOne()=='a' && readOne()=='l' && readOne()=='s' && readOne()=='e') return false;
else throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting false";
}
throw QString("Unexpected char ")+ch+" (code "+ch+"): expected {}, [], \"string\", number, null, true or false";
throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting {}, [], \"string\", number, null, true or false";
}
inline int toHex(unsigned char ch) {
if(ch<'0') return -1;
if(ch<='9') return ch-'0';
if(ch<'A') return -1;
if(ch<='F') return ch-55;
if(ch<'a') return -1;
if(ch<='f') return ch-87;
return -1;
}
QString JParser::readStr() {
QString buf;
while((ch = readOne(in)) != '"') {
QByteArray buf;
while(readOne() != '"') {
if(ch==0) throw "Unexpected end-of-input: was expecting closing quote for string";
if(ch=='\\') {
in>>ch;
if(ch==0) throw "Unexpected end-of-input in char escape sequence";
if(readOne()==0) throw "Unexpected end-of-input in char escape sequence";
if(ch=='"' || ch=='\\' || ch=='/') buf.append(ch);
else if(ch=='n') buf.append('\n');
else if(ch=='r') buf.append('\r');
@ -97,24 +100,50 @@ QString JParser::readStr() {
else if(ch=='f') buf.append('\f');
else if(ch=='b') buf.append('\b');
else if(ch=='u') {
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+")";
uint hex = 0;
for(int i=3; i>=0; i--) {
if(readOne()==0) throw "Unexpected end-of-input in char escape sequence";
auto h = toHex(ch);
if(h==-1) throw "Illegal hex-digits in char escape sequence: \\u"+(hex==0?"":QString::number(hex, 16)+(char)ch);
hex |= h<<(i<<2);
}
buf.append(QString(QChar(hex)).toUtf8());
} else throw QString("Unrecognized char-escape ")+(char)ch+" (code "+QString::number(ch)+") after '\\'";
} else buf.append(ch);
}
return buf;
return QString::fromUtf8(buf);
}
void JParser::skipSpace() {
if(bk.unicode()) {
bk = QChar::Null;
if(! ch.isSpace()) return;
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)+")";
}
in.skipWhiteSpace();
in >> ch;
if(ch==0) throw "Unexpected end-of-input";
}
void JOut::write(const JValue &value) {

View File

@ -3,15 +3,18 @@
#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:
long long data = 0;
int64_t data = 0;
enum Type {
Null, Long, Ulong, Double, Bool, Obj, Array, Str
};
@ -117,16 +120,28 @@ public:
const JValue operator[](const QString &key) const {
return type==Obj ? (*(const JObj*) &data)[key] : JValue();
}
const JValue operator[](int i) const {
const JValue operator[](uint64_t i) const {
return type==Array ? (*(const JArray*) &data)[i] : JValue();
}
JValue &ref(const QString &key) {
return (*(JObj*) &data)[key];
}
JValue &ref(uint64_t i) {
return (*(JArray*) &data)[i];
}
JArray::iterator begin() const noexcept {
return type==Array ? ((const JArray*) &data)->begin() : JArray::iterator();
}
JArray::iterator end() const noexcept {
return type==Array ? ((const JArray*) &data)->end() : JArray::iterator();
}
bool empty() const noexcept {
if(type==Array) return ((const JArray*) &data)->empty();
else if(type==Obj) return ((const JObj*) &data)->empty();
return 0;
}
size_t size() const noexcept {
if(type==Array) return ((const JArray*) &data)->size();
else if(type==Obj) return ((const JObj*) &data)->size();
@ -157,31 +172,32 @@ private:
JValue(const void *) = delete; // avoid implicit conversions from char * to bool
};
QDebug operator<<(QDebug debug, const JValue &val);
class JParser {
public:
JParser(QTextStream &in) : in(in) {
#if(QT_VERSION_MAJOR < 6)
in.setCodec("UTF-8");
#endif
}
JParser(QDataStream &in) : in(in) {}
inline JValue read() {
skipSpace();
JValue read() {
in >> ch;
if(ch==0) throw "Unexpected end-of-input";
if(ch==0xEF && (readOne()!=0xBB || readOne()!=0xBF)) throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting an UTF-8 BOM";
if(ch<33) skipSpace();
return readValue();
}
protected:
JValue readValue();
QString readStr();
void skipSpace();
unsigned char readOne() {
in >> ch;
return ch;
}
QTextStream &in;
QChar ch{0}, bk{0};
QDataStream &in;
unsigned char ch{0}, bk{0};
};
inline JValue JFrom(const QByteArray &json, QString *err = 0) {
QTextStream in(json);
QDataStream in(json);
try {
return JParser(in).read();
} catch (QString anerr) {
@ -194,7 +210,7 @@ inline JValue JFrom(const QByteArray &json, QString *err = 0) {
return JValue();
}
inline JValue JFrom(QIODevice *device, QString *err = 0) {
QTextStream in(device);
QDataStream in(device);
try {
return JParser(in).read();
} catch (QString anerr) {

View File

@ -22,6 +22,22 @@ 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,20 +93,23 @@ public:
};
QString errStr(QNetworkReply *);
QString errStrWithData(QNetworkReply *, QJsonDocument * = 0);
QString errStrWithData(QNetworkReply *, JValue * = 0);
QString errStrWithData(QNetworkReply *, QJsonDocument *);
inline int waitFinished(QNetworkReply *reply, bool excludeUser = false) {
inline int waitFinished(QNetworkReply *reply, QObject *context, bool excludeUser = false) {
if(reply->isFinished()) return 0;
QEventLoop loop;
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
if(context) QObject::connect(context, &QObject::destroyed, &loop, [&] {
reply->deleteLater();
loop.exit(1);
});
return excludeUser ? loop.exec(QEventLoop::ExcludeUserInputEvents) : loop.exec();
}
inline void abortSilence(QNetworkReply *reply) {
reply->blockSignals(true);
reply->abort();
reply->blockSignals(false);
reply->deleteLater();
}
#define ConnReply(reply, context)\
QObject::connect(context, &QObject::destroyed, reply, &QNetworkReply::deleteLater);\
QObject::connect(reply, &QNetworkReply::finished, context,
const char* socketErrKey(int value);

View File

@ -25,14 +25,6 @@ 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

@ -1,14 +0,0 @@
#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

@ -1,22 +0,0 @@
#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

@ -1,68 +0,0 @@
<?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>

View File

@ -1,80 +0,0 @@
<?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,6 +4,9 @@
#include <QMessageBox>
#include <QSplashScreen>
#include <QStandardPaths>
#if(QT_VERSION_MAJOR > 5)
#include <QImageReader>
#endif
#ifdef _MSC_VER //MSVC编译器
#include <Windows.h>
@ -27,12 +30,15 @@ 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);
QApplication::setOrganizationName("Shanghai Xixun Electronic Technology Co., Ltd.");
#endif
QApplication::setOrganizationName("Sysolution");
QApplication::setOrganizationDomain("www.ledok.cn");
QApplication::setApplicationName("LedOK Express");
QApplication::setStyle("Fusion");
@ -44,7 +50,7 @@ int main(int argc, char *argv[]) {
QFile file(":/css.css");
if(file.exists() && file.open(QFile::ReadOnly)) {
a.setStyleSheet(css = file.readAll());
a.setStyleSheet(file.readAll());
file.close();
}
QFont font;

View File

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

View File

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

View File

@ -1,153 +0,0 @@
/**
* @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

@ -1,93 +0,0 @@
/**
* @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

@ -1,141 +0,0 @@
/**
* @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

@ -1,128 +0,0 @@
/**
* @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

@ -1,86 +0,0 @@
#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

@ -1,61 +0,0 @@
#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

@ -1,768 +0,0 @@
/**
* @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

@ -1,508 +0,0 @@
/**
* @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

View File

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

View File

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

View File

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

View File

@ -1,20 +0,0 @@
#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

@ -0,0 +1,231 @@
#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

@ -1,67 +1,67 @@
#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
#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

View File

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

View File

@ -1,14 +0,0 @@
#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);
}

View File

@ -1,15 +0,0 @@
#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

@ -1,104 +0,0 @@
#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

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

View File

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

View File

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

View File

@ -1,24 +1,25 @@
#ifndef ELETIMER_H
#define ELETIMER_H
#include "gutil/qjson.h"
#include <QWidget>
#include <QDateTime>
class EleTimer : public QWidget {
Q_OBJECT
public:
explicit EleTimer(const QJsonObject&, QWidget *parent = 0);
explicit EleTimer(const JValue &, QWidget *parent = 0);
QDateTime targetTime;
QString text;
QColor textColor;
QColor backColor;
QString title;
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,176 +1,184 @@
#include "playwin.h"
#include "digiclock.h"
#include "eledigiclock.h"
#include "eleanaclock.h"
#include "eleborder.h"
#include "elegif.h"
#include "eleimg.h"
#include "elemultipng.h"
#include "elescroll.h"
#include "eletimer.h"
#include "elevideo.h"
#include "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};
Page::Page(QWidget *parent) : QWidget{parent} {
}
PlayWin *PlayWin::newIns(int width, int height, QString dir, const QJsonObject &aprog, QWidget *parent) {
PlayWin *PlayWin::newIns(int width, int height, QString dir, const JValue &aprog, QWidget *parent) {
if(! gPlayPos.isNull() && QGuiApplication::screenAt(QPoint(gPlayPos.x()+width/2, gPlayPos.y()+height/2))==0) gPlayPos = QPoint();
return new PlayWin(gPlayPos.x(), gPlayPos.y(), width, height, dir, aprog, parent);
}
PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const QJsonObject &aprog, QWidget *parent) : QWidget(parent) {
PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const JValue &aprog, QWidget *parent) : QWidget(parent) {
self = this;
setAttribute(Qt::WA_DeleteOnClose);
setAttribute(Qt::WA_QuitOnClose, false);
setWindowFlag(Qt::FramelessWindowHint);
setWindowFlag(Qt::WindowStaysOnTopHint);
setGeometry(x, y, width, height);
QPalette plt = palette();
plt.setColor(QPalette::Window, QColor(0,0,0));
setGeometry(x, y, width, height+1);
auto plt = palette();
plt.setColor(QPalette::Window, Qt::black);
setPalette(plt);
connect(this, &PlayWin::sigSetVisible, this, &PlayWin::sltSetVisible);
gl = new QOpenGLWidget(this);
gl->setGeometry(0, height, width, 1);
connect(gl, &QOpenGLWidget::frameSwapped, gl, (void(QOpenGLWidget::*)())&QOpenGLWidget::update);
auto task = aprog["task"];
auto jpages = task["items"];
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"];
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"];
EleBorder *bdEle = 0;
int bdWidth = 0, bdStart = 0xffff, bdEnd = 0;
if(! border.isNull()) {
bdEle = new EleBorder(dir+"/"+border["img"].toString(), border["eff"].toString(), border["speed"].toInt(), page);
bdEle = new EleBorder(dir+"/"+border["img"].toString(), border["eff"].toString(), border["speed"].toInt(), box);
bdWidth = bdEle->img.height();
}
foreach(QJsonValue srcMap, srcMaps) {
ele.type = srcMap["_type"].toString();
if(ele.type.isEmpty()) continue;
auto timeSpan = srcMap["timeSpan"].toInt()*1000;
Source src;
for(auto &source : sources) {
src.type = source["_type"].toString();
if(src.type.isEmpty()) continue;
auto timeSpan = source["timeSpan"].toInt()*1000;
if(timeSpan==0) continue;
ele.x = srcMap["left"].toInt()+bdWidth;
ele.y = srcMap["top"].toInt()+bdWidth;
ele.w = srcMap["width"].toInt()-bdWidth-bdWidth;
ele.h = srcMap["height"].toInt()-bdWidth-bdWidth;
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());
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());
break;
}
} else if(ele.type=="MultiPng") {
QJsonArray imgs = srcMap["arrayPics"].toArray();
if(imgs.isEmpty()) continue;
if(imgs.size()==1 && imgs.at(0)["picDuration"].toInt()==0) ele.wgt = new EleScroll(page, dir+"/", imgs[0].toObject());
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);
}
}
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);
} 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);
ele.wgt = video;
} else if(ele.type=="WebURL") {
auto web = new QWebEngineView(page);
web->load(QUrl(srcMap["url"].toString()));
ele.wgt = web;
src.view = video;
} else if(src.type=="WebURL") {
auto web = new QWebEngineView(box);
web->load(QUrl(source["url"].toString()));
src.view = web;
}
else if(ele.type=="Timer") ele.wgt = new EleTimer(srcMap.toObject(), page);
else if(src.type=="Timer") src.view = new EleTimer(source, box);
else continue;
if(ele.wgt==0) continue;
if(ele.startTime>0) ele.wgt->setVisible(false);
if(ele.w) ele.wgt->setGeometry(ele.x, ele.y, ele.w, ele.h);
page->eles.append(ele);
if(src.view==0) continue;
src.view->setVisible(false);
if(w) src.view->setGeometry(x, y, w, h);
layer.srcs.push_back(src);
}
if(bdEle && ! 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(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->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));
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(src->endTime > page.sDur) src->endTime = page.sDur;
}
if(layer->dur > page.sDur) layer->dur = page.sDur;
if(layer->dur == page.sDur) layer->isLoop = false;
conti_layer:;
}
pages.emplace_back(std::move(page));
}
menu = new QMenu(this);
@ -188,47 +196,51 @@ PlayWin::PlayWin(int x, int y, int width, int height, QString dir, const QJsonOb
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::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));
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;
}
}
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[curAva].setMillis(lastPage.endMilli);
} else {
for(auto &layer : lastPage.layers) {
for(auto &src : layer.srcs) {
if(src.view->isVisible()) {
if(milli >= src.endMilli) src.hide();
else src.doEff();
} else if(milli < src.endMilli && milli >= src.startMilli) src.show();
}
if(milli >= layer.endMilli) {
layer.endMilli += layer.dur;
for(auto &src : layer.srcs) {
src.endMilli += layer.dur;
src.startMilli += layer.dur;
if(src.startTime > 0) src.hide();
else src.show();
}
}
}
pages[cur]->setVisible(true);
timer = new SyncTimer(pages[cur]->timeSpan);
connect(timer, &SyncTimer::timeout, this, &PlayWin::sltNext, Qt::BlockingQueuedConnection);
timer->start();
}
QWidget::paintEvent(e);
}
void PlayWin::mousePressEvent(QMouseEvent *e) {

View File

@ -1,50 +1,225 @@
#ifndef PLAYWIN_H
#define PLAYWIN_H
#include "elebase.h"
#include "synctimer.h"
#include <QWidget>
#include "gutil/qjson.h"
#include <QMenu>
#include <QVector>
#include <QMap>
class Page : public QWidget {
public:
explicit Page(QWidget *parent = nullptr);
int timeSpan{0};
QVector<EleBase> eles;
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 TimerValue{
class Source {
public:
TimerValue(QWidget *ele = nullptr, bool visible = false): ele(ele), visible(visible){}
QWidget* ele;
bool visible;
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;
};
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 PlayWin : public QWidget {
Q_OBJECT
public:
static PlayWin *self;
static PlayWin *newIns(int width, int height, QString dir, const QJsonObject &prog, QWidget *parent = nullptr);
PlayWin(int x, int y, int width, int height, QString dir, const QJsonObject &prog, QWidget *parent = nullptr);
static PlayWin *newIns(int width, int height, QString dir, const JValue &prog, QWidget *parent = nullptr);
PlayWin(int x, int y, int width, int height, QString dir, const JValue &prog, QWidget *parent = nullptr);
SyncTimer* timer = 0;
QOpenGLWidget *gl;
int cur = 0;
QVector<Page*> pages;
QMap<int,TimerValue> timerMap;
std::vector<Page> pages;
std::vector<Page> avas;
int curAva = 0, curTimes = 1;
QPoint mPressRel;
QMenu *menu;
public slots:
void sltNext();
void sltSetVisible(QWidget *wgt, bool visible){
wgt->setVisible(visible);
}
signals:
void sigSetVisible(QWidget *, bool);
void doFrame();
protected:
void paintEvent(QPaintEvent *) override;
void timerEvent(QTimerEvent *) override;
void mousePressEvent(QMouseEvent *) override;
void mouseReleaseEvent(QMouseEvent *) override;
void mouseMoveEvent(QMouseEvent *) override;

11
LedOK/player/srccopy.cpp Normal file
View File

@ -0,0 +1,11 @@
#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);
}

16
LedOK/player/srccopy.h Normal file
View File

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

View File

@ -2,7 +2,6 @@
#define PROGPANEL_H
#include "base/loqtreewidget.h"
#include "program/progitem.h"
#include <QPushButton>
#include <QSettings>
#include <QTableWidget>
@ -18,15 +17,14 @@ protected:
void changeEvent(QEvent *) override;
void transUi();
bool checkIfNameRepeated(const QString &name, QTreeWidgetItem *skip = nullptr);
void addProFile(const QString &);
public slots:
void onEditClicked(bool f);
void onDeleteClicked(bool f);
void onCreateNewProgramOnOpenEditProgramWidget(QString name, QSize res, QString remarks, QList<int> &, 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);
foreach(QFileInfo fileInfo, fileInfos) {
for(auto &fileInfo : fileInfos) {
if(fileInfo.isDir()) { //< 当为目录时递归的进行copy
if(! copyDir(fileInfo.filePath(), targetDir.filePath(fileInfo.fileName()), coverIfExist)) return false;
} else { //当允许覆盖操作时,将旧文件进行删除操作
@ -30,3 +30,29 @@ bool CopyDirThread::copyDir(const QString &fromDir, const QString &toDir, bool c
}
return true;
}
void CopyDirThread::move() {
for(; i<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,9 +9,11 @@ public:
CopyDirThread();
QStringList dirSrcs;
QString dirDst;
protected:
void run();
void move();
protected:
bool copyDir(const QString &fromDir, const QString &toDir, bool coverFileIfExist);
bool moveDir(const QString &fromDir, const QString &toDir);
int i{0};
int copiedSize = 0;

View File

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

View File

@ -21,28 +21,23 @@ 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 QJsonObject &json, EBase *multiWin = nullptr);
explicit EAClock(const JObj &json, EBase *multiWin = nullptr);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
int type() const override { return EBase::AClock; }
QWidget* attrWgt() override;
bool save(const QString &pRoot) override;
QJsonObject attrJson() const override;
JObj attrJson() const override;
protected:
void timerEvent(QTimerEvent *) override;
@ -52,10 +47,6 @@ protected:
void paintDial(QPainter *painter);
void paintText(QPainter *painter);
qreal radius() const {
return (qMin(rect().width(), rect().height()) - qMax(m_attr.minMarkSize, m_attr.hourMarkSize)) / 2;
}
void cal();
Data m_attr;

View File

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

View File

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

View File

@ -30,7 +30,7 @@ EDClock::EDClock(EBase *multiWin) : EBase(multiWin) {
init();
}
EDClock::EDClock(const QJsonObject &json, EBase *multiWin) : EBase(multiWin) {
EDClock::EDClock(const JObj &json, EBase *multiWin) : EBase(multiWin) {
mType = EBase::DClock;
setBaseAttr(json);
auto widget = json["widget"];
@ -52,7 +52,6 @@ EDClock::EDClock(const QJsonObject &json, EBase *multiWin) : EBase(multiWin) {
m_attr.dateStyle = widget["dateStyle"].toInt();
m_attr.timeStyle = widget["timeStyle"].toInt();
m_attr.multiline = widget["multiline"].toBool();
m_attr.playDuration = json["play"]["duration"].toInt();
isSingleMD = m_attr.dateStyle==1||m_attr.dateStyle==2||m_attr.dateStyle==4||m_attr.dateStyle==6||m_attr.dateStyle==8||m_attr.dateStyle==10||m_attr.dateStyle==12;
init();
}
@ -419,41 +418,14 @@ 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;
}
QJsonObject EDClock::attrJson() const{
QJsonObject oWidget;
JObj EDClock::attrJson() const{
JObj oWidget;
oWidget["timeZone"] = QString::fromUtf8(m_attr.timeZoneId);
oWidget["year"] = m_attr.year;
oWidget["month"] = m_attr.month;
@ -468,7 +440,7 @@ QJsonObject EDClock::attrJson() const{
oWidget["dateStyle"] = m_attr.dateStyle;
oWidget["timeStyle"] = m_attr.timeStyle;
oWidget["multiline"] = m_attr.multiline;
oWidget["font"] = QJsonObject{
oWidget["font"] = JObj{
{"family", m_attr.font.family()},
{"size", m_attr.font.pixelSize()},
{"bold", m_attr.font.bold()},
@ -476,10 +448,9 @@ QJsonObject EDClock::attrJson() const{
{"underline", m_attr.font.underline()},
{"color", Tools::color2Int(m_attr.textColor)}
};
QJsonObject oRoot;
JObj oRoot;
addBaseAttr(oRoot);
oRoot["elementType"] = "DClock";
oRoot["widget"] = oWidget;
oRoot["play"] = QJsonObject{{"duration", m_attr.playDuration}};
return oRoot;
}

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -3,55 +3,63 @@
#include "ebase.h"
#include "gutil/qgui.h"
struct EnvironItem {
QString text;
QString unit;
QString label;
bool has = true;
};
class EEnviron : public EBase {
Q_OBJECT
public:
struct Data {
QString title;
QString labelTemp;
QString labelHum;
QString labelNoise;
QString labelWindSpeed;
QString labelWindDirectiton;
QString labelPm25;
QString labelPm10;
int tempType = 0;
int compensation = 0;
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;
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 &);
static JObj genProg(const JValue &, const QString &, const QString &);
explicit EEnviron(EBase *multiWin = nullptr);
explicit EEnviron(const QJsonObject &json, EBase *multiWin = nullptr);
explicit EEnviron(const JObj &json, EBase *multiWin = nullptr);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
void timerEvent(QTimerEvent *) override;
int type() const override { return EBase::Environ; }
QWidget* attrWgt() override;
bool save(const QString &pRoot) override;
QJsonObject attrJson() const override;
JObj attrJson() const override;
private:
void init();
void drawText(QPainter*, QRectF&);
void calAttr();
Data m_attr;
int scroll_width;
QString scroll_txt;
int item_cnt = 0;

View File

@ -1,6 +1,7 @@
#include "egif.h"
#include "cfg.h"
#include "tools.h"
#include "globaldefine.h"
#include <QBoxLayout>
#include <QDir>
#include <QLabel>
@ -23,7 +24,7 @@ EGif *EGif::create(const QString &file, PageListItem *pageItem, EBase *multiWin)
QFileInfo info(file);
return new EGif(movie, info.absolutePath(), info.fileName(), pageItem, multiWin);
}
EGif *EGif::create(const QJsonObject &json, PageListItem *pageItem, EBase *multiWin) {
EGif *EGif::create(const JObj &json, PageListItem *pageItem, EBase *multiWin) {
auto widget = json["widget"];
auto dir = widget["path"].toString();
auto name = widget["file"].toString();
@ -41,9 +42,6 @@ EGif *EGif::create(const QJsonObject &json, PageListItem *pageItem, EBase *multi
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;
}
@ -143,46 +141,6 @@ QWidget* EGif::attrWgt() {
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addWidget(new QLabel(tr("Play Properties")));
line = new QFrame();
line->setFrameShape(QFrame::HLine);
line->setFrameShadow(QFrame::Sunken);
hBox->addWidget(line, 1);
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Play Duration")));
auto wPlayDuration = new QSpinBox();
wPlayDuration->setRange(1, 99999);
wPlayDuration->setValue(mDuration);
connect(wPlayDuration, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
mDuration = value;
});
hBox->addWidget(wPlayDuration);
hBox->addWidget(new QLabel(tr("s")));
hBox->addStretch();
vBox->addLayout(hBox);
hBox = new QHBoxLayout();
hBox->addSpacing(6);
hBox->addWidget(new QLabel(tr("Play Times")));
auto wPlayTimes = new QSpinBox();
wPlayTimes->setRange(1, 99999);
wPlayTimes->setValue(mPlayTimes);
connect(wPlayTimes, (void(QSpinBox::*)(int))&QSpinBox::valueChanged, this, [this](int value) {
mPlayTimes = value;
});
hBox->addWidget(wPlayTimes);
hBox->addStretch();
vBox->addLayout(hBox);
vBox->addStretch();
return wgtAttr;
}
@ -197,17 +155,13 @@ bool EGif::save(const QString &pageDir) {
return true;
}
QJsonObject EGif::attrJson() const {
QJsonObject oRoot;
JObj EGif::attrJson() const {
JObj oRoot;
addBaseAttr(oRoot);
oRoot["elementType"] = "Gif";
oRoot["widget"] = QJsonObject{
oRoot["widget"] = JObj{
{"file", mName},
{"path", mDir}
};
oRoot["play"] = QJsonObject{
{"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 QJsonObject &, PageListItem *pageItem, EBase *multiWin = nullptr);
static EGif *create(const JObj &, PageListItem *pageItem, EBase *multiWin = nullptr);
explicit EGif(QMovie*, const QString &dir, const QString &name, PageListItem *pageItem, EBase *multiWin = nullptr);
~EGif();
@ -17,7 +17,7 @@ public:
void paint(QPainter*, const QStyleOptionGraphicsItem *, QWidget *) override;
QWidget* attrWgt() override;
bool save(const QString &pRoot) override;
QJsonObject attrJson() const override;
JObj attrJson() const override;
void loadFiles() override;
void freeFiles() override;
@ -29,9 +29,7 @@ public slots:
protected:
PageListItem *mPageItem;
int mDuration = 10;
int mPlayTimes = 1;
SyncTimer* timer = nullptr;
SyncTimer* timer = 0;
};
#endif // EGIF_H

View File

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

View File

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

View File

@ -6,41 +6,27 @@
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 QJsonObject &, PageListItem *pageItem, EBase *multiWin = nullptr);
static EPhoto *create(const JObj &, PageListItem *pageItem, EBase *multiWin = nullptr);
explicit EPhoto(const QImage&, const QString &dir, const QString &name, PageListItem *pageItem, EBase *multiWin = nullptr);
void scaleImgIfNeed();
int type() const override { return EBase::Photo; }
int type() const override { return EBase::Image; }
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
QJsonObject attrJson() const override;
JObj attrJson() const override;
void freeFiles() override;
void loadFiles() override;
bool save(const QString &pageDir) override;
QWidget* attrWgt() override;
QImage img;
QString mDir;
QString mName;
QString mDir, mName;
protected:
PageListItem *mPageItem;
int mDuration = 10;
int mEnterStyle = 0;
int mEnterDuration = 0;
};
#endif // EPHOTO_H

View File

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

View File

@ -6,38 +6,22 @@
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 QJsonObject &json, EBase *multiWin = nullptr);
explicit EText(const JObj &json, EBase *multiWin = nullptr);
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
int type() const override { return EBase::Text; }
QWidget* attrWgt() override;
bool save(const QString &pRoot) override;
QJsonObject attrJson() const override;
JObj attrJson() const override;
QString text;
Qt::Alignment align;
QColor backColor{Qt::transparent};
QString playMode = "Flip";
QString direction = "left";
int speed = 60;
int headTailSpacing{10};
public slots:
void updImg();
@ -48,7 +32,6 @@ 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