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) {
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 += separate_debug_info
}

View File

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

View File

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

View File

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

View File

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

View File

@ -93,7 +93,7 @@ QString checkReplyForJson(QNetworkReply *, QString errField);
waitingDlg->show();\
auto card = gSelCards[0];\
auto reply = NetReq("http://"+card.ip+":2016/settings").timeout(120000).post(json);\
waitingDlg->connAbort(reply);
connect(waitingDlg, &WaitingDlg::rejected, reply, &QNetworkReply::deleteLater);
#define Def_CtrlSetReqAfter \
QString err = checkReplyForJson(reply);\

View File

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

View File

@ -6,7 +6,7 @@
const Qt::Alignment AlignRight = Qt::AlignRight | Qt::AlignVCenter;
ColItem TreeWidget::addCol(const QString& field, const QString& text, int width, QHeaderView::ResizeMode resizeMode) {
int i = fdmap.size();
int i = (int) fdmap.size();
auto item = headerItem();
item->setText(i, text);
item->setData(i, FieldRole, field);
@ -106,8 +106,40 @@ bool TreeWidget::adjSections(int index, int size) {
class TreeItemMarginStyle : public QProxyStyle {
public:
using QProxyStyle::QProxyStyle;
TreeItemMarginStyle(QWidget *wgt) : QProxyStyle(wgt->style()), _wgt(wgt) {}
TreeItemMarginStyle(TreeWidget *wgt) : QProxyStyle(wgt->style()), _wgt(wgt) {}
#if(QT_VERSION_MAJOR > 5)
void drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override { //draw big indicator and cell focus mask
if(option && option->type==QStyleOption::SO_ViewItem && ((QStyleOptionViewItem*) option)->features & QStyleOptionViewItem::HasCheckIndicator && widget==_wgt) { //PE_PanelItemViewItem PE_IndicatorItemViewItemCheck
auto opt = (QStyleOptionViewItem*) option;
auto add = _wgt->headerItem()->data(opt->index.column(), MarginRole).toInt();
if(add) {
if(element==PE_IndicatorItemViewItemCheck) opt->rect.translate(add, 0); //move big indicator
else if((opt->features & QStyleOptionViewItem::HasDisplay)==0) opt->rect.setLeft(opt->rect.right() + 1); //remove cell focus mask
else {
opt->rect.setLeft(opt->rect.x() + (add << 1)); //move cell focus mask
if(opt->rect.width() < 0) opt->rect.setWidth(0);
}
}
}
QProxyStyle::drawPrimitive(element, option, painter, widget);
}
void drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget = nullptr) const override { //draw text, small indicator and focus mask around text
if(option && widget==_wgt) {
auto opt = (QStyleOptionViewItem*) option;
opt->state &= ~State_HasFocus; //remove focus mask around text
if(element==CE_ItemViewItem && option->type==QStyleOption::SO_ViewItem) {
auto add = _wgt->headerItem()->data(opt->index.column(), MarginRole).toInt();
if(add) { //move text and small indicator
if(opt->displayAlignment & Qt::AlignRight) opt->rect.setRight(opt->rect.right() - add);
if(opt->features & QStyleOptionViewItem::HasCheckIndicator) opt->rect.setLeft(opt->rect.x() + (add<<1));
else if((opt->displayAlignment & (Qt::AlignHCenter | Qt::AlignRight))==0) opt->rect.setLeft(opt->rect.x() + add);
if(opt->rect.width() < 0) opt->rect.setWidth(0);
}
}
}
QProxyStyle::drawControl(element, option, painter, widget);
}
#else
QRect subElementRect(SubElement element, const QStyleOption *option, const QWidget *widget) const override {
auto res = QProxyStyle::subElementRect(element, option, widget);
auto width = res.width();
@ -125,9 +157,11 @@ public:
}
}
} else if(((QStyleOptionViewItem*)option)->features & QStyleOptionViewItem::HasCheckIndicator) {
auto add = ((TreeWidget*)widget)->headerItem()->data(((QStyleOptionViewItem*)option)->index.column(), MarginRole).toInt();
auto index = ((QStyleOptionViewItem*)option)->index;
auto add = ((TreeWidget*)widget)->headerItem()->data(index.column(), MarginRole).toInt();
if(add) {
add += add>>1;
if(width < (add+3)<<1) add = width;
else add += add>>1;
res.setLeft(res.x() + add);
if(width < add) res.setWidth(0);
}
@ -140,7 +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();
return res;
}
QWidget *_wgt = 0;
#endif
TreeWidget *_wgt = 0;
};
ColItem &ColItem::margin(int margin) {

View File

@ -293,11 +293,11 @@ protected:
};
inline int operator*(const QString& key, QTreeView &table) {
if((size_t)&table==0) return 0;
if((size_t)&table==0) return -1;
return ((TreeWidget&)table).fdmap.at(key);
}
inline int operator*(const char *key, QTreeView &table) {
if((size_t)&table==0) return 0;
if((size_t)&table==0) return -1;
return ((TreeWidget&)table).fdmap.at(key);
}

View File

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

View File

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

View File

@ -22,6 +22,22 @@ QString errStr(QNetworkReply *reply) {
if(status != 200) return QString::number(status)+" "+reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString();
return "";
}
QString errStrWithData(QNetworkReply *reply, JValue *outJson) {
auto err = errStr(reply);
if(! err.isEmpty()) {
auto data = reply->readAll();
if(! data.isEmpty()) err += "\n"+data;
return err;
}
if(outJson) {
auto data = reply->readAll();
QString error;
*outJson = JFrom(data, &error);
if(! error.isEmpty()) return "JSON "+QCoreApplication::translate("Net","Error")+": "+error+"\n"+data;
}
return "";
}
QString errStrWithData(QNetworkReply *reply, QJsonDocument *outJson) {
auto err = errStr(reply);
if(! err.isEmpty()) {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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