#include "devicepanel.h" #include "devicectrlpanel.h" #include "tools.h" #include "gqt.h" #include #include #include #include #include #include #include #include DevicePanel *gDevicePanel; QList *gSelCards; //设备管理响应页面 DevicePanel::DevicePanel(QSettings &settings, QWidget *parent) : QWidget(parent) { gDevicePanel = this; gSelCards = &mSelCards; setAutoFillBackground(true); QPalette pal; pal.setBrush(QPalette::Window, QColor(0xeeeeee)); setPalette(pal); auto vBox = new VBox(this); vBox->setContentsMargins(0, 0, 0, 0); vBox->setSpacing(0); auto hBox = new HBox(vBox); hBox->setContentsMargins(6, 2, 6, 2); hBox->setSpacing(2); auto label = new QLabel(); label->setPixmap({":/res/DeviceManager/DeviceNum_All.png"}); label->setScaledContents(true); label->setFixedSize(33, 24); hBox->addWidget(label); label_3 = new QLabel(tr("All")); hBox->addWidget(label_3); nDeviceNum = new QLabel(); nDeviceNum->setFixedSize(40, 20); hBox->addWidget(nDeviceNum); auto fdSearch = new QLineEdit(); fdSearch->setClearButtonEnabled(true); fdSearch->setFixedSize(220, 30); fdSearch->addAction(new QAction(QIcon(":/res/ProgramManager/bnSearch.png"), QString()), QLineEdit::LeadingPosition); fdSearch->setStyleSheet("border: 1px solid #aaaaaa;"); connect(fdSearch, &QLineEdit::textChanged, this, &DevicePanel::FilterProgram); hBox->addWidget(fdSearch); hBox->addSpacing(10); fdCardNumInfo = new QLabel(tr("Current Screen")+": "+tr("none")); fdCardNumInfo->setStyleSheet("QLabel{color: #15f;}"); fdCardNumInfo->hide(); hBox->addWidget(fdCardNumInfo); hBox->addStretch(); auto areaFlash = new QWidget(); areaFlash->setFixedSize(100, 34); bnSpecifyIP = new QComboBox(areaFlash); bnSpecifyIP->addItem(tr("Specify IP")); bnSpecifyIP->setGeometry(0, 0, areaFlash->width(), areaFlash->height()); bnSpecifyIP->setItemDelegate(new QStyledItemDelegate); connect(bnSpecifyIP, &QComboBox::textActivated, this, [this] { mUdpTimer.stop(); specifyIPDlg->exec(); mUdpTimer.start(30000); }); bnSpecifyIP->setStyleSheet(R"rrr( QComboBox { border: none; border-radius: 5px; background-color: #19c; } QComboBox:hover {background-color: #08b;} QComboBox::drop-down {width: 25px;} QComboBox::down-arrow {image: url(:/res/DeviceManager/FlashArrow.png);} QComboBox QAbstractItemView::item { height: 28px; color: #fff; } QComboBox QAbstractItemView::item:selected {background-color: #09c;} )rrr"); btnRefresh = new QPushButton(tr("Refresh"), areaFlash); btnRefresh->setGeometry(0, 0, 75, areaFlash->height()); connect(btnRefresh, &QPushButton::clicked, this, [this] { LedCardList.clear(); mDeviceTable->onCheckAll(false); mDeviceTable->clear(); nDeviceNum->setText("0"); sendGetInfo(); }); btnRefresh->setStyleSheet(R"rrr( QPushButton { border-radius: 5px; background-color: #19c; color: #fff; } QPushButton:hover {background-color: #08b;} )rrr"); hBox->addWidget(areaFlash); mHBox = new QHBoxLayout(); mDeviceTable = new LoQTreeWidget(this); mDeviceTable->setIndentation(0); mDeviceTable->setSortingEnabled(true); mHBox->addWidget(mDeviceTable); vBox->addLayout(mHBox); connect(&mUdpTimer, &QTimer::timeout, this, &DevicePanel::sendGetInfo); connect(&mUdpSocket, &QUdpSocket::readyRead, this, [this] { while(mUdpSocket.hasPendingDatagrams()) { auto gram = mUdpSocket.receiveDatagram(); auto data = gram.data(); if(data.isEmpty()) continue; auto senderAddress = gram.senderAddress(); bool ok = true; if(senderAddress.protocol()==QUdpSocket::IPv6Protocol) senderAddress.setAddress(senderAddress.toIPv4Address(&ok)); auto addr = ok ? senderAddress.toString() : ""; if(data.startsWith("{\"")) { QJsonParseError error; QJsonDocument document = QJsonDocument::fromJson(gram.data(), &error); if(error.error != QJsonParseError::NoError) { qDebug()<<"DeviceItem OnProHttpResponse 解析json文件错误!"; continue; } parseInfo(document.object(), addr); } else { auto bytes = gram.data(); STREAM_PACKET *pStreamPacket = (STREAM_PACKET *)bytes.data(); LedCard *pLedCard = new LedCard(this);//alahover 没有释放 pLedCard->m_strCardId = pStreamPacket->ucSerialCode; pLedCard->m_strCardIp = addr; for(int i=0;im_strCardId==pLedCard->m_strCardId ) {//如果已经存在在列表中 auto pOldLedCard = LedCardList.at(i);//获取到旧的对象指针 pOldLedCard->m_bOnLine = true; if(pOldLedCard->CompareHTTPGetParam(pLedCard)==false) {//如果ip地址变化了 pOldLedCard->copyLedCardHTTPGetParam(pLedCard); addLedCard(pOldLedCard);//发送信号到界面 } else { //post失败的概率比较小,所以这里是否需要平凡的更新,不需要刻意屏蔽该操作改为在其他点击操作中进行 clearUdpHeartbeat(pOldLedCard); } delete pLedCard; return; } LedCardList.append(pLedCard); addLedCard(pLedCard);//发送信号到界面 } } }); m_headerItem = new QTreeWidgetItem(); for(int i=1; isetTextAlignment(i, Qt::AlignCenter); mDeviceTable->setHeaderItem(m_headerItem); mDeviceTable->header()->setSectionResizeMode(DeviceTable_Check, QHeaderView::Fixed); mDeviceTable->setColumnWidth(DeviceTable_Check, 48); 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, SIGNAL(sigCheckStateChanged(int)), this, SLOT(onCheckStateChanged(int))); mDeviceTable->setSelectionMode(QAbstractItemView::SingleSelection); mDeviceTable->hideColumn(0); mDeviceTable->fdIsSelAll->hide(); specifyIPDlg = new QDialog(this); specifyIPDlg->setWindowTitle(tr("Specify IP")); vBox = new VBox(specifyIPDlg); vBox->addStretch(); label = new QLabel(tr("Specify IP list")); label->setAlignment(Qt::AlignCenter); vBox->addWidget(label); fdIP = new QTextEdit; auto ipstr = settings.value("SpecifyIP").toString(); if(! ipstr.isEmpty()) fdIP->setText(ipstr); fdIP->setPlaceholderText("192.168.1.1\n192.168.1.2\n ..."); fdIP->setMinimumWidth(160); vBox->addWidget(fdIP); hBox = new HBox(vBox); hBox->addStretch(); auto bnSearch = new QPushButton(tr("Search")); connect(bnSearch, &QPushButton::clicked, this, [this] { QString ipsStr = fdIP->toPlainText(); if(ipsStr.isEmpty()) { QMessageBox::warning(gMainWin, tr("Attention"), tr("Please input IP address!")); return; } auto ips = ipsStr.split("\n", Qt::SkipEmptyParts); if(ips.isEmpty()) { QMessageBox::warning(gMainWin, tr("Attention"), tr("Please input IP address!")); return; } QByteArray data = QJsonDocument({{"action", "getInfo"}}).toJson(QJsonDocument::Compact); foreach(auto ip, ips) { if(gDevicePanel->mUdpSocket.writeDatagram(data, QHostAddress(ip), 22222) != data.length()) qDebug() << "Specify IP write Failed." << ip; } specifyIPDlg->accept(); }); hBox->addWidget(bnSearch); auto btnCancel = new QPushButton(tr("Cancel")); connect(btnCancel, &QPushButton::clicked, specifyIPDlg, &QDialog::reject); hBox->addWidget(btnCancel); hBox->addStretch(); transUi(); sendGetInfo(); mUdpTimer.start(30000); } DevicePanel::~DevicePanel() { mUdpSocket.close(); mUdpTimer.stop(); } void DevicePanel::sendGetInfo() { QByteArray data = QJsonDocument({{"action", "getInfo"}}).toJson(QJsonDocument::Compact); // if(mUdpSocket.writeDatagram(data, QHostAddress("255.255.255.255"), 22222) != data.length()) { // qDebug() << "getInfo writeDatagram to 255.255.255.255 Failed"; // } QList networkinterfaces = QNetworkInterface::allInterfaces(); foreach(QNetworkInterface face, networkinterfaces) { auto flags = face.flags(); bool can = (flags & QNetworkInterface::IsRunning) && (flags & QNetworkInterface::CanBroadcast) && ! (flags & QNetworkInterface::IsLoopBack); if(! can) continue; qDebug() << face; auto addrEntries = face.addressEntries(); foreach(QNetworkAddressEntry addrEntry, addrEntries) { auto ip = addrEntry.ip(); if(ip.protocol()!=QAbstractSocket::IPv4Protocol) continue; auto broadcast = addrEntry.broadcast(); if(mUdpSocket.writeDatagram(data, broadcast, 22222) != data.length()) qDebug() << "getInfo writeDatagram Failed." << ip.toString() << "->" << broadcast.toString(); } } auto ipstr = fdIP->toPlainText(); if(! ipstr.isEmpty()) { auto ips = ipstr.split("\n", Qt::SkipEmptyParts); foreach(auto ip, ips) { if(gDevicePanel->mUdpSocket.writeDatagram(data, QHostAddress(ip), 22222) != data.length()) qDebug() << "Specify IP write Failed." << ip; } } } void DevicePanel::ShowDevicesInfoOrControlWidget(int index){ m_intIndexFlagOfInfoOrControl=index; if(index==MainPage_DeviceManager) { //设备信息列表页面 mDeviceTable->hideColumn(0); mDeviceTable->fdIsSelAll->hide(); if(mDeviceCtrlPanel!=nullptr) { for(int j=DeviceTable_ScreenSize;jshowColumn(j); mDeviceTable->setMaximumWidth(0xffffff); mDeviceCtrlPanel->hide(); fdCardNumInfo->hide(); } } else if(index==MainPage_Setting) { //终端控制页面 mDeviceTable->showColumn(0); mDeviceTable->fdIsSelAll->show(); for(int j=DeviceTable_ScreenSize; jhideColumn(j); if(mDeviceCtrlPanel==nullptr) mHBox->addWidget(mDeviceCtrlPanel = new DeviceCtrlPanel(this)); else mDeviceCtrlPanel->show(); fdCardNumInfo->show(); mDeviceTable->setMaximumWidth(340); GetSelectDeviceNum(); emit sigSelectedDeviceList(&mSelCards); } int cnt = mDeviceTable->topLevelItemCount(); if(cnt>0)//切换到终点管理页面是刷新列表中控制卡的状态参数 for(int i=0; i(mDeviceTable->topLevelItem(i))->SetMainTabWidgetIndex(m_intIndexFlagOfInfoOrControl); } void DevicePanel::changeEvent(QEvent *event) { QWidget::changeEvent(event); if(event->type() == QEvent::LanguageChange) transUi(); } void DevicePanel::transUi() { btnRefresh->setText(tr("Refresh")); bnSpecifyIP->setItemText(0,tr("Specify IP")); label_3->setText(tr("All")); m_headerItem->setData(DeviceTable_Check, 0, ""); m_headerItem->setData(DeviceTable_Online, 0, tr("Online")); m_headerItem->setData(DeviceTable_ID, 0, tr("Screen ID")); m_headerItem->setData(DeviceTable_IP, 0, tr("Screen IP")); m_headerItem->setData(DeviceTable_ScreenSize, 0, tr("Screen Size")); m_headerItem->setData(DeviceTable_Remark, 0, tr("Remark Name")); m_headerItem->setData(DeviceTable_Screenshot, 0, tr("readback pic")); m_headerItem->setData(DeviceTable_Brightness, 0, tr("Cur Brightness")); m_headerItem->setData(DeviceTable_Power, 0, tr("Power Status")); m_headerItem->setData(DeviceTable_Password, 0, tr("Security")); m_headerItem->setData(DeviceTable_Info, 0, tr("More Info")); auto cnt = mDeviceTable->topLevelItemCount(); for(int i=0; i(mDeviceTable->topLevelItem(i))->refreshLable(); } void DevicePanel::FilterProgram(const QString &strtemp){ if (strtemp.isEmpty()) //显示全部 { for (int i = 0; i< mDeviceTable->topLevelItemCount(); ++i){ QTreeWidgetItem* topItem = mDeviceTable->topLevelItem(i); mDeviceTable->setRowHidden(i,mDeviceTable->indexFromItem(topItem->parent()),false); } } else { QList resultList = mDeviceTable->findItems(strtemp, Qt::MatchContains,DeviceTable_ID); //搜索结果 if (resultList.size() > 0) { for (int i = 0; i< mDeviceTable->topLevelItemCount(); ++i) { QTreeWidgetItem* topItem = mDeviceTable->topLevelItem(i); if (resultList.contains(topItem)) mDeviceTable->setRowHidden(i,mDeviceTable->indexFromItem(topItem->parent()),false); //显示匹配的结果 else mDeviceTable->setRowHidden(i,mDeviceTable->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果 } } else { QList resultList1 = mDeviceTable->findItems(strtemp, Qt::MatchContains,DeviceTable_Remark); //搜索结果 if (resultList1.size() > 0) { for (int i = 0; i< mDeviceTable->topLevelItemCount(); ++i) { QTreeWidgetItem* topItem = mDeviceTable->topLevelItem(i); if (resultList1.contains(topItem)) mDeviceTable->setRowHidden(i,mDeviceTable->indexFromItem(topItem->parent()),false); //显示匹配的结果 else mDeviceTable->setRowHidden(i,mDeviceTable->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果 } } else { QList resultList2 = mDeviceTable->findItems(strtemp, Qt::MatchContains,DeviceTable_IP); //搜索结果 if (resultList2.size() > 0) { for (int i = 0; i< mDeviceTable->topLevelItemCount(); ++i) { QTreeWidgetItem* topItem = mDeviceTable->topLevelItem(i); if (resultList2.contains(topItem)) mDeviceTable->setRowHidden(i,mDeviceTable->indexFromItem(topItem->parent()),false); //显示匹配的结果 else mDeviceTable->setRowHidden(i,mDeviceTable->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果 } } else { for (int i = 0; i< mDeviceTable->topLevelItemCount(); ++i) { QTreeWidgetItem* topItem = mDeviceTable->topLevelItem(i); mDeviceTable->setRowHidden(i,mDeviceTable->indexFromItem(topItem->parent()),true); //隐藏不匹配的结果 } } } } } } void DevicePanel::OnControlTcpSend(int iProgramIndex){ int cnt = mDeviceTable->topLevelItemCount(); for(int i=0; itopLevelItem(i)->checkState(0) == Qt::Checked) static_cast(mDeviceTable->topLevelItem(i))->OnControlTcpSend(iProgramIndex); } void DevicePanel::OnControlSendJson(QJsonObject &json,QString strFanYi){ int cnt = mDeviceTable->topLevelItemCount(); for(int i=0; itopLevelItem(i)->checkState(0) == Qt::Checked) { DeviceItem *item = static_cast(mDeviceTable->topLevelItem(i)); item->HttpPostByTypeJsonObject(json); QString strCardId=item->m_pLedCard->m_strCardId; mDeviceCtrlPanel->OnOutputInfo(strCardId+":"+tr("send")+"->"+strFanYi); } } int DevicePanel::GetSelectDeviceNum() { int cnt = mDeviceTable->topLevelItemCount(); int iSelectCount=0; mSelCards.clear(); for(int i=0; itopLevelItem(i)->checkState(0) == Qt::Checked) { iSelectCount++; mSelCards.append(static_cast(mDeviceTable->topLevelItem(i))->m_pLedCard); } return iSelectCount; } void DevicePanel::OnOutputInfo(QString strInfo) { if(m_intIndexFlagOfInfoOrControl==MainPage_Setting && mDeviceCtrlPanel!=nullptr) mDeviceCtrlPanel->OnOutputInfo(strInfo); } void DevicePanel::onCheckStateChanged(int f){ Q_UNUSED(f); if(m_intIndexFlagOfInfoOrControl==MainPage_Setting){ GetSelectDeviceNum(); emit sigSelectedDeviceList(&mSelCards); } } void DevicePanel::addLedCard(LedCard *p){ int cnt = mDeviceTable->topLevelItemCount(); for(int i=0; i(mDeviceTable->topLevelItem(i)); if(item->m_pLedCard->m_strCardId != p->m_strCardId) continue; item->setData(DeviceTable_ID, 0, p->m_strCardId); item->setData(DeviceTable_IP, 0, p->m_strCardIp); item->setData(DeviceTable_ScreenSize, 0, QString("%1 x %2").arg(p->m_iWidth).arg(p->m_iHeight)); return; } new DeviceItem(p, mDeviceTable, this); nDeviceNum->setText(QString::number(mDeviceTable->topLevelItemCount())); } void DevicePanel::clearUdpHeartbeat(LedCard *p) { int cnt = mDeviceTable->topLevelItemCount(); for(int i=0; i(mDeviceTable->topLevelItem(i)); if(item->m_pLedCard->m_strCardId != p->m_strCardId) continue; item->m_HeartbeatCount = 0; if(item->m_ImageOnline) { item->m_pLedCard->m_bOnLine = true; item->m_ImageOnline->setPixmap(QPixmap(":/res/DeviceManager/O_Online.png")); } return; } } void DevicePanel::parseInfo(const QJsonObject &subObj, const QString &strIp) { LedCard *pLedCard = new LedCard(this);//alahover 没有释放 pLedCard->m_strCardId=subObj["cardId"].toString(); if(! strIp.isEmpty()) pLedCard->m_strCardIp = strIp; else { pLedCard->m_strCardIp = subObj["newIp"].toString(); if(pLedCard->m_strCardIp.isEmpty()) pLedCard->m_strCardIp = subObj["ip"].toString(); } pLedCard->m_iWidth=subObj["width"].toInt(); pLedCard->m_iHeight=subObj["height"].toInt(); pLedCard->starterversionName=subObj["versionName"].toString(); pLedCard->starterPort=subObj["starterPort"].toInt(); pLedCard->androidVersion=subObj["androidVersion"].toString(); pLedCard->iHttpGetId=subObj["id"].toInt(); pLedCard->androidHeight=subObj["androidHeight"].toInt(); pLedCard->androidWidth=subObj["androidWidth"].toInt(); pLedCard->lastActive=subObj["lastActive"].toInt(); for(int i=0;im_strCardId==pLedCard->m_strCardId ) { //如果已经存在在列表中 auto pOldLedCard = LedCardList.at(i);//获取到旧的对象指针 pOldLedCard->m_bOnLine = true; if(! pOldLedCard->CompareHTTPGetParam(pLedCard)) {//如果ip地址变化了 pOldLedCard->copyLedCardHTTPGetParam(pLedCard); addLedCard(pOldLedCard);//发送信号到界面 } else { //post失败的概率比较小,所以这里是否需要平凡的更新,不需要刻意屏蔽该操作改为在其他点击操作中进行 clearUdpHeartbeat(pOldLedCard); } delete pLedCard; return; } LedCardList.append(pLedCard); addLedCard(pLedCard);//发送信号到界面 } STREAM_PACKET LedOkMakeStreamPacket(int iComType,int iLen,unsigned char *ucBuf,QString str) { STREAM_PACKET Temp; memset(&Temp, 0, sizeof(STREAM_PACKET)); if(iLen>2048) return Temp; memset(Temp.SyncHead,STREAM_SYNC_HEAD,STREAM_SYNC_HEAD_NUM); memset(Temp.ucSerialCode,0x00,20); char* ch; QByteArray ba = str.toLatin1(); // must ch=ba.data(); memcpy(Temp.ucSerialCode,ch,ba.size()); Temp.iLength=iLen; Temp.ucCommType=iComType; memcpy(Temp.pDataBuffer,ucBuf,iLen); Temp.pDataBuffer[Temp.iLength] = GetCheckCodeIn8(&Temp.ucCommType,Temp.iLength+sizeof(Temp.ucCommType)+sizeof(char)*20+sizeof(Temp.iLength)); return Temp; } //UDP多网卡广播 void DevicePanel::RestoreLedCardIpByUdpCmd() { QList networkinterfaces = QNetworkInterface::allInterfaces(); foreach (QNetworkInterface interfaces, networkinterfaces) {//networkinterfaces负责提供主机的IP地址和网络接口的列表 foreach (QNetworkAddressEntry entry, interfaces.addressEntries()) {//QNetworkAddressEntry存储了一个IP地址,子网掩码和广播地址 entry.setBroadcast(QHostAddress::Broadcast); QHostAddress broadcastAddress("255.255.255.255"); entry.setBroadcast(QHostAddress::Broadcast); RESTORE_IP stTempIp; memset(&stTempIp,0x00,sizeof(RESTORE_IP)); QString strNew=entry.ip().toString(); int itempOffset = strNew.lastIndexOf("."); QString sstrNew=strNew.left(itempOffset)+".254"; if(sstrNew.length()<=20) memcpy(stTempIp.cNewIp,sstrNew.toLatin1().data(),sstrNew.length()); QString strMask=entry.netmask().toString(); if(strMask.length()<=20) memcpy(stTempIp.cMask,strMask.toLatin1().data(),strMask.length()); QString strGateway=entry.ip().toString(); if(strGateway.length()<=20) memcpy(stTempIp.cGateway,strGateway.toLatin1().data(),strGateway.length()); if(strGateway.length()<=20) memcpy(stTempIp.cDns,strGateway.toLatin1().data(),strGateway.length()); STREAM_PACKET tempStreadPacket = LedOkMakeStreamPacket(COMMAND_ONLY_RESET_CARD_IP, 80, (unsigned char *)&stTempIp,"Broadcast!"); int iLenPacket=tempStreadPacket.iLength+sizeof(int)+STREAM_SYNC_HEAD_NUM*sizeof(unsigned char)+sizeof(char)+20*sizeof(char)+sizeof(char);/////除正文外的协议结构大小; QUdpSocket *tempUdpSocket = new QUdpSocket(this); if(!tempUdpSocket->bind(entry.ip())) break; tempUdpSocket->writeDatagram((char *)&tempStreadPacket,iLenPacket,broadcastAddress, 31296); } } }