#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 lock(mutex_); std::vector::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 lock(mutex_); std::vector::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& dev_names) { std::lock_guard 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* dev_cfgs) { std::lock_guard 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::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& 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); }