diff --git a/DSView/pv/dialogs/deviceoptions.cpp b/DSView/pv/dialogs/deviceoptions.cpp index 2b42e2c4..6eba719a 100644 --- a/DSView/pv/dialogs/deviceoptions.cpp +++ b/DSView/pv/dialogs/deviceoptions.cpp @@ -1,914 +1,939 @@ -/* - * This file is part of the DSView project. - * DSView is based on PulseView. - * - * Copyright (C) 2012 Joel Holdsworth - * Copyright (C) 2013 DreamSourceLab - * - * 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 2 of the License, 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, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "deviceoptions.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "dsmessagebox.h" -#include "../prop/property.h" -#include "../dsvdef.h" -#include "../config/appconfig.h" -#include "../appcontrol.h" -#include "../sigsession.h" -#include "../ui/langresource.h" -#include "../log.h" -#include "../ui/msgbox.h" - -using namespace boost; -using namespace std; - -//--------------------------ChannelLabel - -ChannelLabel::ChannelLabel(IChannelCheck *check, QWidget *parent, int chanIndex) -: QWidget(parent) -{ - _checked = check; - _index = chanIndex; - - QGridLayout *lay = new QGridLayout(); - lay->setContentsMargins(0,0,0,0); - lay->setSpacing(0); - this->setLayout(lay); - QLabel *lb = new QLabel(QString::number(chanIndex)); - lb->setAlignment(Qt::AlignCenter); - _box = new QCheckBox(); - _box->setFixedSize(20,20); - lay->addWidget(lb, 0, 0, Qt::AlignCenter); - lay->addWidget(_box, 1, 0, Qt::AlignCenter); - - QFont font = this->font(); - font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); - lb->setFont(font); - - int fh = lb->fontMetrics().height(); - int w = lb->fontMetrics().horizontalAdvance(lb->text()) + 5; - w = w < 30 ? 30 : w; - int h = fh + _box->height() + 2; - setFixedSize(w, h); - - connect(_box, SIGNAL(released()), this, SLOT(on_checked())); -} - -void ChannelLabel::on_checked() -{ - assert(_checked); - _checked->ChannelChecked(_index, _box); -} - -//--------------------------DeviceOptions - -namespace pv { -namespace dialogs { - -DeviceOptions::DeviceOptions(QWidget *parent) : - DSDialog(parent) -{ - _scroll_panel = NULL; - _container_panel = NULL; - _scroll = NULL; - _width = 0; - _groupHeight1 = 0; - _groupHeight2 = 0; - _dynamic_panel = NULL; - _container_lay = NULL; - _isBuilding = false; - _cur_analog_tag_index = 0; - _have_no_channel = false; - - SigSession *session = AppControl::Instance()->GetSession(); - _device_agent = session->get_device(); - - this->setTitle(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_DEVICE_OPTIONS), "Device Options")); - this->SetTitleSpace(0); - this->layout()->setSpacing(0); - this->layout()->setDirection(QBoxLayout::TopToBottom); - this->layout()->setAlignment(Qt::AlignTop); - - // scroll panel - _scroll_panel = new QWidget(); - QVBoxLayout *scroll_lay = new QVBoxLayout(); - scroll_lay->setContentsMargins(0, 0, 0, 0); - scroll_lay->setAlignment(Qt::AlignLeft); - scroll_lay->setDirection(QBoxLayout::TopToBottom); - _scroll_panel->setLayout(scroll_lay); - this->layout()->addWidget(_scroll_panel); - - // container - _container_panel = new QWidget(); - _container_lay = new QVBoxLayout(); - _container_lay->setDirection(QBoxLayout::TopToBottom); - _container_lay->setAlignment(Qt::AlignTop); - _container_lay->setContentsMargins(0, 0, 0, 0); - _container_lay->setSpacing(5); - _container_panel->setLayout(_container_lay); - scroll_lay->addWidget(_container_panel); - - QFont font = this->font(); - font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); - - // mode group box - QGroupBox *props_box = new QGroupBox(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_MODE), "Mode"), this); - props_box->setFont(font); - QLayout *props_lay = get_property_form(props_box); - props_lay->setContentsMargins(5, 20, 5, 5); - props_box->setLayout(props_lay); - _container_lay->addWidget(props_box); - - QWidget *minWid = new QWidget(); - minWid->setFixedHeight(1); - minWid->setMinimumWidth(230); - _container_lay->addWidget(minWid); - - // chnnels group box - this->build_dynamic_panel(); - - // space - QWidget *space = new QWidget(); - space->setMinimumHeight(5); - this->layout()->addWidget(space); - - //button - auto button_box = new QDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, this); - this->layout()->addWidget(button_box); - - _device_agent->get_config_int16(SR_CONF_OPERATION_MODE, _opt_mode); - - if (_device_agent->is_demo()) - _demo_operation_mode = _device_agent->get_demo_operation_mode(); - - try_resize_scroll(); - - connect(&_mode_check_timer, SIGNAL(timeout()), this, SLOT(mode_check_timeout())); - connect(button_box, SIGNAL(accepted()), this, SLOT(accept())); - - _mode_check_timer.setInterval(100); - _mode_check_timer.start(); -} - -DeviceOptions::~DeviceOptions() -{ -} - -void DeviceOptions::ChannelChecked(int index, QObject *object) -{ - (void)index; - - QCheckBox* sc = dynamic_cast(object); - channel_checkbox_clicked(sc); -} - -void DeviceOptions::accept() -{ - using namespace Qt; - bool hasEnabled = false; - - // Commit the properties - const auto &dev_props = _device_options_binding.properties(); - - for(auto p : dev_props) { - p->commit(); - } - - // Commit the probes - int mode = _device_agent->get_work_mode(); - if (mode == LOGIC || mode == ANALOG) { - int index = 0; - for (const GSList *l = _device_agent->get_channels(); l; l = l->next) { - sr_channel *const probe = (sr_channel*)l->data; - assert(probe); - probe->enabled = _probes_checkBox_list.at(index)->isChecked(); - index++; - if (probe->enabled) - hasEnabled = true; - } - } - else { - hasEnabled = true; - } - - if (hasEnabled) { - auto it = _probe_options_binding_list.begin(); - while(it != _probe_options_binding_list.end()) { - const auto &probe_props = (*it)->properties(); - - for(auto p :probe_props) { - p->commit(); - } - it++; - } - - _have_no_channel = false; - - QDialog::accept(); - } - else { - _have_no_channel = true; - QString strMsg(L_S(STR_PAGE_MSG, S_ID(IDS_MSG_ALL_CHANNEL_DISABLE), "All channel disabled! Please enable at least one channel.")); - MsgBox::Show(strMsg); - } -} - -void DeviceOptions::reject() -{ - using namespace Qt; - - QDialog::reject(); -} - -QLayout * DeviceOptions::get_property_form(QWidget * parent) -{ - QGridLayout *const layout = new QGridLayout(parent); - layout->setVerticalSpacing(2); - const auto &properties =_device_options_binding.properties(); - - QFont font = this->font(); - font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); - - int i = 0; - for(auto p : properties) - { - const QString label = p->labeled_widget() ? QString() : p->label(); - QString lable_text = ""; - - if (label != ""){ - QByteArray bytes = label.toLocal8Bit(); - const char *lang_str = LangResource::Instance()->get_lang_text(STR_PAGE_DSL, bytes.data(), bytes.data()); - lable_text = QString(lang_str); - } - - QLabel *lb = new QLabel(lable_text, parent); - lb->setFont(font); - layout->addWidget(lb, i, 0); - - if (label == QString("Operation Mode")){ - QWidget *wid = p->get_widget(parent, true); - wid->setFont(font); - layout->addWidget(wid, i, 1); - } - else{ - QWidget *wid = p->get_widget(parent); - wid->setFont(font); - layout->addWidget(wid, i, 1); - } - layout->setRowMinimumHeight(i, 22); - i++; - } - - _groupHeight1 = parent->sizeHint().height(); - parent->setFixedHeight(_groupHeight1); - - return layout; -} - -void DeviceOptions::logic_probes(QVBoxLayout &layout) -{ - using namespace Qt; - - layout.setSpacing(2); - - int row1 = 0; - int row2 = 0; - int vld_ch_num = 0; - int cur_ch_num = 0; - int contentHeight = 0; - - _probes_checkBox_list.clear(); - - QFont font = this->font(); - font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); - - //channel count checked - if (_device_agent->get_work_mode()== LOGIC) { - GVariant * gvar_opts = _device_agent->get_config_list(NULL, SR_CONF_CHANNEL_MODE); - - if (gvar_opts != NULL) - { - struct sr_list_item *plist = (struct sr_list_item*)g_variant_get_uint64(gvar_opts); - g_variant_unref(gvar_opts); - - int ch_mode = 0; - _device_agent->get_config_int16(SR_CONF_CHANNEL_MODE, ch_mode); - _channel_mode_indexs.clear(); - - while (plist != NULL && plist->id >= 0) - { - row1++; - QString mode_bt_text = LangResource::Instance()->get_lang_text(STR_PAGE_DSL, plist->name, plist->name); - QRadioButton *mode_button = new QRadioButton(mode_bt_text); - mode_button->setFont(font); - ChannelModePair mode_index; - mode_index.key = mode_button; - mode_index.value = plist->id; - _channel_mode_indexs.push_back(mode_index); - - layout.addWidget(mode_button); - contentHeight += mode_button->sizeHint().height(); //radio button height - - connect(mode_button, SIGNAL(pressed()), this, SLOT(channel_check())); - - if (plist->id == ch_mode) - mode_button->setChecked(true); - - plist++; - } - } - } - - _device_agent->get_config_int16(SR_CONF_VLD_CH_NUM, vld_ch_num); - - // channels - QWidget *channel_pannel = new QWidget(); - QGridLayout *channel_grid = new QGridLayout(); - channel_grid->setContentsMargins(0,0,0,0); - channel_grid->setSpacing(0); - channel_pannel->setLayout(channel_grid); - - int channel_row = 0; - int channel_column = 0; - int channel_line_height = 0; - row2++; - - for (const GSList *l = _device_agent->get_channels(); l; l = l->next) { - sr_channel *const probe = (sr_channel*)l->data; - - if (probe->enabled) - cur_ch_num++; - - if (cur_ch_num > vld_ch_num) - probe->enabled = false; - - ChannelLabel *ch_item = new ChannelLabel(this, NULL, probe->index); - channel_grid->addWidget(ch_item, channel_row, channel_column++, Qt::AlignCenter); - _probes_checkBox_list.push_back(ch_item->getCheckBox()); - ch_item->getCheckBox()->setCheckState(probe->enabled ? Qt::Checked : Qt::Unchecked); - channel_line_height = ch_item->height(); - - if (channel_column == 8){ - channel_column = 0; - channel_row++; - - if (l->next != NULL){ - row2++; - } - } - } - - layout.addWidget(channel_pannel); - - // space - QWidget *space = new QWidget(); - space->setFixedHeight(10); - layout.addWidget(space); - contentHeight += 10; - - // buttons - QHBoxLayout *line_lay = new QHBoxLayout(); - layout.addLayout(line_lay); - line_lay->setSpacing(10); - - QPushButton *enable_all_probes = new QPushButton(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_ENABLE_ALL), "Enable All")); - QPushButton *disable_all_probes = new QPushButton(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_DISABLE_ALL), "Disable All")); - enable_all_probes->setMaximumHeight(33); - disable_all_probes->setMaximumHeight(33); - enable_all_probes->setFont(font); - disable_all_probes->setFont(font); - - int bt_width = enable_all_probes->fontMetrics().horizontalAdvance(enable_all_probes->text()) + 20; - enable_all_probes->setMaximumWidth(bt_width); - disable_all_probes->setMaximumWidth(bt_width); - - this->update_font(); - - contentHeight += enable_all_probes->sizeHint().height(); - contentHeight += channel_line_height * row2 + 50; - - connect(enable_all_probes, SIGNAL(clicked()), - this, SLOT(enable_all_probes())); - connect(disable_all_probes, SIGNAL(clicked()), - this, SLOT(disable_all_probes())); - - line_lay->addWidget(enable_all_probes); - line_lay->addWidget(disable_all_probes); - - _groupHeight2 = contentHeight + (row1 + row2) * 2 + 38; - -#ifdef Q_OS_DARWIN - _groupHeight2 += 5; -#endif - - _dynamic_panel->setFixedHeight(_groupHeight2); -} - -void DeviceOptions::set_all_probes(bool set) -{ - for (auto box : _probes_checkBox_list) { - box->setCheckState(set ? Qt::Checked : Qt::Unchecked); - } -} - -void DeviceOptions::enable_max_probes() { - int cur_ch_num = 0; - for (auto box : _probes_checkBox_list) { - if (box->isChecked()) - cur_ch_num++; - } - - int vld_ch_num; - - if (_device_agent->get_config_int16(SR_CONF_VLD_CH_NUM, vld_ch_num) == false) - return; - - while(cur_ch_num < vld_ch_num && cur_ch_num < (int)_probes_checkBox_list.size()) { - auto box = _probes_checkBox_list[cur_ch_num]; - if (box->isChecked() == false) { - box->setChecked(true); - cur_ch_num++; - } - } -} - -void DeviceOptions::enable_all_probes() -{ - bool stream_mode; - - if (_device_agent->get_config_bool(SR_CONF_STREAM, stream_mode)) { - if (stream_mode) { - enable_max_probes(); - return; - } - } - - set_all_probes(true); -} - -void DeviceOptions::disable_all_probes() -{ - set_all_probes(false); -} - -void DeviceOptions::zero_adj() -{ - using namespace Qt; - QDialog::accept(); - - QString strMsg(L_S(STR_PAGE_MSG, S_ID(IDS_MSG_AUTO_CALIB_START), - "Auto Calibration program will be started. Don't connect any probes. \nIt can take a while!")); - bool bRet = MsgBox::Confirm(strMsg); - - if (bRet) { - _device_agent->set_config_bool(SR_CONF_ZERO, true); - } - else { - _device_agent->set_config_bool(SR_CONF_ZERO, false); - } -} - -void DeviceOptions::on_calibration() -{ - using namespace Qt; - QDialog::accept(); - _device_agent->set_config_bool(SR_CONF_CALI, true); -} - -void DeviceOptions::mode_check_timeout() -{ - if (_isBuilding) - return; - - if (_device_agent->is_hardware()) - { - bool test; - int mode; - - if (_device_agent->get_config_int16(SR_CONF_OPERATION_MODE, mode)) { - if (mode != _opt_mode) { - _opt_mode = mode; - build_dynamic_panel(); - try_resize_scroll(); - } - } - - if (_device_agent->get_config_bool(SR_CONF_TEST, test)) { - if (test) { - for (auto box : _probes_checkBox_list) { - box->setCheckState(Qt::Checked); - box->setDisabled(true); - } - } - } - } - else if (_device_agent->is_demo()) - { - QString opt_mode = _device_agent->get_demo_operation_mode(); - if (opt_mode != _demo_operation_mode){ - _demo_operation_mode = opt_mode; - build_dynamic_panel(); - try_resize_scroll(); - } - } -} - -void DeviceOptions::channel_check() -{ - QRadioButton* bt = dynamic_cast(sender()); - assert(bt); - - int mode_index = -1; - - for( auto p : _channel_mode_indexs){ - if (p.key == bt){ - mode_index = p.value; - break; - } - } - assert(mode_index >= 0); - _device_agent->set_config_int16(SR_CONF_CHANNEL_MODE, mode_index); - - build_dynamic_panel(); - try_resize_scroll(); -} - -void DeviceOptions::analog_channel_check() -{ - QCheckBox* sc=dynamic_cast(sender()); - if(sc != NULL) - { - for (const GSList *l = _device_agent->get_channels(); l; l = l->next) { - sr_channel *const probe = (sr_channel*)l->data; - - if (sc->property("index").toInt() == probe->index){ - _device_agent->set_config_bool(SR_CONF_PROBE_MAP_DEFAULT, sc->isChecked(), probe); - } - } - } - - build_dynamic_panel(); - try_resize_scroll(); -} - -void DeviceOptions::on_analog_channel_enable() -{ - QCheckBox* sc = dynamic_cast(sender()); - channel_checkbox_clicked(sc); -} - -void DeviceOptions::channel_checkbox_clicked(QCheckBox *sc) -{ - if (_device_agent->get_work_mode() == LOGIC) { - if (sc == NULL || !sc->isChecked()) - return; - - bool stream_mode; - if (_device_agent->get_config_bool(SR_CONF_STREAM, stream_mode) == false) - return; - - if (!stream_mode) - return; - - int cur_ch_num = 0; - for (auto box : _probes_checkBox_list) { - if (box->isChecked()) - cur_ch_num++; - } - - int vld_ch_num; - if (_device_agent->get_config_int16(SR_CONF_VLD_CH_NUM, vld_ch_num) == false) - return; - - if (cur_ch_num > vld_ch_num) { - QString msg_str(L_S(STR_PAGE_MSG, S_ID(IDS_MSG_MAX_CHANNEL_COUNT_WARNING), "max count of channels!")); - msg_str = msg_str.replace("{0}", QString::number(vld_ch_num) ); - MsgBox::Show(msg_str); - - sc->setChecked(false); - } - } - else if (_device_agent->get_work_mode() == ANALOG) { - if (sc != NULL) { - QGridLayout *const layout = (QGridLayout *)sc->property("Layout").value(); - int i = layout->count(); - - int ck_index = -1; - int i_dex = 0; - bool map_default = false; - - for(auto ck : _probes_checkBox_list){ - if (ck == sc){ - ck_index = i_dex; - break; - } - i_dex++; - } - - if (ck_index != -1) - { - _device_agent->get_config_bool(SR_CONF_PROBE_MAP_DEFAULT, - map_default, _dso_channel_list[ck_index], NULL); - } - - while(i--) - { - QWidget* w = layout->itemAt(i)->widget(); - - if (w->objectName() == "map-enable"){ - QCheckBox *map_ckbox = dynamic_cast(w); - map_ckbox->isChecked(); - } - - if (w->property("Enable").isNull()) { - - if (map_default && w->objectName() == "map-row"){ - w->setEnabled(false); - } - else{ - w->setEnabled(sc->isChecked()); - } - } - } - } - } -} - -void DeviceOptions::analog_probes(QGridLayout &layout) -{ - using namespace Qt; - - _probes_checkBox_list.clear(); - _probe_options_binding_list.clear(); - _dso_channel_list.clear(); - - QTabWidget *tabWidget = new QTabWidget(); - tabWidget->setTabPosition(QTabWidget::North); - tabWidget->setUsesScrollButtons(false); - - QFont font = this->font(); - font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); - - for (const GSList *l = _device_agent->get_channels(); l; l = l->next) { - sr_channel *const probe = (sr_channel*)l->data; - assert(probe); - - _dso_channel_list.push_back(probe); - - QWidget *probe_widget = new QWidget(tabWidget); - QGridLayout *probe_layout = new QGridLayout(probe_widget); - probe_widget->setLayout(probe_layout); - - QCheckBox *probe_checkBox = new QCheckBox(this); - QVariant vlayout = QVariant::fromValue((void *)probe_layout); - probe_checkBox->setProperty("Layout", vlayout); - probe_checkBox->setProperty("Enable", true); - probe_checkBox->setCheckState(probe->enabled ? Qt::Checked : Qt::Unchecked); - _probes_checkBox_list.push_back(probe_checkBox); - - QLabel *en_label = new QLabel(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_ENABLE), "Enable: "), this); - en_label->setFont(font); - en_label->setProperty("Enable", true); - probe_layout->addWidget(en_label, 0, 0, 1, 1); - probe_layout->addWidget(probe_checkBox, 0, 1, 1, 3); - - auto *probe_options_binding = new pv::prop::binding::ProbeOptions(probe); - const auto &properties = probe_options_binding->properties(); - int i = 1; - - for(auto p : properties) - { - const QString label = p->labeled_widget() ? QString() : p->label(); - QLabel *lb = new QLabel(label, probe_widget); - lb->setFont(font); - probe_layout->addWidget(lb, i, 0, 1, 1); - - QWidget * pow = p->get_widget(probe_widget); - pow->setEnabled(probe_checkBox->isChecked()); - pow->setFont(font); - - if (p->name().contains("Map Default")) { - pow->setProperty("index", probe->index); - connect(pow, SIGNAL(clicked()), this, SLOT(analog_channel_check())); - } - else { - if (probe_checkBox->isChecked() && p->name().contains("Map")) { - bool map_default = true; - - _device_agent->get_config_bool(SR_CONF_PROBE_MAP_DEFAULT, map_default, probe, NULL); - - if (map_default) - pow->setEnabled(false); - - pow->setObjectName("map-row"); - } - } - probe_layout->addWidget(pow, i, 1, 1, 3); - i++; - } - _probe_options_binding_list.push_back(probe_options_binding); - - connect(probe_checkBox, SIGNAL(released()), this, SLOT(on_analog_channel_enable())); - - QString tabName = QString::fromUtf8(probe->name); - tabName += " "; - - tabWidget->addTab(probe_widget, tabName); - } - - layout.addWidget(tabWidget, 0, 0, 1, 1); - - this->update_font(); - _groupHeight2 = tabWidget->sizeHint().height() + 10; - _dynamic_panel->setFixedHeight(_groupHeight2); - - connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(on_anlog_tab_changed(int))); - tabWidget->setCurrentIndex(_cur_analog_tag_index); -} - -void DeviceOptions::on_anlog_tab_changed(int index) -{ - _cur_analog_tag_index = index; -} - -QString DeviceOptions::dynamic_widget(QLayout *lay) - { - int mode = _device_agent->get_work_mode(); - - if (mode == LOGIC) { - QVBoxLayout *grid = dynamic_cast(lay); - assert(grid); - logic_probes(*grid); - //tr - return L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CHANNEL), "Channel"); - } - else if (mode == DSO) { - bool have_zero; - - if (_device_agent->get_config_bool(SR_CONF_HAVE_ZERO, have_zero)) { - QGridLayout *grid = dynamic_cast(lay); - assert(grid); - - QFont font = this->font(); - font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); - - if (have_zero) { - auto config_button = new QPushButton(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_AUTO_CALIBRATION), "Auto Calibration"), this); - config_button->setFont(font); - grid->addWidget(config_button, 0, 0, 1, 1); - connect(config_button, SIGNAL(clicked()), this, SLOT(zero_adj())); - - auto cali_button = new QPushButton(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_MANUAL_CALIBRATION), "Manual Calibration"), this); - cali_button->setFont(font); - grid->addWidget(cali_button, 1, 0, 1, 1); - connect(cali_button, SIGNAL(clicked()), this, SLOT(on_calibration())); - - config_button->setFixedHeight(35); - cali_button->setFixedHeight(35); - - _groupHeight2 = 135; - _dynamic_panel->setFixedHeight(_groupHeight2); - - //tr - return L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CALIBRATION), "Calibration"); - } - } - } - else if (mode == ANALOG) { - QGridLayout *grid = dynamic_cast(lay); - assert(grid); - analog_probes(*grid); - //tr - return L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CHANNEL), "Channel"); - } - return NULL; -} - -void DeviceOptions::build_dynamic_panel() -{ - _isBuilding = true; - - if (_dynamic_panel != NULL){ - _dynamic_panel->deleteLater(); - _dynamic_panel = NULL; - } - - QFont font = this->font(); - font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); - - if (_dynamic_panel == NULL) - { - _dynamic_panel = new QGroupBox("group", _dynamic_panel); - _dynamic_panel->setFont(font); - _container_lay->addWidget(_dynamic_panel); - - if (_device_agent->get_work_mode() == LOGIC) - _dynamic_panel->setLayout(new QVBoxLayout()); - else - _dynamic_panel->setLayout(new QGridLayout()); - } - - QString title = dynamic_widget(_dynamic_panel->layout()); - QGroupBox *box = dynamic_cast(_dynamic_panel); - box->setFont(font); - box->setTitle(title); - - if (title == ""){ - box->setVisible(false); - } - - _dynamic_panel->layout()->setContentsMargins(5, 20, 5, 5); - - _isBuilding = false; -} - -void DeviceOptions::try_resize_scroll() -{ - this->update_font(); - - // content area height - int contentHeight = _groupHeight1 + _groupHeight2 + 20; // +space - //dialog height - int dlgHeight = contentHeight + 100; // +bottom buttton - -#ifdef Q_OS_DARWIN - dlgHeight += 20; -#endif - - float sk = QGuiApplication::primaryScreen()->logicalDotsPerInch() / 96; - - int srcHeight = 600; - int w = _width; - - if (w == 0) - { - w = this->sizeHint().width(); - _width = w; - } - - QScrollArea *scroll = _scroll; - if (scroll == NULL) - { - scroll = new QScrollArea(_scroll_panel); - scroll->setWidget(_container_panel); - scroll->setStyleSheet("QScrollArea{border:none;}"); - scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - _scroll = scroll; - } - - _container_panel->setFixedHeight(contentHeight); - int sclw = w - 23; - -#ifdef Q_OS_DARWIN - sclw -= 20; -#endif - - if (sk * dlgHeight > srcHeight) - { - int exth = 120; - this->setFixedSize(w + 12, srcHeight); - _scroll_panel->setFixedSize(w, srcHeight - exth); - _scroll->setFixedSize(sclw, srcHeight - exth); - } - else - { - this->setFixedSize(w + 12, dlgHeight); - _scroll_panel->setFixedSize(w, contentHeight); - _scroll->setFixedSize(sclw, contentHeight); - } -} - -void DeviceOptions::keyPressEvent(QKeyEvent *event) -{ - if (event->key() == Qt::Key_Escape && _have_no_channel) { - event->ignore(); - return; - } - - QDialog::keyPressEvent(event); -} - -} // namespace dialogs -} // namespace pv +/* + * This file is part of the DSView project. + * DSView is based on PulseView. + * + * Copyright (C) 2012 Joel Holdsworth + * Copyright (C) 2013 DreamSourceLab + * + * 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 2 of the License, 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "deviceoptions.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "dsmessagebox.h" +#include "../prop/property.h" +#include "../dsvdef.h" +#include "../config/appconfig.h" +#include "../appcontrol.h" +#include "../sigsession.h" +#include "../ui/langresource.h" +#include "../log.h" +#include "../ui/msgbox.h" + +using namespace boost; +using namespace std; + +//--------------------------ChannelLabel + +ChannelLabel::ChannelLabel(IChannelCheck *check, QWidget *parent, int chanIndex) +: QWidget(parent) +{ + _checked = check; + _index = chanIndex; + + QGridLayout *lay = new QGridLayout(); + lay->setContentsMargins(0,0,0,0); + lay->setSpacing(0); + this->setLayout(lay); + QLabel *lb = new QLabel(QString::number(chanIndex)); + lb->setAlignment(Qt::AlignCenter); + _box = new QCheckBox(); + _box->setFixedSize(20,20); + lay->addWidget(lb, 0, 0, Qt::AlignCenter); + lay->addWidget(_box, 1, 0, Qt::AlignCenter); + + QFont font = this->font(); + font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); + lb->setFont(font); + + int fh = lb->fontMetrics().height(); + int w = lb->fontMetrics().horizontalAdvance(lb->text()) + 5; + w = w < 30 ? 30 : w; + int h = fh + _box->height() + 2; + setFixedSize(w, h); + + connect(_box, SIGNAL(released()), this, SLOT(on_checked())); +} + +void ChannelLabel::on_checked() +{ + assert(_checked); + _checked->ChannelChecked(_index, _box); +} + +//--------------------------DeviceOptions + +namespace pv { +namespace dialogs { + +DeviceOptions::DeviceOptions(QWidget *parent) : + DSDialog(parent) +{ + _scroll_panel = NULL; + _container_panel = NULL; + _scroll = NULL; + _width = 0; + _groupHeight1 = 0; + _groupHeight2 = 0; + _dynamic_panel = NULL; + _container_lay = NULL; + _isBuilding = false; + _cur_analog_tag_index = 0; + _have_no_channel = false; + + SigSession *session = AppControl::Instance()->GetSession(); + _device_agent = session->get_device(); + + this->setTitle(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_DEVICE_OPTIONS), "Device Options")); + this->SetTitleSpace(0); + this->layout()->setSpacing(0); + this->layout()->setDirection(QBoxLayout::TopToBottom); + this->layout()->setAlignment(Qt::AlignTop); + + // scroll panel + _scroll_panel = new QWidget(); + QVBoxLayout *scroll_lay = new QVBoxLayout(); + scroll_lay->setContentsMargins(0, 0, 0, 0); + scroll_lay->setAlignment(Qt::AlignLeft); + scroll_lay->setDirection(QBoxLayout::TopToBottom); + _scroll_panel->setLayout(scroll_lay); + this->layout()->addWidget(_scroll_panel); + + // container + _container_panel = new QWidget(); + _container_lay = new QVBoxLayout(); + _container_lay->setDirection(QBoxLayout::TopToBottom); + _container_lay->setAlignment(Qt::AlignTop); + _container_lay->setContentsMargins(0, 0, 0, 0); + _container_lay->setSpacing(5); + _container_panel->setLayout(_container_lay); + scroll_lay->addWidget(_container_panel); + + QFont font = this->font(); + font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); + + // mode group box + QGroupBox *props_box = new QGroupBox(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_MODE), "Mode"), this); + props_box->setFont(font); + QLayout *props_lay = get_property_form(props_box); + props_lay->setContentsMargins(5, 20, 5, 5); + props_box->setLayout(props_lay); + _container_lay->addWidget(props_box); + + QWidget *minWid = new QWidget(); + minWid->setFixedHeight(1); + minWid->setMinimumWidth(230); + _container_lay->addWidget(minWid); + + // chnnels group box + this->build_dynamic_panel(); + + // space + QWidget *space = new QWidget(); + space->setMinimumHeight(5); + this->layout()->addWidget(space); + + //button + auto button_box = new QDialogButtonBox(QDialogButtonBox::Ok, Qt::Horizontal, this); + this->layout()->addWidget(button_box); + + _device_agent->get_config_int16(SR_CONF_OPERATION_MODE, _opt_mode); + + if (_device_agent->is_demo()) + _demo_operation_mode = _device_agent->get_demo_operation_mode(); + + try_resize_scroll(); + + connect(&_mode_check_timer, SIGNAL(timeout()), this, SLOT(mode_check_timeout())); + connect(button_box, SIGNAL(accepted()), this, SLOT(accept())); + + _mode_check_timer.setInterval(100); + _mode_check_timer.start(); +} + +DeviceOptions::~DeviceOptions() +{ +} + +void DeviceOptions::ChannelChecked(int index, QObject *object) +{ + (void)index; + + QCheckBox* sc = dynamic_cast(object); + channel_checkbox_clicked(sc); +} + +void DeviceOptions::accept() +{ + using namespace Qt; + bool hasEnabled = false; + + // Commit the properties + const auto &dev_props = _device_options_binding.properties(); + + for(auto p : dev_props) { + p->commit(); + } + + // Commit the probes + int mode = _device_agent->get_work_mode(); + if (mode == LOGIC || mode == ANALOG) { + int index = 0; + for (const GSList *l = _device_agent->get_channels(); l; l = l->next) { + sr_channel *const probe = (sr_channel*)l->data; + assert(probe); + probe->enabled = _probes_checkBox_list.at(index)->isChecked(); + index++; + if (probe->enabled) + hasEnabled = true; + } + } + else { + hasEnabled = true; + } + + if (hasEnabled) { + auto it = _probe_options_binding_list.begin(); + while(it != _probe_options_binding_list.end()) { + const auto &probe_props = (*it)->properties(); + + for(auto p :probe_props) { + p->commit(); + } + it++; + } + + _have_no_channel = false; + + QDialog::accept(); + } + else { + _have_no_channel = true; + QString strMsg(L_S(STR_PAGE_MSG, S_ID(IDS_MSG_ALL_CHANNEL_DISABLE), "All channel disabled! Please enable at least one channel.")); + MsgBox::Show(strMsg); + } +} + +void DeviceOptions::reject() +{ + using namespace Qt; + + QDialog::reject(); +} + +QLayout * DeviceOptions::get_property_form(QWidget * parent) +{ + QGridLayout *const layout = new QGridLayout(parent); + layout->setVerticalSpacing(2); + const auto &properties =_device_options_binding.properties(); + + QFont font = this->font(); + font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); + + int i = 0; + for(auto p : properties) + { + const QString label = p->labeled_widget() ? QString() : p->label(); + QString lable_text = ""; + + if (label != ""){ + QByteArray bytes = label.toLocal8Bit(); + const char *lang_str = LangResource::Instance()->get_lang_text(STR_PAGE_DSL, bytes.data(), bytes.data()); + lable_text = QString(lang_str); + } + + QLabel *lb = new QLabel(lable_text, parent); + lb->setFont(font); + layout->addWidget(lb, i, 0); + + if (label == QString("Operation Mode")){ + QWidget *wid = p->get_widget(parent, true); + wid->setFont(font); + layout->addWidget(wid, i, 1); + } + else{ + QWidget *wid = p->get_widget(parent); + wid->setFont(font); + layout->addWidget(wid, i, 1); + } + layout->setRowMinimumHeight(i, 22); + i++; + } + + _groupHeight1 = parent->sizeHint().height(); + parent->setFixedHeight(_groupHeight1); + + return layout; +} + +void DeviceOptions::logic_probes(QVBoxLayout &layout) +{ + using namespace Qt; + + layout.setSpacing(2); + + int row1 = 0; + int row2 = 0; + int vld_ch_num = 0; + int cur_ch_num = 0; + int contentHeight = 0; + + _probes_checkBox_list.clear(); + + QFont font = this->font(); + font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); + + //channel count checked + if (_device_agent->get_work_mode()== LOGIC) { + GVariant * gvar_opts = _device_agent->get_config_list(NULL, SR_CONF_CHANNEL_MODE); + + if (gvar_opts != NULL) + { + struct sr_list_item *plist = (struct sr_list_item*)g_variant_get_uint64(gvar_opts); + g_variant_unref(gvar_opts); + + int ch_mode = 0; + _device_agent->get_config_int16(SR_CONF_CHANNEL_MODE, ch_mode); + _channel_mode_indexs.clear(); + + while (plist != NULL && plist->id >= 0) + { + row1++; + QString mode_bt_text = LangResource::Instance()->get_lang_text(STR_PAGE_DSL, plist->name, plist->name); + QRadioButton *mode_button = new QRadioButton(mode_bt_text); + mode_button->setFont(font); + ChannelModePair mode_index; + mode_index.key = mode_button; + mode_index.value = plist->id; + _channel_mode_indexs.push_back(mode_index); + + layout.addWidget(mode_button); + contentHeight += mode_button->sizeHint().height(); //radio button height + + connect(mode_button, SIGNAL(pressed()), this, SLOT(channel_check())); + + if (plist->id == ch_mode) + mode_button->setChecked(true); + + plist++; + } + } + } + + _device_agent->get_config_int16(SR_CONF_VLD_CH_NUM, vld_ch_num); + + // channels + QWidget *channel_pannel = new QWidget(); + QGridLayout *channel_grid = new QGridLayout(); + channel_grid->setContentsMargins(0,0,0,0); + channel_grid->setSpacing(0); + channel_pannel->setLayout(channel_grid); + + int channel_row = 0; + int channel_column = 0; + int channel_line_height = 0; + row2++; + + for (const GSList *l = _device_agent->get_channels(); l; l = l->next) { + sr_channel *const probe = (sr_channel*)l->data; + + if (probe->enabled) + cur_ch_num++; + + if (cur_ch_num > vld_ch_num) + probe->enabled = false; + + ChannelLabel *ch_item = new ChannelLabel(this, NULL, probe->index); + channel_grid->addWidget(ch_item, channel_row, channel_column++, Qt::AlignCenter); + _probes_checkBox_list.push_back(ch_item->getCheckBox()); + ch_item->getCheckBox()->setCheckState(probe->enabled ? Qt::Checked : Qt::Unchecked); + channel_line_height = ch_item->height(); + + if (channel_column == 8){ + channel_column = 0; + channel_row++; + + if (l->next != NULL){ + row2++; + } + } + } + + layout.addWidget(channel_pannel); + + // space + QWidget *space = new QWidget(); + space->setFixedHeight(10); + layout.addWidget(space); + contentHeight += 10; + + // buttons + QHBoxLayout *line_lay = new QHBoxLayout(); + layout.addLayout(line_lay); + line_lay->setSpacing(10); + + QPushButton *enable_all_probes = new QPushButton(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_ENABLE_ALL), "Enable All")); + QPushButton *disable_all_probes = new QPushButton(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_DISABLE_ALL), "Disable All")); + enable_all_probes->setMaximumHeight(33); + disable_all_probes->setMaximumHeight(33); + enable_all_probes->setFont(font); + disable_all_probes->setFont(font); + + int bt_width = enable_all_probes->fontMetrics().horizontalAdvance(enable_all_probes->text()) + 20; + enable_all_probes->setMaximumWidth(bt_width); + disable_all_probes->setMaximumWidth(bt_width); + + this->update_font(); + + contentHeight += enable_all_probes->sizeHint().height(); + contentHeight += channel_line_height * row2 + 50; + + connect(enable_all_probes, SIGNAL(clicked()), + this, SLOT(enable_all_probes())); + connect(disable_all_probes, SIGNAL(clicked()), + this, SLOT(disable_all_probes())); + + line_lay->addWidget(enable_all_probes); + line_lay->addWidget(disable_all_probes); + + _groupHeight2 = contentHeight + (row1 + row2) * 2 + 38; + +#ifdef Q_OS_DARWIN + _groupHeight2 += 5; +#endif + + _dynamic_panel->setFixedHeight(_groupHeight2); +} + +void DeviceOptions::set_all_probes(bool set) +{ + for (auto box : _probes_checkBox_list) { + box->setCheckState(set ? Qt::Checked : Qt::Unchecked); + } +} + +void DeviceOptions::enable_max_probes() { + int cur_ch_num = 0; + for (auto box : _probes_checkBox_list) { + if (box->isChecked()) + cur_ch_num++; + } + + int vld_ch_num; + + if (_device_agent->get_config_int16(SR_CONF_VLD_CH_NUM, vld_ch_num) == false) + return; + + while(cur_ch_num < vld_ch_num && cur_ch_num < (int)_probes_checkBox_list.size()) { + auto box = _probes_checkBox_list[cur_ch_num]; + if (box->isChecked() == false) { + box->setChecked(true); + cur_ch_num++; + } + } +} + +void DeviceOptions::enable_all_probes() +{ + bool stream_mode; + + if (_device_agent->get_config_bool(SR_CONF_STREAM, stream_mode)) { + if (stream_mode) { + enable_max_probes(); + return; + } + } + + set_all_probes(true); +} + +void DeviceOptions::disable_all_probes() +{ + set_all_probes(false); +} + +void DeviceOptions::zero_adj() +{ + using namespace Qt; + QDialog::accept(); + + QString strMsg(L_S(STR_PAGE_MSG, S_ID(IDS_MSG_AUTO_CALIB_START), + "Auto Calibration program will be started. Don't connect any probes. \nIt can take a while!")); + bool bRet = MsgBox::Confirm(strMsg); + + if (bRet) { + _device_agent->set_config_bool(SR_CONF_ZERO, true); + } + else { + _device_agent->set_config_bool(SR_CONF_ZERO, false); + } +} + +void DeviceOptions::on_calibration() +{ + using namespace Qt; + QDialog::accept(); + _device_agent->set_config_bool(SR_CONF_CALI, true); +} + +void DeviceOptions::mode_check_timeout() +{ + if (_isBuilding) + return; + + if (_device_agent->is_hardware()) + { + bool test; + int mode; + + if (_device_agent->get_config_int16(SR_CONF_OPERATION_MODE, mode)) { + if (mode != _opt_mode) { + _opt_mode = mode; + build_dynamic_panel(); + try_resize_scroll(); + } + } + + if (_device_agent->get_config_bool(SR_CONF_TEST, test)) { + if (test) { + for (auto box : _probes_checkBox_list) { + box->setCheckState(Qt::Checked); + box->setDisabled(true); + } + } + } + } + else if (_device_agent->is_demo()) + { + QString opt_mode = _device_agent->get_demo_operation_mode(); + if (opt_mode != _demo_operation_mode){ + _demo_operation_mode = opt_mode; + build_dynamic_panel(); + try_resize_scroll(); + } + } +} + +void DeviceOptions::channel_check() +{ + QRadioButton* bt = dynamic_cast(sender()); + assert(bt); + + int mode_index = -1; + + for( auto p : _channel_mode_indexs){ + if (p.key == bt){ + mode_index = p.value; + break; + } + } + assert(mode_index >= 0); + _device_agent->set_config_int16(SR_CONF_CHANNEL_MODE, mode_index); + + build_dynamic_panel(); + try_resize_scroll(); +} + +void DeviceOptions::analog_channel_check() +{ + QCheckBox* sc=dynamic_cast(sender()); + if(sc != NULL) + { + for (const GSList *l = _device_agent->get_channels(); l; l = l->next) { + sr_channel *const probe = (sr_channel*)l->data; + + if (sc->property("index").toInt() == probe->index){ + _device_agent->set_config_bool(SR_CONF_PROBE_MAP_DEFAULT, sc->isChecked(), probe); + } + } + } + + build_dynamic_panel(); + try_resize_scroll(); +} + +void DeviceOptions::on_analog_channel_enable() +{ + QCheckBox* sc = dynamic_cast(sender()); + channel_checkbox_clicked(sc); +} + +void DeviceOptions::channel_checkbox_clicked(QCheckBox *sc) +{ + if (_device_agent->get_work_mode() == LOGIC) { + if (sc == NULL || !sc->isChecked()) + return; + + bool stream_mode; + if (_device_agent->get_config_bool(SR_CONF_STREAM, stream_mode) == false) + return; + + if (!stream_mode) + return; + + int cur_ch_num = 0; + for (auto box : _probes_checkBox_list) { + if (box->isChecked()) + cur_ch_num++; + } + + int vld_ch_num; + if (_device_agent->get_config_int16(SR_CONF_VLD_CH_NUM, vld_ch_num) == false) + return; + + if (cur_ch_num > vld_ch_num) { + QString msg_str(L_S(STR_PAGE_MSG, S_ID(IDS_MSG_MAX_CHANNEL_COUNT_WARNING), "max count of channels!")); + msg_str = msg_str.replace("{0}", QString::number(vld_ch_num) ); + MsgBox::Show(msg_str); + + sc->setChecked(false); + } + } + else if (_device_agent->get_work_mode() == ANALOG) { + if (sc != NULL) { + QGridLayout *const layout = (QGridLayout *)sc->property("Layout").value(); + int i = layout->count(); + + int ck_index = -1; + int i_dex = 0; + bool map_default = false; + + for(auto ck : _probes_checkBox_list){ + if (ck == sc){ + ck_index = i_dex; + break; + } + i_dex++; + } + + if (ck_index != -1) + { + _device_agent->get_config_bool(SR_CONF_PROBE_MAP_DEFAULT, + map_default, _dso_channel_list[ck_index], NULL); + } + + while(i--) + { + QWidget* w = layout->itemAt(i)->widget(); + + if (w->objectName() == "map-enable"){ + QCheckBox *map_ckbox = dynamic_cast(w); + map_ckbox->isChecked(); + } + + if (w->property("Enable").isNull()) { + + if (map_default && w->objectName() == "map-row"){ + w->setEnabled(false); + } + else{ + w->setEnabled(sc->isChecked()); + } + } + } + } + } +} + +void DeviceOptions::analog_probes(QGridLayout &layout) +{ + using namespace Qt; + + _probes_checkBox_list.clear(); + _probe_options_binding_list.clear(); + _dso_channel_list.clear(); + + QTabWidget *tabWidget = new QTabWidget(); + tabWidget->setTabPosition(QTabWidget::North); + tabWidget->setUsesScrollButtons(false); + + QFont font = this->font(); + font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); + + for (const GSList *l = _device_agent->get_channels(); l; l = l->next) { + sr_channel *const probe = (sr_channel*)l->data; + assert(probe); + + _dso_channel_list.push_back(probe); + + QWidget *probe_widget = new QWidget(tabWidget); + QGridLayout *probe_layout = new QGridLayout(probe_widget); + probe_widget->setLayout(probe_layout); + + QCheckBox *probe_checkBox = new QCheckBox(this); + QVariant vlayout = QVariant::fromValue((void *)probe_layout); + probe_checkBox->setProperty("Layout", vlayout); + probe_checkBox->setProperty("Enable", true); + probe_checkBox->setCheckState(probe->enabled ? Qt::Checked : Qt::Unchecked); + _probes_checkBox_list.push_back(probe_checkBox); + + QLabel *en_label = new QLabel(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_ENABLE), "Enable: "), this); + en_label->setFont(font); + en_label->setProperty("Enable", true); + probe_layout->addWidget(en_label, 0, 0, 1, 1); + probe_layout->addWidget(probe_checkBox, 0, 1, 1, 3); + + auto *probe_options_binding = new pv::prop::binding::ProbeOptions(probe); + const auto &properties = probe_options_binding->properties(); + int i = 1; + + for(auto p : properties) + { + const QString label = p->labeled_widget() ? QString() : p->label(); + QLabel *lb = new QLabel(label, probe_widget); + lb->setFont(font); + probe_layout->addWidget(lb, i, 0, 1, 1); + + QWidget * pow = p->get_widget(probe_widget); + pow->setEnabled(probe_checkBox->isChecked()); + pow->setFont(font); + + if (p->name().contains("Map Default")) { + pow->setProperty("index", probe->index); + connect(pow, SIGNAL(clicked()), this, SLOT(analog_channel_check())); + } + else { + if (probe_checkBox->isChecked() && p->name().contains("Map")) { + bool map_default = true; + + _device_agent->get_config_bool(SR_CONF_PROBE_MAP_DEFAULT, map_default, probe, NULL); + + if (map_default) + pow->setEnabled(false); + + pow->setObjectName("map-row"); + } + } + probe_layout->addWidget(pow, i, 1, 1, 3); + i++; + } + _probe_options_binding_list.push_back(probe_options_binding); + + connect(probe_checkBox, SIGNAL(released()), this, SLOT(on_analog_channel_enable())); + + QString tabName = QString::fromUtf8(probe->name); + tabName += " "; + + tabWidget->addTab(probe_widget, tabName); + } + + layout.addWidget(tabWidget, 0, 0, 1, 1); + + this->update_font(); + _groupHeight2 = tabWidget->sizeHint().height() + 10; + _dynamic_panel->setFixedHeight(_groupHeight2); + + connect(tabWidget, SIGNAL(currentChanged(int)), this, SLOT(on_anlog_tab_changed(int))); + tabWidget->setCurrentIndex(_cur_analog_tag_index); +} + +void DeviceOptions::on_anlog_tab_changed(int index) +{ + _cur_analog_tag_index = index; +} + +QString DeviceOptions::dynamic_widget(QLayout *lay) + { + int mode = _device_agent->get_work_mode(); + + if (mode == LOGIC) { + QVBoxLayout *grid = dynamic_cast(lay); + assert(grid); + logic_probes(*grid); + //tr + return L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CHANNEL), "Channel"); + } + else if (mode == DSO) { + bool have_zero; + + if (_device_agent->get_config_bool(SR_CONF_HAVE_ZERO, have_zero)) { + QGridLayout *grid = dynamic_cast(lay); + assert(grid); + + QFont font = this->font(); + font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); + + if (have_zero) { + auto config_button = new QPushButton(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_AUTO_CALIBRATION), "Auto Calibration"), this); + config_button->setFont(font); + grid->addWidget(config_button, 0, 0, 1, 1); + connect(config_button, SIGNAL(clicked()), this, SLOT(zero_adj())); + + auto cali_button = new QPushButton(L_S(STR_PAGE_DLG, S_ID(IDS_DLG_MANUAL_CALIBRATION), "Manual Calibration"), this); + cali_button->setFont(font); + grid->addWidget(cali_button, 1, 0, 1, 1); + connect(cali_button, SIGNAL(clicked()), this, SLOT(on_calibration())); + + config_button->setFixedHeight(35); + cali_button->setFixedHeight(35); + + _groupHeight2 = 135; + _dynamic_panel->setFixedHeight(_groupHeight2); + + //tr + return L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CALIBRATION), "Calibration"); + } + } + } + else if (mode == ANALOG) { + QGridLayout *grid = dynamic_cast(lay); + assert(grid); + analog_probes(*grid); + //tr + return L_S(STR_PAGE_DLG, S_ID(IDS_DLG_CHANNEL), "Channel"); + } + return NULL; +} + +void DeviceOptions::build_dynamic_panel() +{ + _isBuilding = true; + + if (_dynamic_panel != NULL){ + _dynamic_panel->deleteLater(); + _dynamic_panel = NULL; + } + + QFont font = this->font(); + font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); + + if (_dynamic_panel == NULL) + { + _dynamic_panel = new QGroupBox("group", _dynamic_panel); + _dynamic_panel->setFont(font); + _container_lay->addWidget(_dynamic_panel); + + if (_device_agent->get_work_mode() == LOGIC) + _dynamic_panel->setLayout(new QVBoxLayout()); + else + _dynamic_panel->setLayout(new QGridLayout()); + } + + QString title = dynamic_widget(_dynamic_panel->layout()); + QGroupBox *box = dynamic_cast(_dynamic_panel); + box->setFont(font); + box->setTitle(title); + + if (title == ""){ + box->setVisible(false); + } + + _dynamic_panel->layout()->setContentsMargins(5, 20, 5, 5); + + _isBuilding = false; +} + +void DeviceOptions::try_resize_scroll() +{ + this->update_font(); + + // content area height + int contentHeight = _groupHeight1 + _groupHeight2 + 20; // +space + //dialog height + int dlgHeight = contentHeight + 100; // +bottom buttton + +#ifdef Q_OS_DARWIN + dlgHeight += 20; +#endif + + float sk = QGuiApplication::primaryScreen()->logicalDotsPerInch() / 96; + + int srcHeight = 600; + int w = _width; + + +#ifdef _WIN32 + QFont font = this->font(); + font.setPointSizeF(AppConfig::Instance().appOptions.fontSize); + QFontMetrics fm(font); + + auto labels = this->findChildren(); + int max_label_width = 0; + for(auto o : labels) + { + QRect rc = fm.boundingRect(o->text()); + QSize size(rc.width() + 15, rc.height()); + o->setFixedSize(size); + + if (size.width() > max_label_width){ + max_label_width = size.width(); + } + } + + if (_device_agent->get_work_mode() == LOGIC + && _device_agent->is_demo()){ + _dynamic_panel->setFixedWidth(max_label_width + 150); + } +#endif + + if (w == 0) + { + w = this->sizeHint().width(); + _width = w; + } + + QScrollArea *scroll = _scroll; + if (scroll == NULL) + { + scroll = new QScrollArea(_scroll_panel); + scroll->setWidget(_container_panel); + scroll->setStyleSheet("QScrollArea{border:none;}"); + scroll->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); + _scroll = scroll; + } + + _container_panel->setFixedHeight(contentHeight); + int sclw = w - 23; + +#ifdef Q_OS_DARWIN + sclw -= 20; +#endif + + if (sk * dlgHeight > srcHeight) + { + int exth = 120; + this->setFixedSize(w + 12, srcHeight); + _scroll_panel->setFixedSize(w, srcHeight - exth); + _scroll->setFixedSize(sclw, srcHeight - exth); + } + else + { + this->setFixedSize(w + 12, dlgHeight); + _scroll_panel->setFixedSize(w, contentHeight); + _scroll->setFixedSize(sclw, contentHeight); + } +} + +void DeviceOptions::keyPressEvent(QKeyEvent *event) +{ + if (event->key() == Qt::Key_Escape && _have_no_channel) { + event->ignore(); + return; + } + + QDialog::keyPressEvent(event); +} + +} // namespace dialogs +} // namespace pv