X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=blobdiff_plain;f=pv%2Ftoolbars%2Fmainbar.cpp;h=30cff789a3436abdd1216f94d25e4abca6668bc1;hp=4ff8235727fd3ffea81c118eb0ab62c847f3503b;hb=2ad82c2e40b6865481733913a2c32735602f63c4;hpb=998b89fd858e0dfc09c97cc4e3de718643f0017b diff --git a/pv/toolbars/mainbar.cpp b/pv/toolbars/mainbar.cpp index 4ff82357..30cff789 100644 --- a/pv/toolbars/mainbar.cpp +++ b/pv/toolbars/mainbar.cpp @@ -32,11 +32,13 @@ #include "mainbar.hpp" #include +#include #include #include #include #include #include +#include #include @@ -52,8 +54,8 @@ using std::vector; using sigrok::Capability; using sigrok::ConfigKey; -using sigrok::Device; using sigrok::Error; +using sigrok::InputFormat; namespace pv { namespace toolbars { @@ -69,8 +71,9 @@ MainBar::MainBar(Session &session, MainWindow &main_window) : device_selector_(this, session.device_manager(), main_window.action_connect()), configure_button_(this), - configure_button_action_(NULL), + configure_button_action_(nullptr), channels_button_(this), + channels_button_action_(nullptr), sample_count_(" samples", this), sample_rate_("Hz", this), updating_sample_rate_(false), @@ -80,6 +83,7 @@ MainBar::MainBar(Session &session, MainWindow &main_window) : icon_green_(":/icons/status-green.svg"), icon_grey_(":/icons/status-grey.svg"), run_stop_button_(this), + run_stop_button_action_(nullptr), menu_button_(this) { setObjectName(QString::fromUtf8("MainBar")); @@ -88,12 +92,31 @@ MainBar::MainBar(Session &session, MainWindow &main_window) : setFloatable(false); setContextMenuPolicy(Qt::PreventContextMenu); + // Open button + QToolButton *const open_button = new QToolButton(this); + + widgets::ImportMenu *import_menu = new widgets::ImportMenu(this, + session.device_manager().context(), + main_window.action_open()); + connect(import_menu, + SIGNAL(format_selected(std::shared_ptr)), + &main_window_, + SLOT(import_file(std::shared_ptr))); + + open_button->setMenu(import_menu); + open_button->setDefaultAction(main_window.action_open()); + open_button->setPopupMode(QToolButton::MenuButtonPopup); + // Save button QToolButton *const save_button = new QToolButton(this); + vector open_actions; + open_actions.push_back(main_window.action_save_as()); + open_actions.push_back(main_window.action_save_selection_as()); + widgets::ExportMenu *export_menu = new widgets::ExportMenu(this, session.device_manager().context(), - main_window.action_save_as()); + open_actions); connect(export_menu, SIGNAL(format_selected(std::shared_ptr)), &main_window_, @@ -116,13 +139,19 @@ MainBar::MainBar(Session &session, MainWindow &main_window) : add_decoder_button->setMenu(main_window_.menu_decoder_add()); #endif - // Setup the menu + // Setup the burger menu QMenu *const menu = new QMenu(this); + QMenu *const menu_view = new QMenu; + menu_view->setTitle(tr("&View")); + menu_view->addAction(main_window.action_view_sticky_scrolling()); + QMenu *const menu_help = new QMenu; menu_help->setTitle(tr("&Help")); menu_help->addAction(main_window.action_about()); + menu->addAction(menu_view->menuAction()); + menu->addSeparator(); menu->addAction(menu_help->menuAction()); menu->addSeparator(); menu->addAction(main_window.action_quit()); @@ -133,7 +162,7 @@ MainBar::MainBar(Session &session, MainWindow &main_window) : QIcon(":/icons/menu.svg"))); // Setup the toolbar - addAction(main_window.action_open()); + addWidget(open_button); addWidget(save_button); addSeparator(); addAction(main_window.action_view_zoom_in()); @@ -165,10 +194,10 @@ MainBar::MainBar(Session &session, MainWindow &main_window) : addWidget(&device_selector_); configure_button_action_ = addWidget(&configure_button_); - addWidget(&channels_button_); + channels_button_action_ = addWidget(&channels_button_); addWidget(&sample_count_); addWidget(&sample_rate_); - addWidget(&run_stop_button_); + run_stop_button_action_ = addWidget(&run_stop_button_); #ifdef ENABLE_DECODE addSeparator(); addWidget(add_decoder_button); @@ -187,14 +216,13 @@ MainBar::MainBar(Session &session, MainWindow &main_window) : void MainBar::update_device_list() { DeviceManager &mgr = session_.device_manager(); - shared_ptr selected_device = session_.device(); - list< shared_ptr > devs; + shared_ptr selected_device = session_.device(); + list< shared_ptr > devs; copy(mgr.devices().begin(), mgr.devices().end(), back_inserter(devs)); if (std::find(devs.begin(), devs.end(), selected_device) == devs.end()) devs.push_back(selected_device); - assert(selected_device); device_selector_.set_device_list(devs, selected_device); update_device_config_widgets(); @@ -208,46 +236,62 @@ void MainBar::set_capture_state(pv::Session::capture_state state) run_stop_button_.setText((state == pv::Session::Stopped) ? tr("Run") : tr("Stop")); run_stop_button_.setShortcut(QKeySequence(Qt::Key_Space)); + + bool ui_enabled = (state == pv::Session::Stopped) ? true : false; + + device_selector_.setEnabled(ui_enabled); + configure_button_.setEnabled(ui_enabled); + channels_button_.setEnabled(ui_enabled); + sample_count_.setEnabled(ui_enabled); + sample_rate_.setEnabled(ui_enabled); } void MainBar::update_sample_rate_selector() { Glib::VariantContainerBase gvar_dict; GVariant *gvar_list; - const uint64_t *elements = NULL; + const uint64_t *elements = nullptr; gsize num_elements; + map< const ConfigKey*, std::set > keys; - if (updating_sample_rate_) + if (updating_sample_rate_) { + sample_rate_.show_none(); return; + } - const shared_ptr device = device_selector_.selected_device(); + const shared_ptr device = + device_selector_.selected_device(); if (!device) return; assert(!updating_sample_rate_); updating_sample_rate_ = true; - const auto keys = device->config_keys(ConfigKey::DEVICE_OPTIONS); + const shared_ptr sr_dev = device->device(); + + try { + keys = sr_dev->config_keys(ConfigKey::DEVICE_OPTIONS); + } catch (Error) {} + const auto iter = keys.find(ConfigKey::SAMPLERATE); if (iter != keys.end() && (*iter).second.find(sigrok::LIST) != (*iter).second.end()) { try { - gvar_dict = device->config_list(ConfigKey::SAMPLERATE); - } catch(const sigrok::Error &e) { + gvar_dict = sr_dev->config_list(ConfigKey::SAMPLERATE); + } catch (const sigrok::Error &e) { // Failed to enunmerate samplerate (void)e; } } - if (!gvar_dict) { + if (!gvar_dict.gobj()) { sample_rate_.show_none(); updating_sample_rate_ = false; return; } if ((gvar_list = g_variant_lookup_value(gvar_dict.gobj(), - "samplerate-steps", G_VARIANT_TYPE("at")))) - { + "samplerate-steps", G_VARIANT_TYPE("at")))) { elements = (const uint64_t *)g_variant_get_fixed_array( gvar_list, &num_elements, sizeof(uint64_t)); @@ -264,18 +308,15 @@ void MainBar::update_sample_rate_selector() if (step == 1) sample_rate_.show_125_list(min, max); - else - { + else { // When the step is not 1, we cam't make a 1-2-5-10 // list of sample rates, because we may not be able to // make round numbers. Therefore in this case, show a // spin box. sample_rate_.show_min_max_step(min, max, step); } - } - else if ((gvar_list = g_variant_lookup_value(gvar_dict.gobj(), - "samplerates", G_VARIANT_TYPE("at")))) - { + } else if ((gvar_list = g_variant_lookup_value(gvar_dict.gobj(), + "samplerates", G_VARIANT_TYPE("at")))) { elements = (const uint64_t *)g_variant_get_fixed_array( gvar_list, &num_elements, sizeof(uint64_t)); sample_rate_.show_list(elements, num_elements); @@ -291,12 +332,13 @@ void MainBar::update_sample_rate_selector_value() if (updating_sample_rate_) return; - const shared_ptr device = device_selector_.selected_device(); + const shared_ptr device = + device_selector_.selected_device(); if (!device) return; try { - auto gvar = device->config_get(ConfigKey::SAMPLERATE); + auto gvar = device->device()->config_get(ConfigKey::SAMPLERATE); uint64_t samplerate = Glib::VariantBase::cast_dynamic>(gvar).get(); assert(!updating_sample_rate_); @@ -314,15 +356,17 @@ void MainBar::update_sample_count_selector() if (updating_sample_count_) return; - const shared_ptr device = device_selector_.selected_device(); + const shared_ptr device = + device_selector_.selected_device(); if (!device) return; + const shared_ptr sr_dev = device->device(); + assert(!updating_sample_count_); updating_sample_count_ = true; - if (!sample_count_supported_) - { + if (!sample_count_supported_) { sample_count_.show_none(); updating_sample_count_ = false; return; @@ -335,17 +379,17 @@ void MainBar::update_sample_count_selector() if (sample_count == 0) sample_count = DefaultSampleCount; - const auto keys = device->config_keys(ConfigKey::DEVICE_OPTIONS); + const auto keys = sr_dev->config_keys(ConfigKey::DEVICE_OPTIONS); const auto iter = keys.find(ConfigKey::LIMIT_SAMPLES); if (iter != keys.end() && (*iter).second.find(sigrok::LIST) != (*iter).second.end()) { try { auto gvar = - device->config_list(ConfigKey::LIMIT_SAMPLES); - if (gvar) + sr_dev->config_list(ConfigKey::LIMIT_SAMPLES); + if (gvar.gobj()) g_variant_get(gvar.gobj(), "(tt)", &min_sample_count, &max_sample_count); - } catch(const sigrok::Error &e) { + } catch (const sigrok::Error &e) { // Failed to query sample limit (void)e; } @@ -358,7 +402,7 @@ void MainBar::update_sample_count_selector() min_sample_count, max_sample_count); try { - auto gvar = device->config_get(ConfigKey::LIMIT_SAMPLES); + auto gvar = sr_dev->config_get(ConfigKey::LIMIT_SAMPLES); sample_count = g_variant_get_uint64(gvar.gobj()); if (sample_count == 0) sample_count = DefaultSampleCount; @@ -375,12 +419,25 @@ void MainBar::update_device_config_widgets() { using namespace pv::popups; - const shared_ptr device = device_selector_.selected_device(); - if (!device) + const shared_ptr device = + device_selector_.selected_device(); + + // Hide the widgets if no device is selected + channels_button_action_->setVisible(!!device); + run_stop_button_action_->setVisible(!!device); + if (!device) { + configure_button_action_->setVisible(false); + sample_count_.show_none(); + sample_rate_.show_none(); + return; + } + + const shared_ptr sr_dev = device->device(); + if (!sr_dev) return; // Update the configure popup - DeviceOptions *const opts = new DeviceOptions(device, this); + DeviceOptions *const opts = new DeviceOptions(sr_dev, this); configure_button_action_->setVisible( !opts->binding().properties().empty()); configure_button_.set_popup(opts); @@ -393,8 +450,7 @@ void MainBar::update_device_config_widgets() sample_count_supported_ = false; try { - for (auto entry : device->config_keys(ConfigKey::DEVICE_OPTIONS)) - { + for (auto entry : sr_dev->config_keys(ConfigKey::DEVICE_OPTIONS)) { auto key = entry.first; auto capabilities = entry.second; switch (key->id()) { @@ -403,9 +459,8 @@ void MainBar::update_device_config_widgets() sample_count_supported_ = true; break; case SR_CONF_LIMIT_FRAMES: - if (capabilities.count(Capability::SET)) - { - device->config_set(ConfigKey::LIMIT_FRAMES, + if (capabilities.count(Capability::SET)) { + sr_dev->config_set(ConfigKey::LIMIT_FRAMES, Glib::Variant::create(1)); on_config_changed(); } @@ -430,64 +485,64 @@ void MainBar::commit_sample_count() { uint64_t sample_count = 0; - if (updating_sample_count_) - return; - - const shared_ptr device = device_selector_.selected_device(); + const shared_ptr device = + device_selector_.selected_device(); if (!device) return; - sample_count = sample_count_.value(); + const shared_ptr sr_dev = device->device(); - // Set the sample count - assert(!updating_sample_count_); - updating_sample_count_ = true; - if (sample_count_supported_) - { + sample_count = sample_count_.value(); + if (sample_count_supported_) { try { - device->config_set(ConfigKey::LIMIT_SAMPLES, + sr_dev->config_set(ConfigKey::LIMIT_SAMPLES, Glib::Variant::create(sample_count)); - on_config_changed(); + update_sample_count_selector(); } catch (Error error) { qDebug() << "Failed to configure sample count."; return; } } - updating_sample_count_ = false; + + // Devices with built-in memory might impose limits on certain + // configurations, so let's check what sample rate the driver + // lets us use now. + update_sample_rate_selector(); } void MainBar::commit_sample_rate() { uint64_t sample_rate = 0; - if (updating_sample_rate_) - return; - - const shared_ptr device = device_selector_.selected_device(); + const shared_ptr device = + device_selector_.selected_device(); if (!device) return; + const shared_ptr sr_dev = device->device(); + sample_rate = sample_rate_.value(); if (sample_rate == 0) return; - // Set the samplerate - assert(!updating_sample_rate_); - updating_sample_rate_ = true; try { - device->config_set(ConfigKey::SAMPLERATE, + sr_dev->config_set(ConfigKey::SAMPLERATE, Glib::Variant::create(sample_rate)); - on_config_changed(); + update_sample_rate_selector(); } catch (Error error) { qDebug() << "Failed to configure samplerate."; return; } - updating_sample_rate_ = false; + + // Devices with built-in memory might impose limits on certain + // configurations, so let's check what sample count the driver + // lets us use now. + update_sample_count_selector(); } void MainBar::on_device_selected() { - shared_ptr device = device_selector_.selected_device(); + shared_ptr device = device_selector_.selected_device(); if (!device) return; @@ -498,12 +553,14 @@ void MainBar::on_device_selected() void MainBar::on_sample_count_changed() { - commit_sample_count(); + if (!updating_sample_count_) + commit_sample_count(); } void MainBar::on_sample_rate_changed() { - commit_sample_rate(); + if (!updating_sample_rate_) + commit_sample_rate(); } void MainBar::on_run_stop() @@ -516,19 +573,19 @@ void MainBar::on_run_stop() void MainBar::on_config_changed() { commit_sample_count(); - update_sample_count_selector(); commit_sample_rate(); - update_sample_rate_selector(); } bool MainBar::eventFilter(QObject *watched, QEvent *event) { - if ((watched == &sample_count_ || watched == &sample_rate_) && - (event->type() == QEvent::ToolTip)) { - double sec = (double)sample_count_.value() / sample_rate_.value(); + if (sample_count_supported_ && (watched == &sample_count_ || + watched == &sample_rate_) && + (event->type() == QEvent::ToolTip)) { + auto sec = pv::util::Timestamp(sample_count_.value()) / sample_rate_.value(); QHelpEvent *help_event = static_cast(event); - QString str = tr("Total sampling time: %1").arg(pv::util::format_second(sec)); + QString str = tr("Total sampling time: %1").arg( + pv::util::format_time_si(sec, pv::util::SIPrefix::unspecified, 0, "s", false)); QToolTip::showText(help_event->globalPos(), str); return true;