ukui-screensaver/BiometricAuth/biometricdeviceswidget.cpp

280 lines
8.5 KiB
C++

/*
* Copyright (C) 2018 Tianjin KYLIN Information Technology Co., Ltd.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
**/
#include "biometricdeviceswidget.h"
#include <QLabel>
#include <QPushButton>
#include <QComboBox>
#include <QDebug>
#include <QAbstractItemView>
#include <QStyledItemDelegate>
BiometricDevicesWidget::BiometricDevicesWidget(BiometricProxy *proxy, int uid,QWidget *parent)
: QWidget(parent),
proxy(proxy),
m_uid(uid)
{
initUI();
if(proxy && proxy->isValid())
{
connect(proxy, &BiometricProxy::USBDeviceHotPlug,
this, &BiometricDevicesWidget::onUSBDeviceHotPlug);
updateDevice();
}
resize(500, 500);
}
void BiometricDevicesWidget::initUI()
{
lblPrompt = new QLabel(this);
lblPrompt->setObjectName(QStringLiteral("lblBioetricDevicesPrompt"));
lblPrompt->setText(tr("Please select the biometric device"));
lblPrompt->setAlignment(Qt::AlignHCenter);
lblDeviceType = new QLabel(this);
lblDeviceType->setObjectName(QStringLiteral("lblDeviceType"));
lblDeviceType->setText(tr("Device type:"));
lblDeviceType->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
QStyledItemDelegate* itemDelegate = new QStyledItemDelegate();
cmbDeviceType = new QComboBox(this);
cmbDeviceType->view()->parentWidget()->setWindowFlags(Qt::Popup|Qt::FramelessWindowHint);
cmbDeviceType->view()->parentWidget()->setAttribute(Qt::WA_TranslucentBackground);
cmbDeviceType->setObjectName(QStringLiteral("cmbDeviceType"));
cmbDeviceType->setMaxVisibleItems(5);
cmbDeviceType->setItemDelegate(itemDelegate);
connect(cmbDeviceType, SIGNAL(currentIndexChanged(int)),
this, SLOT(onCmbDeviceTypeCurrentIndexChanged(int)));
lblDeviceName = new QLabel(this);
lblDeviceName->setObjectName(QStringLiteral("lblDeviceName"));
lblDeviceName->setText(tr("Device name:"));
lblDeviceName->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
cmbDeviceName = new QComboBox(this);
cmbDeviceName->view()->parentWidget()->setWindowFlags(Qt::Popup|Qt::FramelessWindowHint);
cmbDeviceName->view()->parentWidget()->setAttribute(Qt::WA_TranslucentBackground);
cmbDeviceName->setObjectName(QStringLiteral("cmbDeviceName"));
cmbDeviceName->setMaxVisibleItems(5);
cmbDeviceName->setItemDelegate(itemDelegate);
btnOK = new QPushButton(tr("OK"), this);
btnOK->setObjectName(QStringLiteral("OKButton"));
btnOK->setCursor(Qt::PointingHandCursor);
connect(btnOK, &QPushButton::clicked,
this, &BiometricDevicesWidget::onOKButtonClicked);
}
void BiometricDevicesWidget::setUser(int user)
{
m_uid = user;
}
void BiometricDevicesWidget::resizeEvent(QResizeEvent */*event*/)
{
lblPrompt->setGeometry(0, 0, width(), 40);
lblDeviceType->setGeometry(100, lblPrompt->geometry().bottom() + 40,
120, 20);
cmbDeviceType->setGeometry(100, lblDeviceType->geometry().bottom() + 15,
300, 40);
lblDeviceName->setGeometry(100, cmbDeviceType->geometry().bottom() + 80,
120, 20);
cmbDeviceName->setGeometry(100, lblDeviceName->geometry().bottom() + 15,
300, 40);
btnOK->setGeometry(100, cmbDeviceName->geometry().bottom() + 80, 140, 38);
}
void BiometricDevicesWidget::updateDevice()
{
deviceMap.clear();
DeviceList deviceList = proxy->GetDevList();
for(auto pDeviceInfo : deviceList)
{
qDebug() << *pDeviceInfo;
if(proxy->GetUserDevFeatureCount(m_uid,pDeviceInfo->id) > 0)
deviceMap[pDeviceInfo->deviceType].push_back(pDeviceInfo);
}
cmbDeviceType->clear();
for(int type : deviceMap.keys())
{
QString iconPath = QString(UKUI_BIOMETRIC_IMAGES_PATH"icon/%1.png")
.arg(DeviceType::getDeviceType(type));
qDebug() << iconPath;
cmbDeviceType->addItem(QIcon(iconPath), DeviceType::getDeviceType_tr(type), type);
}
if(deviceMap.size() > 0)
{
int index = deviceMap.keys().at(0);
setCurrentDevice(deviceMap[index].at(0));
}
}
void BiometricDevicesWidget::setCurrentDevice(int drvid)
{
DeviceInfoPtr pDeviceInfo = findDeviceById(drvid);
if(pDeviceInfo)
{
setCurrentDevice(pDeviceInfo);
}
}
void BiometricDevicesWidget::setCurrentDevice(const QString &deviceName)
{
DeviceInfoPtr pDeviceInfo = findDeviceByName(deviceName);
if(pDeviceInfo)
{
setCurrentDevice(pDeviceInfo);
}
}
void BiometricDevicesWidget::setCurrentDevice(const DeviceInfoPtr &pDeviceInfo)
{
this->currentDevice = pDeviceInfo;
cmbDeviceType->setCurrentText(DeviceType::getDeviceType_tr(pDeviceInfo->deviceType));
cmbDeviceName->setCurrentText(pDeviceInfo->shortName);
}
bool BiometricDevicesWidget::deviceExists(int drvid)
{
return (findDeviceById(drvid) != nullptr);
}
bool BiometricDevicesWidget::deviceExists(const QString &deviceName)
{
return (findDeviceByName(deviceName) != nullptr);
}
DeviceInfoPtr BiometricDevicesWidget::findDeviceById(int drvid)
{
for(int type : deviceMap.keys())
{
DeviceList &deviceList = deviceMap[type];
auto iter = std::find_if(deviceList.begin(), deviceList.end(),
[&](DeviceInfoPtr ptr){
return ptr->id == drvid;
});
if(iter != deviceList.end())
{
return *iter;
}
}
return DeviceInfoPtr();
}
DeviceInfoPtr BiometricDevicesWidget::findDeviceByName(const QString &name)
{
for(int type : deviceMap.keys())
{
DeviceList &deviceList = deviceMap[type];
auto iter = std::find_if(deviceList.begin(), deviceList.end(),
[&](DeviceInfoPtr ptr){
return ptr->shortName == name;
});
if(iter != deviceList.end())
{
return *iter;
}
}
return DeviceInfoPtr();
}
void BiometricDevicesWidget::onCmbDeviceTypeCurrentIndexChanged(int index)
{
if(index < 0 || index >= deviceMap.keys().size())
{
return;
}
int type = cmbDeviceType->itemData(index).toInt();
cmbDeviceName->clear();
for(auto &deviceInfo : deviceMap.value(type))
{
cmbDeviceName->addItem(deviceInfo->shortName);
}
}
void BiometricDevicesWidget::onOKButtonClicked()
{
int type = cmbDeviceType->currentData().toInt();
int index = cmbDeviceName->currentIndex();
qDebug() << type << index;
DeviceInfoPtr deviceInfo = deviceMap.value(type).at(index);
Q_EMIT deviceChanged(deviceInfo);
hide();
}
void BiometricDevicesWidget::onUSBDeviceHotPlug(int drvid, int action, int /*devNum*/)
{
int savedDeviceId = currentDevice->id;
int savedCount = 0;
for(int type : deviceMap.keys())
savedCount += deviceMap.value(type).count();
switch(action)
{
case ACTION_ATTACHED:
{
//插入设备后,需要更新设备列表
deviceMap.clear();
updateDevice();
setCurrentDevice(savedDeviceId);
break;
}
case ACTION_DETACHED:
{
DeviceInfoPtr pDeviceInfo = findDeviceById(drvid);
if(pDeviceInfo)
{
int type = pDeviceInfo->deviceType;
deviceMap[type].removeOne(pDeviceInfo);
int index = cmbDeviceName->findText(pDeviceInfo->shortName);
cmbDeviceName->removeItem(index);
//如果该类型的设备全被移除,删除该类型相关的列表
if(deviceMap[type].isEmpty())
{
deviceMap.remove(type);
index = cmbDeviceType->findData(type);
cmbDeviceType->removeItem(index);
}
}
if(savedDeviceId != drvid)
{
setCurrentDevice(savedDeviceId);
}
break;
}
}
int count = 0;
for(int type : deviceMap.keys())
count += deviceMap.value(type).count();
//设备数量发生了变化
if(count != savedCount)
{
Q_EMIT deviceCountChanged(count);
}
}