code_app/app/scanner/device_menu.cpp

180 lines
4.9 KiB
C++

#include "device_menu.h"
#define ACTION_DEVICE_NAME_PROPERTY "device_name"
device_menu::device_menu(QWidget *parent)
: QMenu(parent)
, cur_action_(nullptr), none_action_(nullptr)
{
group_action_ = new QActionGroup(this);
update(nullptr);
connect(group_action_, SIGNAL(triggered(QAction*)), this, SLOT(on_act_triggered(QAction*)));
}
device_menu::device_menu(const QString &title, QWidget *parent)
: QMenu(title, parent)
, cur_action_(nullptr), none_action_(nullptr)
{
group_action_ = new QActionGroup(this);
update(nullptr);
connect(group_action_, SIGNAL(triggered(QAction*)), this, SLOT(on_act_triggered(QAction*)));
}
QMenu* device_menu::find_device_menu(const QString& dev_name)
{
std::lock_guard<std::mutex> lock(mutex_);
std::vector<POPMENU>::iterator it = std::find(menus_.begin(), menus_.end(), dev_name);
if(it == menus_.end())
return nullptr;
else
return it->menu;
}
QAction* device_menu::find_device_config(const QString& dev_name, const QString& cfg_name)
{
std::lock_guard<std::mutex> lock(mutex_);
std::vector<POPMENU>::iterator it = std::find(menus_.begin(), menus_.end(), dev_name);
if(it == menus_.end())
return NULL;
for(size_t i = 0; i < it->actions.size(); ++i)
{
if(it->actions[i]->text() == cfg_name)
return it->actions[i];
}
return NULL;
}
void device_menu::connectedDevice(const QString &device)
{
QMenu* menu = find_device_menu(device);
if (menu)
menu->setEnabled(true);
}
void device_menu::disconnectedDevice(const QString &device)
{
QMenu* menu = find_device_menu(device);
if (menu)
menu->setEnabled(false);
}
void device_menu::setOptionChecked(const QString &device, const QString &opt, bool checked)
{
QAction* act = find_device_config(device, opt);
if(act)
{
act->setChecked(checked);
if(checked)
cur_action_ = act;
else
{
if(cur_action_ == act)
cur_action_ = nullptr;
}
}
else if(checked)
cur_action_ = nullptr;
}
void device_menu::get_online_devices(QList<QString>& dev_names)
{
std::lock_guard<std::mutex> lock(mutex_);
for(size_t i = 0; i < menus_.size(); ++i)
{
if(menus_[i].menu->isEnabled())
dev_names.push_back(menus_[i].menu->title());
}
}
void device_menu::update(const std::vector<DEVCFG>* dev_cfgs)
{
std::lock_guard<std::mutex> lock(mutex_);
if(none_action_)
{
removeAction(none_action_);
none_action_ = nullptr;
}
for(size_t i = 0; i < menus_.size(); ++i)
menus_[i].menu->setEnabled(false);
if (!dev_cfgs || dev_cfgs->empty())
{
if(menus_.empty())
{
none_action_ = addAction(tr("no device"));
none_action_->setEnabled(false);
}
return;
}
for (size_t i = 0; i < dev_cfgs->size(); i++)
{
std::vector<POPMENU>::iterator it = std::find(menus_.begin(), menus_.end(), QString::fromStdString((*dev_cfgs)[i].name));
POPMENU pm;
if(it == menus_.end())
pm.menu = addMenu(QString::fromStdString((*dev_cfgs)[i].name));
else
{
pm = *it;
menus_.erase(it);
}
pm.menu->setEnabled(true);
pm.menu->setToolTipsVisible(true);
for(size_t j = 0; j < pm.actions.size(); ++j)
{
pm.menu->removeAction(pm.actions[j]);
group_action_->removeAction(pm.actions[j]);
}
pm.actions.clear();
for (size_t j = 0; j < (*dev_cfgs)[i].schemes.size(); j++)
{
QAction* child = group_action_->addAction(QString::fromStdString((*dev_cfgs)[i].schemes[j].name));
child->setProperty(ACTION_DEVICE_NAME_PROPERTY, pm.menu->title());
child->setCheckable(true);
child->setChecked(false);
pm.menu->addAction(child);
pm.actions.push_back(child);
const std::vector<OPTVAL>& opts = (*dev_cfgs)[i].schemes[j].opts;
QString tips;
for(size_t k = 0; k < opts.size(); ++k)
{
tips += QString::fromStdString(opts[k].name + ": " + opts[k].val + "\n");
}
if(tips.isNull())
tips = tr("default setting");
child->setToolTip(tips);
}
menus_.push_back(pm);
}
}
void device_menu::on_act_triggered(QAction* act)
{
QString deviceName = act->property(ACTION_DEVICE_NAME_PROPERTY).toString();
QString opt = act->text();
bool checked_now = act->isChecked();
if(cur_action_ == act)
{
checked_now = false;
act->setChecked(false);
cur_action_ = nullptr;
// emit scanOptionsChanged("", "", false);
// return;
}
else {
cur_action_ = act;
checked_now = true;
}
emit scanOptionsChanged(deviceName, opt, checked_now);
}