X-Git-Url: http://git.code-monkey.de/?p=pulseview.git;a=blobdiff_plain;f=pv%2Fpopups%2Fprobes.cpp;h=a20dfccafb4f345c51d76147f69a2f4852245bde;hp=9684d435093cbcae8d6fc7a022eb02ab2bbc5f10;hb=733eee0e51348243edb5547a33455f96097b7273;hpb=51d4a9ab96a6bf64a1fcd1700e7e174498d4c118 diff --git a/pv/popups/probes.cpp b/pv/popups/probes.cpp index 9684d43..a20dfcc 100644 --- a/pv/popups/probes.cpp +++ b/pv/popups/probes.cpp @@ -18,79 +18,230 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include + +#include +#include +#include +#include + #include "probes.h" +#include +#include +#include +#include + using namespace Qt; +using std::map; +using std::set; +using std::shared_ptr; +using std::vector; + +using pv::view::Signal; + namespace pv { namespace popups { -Probes::Probes(sr_dev_inst *sdi, QWidget *parent) : +Probes::Probes(SigSession &session, QWidget *parent) : Popup(parent), - _sdi(sdi), - _layout(this), - _probes(this), - _probes_bar(this), - _enable_all_probes(this), - _disable_all_probes(this) + _session(session), + _updating_probes(false), + _enable_all_probes(tr("Enable All"), this), + _disable_all_probes(tr("Disable All"), this), + _check_box_mapper(this) { - assert(_sdi); - + // Create the layout setLayout(&_layout); + shared_ptr dev_inst = _session.get_device(); + assert(dev_inst); + const sr_dev_inst *const sdi = dev_inst->dev_inst(); + assert(sdi); + + // Collect a set of signals + map > signal_map; + const vector< shared_ptr > sigs = _session.get_signals(); + + for (const shared_ptr &sig : sigs) + signal_map[sig->probe()] = sig; + + // Populate channel groups + for (const GSList *g = sdi->channel_groups; g; g = g->next) + { + const sr_channel_group *const group = + (const sr_channel_group*)g->data; + assert(group); + + // Make a set of signals and remove these signals from the + // signal map. + vector< shared_ptr > group_sigs; + for (const GSList *p = group->channels; p; p = p->next) + { + const sr_channel *const probe = (const sr_channel*)p->data; + assert(probe); + + const auto iter = signal_map.find(probe); + + if (iter == signal_map.end()) + break; + + group_sigs.push_back((*iter).second); + signal_map.erase(iter); + } + + populate_group(group, group_sigs); + } + + // Make a vector of the remaining probes + vector< shared_ptr > global_sigs; + for (const GSList *p = sdi->channels; p; p = p->next) + { + const sr_channel *const probe = (const sr_channel*)p->data; + assert(probe); + + const map >:: + const_iterator iter = signal_map.find(probe); + if (iter != signal_map.end()) + global_sigs.push_back((*iter).second); + } + + // Create a group + populate_group(NULL, global_sigs); + + // Create the enable/disable all buttons connect(&_enable_all_probes, SIGNAL(clicked()), this, SLOT(enable_all_probes())); connect(&_disable_all_probes, SIGNAL(clicked()), this, SLOT(disable_all_probes())); - _layout.addWidget(&_probes); + _enable_all_probes.setFlat(true); + _disable_all_probes.setFlat(true); - _enable_all_probes.setText(tr("Enable All")); - _probes_bar.addWidget(&_enable_all_probes); + _buttons_bar.addWidget(&_enable_all_probes); + _buttons_bar.addWidget(&_disable_all_probes); + _buttons_bar.addStretch(1); - _disable_all_probes.setText(tr("Disable All")); - _probes_bar.addWidget(&_disable_all_probes); + _layout.addRow(&_buttons_bar); - _layout.addWidget(&_probes_bar); + // Connect the check-box signal mapper + connect(&_check_box_mapper, SIGNAL(mapped(QWidget*)), + this, SLOT(on_probe_checked(QWidget*))); +} - for (const GSList *l = _sdi->probes; l; l = l->next) { - sr_probe *const probe = (sr_probe*)l->data; - assert(probe); - QListWidgetItem *const item = new QListWidgetItem( - probe->name, &_probes); - assert(item); - item->setData(UserRole, - qVariantFromValue((void*)probe)); - item->setCheckState(probe->enabled ? - Checked : Unchecked); - _probes.addItem(item); +void Probes::set_all_probes(bool set) +{ + _updating_probes = true; + + for (map >::const_iterator i = + _check_box_signal_map.begin(); + i != _check_box_signal_map.end(); i++) + { + const shared_ptr sig = (*i).second; + assert(sig); + + sig->enable(set); + (*i).first->setChecked(set); } - connect(&_probes, SIGNAL(itemChanged(QListWidgetItem*)), - this, SLOT(item_changed(QListWidgetItem*))); + _updating_probes = false; } -void Probes::set_all_probes(bool set) +void Probes::populate_group(const sr_channel_group *group, + const vector< shared_ptr > sigs) { - for (int i = 0; i < _probes.count(); i++) { - QListWidgetItem *const item = _probes.item(i); - assert(item); - item->setCheckState(set ? Qt::Checked : Qt::Unchecked); + using pv::prop::binding::DeviceOptions; - sr_probe *const probe = (sr_probe*) - item->data(UserRole).value(); - assert(probe); - probe->enabled = item->checkState() == Checked; + // Only bind options if this is a group. We don't do it for general + // options, because these properties are shown in the device config + // popup. + shared_ptr binding; + if (group) + binding = shared_ptr(new DeviceOptions( + _session.get_device(), group)); + + // Create a title if the group is going to have any content + if ((!sigs.empty() || (binding && !binding->properties().empty())) && + group && group->name) + _layout.addRow(new QLabel( + QString("

