This commit is contained in:
Gangphon 2023-10-23 11:44:22 +08:00
parent 4c2a30cbe1
commit bedfe3c2c7
28 changed files with 4410 additions and 4260 deletions

View File

@ -29,11 +29,6 @@ msvc {
contains(QT_ARCH, i386) { contains(QT_ARCH, i386) {
QMAKE_LFLAGS += /LARGEADDRESSAWARE QMAKE_LFLAGS += /LARGEADDRESSAWARE
} }
# lessThan(QT_MAJOR_VERSION, 6) {
# QMAKE_CXXFLAGS += -execution-charset:utf-8
# QMAKE_CXXFLAGS += -source-charset:utf-8
# }
CONFIG += force_debug_info CONFIG += force_debug_info
CONFIG += separate_debug_info CONFIG += separate_debug_info
} }

View File

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

View File

@ -1,25 +1,40 @@
#ifndef UPGRADEAPKDIALOG_H #ifndef UPGRADEAPKDIALOG_H
#define UPGRADEAPKDIALOG_H #define UPGRADEAPKDIALOG_H
#include "base/loqtreewidget.h"
#include <QDialog> #include <QDialog>
#include <QTreeWidgetItem> #include <QProgressBar>
#include "wupgradeapkitem.h"
class UpdateApkItem;
class UpgradeApkDialog : public QDialog { class UpgradeApkDialog : public QDialog {
Q_OBJECT Q_OBJECT
public: public:
explicit UpgradeApkDialog(QWidget *parent = nullptr); explicit UpgradeApkDialog(QWidget *parent = nullptr);
void sendProgress(UpdateApkItem *item);
QString filePath, fileId; QString filePath, fileId;
protected: protected:
virtual void keyPressEvent(QKeyEvent *ev); virtual void keyPressEvent(QKeyEvent *ev);
protected slots:
void FilterProgram(const QString &strtemp);
private:
void onAddLedCard(LedCard p);
LoQTreeWidget *table; LoQTreeWidget *table;
QTreeWidgetItem *m_headerItem=nullptr; };
class UpdateApkItem : public TreeWidgetItem {
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();
void OnCheckFpgaVersions();
QLabel *fdOnline;
QProgressBar *fdProgress;
QPushButton *btnUnlock = 0;
bool isUpdating = false;
bool isLocked = true;
}; };
#endif // UpgradeApkDialog_H #endif // UpgradeApkDialog_H

View File