%1

").arg(group->name))); + + // Create the channel group grid + QGridLayout *const probe_grid = + create_channel_group_grid(sigs); + _layout.addRow(probe_grid); + + // Create the channel group options + if (binding) + { + binding->add_properties_to_form(&_layout, true); + _group_bindings.push_back(binding); } } -void Probes::item_changed(QListWidgetItem *item) +QGridLayout* Probes::create_channel_group_grid( + const vector< shared_ptr > sigs) { - assert(item); - sr_probe *const probe = (sr_probe*) - item->data(UserRole).value(); - assert(probe); - probe->enabled = item->checkState() == Checked; + int row = 0, col = 0; + QGridLayout *const grid = new QGridLayout(); + + for (const shared_ptr& sig : sigs) + { + assert(sig); + + QCheckBox *const checkbox = new QCheckBox(sig->get_name()); + _check_box_mapper.setMapping(checkbox, checkbox); + connect(checkbox, SIGNAL(toggled(bool)), + &_check_box_mapper, SLOT(map())); + + grid->addWidget(checkbox, row, col); + + _check_box_signal_map[checkbox] = sig; + + if(++col >= 8) + col = 0, row++; + } + + return grid; +} + +void Probes::showEvent(QShowEvent *e) +{ + pv::widgets::Popup::showEvent(e); + + _updating_probes = true; + + for (map >::const_iterator i = + _check_box_signal_map.begin(); + i != _check_box_signal_map.end(); i++) + { + const shared_ptr sig = (*i).second; + assert(sig); + + (*i).first->setChecked(sig->enabled()); + } + + _updating_probes = false; +} + +void Probes::on_probe_checked(QWidget *widget) +{ + if (_updating_probes) + return; + + QCheckBox *const check_box = (QCheckBox*)widget; + assert(check_box); + + // Look up the signal of this check-box + map< QCheckBox*, shared_ptr >::const_iterator iter = + _check_box_signal_map.find((QCheckBox*)check_box); + assert(iter != _check_box_signal_map.end()); + + const shared_ptr s = (*iter).second; + assert(s); + + s->enable(check_box->isChecked()); } void Probes::enable_all_probes()