@ -1,6 +1,7 @@
#include "deviceitem.h" #include "deviceitem.h"
#include "devicepanel.h"
#include "globaldefine.h" #include "globaldefine.h"
#include "base/waitingdlg.h" #include "gutil/qwaitingdlg.h"
#include "gutil/qgui.h" #include "gutil/qgui.h"
#include "gutil/qnetwork.h" #include "gutil/qnetwork.h"
#include <QMessageBox> #include <QMessageBox>
@ -8,86 +9,73 @@
#include <QInputDialog> #include <QInputDialog>
#include <QJsonObject> #include <QJsonObject>
DeviceItem::DeviceItem(LoQTreeWidget *parent) : QObject(parent), QTreeWidgetItem(UserType), m_parent(parent) { DeviceItem::DeviceItem(LoQTreeWidget *parent) : TreeWidgetItem(parent) {
setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled); setFlags(flags() & ~Qt::ItemIsUserCheckable);
setCheckState(0, Qt::Unchecked); setCheckState("check", Qt::Unchecked);
m_parent->addTopLevelItem(this); auto ft = treeWidget()->font();
ft.setPixelSize(14);
for(int i=2; i<treeWidget()->columnCount()-2; i++) setFont(i, ft);
m_bnCardDetailInfo = new QPushButton(); auto btnGetCapture = new QPushButton;
m_bnCardDetailInfo->setToolTip(tr("GetScreenDetailInfo")); btnGetCapture->setCursor(QCursor(Qt::PointingHandCursor));
m_bnCardDetailInfo->setCursor(QCursor(Qt::PointingHandCursor)); btnGetCapture->setIcon(QIcon(":/res/deviceReadbackPic.png"));
m_bnCardDetailInfo->setStyleSheet(R"rrr( btnGetCapture->setIconSize({28, 28});
QPushButton { QObject::connect(btnGetCapture, &QPushButton::clicked, btnGetCapture, [=] {
border-radius: 4px;
image: url(:/res/bnDetail.png);
}
QPushButton:hover{background-color: #ccc;}
)rrr");
m_parent->setItemWidget(this, DeviceTable_Info, m_bnCardDetailInfo);
m_bnReadbackPic = new QPushButton();
m_bnReadbackPic->setToolTip(tr("ReadbackPic"));
m_bnReadbackPic->setCursor(QCursor(Qt::PointingHandCursor));
m_bnReadbackPic->setStyleSheet(R"rrr(
QPushButton {
border-radius: 4px;
image: url(:/res/deviceReadbackPic.png);
}
QPushButton:hover{background-color: #ccc;}
)rrr");
connect(m_bnReadbackPic, &QPushButton::clicked, this, [this] {
QJsonObject json; QJsonObject json;
json.insert("_id", "GetScreenshotFull"); json.insert("_id", "GetScreenshotFull");
json.insert("_type", "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(); waitingDlg->show();
auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json); auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(120000).post(json);
waitingDlg->connAbort(reply); ConnReply(reply, waitingDlg) [=] {
connect(reply, &QNetworkReply::finished, this, [=] {
waitingDlg->close(); waitingDlg->close();
QJsonDocument json; QJsonDocument json;
QString err = checkReplyForJson(reply, &json); QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) { if(! err.isEmpty()) {
QMessageBox::critical(treeWidget(), tr("Error"), err); QMessageBox::critical(treeWidget(), DevicePanel::tr("Error"), err);
return; return;
} }
ImgDlg dlg(QByteArray::fromBase64(json["data"].toString().toLatin1()), treeWidget()); ImgDlg dlg(QByteArray::fromBase64(json["data"].toString().toLatin1()), treeWidget());
dlg.exec(); dlg.exec();
}); });
}); });
m_parent->setItemWidget(this, DeviceTable_Screenshot, m_bnReadbackPic); setCellWidget("screenshot", btnGetCapture);
m_ImageOnline = new QLabel; fdOnline = new QLabel;
m_ImageOnline->setPixmap(QPixmap(":/res/O_Online.png")); fdOnline->setPixmap({":/res/online.png"});
m_ImageOnline->setAlignment(Qt::AlignCenter); fdOnline->setScaledContents(true);
m_parent->setItemWidget(this, DeviceTable_Online, m_ImageOnline); 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 = new QPushButton;
btnUnlock->setMaximumHeight(40); btnUnlock->setMaximumHeight(40);
connect(btnUnlock, &QPushButton::clicked, this, [this] { QObject::connect(btnUnlock, &QPushButton::clicked, btnUnlock, [this] {
if(! mCard.isLocked) return; if(! mCard.isLocked) return;
bool ok; 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; if(! ok) return;
QJsonObject json; QJsonObject json;
json.insert("_id", "VerifyPassword"); json.insert("_id", "VerifyPassword");
json.insert("_type", "VerifyPassword"); json.insert("_type", "VerifyPassword");
json.insert("pwd", pwd); json.insert("pwd", pwd);
auto waitingDlg = new WaitingDlg(treeWidget(), tr("VerifyPassword")+" ..."); auto waitingDlg = new WaitingDlg(btnUnlock, DevicePanel::tr("VerifyPassword")+" ...");
waitingDlg->show(); waitingDlg->show();
auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(60000).post(json); auto reply = NetReq("http://"+mCard.ip+":2016/settings").timeout(60000).post(json);
waitingDlg->connAbort(reply); ConnReply(reply, waitingDlg) [=] {
connect(reply, &QNetworkReply::finished, this, [=] {
QJsonDocument json; QJsonDocument json;
QString err = checkReplyForJson(reply, &json); QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) { if(! err.isEmpty()) {
waitingDlg->close(); waitingDlg->close();
QMessageBox::critical(treeWidget(), tr("Error"), err); QMessageBox::critical(treeWidget(), DevicePanel::tr("Error"), err);
return; return;
} }
if(! json["result"].toBool()) { if(! json["result"].toBool()) {
waitingDlg->close(); 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; return;
} }
waitingDlg->success(); waitingDlg->success();
@ -95,122 +83,17 @@ QPushButton:hover{background-color: #ccc;}
btnUnlock->setIcon(QIcon(":/res/UnLock.png")); btnUnlock->setIcon(QIcon(":/res/UnLock.png"));
}); });
}); });
auto wgt = new QWidget; wgt = new QWidget;
auto hBox = new HBox(wgt); hhh = new HBox(wgt);
hBox->setContentsMargins(0,0,0,0); hhh->setContentsMargins(0,0,0,0);
hBox->addWidget(btnUnlock); hhh->addWidget(btnUnlock);
m_parent->setItemWidget(this, DeviceTable_Password, wgt); setCellWidget("password", wgt);
auto ft = font(0);
ft.setPixelSize(14);
for(int i=1; i<DeviceTable_Screenshot; i++) {
setFont(i, ft);
setTextAlignment(i, Qt::AlignCenter);
}
} }
void DeviceItem::init() { void DeviceItem::init() {
setData(DeviceTable_ID, 0, mCard.id); setText("id", mCard.id);
setData(DeviceTable_IP, 0, mCard.ip); setText("ip", mCard.ip);
setData(DeviceTable_ScreenSize, 0, QString("%1 x %2").arg(mCard.mWidth).arg(mCard.mHeight)); 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")); if(mCard.hasPassword) btnUnlock->setIcon(QIcon(mCard.isLocked ? ":/res/Lock.png" : ":/res/UnLock.png"));
else btnUnlock->hide(); 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

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

View File

@ -19,6 +19,7 @@
#include <QJsonArray> #include <QJsonArray>
#include <QStyledItemDelegate> #include <QStyledItemDelegate>
#include <QToolButton> #include <QToolButton>
#include <QPainter>
DevicePanel *gDevicePanel; DevicePanel *gDevicePanel;
QTextEdit *gFdResInfo; QTextEdit *gFdResInfo;
@ -57,21 +58,27 @@ DevicePanel::DevicePanel(QSettings &settings, QWidget *parent) : QWidget(parent)
label_3 = new QLabel(tr("All")); label_3 = new QLabel(tr("All"));
hBox->addWidget(label_3); hBox->addWidget(label_3);
nDeviceNum = new QLabel(); nDeviceNum = new QLabel;
nDeviceNum->setFixedSize(40, 20); nDeviceNum->setFixedSize(40, 20);
hBox->addWidget(nDeviceNum); hBox->addWidget(nDeviceNum);
auto fdSearch = new QLineEdit(); auto fdSearch = new QLineEdit;
fdSearch->setClearButtonEnabled(true); fdSearch->setClearButtonEnabled(true);
fdSearch->setFixedSize(220, 30); fdSearch->setFixedSize(220, 30);
fdSearch->addAction(new QAction(QIcon(":/res/program/bnSearch.png"), QString()), QLineEdit::LeadingPosition); fdSearch->addAction(new QAction(QIcon(":/res/program/bnSearch.png"), QString()), QLineEdit::LeadingPosition);
fdSearch->setStyleSheet("border: 1px solid #aaaaaa;"); 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(); auto cnt = mDeviceTable->topLevelItemCount();
if(search.isEmpty()) for(int i=0; i<cnt; i++) mDeviceTable->topLevelItem(i)->setHidden(false); int sel = 0, unsel = 0;
else for(int i=0; i<cnt; i++) { for(int i=0; i<cnt; i++) {
auto item = mDeviceTable->topLevelItem(i); auto item = mDeviceTable->item(i);
item->setHidden(! (item->text(DeviceTable_ID).contains(search) || item->text(DeviceTable_Remark).contains(search) || item->text(DeviceTable_IP).contains(search))); 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); hBox->addWidget(fdSearch);
@ -116,8 +123,8 @@ QComboBox QAbstractItemView::item:selected {background-color: #09c;}
btnRefresh = new QPushButton(tr("Refresh"), areaFlash); btnRefresh = new QPushButton(tr("Refresh"), areaFlash);
btnRefresh->setGeometry(0, 0, 75, areaFlash->height()); btnRefresh->setGeometry(0, 0, 75, areaFlash->height());
connect(btnRefresh, &QPushButton::clicked, this, [this] { connect(btnRefresh, &QPushButton::clicked, this, [this] {
mDeviceTable->onCheckAll(false);
mDeviceTable->clear(); mDeviceTable->clear();
mDeviceTable->fdCheckAll->setCheckState(Qt::Unchecked);
nDeviceNum->setText("0"); nDeviceNum->setText("0");
sendGetInfo(); sendGetInfo();
}); });
@ -132,48 +139,37 @@ QPushButton:hover {background-color: #08b;}
hBox->addWidget(areaFlash); hBox->addWidget(areaFlash);
mHBox = new QHBoxLayout(); mHBox = new HBox(vBox);
mDeviceTable = new LoQTreeWidget(this); auto table = new LoQTreeWidget;
mDeviceTable->setSelectionMode(QAbstractItemView::NoSelection); table->addCol("#", "", 20);
mDeviceTable->setIndentation(0); table->addCol("check", "", 28).margin(2);
mDeviceTable->setSortingEnabled(true); table->addCol("id", "ID", 130, QHeaderView::Stretch).alignC();
mHBox->addWidget(mDeviceTable); 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); table->hideColumn("check");
table->fdCheckAll->hide();
m_headerItem = new QTreeWidgetItem(); table->sortItems("id", Qt::AscendingOrder);
for(int i=1; i<DeviceTable_End; i++) m_headerItem->setTextAlignment(i, Qt::AlignCenter); connect(table, &LoQTreeWidget::selChanged, table, [=] {
mDeviceTable->setHeaderItem(m_headerItem);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Check, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Check, 36);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Online, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Online, 48);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_ID, QHeaderView::Stretch);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_IP, QHeaderView::Stretch);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_ScreenSize, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_ScreenSize, 108);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Remark, QHeaderView::Stretch);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Brightness, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Brightness, 108);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Power, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Power, 84);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Password, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Password, 72);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Info, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Info, 72);
mDeviceTable->header()->setSectionResizeMode(DeviceTable_Screenshot, QHeaderView::Fixed);
mDeviceTable->setColumnWidth(DeviceTable_Screenshot, 72);
connect(mDeviceTable, &LoQTreeWidget::sigCheckStateChanged, this, [=] {
gSelCards.clear(); gSelCards.clear();
int cnt = mDeviceTable->topLevelItemCount(); int cnt = table->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); 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(); emit sigSelectedDeviceList();
}); });
mDeviceTable->hideColumn(0); mHBox->addWidget(mDeviceTable = table);
mDeviceTable->fdIsSelAll->hide();
mDeviceTable->sortItems(DeviceTable_ID, Qt::AscendingOrder);
connect(&mUdpTimer, &QTimer::timeout, this, &DevicePanel::sendGetInfo); connect(&mUdpTimer, &QTimer::timeout, this, &DevicePanel::sendGetInfo);
connect(&mUdpSocket, &QUdpSocket::readyRead, this, [this] { connect(&mUdpSocket, &QUdpSocket::readyRead, this, [this] {
@ -218,7 +214,14 @@ QPushButton:hover {background-color: #08b;}
item->mCard.id = packet->serialCode; item->mCard.id = packet->serialCode;
item->mCard.ip = addr; item->mCard.ip = addr;
} }
connect(item->m_bnCardDetailInfo, &QPushButton::clicked, item, [=] { 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; QString msgpre;
msgpre.append(tr("Current Brightness")).append(": ").append(QString::number(item->mCard.bright)).append("%").append("\n"); 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("Brightness Level")).append(": ").append(QString::number(item->mCard.BrightnessLevel)).append("\n");
@ -233,10 +236,7 @@ QPushButton:hover {background-color: #08b;}
json.insert("_type", "CheckSoftVersions"); json.insert("_type", "CheckSoftVersions");
auto card = item->mCard; auto card = item->mCard;
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json); auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);
connect(&msgBox, &QMessageBox::finished, reply, [reply] { ConnReply(reply, &msgBox) [=, &msgBox] {
abortSilence(reply);
});
connect(reply, &QNetworkReply::finished, &msgBox, [=, &msgBox] {
QJsonDocument json; QJsonDocument json;
QString err = checkReplyForJson(reply, &json); QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) { if(! err.isEmpty()) {
@ -255,8 +255,8 @@ QPushButton:hover {background-color: #08b;}
}); });
msgBox.exec(); msgBox.exec();
}); });
item->init(); }
item->DeviceItemHttpPost(); init(item);
nDeviceNum->setText(QString::number(mDeviceTable->topLevelItemCount())); nDeviceNum->setText(QString::number(mDeviceTable->topLevelItemCount()));
{ {
QJsonObject json; QJsonObject json;
@ -291,7 +291,7 @@ QPushButton:hover {background-color: #08b;}
hBox->addStretch(); hBox->addStretch();
auto bnSearch = new QPushButton(tr("Search")); auto bnSearch = new QPushButton(tr("Search"));
connect(bnSearch, &QPushButton::clicked, this, [this] { connect(bnSearch, &QPushButton::clicked, fdIP, [this] {
QString ipsStr = fdIP->toPlainText(); QString ipsStr = fdIP->toPlainText();
if(ipsStr.isEmpty()) { if(ipsStr.isEmpty()) {
QMessageBox::warning(this, tr("Attention"), tr("Please input IP address!")); QMessageBox::warning(this, tr("Attention"), tr("Please input IP address!"));
@ -359,21 +359,20 @@ void DevicePanel::transUi() {
bnSpecifyIP->setItemText(0,tr("Specify IP")); bnSpecifyIP->setItemText(0,tr("Specify IP"));
label_3->setText(tr("All")); label_3->setText(tr("All"));
m_headerItem->setText(DeviceTable_Online, tr("Online")); mDeviceTable->setHeaderText("online", tr("Online"));
m_headerItem->setText(DeviceTable_ID, tr("Screen ID")); mDeviceTable->setHeaderText("id", tr("Screen ID"));
m_headerItem->setText(DeviceTable_IP, tr("Screen IP")); mDeviceTable->setHeaderText("screenSize", tr("Screen Size"));
m_headerItem->setText(DeviceTable_ScreenSize, tr("Screen Size")); mDeviceTable->setHeaderText("alias", tr("Alias"));
m_headerItem->setText(DeviceTable_Remark, tr("Alias")); mDeviceTable->setHeaderText("brightness", tr("Screen Brightness"));
m_headerItem->setText(DeviceTable_Screenshot, tr("readback pic")); mDeviceTable->setHeaderText("power", tr("Power Status"));
m_headerItem->setText(DeviceTable_Brightness, tr("Screen Brightness")); mDeviceTable->setHeaderText("password", tr("Security"));
m_headerItem->setText(DeviceTable_Power, tr("Power Status")); mDeviceTable->setHeaderText("info", tr("More Info"));
m_headerItem->setText(DeviceTable_Password, tr("Security")); mDeviceTable->setHeaderText("screenshot", tr("Screenshot"));
m_headerItem->setText(DeviceTable_Info, tr("More Info"));
auto cnt = mDeviceTable->topLevelItemCount(); auto cnt = mDeviceTable->topLevelItemCount();
for(int i=0; i<cnt; i++) { for(int i=0; i<cnt; i++) {
auto item = (DeviceItem*) mDeviceTable->topLevelItem(i); auto item = (DeviceItem*) mDeviceTable->item(i);
item->setData(DeviceTable_Power, 0, item->mCard.isScreenOn ? tr("On") : tr("Off")); item->setText("power", item->mCard.isScreenOn ? tr("On") : tr("Off"));
} }
transCtrl(); transCtrl();
} }
@ -452,9 +451,9 @@ void DevicePanel::newCtrl() {
line->setFrameShadow(QFrame::Sunken); line->setFrameShadow(QFrame::Sunken);
vBox->addWidget(line); vBox->addWidget(line);
hBox = new QHBoxLayout(); hBox = new QHBoxLayout;
scrollArea = new QScrollArea(); scrollArea = new QScrollArea;
scrollArea->setWidgetResizable(true); scrollArea->setWidgetResizable(true);
hBox->addWidget(scrollArea); hBox->addWidget(scrollArea);
@ -479,7 +478,7 @@ void DevicePanel::newCtrl() {
fdInfo->hide(); fdInfo->hide();
btnClear->hide(); btnClear->hide();
connect(this, &DevicePanel::sigSelectedDeviceList, this, [this] { connect(this, &DevicePanel::sigSelectedDeviceList, fdInfo, [this] {
if(gSelCards.count() < 2) { if(gSelCards.count() < 2) {
if(gSelCards.count()==1) fdCardNumInfo->setText(tr("Current Screen")+": "+gSelCards[0].id); if(gSelCards.count()==1) fdCardNumInfo->setText(tr("Current Screen")+": "+gSelCards[0].id);
else fdCardNumInfo->setText(tr("Current Screen")+": "+tr("none")); else fdCardNumInfo->setText(tr("Current Screen")+": "+tr("none"));
@ -497,3 +496,103 @@ void DevicePanel::newCtrl() {
transCtrl(); 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->fdOnline) [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
item->mCard.BrightnessLevel = json["BrightnessLevel"].toInt();
item->mCard.FirmwareVersion = json["FirmwareVersion"].toString();
item->mCard.HardVersion = json["HardVersion"].toString();
item->mCard.ScreenResolution = json["ScreenResolution"].toString();
item->mCard.IMEI = json["IMEI"].toString();
auto androidVersion = json["AndroidVersion"].toString();
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->fdOnline) [=] {
QJsonDocument json;
QString err = checkReplyForJson(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->fdOnline) [=] {
QJsonDocument json;
QString err = checkReplyForJson(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->fdOnline) [=] {
QJsonDocument json;
QString err = checkReplyForJson(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->fdOnline) [=] {
QJsonDocument json;
QString err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) return;
item->mCard.alias = QString::fromUtf8(QByteArray::fromBase64(json["alias"].toString().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->fdOnline) [=] {
QJsonDocument json;
QString err = checkReplyForJson(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();
});
}
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 "base/loqtreewidget.h"
#include "globaldefine.h" #include "globaldefine.h"
#include <QLabel> #include "gutil/qgui.h"
#include <QTimer> #include <QTimer>
#include <QPushButton> #include <QPushButton>
#include <QUdpSocket> #include <QUdpSocket>
@ -12,7 +12,6 @@
#include <QTextEdit> #include <QTextEdit>
#include <QScrollArea> #include <QScrollArea>
#include <QSettings> #include <QSettings>
#include <QHBoxLayout>
class DevicePanel : public QWidget { class DevicePanel : public QWidget {
Q_OBJECT Q_OBJECT
@ -22,6 +21,7 @@ public:
void sendGetInfo(); void sendGetInfo();
void newCtrl(); void newCtrl();
void init(DeviceItem *item);
QLabel *fdCardNumInfo; QLabel *fdCardNumInfo;
LoQTreeWidget *mDeviceTable; LoQTreeWidget *mDeviceTable;
@ -34,8 +34,7 @@ public:
QLabel *label_3, *nDeviceNum; QLabel *label_3, *nDeviceNum;
QComboBox *bnSpecifyIP; QComboBox *bnSpecifyIP;
QPushButton *btnRefresh; QPushButton *btnRefresh;
QTreeWidgetItem *m_headerItem; HBox *mHBox{0};
QHBoxLayout *mHBox{0};
QTextEdit *fdInfo; QTextEdit *fdInfo;
QButtonGroup *mBtnGrp; QButtonGroup *mBtnGrp;
@ -51,6 +50,15 @@ signals:
void sigSelectedDeviceList(); 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 { struct UDPPacket {
unsigned char SyncHead[3]; unsigned char SyncHead[3];
unsigned char ucCommType; unsigned char ucCommType;

View File

@ -93,7 +93,7 @@ QString checkReplyForJson(QNetworkReply *, QString errField);
waitingDlg->show();\ waitingDlg->show();\
auto card = gSelCards[0];\ auto card = gSelCards[0];\
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);\ 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 \ #define Def_CtrlSetReqAfter \
QString err = checkReplyForJson(reply);\ QString err = checkReplyForJson(reply);\

View File

@ -47,7 +47,7 @@ public:
} }
SharedPtr &operator=(SharedPtr &&other) noexcept { SharedPtr &operator=(SharedPtr &&other) noexcept {
auto aaa = ptr; auto aaa = ptr;
ptr = other._pri; ptr = other.ptr;
other.ptr = aaa; other.ptr = aaa;
return *this; return *this;
} }

View File

@ -6,7 +6,7 @@
const Qt::Alignment AlignRight = Qt::AlignRight | Qt::AlignVCenter; const Qt::Alignment AlignRight = Qt::AlignRight | Qt::AlignVCenter;
ColItem TreeWidget::addCol(const QString& field, const QString& text, int width, QHeaderView::ResizeMode resizeMode) { 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(); auto item = headerItem();
item->setText(i, text); item->setText(i, text);
item->setData(i, FieldRole, field); item->setData(i, FieldRole, field);
@ -106,8 +106,40 @@ bool TreeWidget::adjSections(int index, int size) {
class TreeItemMarginStyle : public QProxyStyle { class TreeItemMarginStyle : public QProxyStyle {
public: public:
using QProxyStyle::QProxyStyle; TreeItemMarginStyle(TreeWidget *wgt) : QProxyStyle(wgt->style()), _wgt(wgt) {}
TreeItemMarginStyle(QWidget *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 { QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const override {
auto res = QProxyStyle::subElementRect(element, option, widget); auto res = QProxyStyle::subElementRect(element, option, widget);
auto width = res.width(); auto width = res.width();
@ -125,9 +157,11 @@ public:
} }
} }
} else if(((QStyleOptionViewItem*)option)->features & QStyleOptionViewItem::HasCheckIndicator) { } 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) { if(add) {
add += add>>1; if(width < (add+3)<<1) add = width;
else add += add>>1;
res.setLeft(res.x() + add); res.setLeft(res.x() + add);
if(width < add) res.setWidth(0); if(width < add) res.setWidth(0);
} }
@ -140,7 +174,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(); 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; return res;
} }
QWidget *_wgt = 0; #endif
TreeWidget *_wgt = 0;
}; };
ColItem &ColItem::margin(int margin) { ColItem &ColItem::margin(int margin) {

View File

@ -293,11 +293,11 @@ protected:
}; };
inline int operator*(const QString& key, QTreeView &table) { 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); return ((TreeWidget&)table).fdmap.at(key);
} }
inline int operator*(const char *key, QTreeView &table) { 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); return ((TreeWidget&)table).fdmap.at(key);
} }

View File

@ -8,11 +8,6 @@ QDebug operator<<(QDebug debug, const JValue &val) {
return debug; return debug;
} }
inline QChar readOne(QTextStream &in) {
QChar ch;
in >> ch;
return ch;
}
JValue JParser::readValue() { JValue JParser::readValue() {
if(ch=='{') { if(ch=='{') {
JObj obj; JObj obj;
@ -22,14 +17,14 @@ JValue JParser::readValue() {
if(ch=='}') return obj; if(ch=='}') return obj;
QString key; QString key;
if(ch == '"') key = readStr(); 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"; 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(); 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(); skipSpace();
obj.insert(key, readValue()); obj.insert(key, readValue());
skipSpace(); //ch有两种可能 skipSpace(); //ch有两种可能
if(ch=='}') return obj; 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=='[') { if(ch=='[') {
@ -41,15 +36,15 @@ JValue JParser::readValue() {
list->push_back(readValue()); list->push_back(readValue());
skipSpace(); //ch有两种可能 skipSpace(); //ch有两种可能
if(ch==']') return list; 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=='"') return readStr();
if((ch>='0' && ch<='9') || ch=='-') { if((ch>='0' && ch<='9') || ch=='-') {
QString buf; QByteArray buf;
buf += ch; buf += ch;
bool isInt = true; bool isInt = true;
while(0 != (ch = readOne(in))) { while(readOne()) {
if((ch>'*' && ch<':' && ch!=',' && ch!='/') || ch=='e' || ch=='E') { if((ch>'*' && ch<':' && ch!=',' && ch!='/') || ch=='e' || ch=='E') {
buf.append(ch); buf.append(ch);
if(isInt && ch=='.') isInt = false; if(isInt && ch=='.') isInt = false;
@ -70,26 +65,34 @@ JValue JParser::readValue() {
} }
} }
if(ch=='n') { if(ch=='n') {
if(in.read(3)=="ull") return JValue(); if(readOne()=='u' && readOne()=='l' && readOne()=='l') return JValue();
else throw "Unexpected char n: expected null"; else throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting null";
} }
if(ch=='t') { if(ch=='t') {
if(in.read(3)=="rue") return true; if(readOne()=='r' && readOne()=='u' && readOne()=='e') return true;
else throw "Unexpected char t: expected true"; else throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting true";
} }
if(ch=='f') { if(ch=='f') {
if(in.read(4)=="alse") return false; if(readOne()=='a' && readOne()=='l' && readOne()=='s' && readOne()=='e') return false;
else throw "Unexpected char f: expected 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 JParser::readStr() {
QString buf; QByteArray buf;
while((ch = readOne(in)) != '"') { while(readOne() != '"') {
if(ch==0) throw "Unexpected end-of-input: was expecting closing quote for string"; if(ch==0) throw "Unexpected end-of-input: was expecting closing quote for string";
if(ch=='\\') { if(ch=='\\') {
in>>ch; if(readOne()==0) throw "Unexpected end-of-input in char escape sequence";
if(ch==0) throw "Unexpected end-of-input in char escape sequence";
if(ch=='"' || ch=='\\' || ch=='/') buf.append(ch); if(ch=='"' || ch=='\\' || ch=='/') buf.append(ch);
else if(ch=='n') buf.append('\n'); else if(ch=='n') buf.append('\n');
else if(ch=='r') buf.append('\r'); else if(ch=='r') buf.append('\r');
@ -97,24 +100,50 @@ QString JParser::readStr() {
else if(ch=='f') buf.append('\f'); else if(ch=='f') buf.append('\f');
else if(ch=='b') buf.append('\b'); else if(ch=='b') buf.append('\b');
else if(ch=='u') { else if(ch=='u') {
auto hex = in.read(4); uint hex = 0;
if(hex.size()<4) throw "Unexpected end-of-input in char escape sequence"; for(int i=3; i>=0; i--) {
bool ok; if(readOne()==0) throw "Unexpected end-of-input in char escape sequence";
buf.append(hex.toUShort(&ok, 16)); auto h = toHex(ch);
if(! ok) throw "Illegal hex-digits in char escape sequence: \\u"+hex; if(h==-1) throw "Illegal hex-digits in char escape sequence: \\u"+(hex==0?"":QString::number(hex, 16)+(char)ch);
} else throw QString("Unrecognized char-escape ")+ch+" (code "+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); } else buf.append(ch);
} }
return buf; return QString::fromUtf8(buf);
} }
void JParser::skipSpace() { void JParser::skipSpace() {
if(bk.unicode()) { if(bk) {
bk = QChar::Null; bk = 0;
if(! ch.isSpace()) return; if(ch>=33) return;
} }
in.skipWhiteSpace(); do {
in >> ch; in >> ch;
if(ch==0) throw "Unexpected end-of-input"; if(ch==0) throw "Unexpected end-of-input";
} while(ch < 33); // || ch==65279
if(ch=='/') {
in >> ch;
if(ch=='/') { //skipComment
do {
in >> ch;
if(ch==0) throw "Unexpected end-of-input";
} while(ch!='\n' && ch!='\r');
skipSpace();
return;
}
if(ch=='*') { //skipMultiComment
int last;
do {
last = ch;
in >> ch;
if(ch==0) throw "Unexpected end-of-input";
} while(ch!='/' || last!='*');
skipSpace();
return;
}
throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+")";
}
} }
void JOut::write(const JValue &value) { void JOut::write(const JValue &value) {

View File

@ -3,12 +3,14 @@
#include "cpp.h" #include "cpp.h"
#include "QtCore/qhashfunctions.h" #include "QtCore/qhashfunctions.h"
#include <QDataStream>
#include <QTextStream> #include <QTextStream>
class JValue; class JValue;
using JObj = LinkedMap<QString, JValue>; using JObj = LinkedMap<QString, JValue>;
using JArray = Vector<JValue>; using JArray = Vector<JValue>;
QDebug operator<<(QDebug debug, const JValue &val);
class JValue { class JValue {
public: public:
long long data = 0; long long data = 0;
@ -127,6 +129,11 @@ public:
JArray::iterator end() const noexcept { JArray::iterator end() const noexcept {
return type==Array ? ((const JArray*) &data)->end() : JArray::iterator(); 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 { size_t size() const noexcept {
if(type==Array) return ((const JArray*) &data)->size(); if(type==Array) return ((const JArray*) &data)->size();
else if(type==Obj) return ((const JObj*) &data)->size(); else if(type==Obj) return ((const JObj*) &data)->size();
@ -157,31 +164,30 @@ private:
JValue(const void *) = delete; // avoid implicit conversions from char * to bool JValue(const void *) = delete; // avoid implicit conversions from char * to bool
}; };
QDebug operator<<(QDebug debug, const JValue &val);
class JParser { class JParser {
public: public:
JParser(QTextStream &in) : in(in) { JParser(QDataStream &in) : in(in) {}
#if(QT_VERSION_MAJOR < 6) JValue read() {
in.setCodec("UTF-8"); in >> ch;
#endif if(ch==0) throw "Unexpected end-of-input";
} if(ch==0xEF && (readOne()!=0xBB || readOne()!=0xBF)) throw QString("Unexpected char ")+(char)ch+" (code "+QString::number(ch)+"): was expecting an UTF-8 BOM";
if(ch<33) skipSpace();
inline JValue read() {
skipSpace();
return readValue(); return readValue();
} }
protected: protected:
JValue readValue(); JValue readValue();
QString readStr(); QString readStr();
void skipSpace(); void skipSpace();
unsigned char readOne() {
QTextStream &in; in >> ch;
QChar ch{0}, bk{0}; return ch;
}
QDataStream &in;
unsigned char ch{0}, bk{0};
}; };
inline JValue JFrom(const QByteArray &json, QString *err = 0) { inline JValue JFrom(const QByteArray &json, QString *err = 0) {
QTextStream in(json); QDataStream in(json);
try { try {
return JParser(in).read(); return JParser(in).read();
} catch (QString anerr) { } catch (QString anerr) {
@ -194,7 +200,7 @@ inline JValue JFrom(const QByteArray &json, QString *err = 0) {
return JValue(); return JValue();
} }
inline JValue JFrom(QIODevice *device, QString *err = 0) { inline JValue JFrom(QIODevice *device, QString *err = 0) {
QTextStream in(device); QDataStream in(device);
try { try {
return JParser(in).read(); return JParser(in).read();
} catch (QString anerr) { } 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(); if(status != 200) return QString::number(status)+" "+reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
return ""; 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) { QString errStrWithData(QNetworkReply *reply, QJsonDocument *outJson) {
auto err = errStr(reply); auto err = errStr(reply);
if(! err.isEmpty()) { if(! err.isEmpty()) {

View File

@ -93,20 +93,23 @@ public:
}; };
QString errStr(QNetworkReply *); 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; if(reply->isFinished()) return 0;
QEventLoop loop; QEventLoop loop;
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit); 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(); return excludeUser ? loop.exec(QEventLoop::ExcludeUserInputEvents) : loop.exec();
} }
inline void abortSilence(QNetworkReply *reply) {
reply->blockSignals(true); #define ConnReply(reply, context)\
reply->abort(); QObject::connect(context, &QObject::destroyed, reply, &QNetworkReply::deleteLater);\
reply->blockSignals(false); QObject::connect(reply, &QNetworkReply::finished, context,
reply->deleteLater();
}
const char* socketErrKey(int value); const char* socketErrKey(int value);
@ -154,4 +157,55 @@ protected:
bool connAndExec(int msecs, QEventLoop *loop); bool connAndExec(int msecs, QEventLoop *loop);
}; };
struct NetReplyData {
QNetworkReply* reply;
size_t cnt = 1;
bool isDeleted = false;
};
class NetReply {
public:
NetReply(QNetworkReply *reply) : ptr{new NetReplyData{reply}} {}
~NetReply() {
if(ptr->cnt > 1) ptr->cnt--;
else {
if(! ptr->isDeleted) ptr->reply->deleteLater();
delete ptr;
}
}
NetReply(const NetReply &other) : ptr{other.ptr} {
ptr->cnt++;
}
NetReply &operator=(const NetReply &other) {
NetReply ooo(other);
auto aaa = ptr;
ptr = ooo.ptr;
ooo.ptr = aaa;
return *this;
}
NetReply(NetReply &&other) noexcept : ptr(other.ptr) {
other.ptr = 0;
}
NetReply &operator=(NetReply &&other) noexcept {
auto aaa = ptr;
ptr = other.ptr;
other.ptr = aaa;
return *this;
}
void deleteLater() {
if(ptr->isDeleted) return;
ptr->reply->deleteLater();
ptr->isDeleted = true;
}
QNetworkReply *operator*() const {
return ptr->reply;
}
QNetworkReply *operator->() const {
return ptr->reply;
}
NetReplyData *ptr;
};
#endif // QNETWORK_H #endif // QNETWORK_H

View File

@ -25,14 +25,6 @@ class WaitingDlg : public QDialog {
public: public:
explicit WaitingDlg(QWidget *parent = nullptr, QString text = 0, QString sucText = 0); 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; QLabel *fdText;
QString sucText; QString sucText;
WaitingIndicator *mIndicator; WaitingIndicator *mIndicator;

View File

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

View File

@ -207,7 +207,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
fdAntiTip->setWordWrap(true); fdAntiTip->setWordWrap(true);
hBox->addWidget(fdAntiTip, 1); hBox->addWidget(fdAntiTip, 1);
auto fdWidthSplit = new QCheckBox(tr("Width Split")); auto fdWidthSplit = new QCheckBox(tr("Ultra-Long Screen Split"));
fdWidthSplit->setChecked(gWidthSplit); fdWidthSplit->setChecked(gWidthSplit);
vBox->addWidget(fdWidthSplit); vBox->addWidget(fdWidthSplit);
@ -278,7 +278,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
vBox->addWidget(fdUpdLog); vBox->addWidget(fdUpdLog);
auto reply = NetReq(updates["changelog_zh_CN"].toString()).timeout(60000).get(); auto reply = NetReq(updates["changelog_zh_CN"].toString()).timeout(60000).get();
connect(reply, &QNetworkReply::finished, this, [=] { ConnReply(reply, fdUpdLog) [=] {
auto err = errStr(reply); auto err = errStr(reply);
if(! err.isEmpty()) { if(! err.isEmpty()) {
qCritical()<<"Check Updates"<<err; qCritical()<<"Check Updates"<<err;
@ -301,7 +301,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
auto filePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/ledok-express-updater"; auto filePath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/ledok-express-updater";
auto url = updates["url"].toString(); auto url = updates["url"].toString();
auto idx = url.lastIndexOf('.'); auto idx = url.lastIndexOf('.');
if(idx!=-1) filePath += url.midRef(idx); if(idx!=-1) filePath += url.mid(idx);
qDebug()<<"filePath"<<filePath; qDebug()<<"filePath"<<filePath;
QFile qFile(filePath); QFile qFile(filePath);
if(! qFile.open(QFile::WriteOnly)) { if(! qFile.open(QFile::WriteOnly)) {
@ -313,15 +313,8 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
msgBox.setWindowTitle(tr("Downloading updates")); msgBox.setWindowTitle(tr("Downloading updates"));
msgBox.setText(tr("Downloading updates")+": 0% "); msgBox.setText(tr("Downloading updates")+": 0% ");
auto reply = NetReq(url).timeout(60000).get(); auto reply = NetReq(url).timeout(60000).get();
connect(&msgBox, &QMessageBox::rejected, reply, [reply] { auto pfile = &qFile;
abortSilence(reply); ConnReply(reply, &msgBox) [=, &msgBox] {
});
connect(reply, &QNetworkReply::downloadProgress, &msgBox, [&, reply](qint64 bytesReceived, qint64 bytesTotal) {
if(bytesTotal==0) return;
msgBox.setText(tr("Downloading updates")+": "+QString::number(bytesReceived*100/bytesTotal)+"% ");
qFile.write(reply->readAll());
});
connect(reply, &QNetworkReply::finished, &msgBox, [&, reply] {
auto err = errStr(reply); auto err = errStr(reply);
if(! err.isEmpty()) { if(! err.isEmpty()) {
msgBox.setIcon(QMessageBox::Critical); msgBox.setIcon(QMessageBox::Critical);
@ -330,6 +323,11 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
} }
msgBox.accept(); 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(); auto res = msgBox.exec();
qFile.close(); qFile.close();
if(res != QDialog::Accepted) return; if(res != QDialog::Accepted) return;
@ -339,7 +337,7 @@ MainWindow::MainWindow(QWidget *parent) : BaseWin(parent) {
menu_setting->addAction(act_update); menu_setting->addAction(act_update);
auto reply = NetReq(UpdVerUrl).timeout(60000).get(); auto reply = NetReq(UpdVerUrl).timeout(60000).get();
connect(reply, &QNetworkReply::finished, this, [=] { ConnReply(reply, this) [=] {
auto err = errStr(reply); auto err = errStr(reply);
if(! err.isEmpty()) { if(! err.isEmpty()) {
qCritical()<<"Check Updates"<<err; qCritical()<<"Check Updates"<<err;

View File

@ -19,11 +19,9 @@
#include "program/emultiwin.h" #include "program/emultiwin.h"
#include "program/gentmpthread.h" #include "program/gentmpthread.h"
#include "program/sendprogramdialog.h" #include "program/sendprogramdialog.h"
#include <QBoxLayout>
#include <QCloseEvent> #include <QCloseEvent>
#include <QGraphicsDropShadowEffect> #include <QGraphicsDropShadowEffect>
#include <QInputDialog> #include <QInputDialog>
#include <QJsonArray>
#include <QMessageBox> #include <QMessageBox>
#include <QSettings> #include <QSettings>
#include <QToolBar> #include <QToolBar>
@ -97,7 +95,7 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
action = new QAction(QIcon(":/res/program/Setting.png"), tr("Setting")); action = new QAction(QIcon(":/res/program/Setting.png"), tr("Setting"));
connect(action, &QAction::triggered, this, [this] { connect(action, &QAction::triggered, this, [this] {
QString widthsStr; QString widthsStr;
foreach(auto width, mProgItem->mSplitWidths) { for(auto &width : mProgItem->mSplitWidths) {
if(! widthsStr.isEmpty()) widthsStr.append(" "); if(! widthsStr.isEmpty()) widthsStr.append(" ");
widthsStr.append(QString::number(width)); widthsStr.append(QString::number(width));
} }
@ -108,14 +106,16 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
mProgItem->mRemark = dlg.fdRemark->toPlainText(); mProgItem->mRemark = dlg.fdRemark->toPlainText();
mProgItem->mSplitWidths.clear(); mProgItem->mSplitWidths.clear();
mProgItem->mMaxWidth = 0; mProgItem->mMaxWidth = 0;
if(dlg.fdIsUltraLong->isChecked()) {
auto splitWidths = dlg.fdSplitWidths->text().split(" ", Qt::SkipEmptyParts); auto splitWidths = dlg.fdSplitWidths->text().split(" ", Qt::SkipEmptyParts);
int ttl = 0; int ttl = 0;
foreach(auto splitWidth, splitWidths) { for(auto &splitWidth : splitWidths) {
int val = splitWidth.toInt(); int val = splitWidth.toInt();
if(val==0) continue; if(val==0) continue;
if(mProgItem->mMaxWidth < val) mProgItem->mMaxWidth = val; if(mProgItem->mMaxWidth < val) mProgItem->mMaxWidth = val;
ttl += val;
mProgItem->mSplitWidths.append(val); mProgItem->mSplitWidths.append(val);
ttl += val;
if(ttl>=mProgItem->mWidth) break;
} }
if(mProgItem->mMaxWidth) { if(mProgItem->mMaxWidth) {
while(ttl < mProgItem->mWidth) { while(ttl < mProgItem->mWidth) {
@ -124,12 +124,11 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
} }
if(ttl > mProgItem->mWidth) mProgItem->mSplitWidths.last() -= ttl - mProgItem->mWidth; if(ttl > mProgItem->mWidth) mProgItem->mSplitWidths.last() -= ttl - mProgItem->mWidth;
} }
}
mProgItem->m_last = QDateTime::currentDateTime(); mProgItem->m_last = QDateTime::currentDateTime();
mProgItem->m_fsize = dirFileSize(mProgItem->mProgDir); mProgItem->m_fsize = dirFileSize(mProgItem->mProgDir);
mProgItem->onSetProgram(); mProgItem->onSetProgram();
int cnt = listPage->count(); for(int i=0; i<listPage->count(); i++) {
for(int i=0; i<cnt; i++) {
auto page = (PageListItem*) listPage->item(i); auto page = (PageListItem*) listPage->item(i);
page->mScene->setSceneRect(0, 0, mProgItem->mWidth, mProgItem->mHeight); page->mScene->setSceneRect(0, 0, mProgItem->mWidth, mProgItem->mHeight);
page->mGraView->resetTransform(); page->mGraView->resetTransform();
@ -137,8 +136,8 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
page->mGraView->scale(scale, scale); page->mGraView->scale(scale, scale);
auto items = page->mScene->items(); auto items = page->mScene->items();
foreach(auto item, items) { for(auto item : items) {
auto element = static_cast<EBase*>(item); auto element = (EBase*) item;
if(element->mMultiWin == 0) element->fitProgSize(); if(element->mMultiWin == 0) element->fitProgSize();
} }
page->mScene->update(); page->mScene->update();
@ -184,11 +183,25 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
action->setData(EBase::Timer); action->setData(EBase::Timer);
toolBar->addAction(action); toolBar->addAction(action);
} }
action = new QAction(QIcon(":/res/program/demo-video.png"), tr("Demo Video")); action = new QAction(QIcon(":/res/program/demo-video.png"), tr("Demos"));
connect(action, &QAction::triggered, this, [this] { connect(action, &QAction::triggered, this, [this] {
auto file = QFileDialog::getOpenFileName(this, tr("Open Demo"), "Demos");
if(file.isEmpty()) return;
auto scene = mPageEditor->graphicsView->scene(); auto scene = mPageEditor->graphicsView->scene();
if(scene==0) return; if(scene==0) return;
auto eVideo = EVideo::create(mProgItem->mWidth>1280 && mProgItem->mHeight>720 ? "files/demo-video.mp4" : "files/demo-video-720.mp4", mPageItem); if(file.endsWith("png", Qt::CaseInsensitive)) {
auto ePhoto = EPhoto::create(file, mPageItem);
if(ePhoto==0) return;
auto rect = Tools::centerRect(ePhoto->img.width(), ePhoto->img.height(), mProgItem->mWidth, mProgItem->mHeight);
ePhoto->setPos(rect.topLeft());
ePhoto->setSize(rect.width(), rect.height());
ePhoto->setZValue(mPageEditor->sortedEles().count());
scene->addItem(ePhoto);
auto sels = scene->selectedItems();
if(sels.count() == 1) sels.at(0)->setSelected(false);
ePhoto->setSelected(true);
} else {
auto eVideo = EVideo::create(file, mPageItem);
if(eVideo==0) return; if(eVideo==0) return;
auto rect = Tools::centerRect(eVideo->mCoverImg.width(), eVideo->mCoverImg.height(), mProgItem->mWidth, mProgItem->mHeight); auto rect = Tools::centerRect(eVideo->mCoverImg.width(), eVideo->mCoverImg.height(), mProgItem->mWidth, mProgItem->mHeight);
eVideo->setPos(rect.topLeft()); eVideo->setPos(rect.topLeft());
@ -198,6 +211,7 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
auto sels = scene->selectedItems(); auto sels = scene->selectedItems();
if(sels.count() == 1) sels.at(0)->setSelected(false); if(sels.count() == 1) sels.at(0)->setSelected(false);
eVideo->setSelected(true); eVideo->setSelected(true);
}
}); });
toolBar->addAction(action); toolBar->addAction(action);
@ -218,11 +232,11 @@ ProgEditorWin::ProgEditorWin(ProgItem *progItem, QWidget *parent) : QWidget(pare
waitingDlg->exec(); waitingDlg->exec();
QFile file(mProgItem->mProgDir+"_tmp/program"); QFile file(mProgItem->mProgDir+"_tmp/program");
if(! file.open(QIODevice::ReadOnly | QIODevice::Text)) return; if(! file.open(QIODevice::ReadOnly | QIODevice::Text)) return;
QString value = file.readAll(); auto value = file.readAll();
file.close(); file.close();
QJsonParseError jsErr; QString jsErr;
auto prog = QJsonDocument::fromJson(value.toUtf8(), &jsErr).object(); auto prog = JFrom(value, &jsErr);
if(jsErr.error) return; if(! jsErr.isEmpty()) return;
int www = mProgItem->mWidth, hhh = mProgItem->mHeight; int www = mProgItem->mWidth, hhh = mProgItem->mHeight;
if(mProgItem->mMaxWidth) { if(mProgItem->mMaxWidth) {
www = mProgItem->mMaxWidth; www = mProgItem->mMaxWidth;
@ -539,11 +553,7 @@ bool ProgEditorWin::isProgChanged() {
auto page = (PageListItem*) listPage->item(i); auto page = (PageListItem*) listPage->item(i);
if(page->mAttrWgt==0) continue; if(page->mAttrWgt==0) continue;
page->updateJson(); page->updateJson();
if(page->mAttr != mPageJsons[i]) { if(page->mAttr != mPageJsons[i]) return true;
qDebug()<<page->mAttr;
qDebug()<<mPageJsons[i];
return true;
}
} }
return false; return false;
} }
@ -643,13 +653,13 @@ ProgCreateDlg::ProgCreateDlg(QString name, int width, int height, QString remark
#endif #endif
setWindowTitle(tr("Solution Information")); setWindowTitle(tr("Solution Information"));
auto vBox = new VBox(this); auto vBox = new VBox(this);
vBox->setContentsMargins(6,0,6,6);
auto hBox = new HBox(vBox); auto hBox = new HBox(vBox);
auto label = new QLabel(tr("Solution Name")); auto label = new QLabel(tr("Solution Name"));
label->setMinimumWidth(90); label->setMinimumWidth(90);
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter); label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
hBox->addWidget(label); hBox->addWidget(label);
hBox->addSpacing(6);
fdName = new QLineEdit; fdName = new QLineEdit;
if(name.isEmpty()) name = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz"); if(name.isEmpty()) name = QDateTime::currentDateTime().toString("yyyyMMddhhmmsszzz");
@ -689,21 +699,31 @@ ProgCreateDlg::ProgCreateDlg(QString name, int width, int height, QString remark
label->setMinimumWidth(90); label->setMinimumWidth(90);
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter); label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
hBox->addWidget(label); hBox->addWidget(label);
hBox->addSpacing(6);
fdRemark = new QTextEdit(remarks); fdRemark = new QTextEdit(remarks);
fdRemark->setFixedSize(300, 80); fdRemark->setFixedSize(300, 80);
hBox->addWidget(fdRemark); hBox->addWidget(fdRemark);
hBox = new HBox(vBox); vBox->addSpacing(6);
auto lbSplitWidth = new QLabel(tr("每段打折宽度 (用空格分隔)")); hBox = new HBox(vBox);
hBox->addSpacing(72);
fdIsUltraLong = new QCheckBox(tr("Ultra-Long Screen Split"));
if(! widths.isEmpty()) fdIsUltraLong->setChecked(true);
hBox->addWidget(fdIsUltraLong);
hBox = new HBox(vBox);
auto lbSplitWidth = new QLabel(tr("Part Width"));
lbSplitWidth->setMinimumWidth(90);
lbSplitWidth->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
hBox->addWidget(lbSplitWidth); hBox->addWidget(lbSplitWidth);
fdSplitWidths = new QLineEdit(widths); fdSplitWidths = new QLineEdit(widths.isEmpty() ? "1920" : widths);
fdSplitWidths->setPlaceholderText("256 256 256 ..."); fdSplitWidths->setPlaceholderText("1920");
hBox->addWidget(fdSplitWidths); hBox->addWidget(fdSplitWidths);
if(! gWidthSplit) { if(! gWidthSplit) {
fdIsUltraLong->setVisible(false);
lbSplitWidth->setVisible(false); lbSplitWidth->setVisible(false);
fdSplitWidths->setVisible(false); fdSplitWidths->setVisible(false);
} }

View File

@ -1,6 +1,7 @@
#ifndef PROGEDITORWIN_H #ifndef PROGEDITORWIN_H
#define PROGEDITORWIN_H #define PROGEDITORWIN_H
#include "program/pageeditor.h" #include "program/pageeditor.h"
#include <QCheckBox>
#include <QDialog> #include <QDialog>
#include <QSpinBox> #include <QSpinBox>
#include <QTextEdit> #include <QTextEdit>
@ -40,6 +41,7 @@ public:
QSpinBox *fdWidth; QSpinBox *fdWidth;
QSpinBox *fdHeight; QSpinBox *fdHeight;
QTextEdit *fdRemark; QTextEdit *fdRemark;
QCheckBox *fdIsUltraLong;
QLineEdit *fdSplitWidths; QLineEdit *fdSplitWidths;
}; };

View File

@ -121,11 +121,10 @@ SendProgramDialog::SendProgramDialog(QString progName, QWidget *parent) : QDialo
json.insert("_id", "VerifyPassword"); json.insert("_id", "VerifyPassword");
json.insert("_type", "VerifyPassword"); json.insert("_type", "VerifyPassword");
json.insert("pwd", pwd); json.insert("pwd", pwd);
auto waitingDlg = new WaitingDlg(this, tr("VerifyPassword")+" ..."); auto waitingDlg = new WaitingDlg(item->btnUnlock, tr("VerifyPassword")+" ...");
waitingDlg->show(); waitingDlg->show();
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json); auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(30000).post(json);
waitingDlg->connAbort(reply); ConnReply(reply, waitingDlg) [=] {
connect(reply, &QNetworkReply::finished, item->btnUnlock, [=] {
QJsonDocument json; QJsonDocument json;
auto err = checkReplyForJson(reply, &json); auto err = checkReplyForJson(reply, &json);
if(! err.isEmpty()) { if(! err.isEmpty()) {

View File

@ -44,6 +44,7 @@ void SendProgThread::run() {
req.insert("zVer", "xixun1"); req.insert("zVer", "xixun1");
auto requ = QJsonDocument(req).toJson(QJsonDocument::Compact); auto requ = QJsonDocument(req).toJson(QJsonDocument::Compact);
auto resNum = tcp.write(requ); auto resNum = tcp.write(requ);
tcp.flush();
if(resNum == -1 || ! tcp.waitForBytesWritten()) { if(resNum == -1 || ! tcp.waitForBytesWritten()) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when write 'consult'. size"+QString::number(requ.size())); emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when write 'consult'. size"+QString::number(requ.size()));
tcp.close(); tcp.close();
@ -89,8 +90,8 @@ void SendProgThread::run() {
if(res["_type"].toString()=="consult") { if(res["_type"].toString()=="consult") {
fileInfos.clear(); fileInfos.clear();
fileInfos.append(QFileInfo(prog_dir+"/program")); fileInfos.append(QFileInfo(prog_dir+"/program"));
QJsonArray ids = res["idList"].toArray(); auto ids = res["idList"].toArray();
foreach(auto id, ids) fileInfos.append(QFileInfo(prog_dir+"/"+id.toString())); for(auto id : ids) fileInfos.append(QFileInfo(prog_dir+"/"+id.toString()));
} }
} }
if(stoped) { if(stoped) {
@ -121,7 +122,8 @@ void SendProgThread::run() {
} }
//4.发送协商列表应答里的文件 //4.发送协商列表应答里的文件
long long sentBytes = 0; long long sentBytes = 0;
foreach(auto info, fileInfos) if(info.isFile()) { char buf[8192];
for(auto &info : fileInfos) if(info.isFile()) {
auto baseName = info.baseName(); auto baseName = info.baseName();
auto remain = info.size(); auto remain = info.size();
req = QJsonObject(); req = QJsonObject();
@ -143,8 +145,8 @@ void SendProgThread::run() {
return; return;
} }
while(remain > 0) { while(remain > 0) {
auto readed = file->read(qMin(4*4096LL, remain)); resNum = file->read(buf, qMin(8192LL, remain));
if(readed.isEmpty()) { if(resNum <= 0) {
emit emErr(tr("Read file failed")+" "+file->errorString()); emit emErr(tr("Read file failed")+" "+file->errorString());
tcp.close(); tcp.close();
file->close(); file->close();
@ -155,15 +157,15 @@ void SendProgThread::run() {
file->close(); file->close();
return; return;
}; };
resNum = tcp.write(readed); if(! tcp.waitForBytesWritten(60000)) {
if(resNum == -1) { emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when waitForWritten file: "+file->fileName());
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when write file: "+file->fileName());
tcp.close(); tcp.close();
file->close(); file->close();
return; return;
} }
if(! tcp.waitForBytesWritten(60000)) { resNum = tcp.write(buf, resNum);
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when waitForWritten file: "+file->fileName()); if(resNum <= 0) {
emit emErr(QString(socketErrKey(tcp.error()))+" ("+QString::number(tcp.error())+") "+tcp.errorString()+" when write file: "+file->fileName());
tcp.close(); tcp.close();
file->close(); file->close();
return; return;

View File

@ -16,7 +16,6 @@
const QString str0_9[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}; const QString str0_9[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
extern QTextEdit *gFdResInfo; extern QTextEdit *gFdResInfo;
extern ProgItem *gProgItem; extern ProgItem *gProgItem;
extern QString css;
class Tools : public QObject { class Tools : public QObject {
Q_OBJECT Q_OBJECT

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff