From 787d9b1378d4a2eeca094b33eca2c40520278484 Mon Sep 17 00:00:00 2001 From: dreamsourcelabTAI Date: Tue, 6 Sep 2022 09:12:47 +0800 Subject: [PATCH] Code refactoring 17 --- DSView/pv/deviceagent.cpp | 2 +- DSView/pv/deviceagent.h | 23 +- DSView/pv/dock/measuredock.cpp | 13 +- DSView/pv/dock/measuredock.h | 6 +- DSView/pv/dock/triggerdock.cpp | 78 + DSView/pv/dock/triggerdock.h | 23 +- DSView/pv/eventobject.h | 3 +- DSView/pv/interface/icallbacks.h | 21 +- DSView/pv/mainwindow.cpp | 2666 +++++++++++++--------------- DSView/pv/mainwindow.h | 39 +- DSView/pv/sigsession.cpp | 95 +- DSView/pv/sigsession.h | 35 +- DSView/pv/toolbars/filebar.cpp | 20 +- DSView/pv/toolbars/filebar.h | 11 +- DSView/pv/toolbars/logobar.cpp | 19 - DSView/pv/toolbars/logobar.h | 5 - DSView/pv/toolbars/samplingbar.cpp | 115 +- DSView/pv/toolbars/samplingbar.h | 39 +- DSView/pv/view/devmode.cpp | 3 +- DSView/pv/view/devmode.h | 3 +- DSView/pv/view/view.cpp | 53 +- DSView/pv/view/view.h | 12 +- libsigrok4DSL/lib_main.c | 77 +- 23 files changed, 1687 insertions(+), 1674 deletions(-) diff --git a/DSView/pv/deviceagent.cpp b/DSView/pv/deviceagent.cpp index 444ab528..1d0defe5 100644 --- a/DSView/pv/deviceagent.cpp +++ b/DSView/pv/deviceagent.cpp @@ -294,7 +294,7 @@ bool DeviceAgent::get_status(struct sr_status &status, gboolean prg) ds_free_config(src); } - bool DeviceAgent::is_collecting() + bool DeviceAgent::is_running() { return ds_is_collecting() > 0; } diff --git a/DSView/pv/deviceagent.h b/DSView/pv/deviceagent.h index 73eff5f0..6f2c9bb9 100644 --- a/DSView/pv/deviceagent.h +++ b/DSView/pv/deviceagent.h @@ -28,11 +28,16 @@ #include #include +namespace pv{ + // class SigSession; +} class DeviceAgent: public QObject { Q_OBJECT + // friend class SigSession; + signals: void device_updated(); void config_changed(); @@ -129,7 +134,15 @@ public: */ bool is_trigger_enabled(); - /** + bool have_enabled_channel(); + + bool get_status(struct sr_status &status, gboolean prg); + + bool is_running(); + + GSList* get_channels(); + + /** * Start collect data. */ bool start(); @@ -139,13 +152,7 @@ public: */ bool stop(); - bool have_enabled_channel(); - - bool get_status(struct sr_status &status, gboolean prg); - - bool is_collecting(); - - GSList* get_channels(); +protected: //---------------device config-----------/ public: diff --git a/DSView/pv/dock/measuredock.cpp b/DSView/pv/dock/measuredock.cpp index 209a4bab..c5f8a6b7 100644 --- a/DSView/pv/dock/measuredock.cpp +++ b/DSView/pv/dock/measuredock.cpp @@ -53,9 +53,9 @@ MeasureDock::MeasureDock(QWidget *parent, View &view, SigSession *session) : _session(session), _view(view) { - - _widget = new QWidget(this); - //_widget->setSizePolicy(); + _session->add_msg_listener(this); + + _widget = new QWidget(this); _mouse_groupBox = new QGroupBox(_widget); _fen_checkBox = new QCheckBox(_widget); @@ -691,5 +691,12 @@ void MeasureDock::del_cursor() _view.update(); } +void MeasureDock::OnMessage(int msg) +{ + if (msg == DSV_MSG_DEVICE_OPTIONS_UPDATED){ + this->reload(); + } +} + } // namespace dock } // namespace pv diff --git a/DSView/pv/dock/measuredock.h b/DSView/pv/dock/measuredock.h index 63b77b52..37c316a5 100644 --- a/DSView/pv/dock/measuredock.h +++ b/DSView/pv/dock/measuredock.h @@ -42,6 +42,7 @@ #include #include "../ui/dscombobox.h" +#include "../interface/icallbacks.h" namespace pv { @@ -54,7 +55,7 @@ namespace view { namespace dock { -class MeasureDock : public QScrollArea +class MeasureDock : public QScrollArea, public IMessageListener { Q_OBJECT @@ -77,7 +78,8 @@ private: DsComboBox* create_probe_selector(QWidget *parent); void update_probe_selector(DsComboBox *selector); -signals: + //IMessageListener + void OnMessage(int msg); private slots: void goto_cursor(); diff --git a/DSView/pv/dock/triggerdock.cpp b/DSView/pv/dock/triggerdock.cpp index bcbe3798..feaf1eba 100644 --- a/DSView/pv/dock/triggerdock.cpp +++ b/DSView/pv/dock/triggerdock.cpp @@ -35,6 +35,9 @@ #include #include #include +#include "../config/appconfig.h" +#include "../deviceagent.h" +#include "../view/logicsignal.h" namespace pv { namespace dock { @@ -45,6 +48,8 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession *session) : QScrollArea(parent), _session(session) { + session->add_msg_listener(this); + _cur_ch_num = 16; if (_session->get_device()->have_instance()) { GVariant *gvar = _session->get_device()->get_config(NULL, NULL, SR_CONF_TOTAL_CH_NUM); @@ -885,5 +890,78 @@ void TriggerDock::lineEdit_highlight(QLineEdit *dst) { QCoreApplication::sendEvent(dst, &event); } +void TriggerDock::try_commit_trigger() +{ + int i; + AppConfig &app = AppConfig::Instance(); + + int mode = _session->get_device()->get_work_mode(); + bool bInstant = _session->is_instant(); + + if (mode != LOGIC || bInstant){ + return; + } + + if (this->commit_trigger() == false) + { + /* simple trigger check trigger_enable */ + for(auto &s : _session->get_signals()) + { + assert(s); + view::LogicSignal *logicSig = NULL; + if ((logicSig = dynamic_cast(s))) { + if (logicSig->commit_trig()) + i++; + } + } + + if (app._appOptions.warnofMultiTrig && i > 1) { + dialogs::DSMessageBox msg(this); + msg.mBox()->setText(tr("Trigger")); + msg.mBox()->setInformativeText(tr("Trigger setted on multiple channels! " + "Capture will Only triggered when all setted channels fullfill at one sample")); + msg.mBox()->setIcon(QMessageBox::Information); + + QPushButton *noMoreButton = msg.mBox()->addButton(tr("Not Show Again"), QMessageBox::ActionRole); + QPushButton *cancelButton = msg.mBox()->addButton(tr("Clear Trig"), QMessageBox::ActionRole); + msg.mBox()->addButton(tr("Continue"), QMessageBox::ActionRole); + + msg.exec(); + + if (msg.mBox()->clickedButton() == cancelButton) { + for(auto &s : _session->get_signals()) + { + assert(s); + view::LogicSignal *logicSig = NULL; + if ((logicSig = dynamic_cast(s))) { + logicSig->set_trig(view::LogicSignal::NONTRIG); + logicSig->commit_trig(); + } + } + } + + if (msg.mBox()->clickedButton() == noMoreButton) + { + app._appOptions.warnofMultiTrig = false; + app.SaveApp(); + } + } + } +} + +void TriggerDock::OnMessage(int msg) +{ + switch (msg) + { + case DSV_MSG_DEVICE_OPTIONS_UPDATED: + case DSV_MSG_DEVICE_DURATION_UPDATED: + device_updated(); + break; + case DSV_MSG_COLLECT_START_PREV: + try_commit_trigger(); + break; + } +} + } // namespace dock } // namespace pv diff --git a/DSView/pv/dock/triggerdock.h b/DSView/pv/dock/triggerdock.h index eef9cab3..b599a01a 100644 --- a/DSView/pv/dock/triggerdock.h +++ b/DSView/pv/dock/triggerdock.h @@ -43,6 +43,7 @@ #include #include "../ui/dscombobox.h" +#include "../interface/icallbacks.h" namespace pv { @@ -50,7 +51,7 @@ class SigSession; namespace dock { -class TriggerDock : public QScrollArea +class TriggerDock : public QScrollArea, public IMessageListener { Q_OBJECT @@ -68,12 +69,6 @@ public: QJsonObject get_session(); void set_session(QJsonObject ses); - /* - * commit trigger setting - * return 0: simple trigger - * 1: advanced trigger - */ - bool commit_trigger(); private: void changeEvent(QEvent *event); void retranslateUi(); @@ -82,7 +77,17 @@ private: void setup_adv_tab(); void lineEdit_highlight(QLineEdit *dst); -signals: + /* + * commit trigger setting + * return 0: simple trigger + * 1: advanced trigger + */ + bool commit_trigger(); + + void try_commit_trigger(); + + //IMessageListener + void OnMessage(int msg); public slots: void simple_trigger(); @@ -93,8 +98,6 @@ public slots: void device_updated(); -private: - private: SigSession *_session; diff --git a/DSView/pv/eventobject.h b/DSView/pv/eventobject.h index 2abf5724..1b13c2e5 100644 --- a/DSView/pv/eventobject.h +++ b/DSView/pv/eventobject.h @@ -36,8 +36,6 @@ signals: void show_error(QString error); void capture_state_changed(int state); void data_updated(); - void device_attach(); - void device_detach(); void session_error(); void signals_changed(); @@ -48,6 +46,7 @@ signals: void decode_done(); void receive_data_len(quint64 len); void cur_snap_samplerate_changed(); + void trigger_message(int msg); }; #endif \ No newline at end of file diff --git a/DSView/pv/interface/icallbacks.h b/DSView/pv/interface/icallbacks.h index 7b103461..7039ee06 100644 --- a/DSView/pv/interface/icallbacks.h +++ b/DSView/pv/interface/icallbacks.h @@ -31,7 +31,6 @@ public: virtual void show_error(QString error)=0; virtual void session_error()=0; virtual void capture_state_changed(int state)=0; - virtual void device_attach()=0; virtual void device_detach()=0; virtual void session_save()=0; @@ -54,7 +53,7 @@ public: virtual void receive_header()=0; virtual void data_received()=0; - virtual void device_list_changed() = 0; + virtual void trigger_message(int msg)=0; }; @@ -64,4 +63,22 @@ public: virtual bool genSessionData(std::string &str) = 0; }; + +#define DSV_MSG_DEVICE_LIST_UPDATE 4500 +#define DSV_MSG_COLLECT_START_PREV 5001 +#define DSV_MSG_COLLECT_START 5002 +#define DSV_MSG_COLLECT_END_PREV 5003 +#define DSV_MSG_COLLECT_END 5004 +#define DSV_MSG_BEGIN_DEVICE_OPTIONS 6001 //Begin show device options dialog. +#define DSV_MSG_END_DEVICE_OPTIONS 6002 +#define DSV_MSG_DEVICE_OPTIONS_UPDATED 6003 +#define DSV_MSG_DEVICE_DURATION_UPDATED 6004 +#define DSV_MSG_DEVICE_MODE_CHANGED 6005 + +class IMessageListener +{ +public: + virtual void OnMessage(int msg)=0; +}; + #endif diff --git a/DSView/pv/mainwindow.cpp b/DSView/pv/mainwindow.cpp index 0556e5fb..dd56975d 100644 --- a/DSView/pv/mainwindow.cpp +++ b/DSView/pv/mainwindow.cpp @@ -20,8 +20,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ - - #include #include #include @@ -30,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -91,7 +89,7 @@ #include "appcontrol.h" #include "dsvdef.h" #include "appcontrol.h" -#include "utility/encoding.h" +#include "utility/encoding.h" #include "utility/path.h" #include "log.h" #include "sigsession.h" @@ -99,1499 +97,1371 @@ #define BASE_SESSION_VERSION 2 - -namespace pv { - -MainWindow::MainWindow(QWidget *parent) : - QMainWindow(parent), - _hot_detach(false), - _msg(NULL) -{ - _session = AppControl::Instance()->GetSession(); - _session->set_callback(this); - _device_agent = _session->get_device(); - - _bFirstLoad = true; - - setup_ui(); - - setContextMenuPolicy(Qt::NoContextMenu); -} - -void MainWindow::setup_ui() -{ - setObjectName(QString::fromUtf8("MainWindow")); - setContentsMargins(0,0,0,0); - layout()->setSpacing(0); - - // Setup the central widget - _central_widget = new QWidget(this); - _vertical_layout = new QVBoxLayout(_central_widget); - _vertical_layout->setSpacing(0); - _vertical_layout->setContentsMargins(0, 0, 0, 0); - setCentralWidget(_central_widget); - - // Setup the sampling bar - _sampling_bar = new toolbars::SamplingBar(_session, this); - _sampling_bar->setObjectName("sampling_bar"); - _trig_bar = new toolbars::TrigBar(_session, this); - _trig_bar->setObjectName("trig_bar"); - _file_bar = new toolbars::FileBar(_session, this); - _file_bar->setObjectName("file_bar"); - _logo_bar = new toolbars::LogoBar(_session, this); - _logo_bar->setObjectName("logo_bar"); - - // trigger dock - _trigger_dock=new QDockWidget(tr("Trigger Setting..."),this); - _trigger_dock->setObjectName("trigger_dock"); - _trigger_dock->setFeatures(QDockWidget::DockWidgetMovable); - _trigger_dock->setAllowedAreas(Qt::RightDockWidgetArea); - _trigger_dock->setVisible(false); - _trigger_widget = new dock::TriggerDock(_trigger_dock, _session); - _trigger_dock->setWidget(_trigger_widget); - - _dso_trigger_dock=new QDockWidget(tr("Trigger Setting..."),this); - _dso_trigger_dock->setObjectName("dso_trigger_dock"); - _dso_trigger_dock->setFeatures(QDockWidget::DockWidgetMovable); - _dso_trigger_dock->setAllowedAreas(Qt::RightDockWidgetArea); - _dso_trigger_dock->setVisible(false); - _dso_trigger_widget = new dock::DsoTriggerDock(_dso_trigger_dock, _session); - _dso_trigger_dock->setWidget(_dso_trigger_widget); - - - // Setup _view widget - _view = new pv::view::View(_session, _sampling_bar, this); - _vertical_layout->addWidget(_view); - - setIconSize(QSize(40,40)); - addToolBar(_sampling_bar); - addToolBar(_trig_bar); - addToolBar(_file_bar); - addToolBar(_logo_bar); - - //Setup the dockWidget - _protocol_dock=new QDockWidget(tr("Protocol"),this); - _protocol_dock->setObjectName("protocol_dock"); - _protocol_dock->setFeatures(QDockWidget::DockWidgetMovable); - _protocol_dock->setAllowedAreas(Qt::RightDockWidgetArea); - _protocol_dock->setVisible(false); - _protocol_widget = new dock::ProtocolDock(_protocol_dock, *_view, _session); - _protocol_dock->setWidget(_protocol_widget); - - - // measure dock - _measure_dock=new QDockWidget(tr("Measurement"),this); - _measure_dock->setObjectName("measure_dock"); - _measure_dock->setFeatures(QDockWidget::DockWidgetMovable); - _measure_dock->setAllowedAreas(Qt::RightDockWidgetArea); - _measure_dock->setVisible(false); - _measure_widget = new dock::MeasureDock(_measure_dock, *_view, _session); - _measure_dock->setWidget(_measure_widget); - // search dock - _search_dock=new QDockWidget(tr("Search..."), this); - _search_dock->setObjectName("search_dock"); - _search_dock->setFeatures(QDockWidget::NoDockWidgetFeatures); - _search_dock->setTitleBarWidget(new QWidget(_search_dock)); - _search_dock->setAllowedAreas(Qt::BottomDockWidgetArea); - _search_dock->setVisible(false); - //dock::SearchDock *_search_widget = new dock::SearchDock(_search_dock, *_view, _session); - _search_widget = new dock::SearchDock(_search_dock, *_view, _session); - _search_dock->setWidget(_search_widget); - - - addDockWidget(Qt::RightDockWidgetArea,_protocol_dock); - - addDockWidget(Qt::RightDockWidgetArea,_trigger_dock); - addDockWidget(Qt::RightDockWidgetArea,_dso_trigger_dock); - addDockWidget(Qt::RightDockWidgetArea, _measure_dock); - addDockWidget(Qt::BottomDockWidgetArea, _search_dock); - - // Set the title - QString title = QApplication::applicationName()+" v"+QApplication::applicationVersion(); - std::string std_title = title.toStdString(); - setWindowTitle(QApplication::translate("MainWindow", std_title.c_str(), 0)); - - - // event filter - _view->installEventFilter(this); - _sampling_bar->installEventFilter(this); - _trig_bar->installEventFilter(this); - _file_bar->installEventFilter(this); - _logo_bar->installEventFilter(this); - _dso_trigger_dock->installEventFilter(this); - _trigger_dock->installEventFilter(this); - _protocol_dock->installEventFilter(this); - _measure_dock->installEventFilter(this); - _search_dock->installEventFilter(this); - - // Populate the device list and select the initially selected device - _session->set_default_device(); - - // defaut language - AppConfig &app = AppConfig::Instance(); - switchLanguage(app._frameOptions.language); - switchTheme(app._frameOptions.style); - - // UI initial - _measure_widget->add_dist_measure(); - - retranslateUi(); - - //event - connect(&_event, SIGNAL(capture_state_changed(int)), this, SLOT(on_capture_state_changed(int))); - connect(&_event, SIGNAL(device_attach()), this, SLOT(on_device_attach())); - connect(&_event, SIGNAL(device_detach()), this, SLOT(on_device_detach())); - connect(&_event, SIGNAL(session_error()), this, SLOT(on_session_error())); - connect(&_event, SIGNAL(show_error(QString)), this, SLOT(on_show_error(QString))); - connect(&_event, SIGNAL(signals_changed()), this, SLOT(on_signals_changed())); - connect(&_event, SIGNAL(receive_trigger(quint64)), this, SLOT(on_receive_trigger(quint64))); - connect(&_event, SIGNAL(frame_ended()), this, SLOT(on_frame_ended())); - connect(&_event, SIGNAL(frame_began()), this, SLOT(on_frame_began())); - connect(&_event, SIGNAL(decode_done()), this, SLOT(on_decode_done())); - connect(&_event, SIGNAL(data_updated()), this, SLOT(on_data_updated())); - connect(&_event, SIGNAL(cur_snap_samplerate_changed()), this, SLOT(on_cur_snap_samplerate_changed())); - connect(&_event, SIGNAL(receive_data_len(quint64)), this, SLOT(on_receive_data_len(quint64))); - //view - connect(_view, SIGNAL(cursor_update()), _measure_widget, SLOT(cursor_update())); - connect(_view, SIGNAL(cursor_moving()), _measure_widget, SLOT(cursor_moving())); - connect(_view, SIGNAL(cursor_moved()), _measure_widget, SLOT(reCalc())); - connect(_view, SIGNAL(prgRate(int)), this, SIGNAL(prgRate(int))); - connect(_view, SIGNAL(device_changed(bool)), this, SLOT(device_changed(bool)), Qt::DirectConnection); - connect(_view, SIGNAL(auto_trig(int)), _dso_trigger_widget, SLOT(auto_trig(int))); - - //trig_bar - connect(_trig_bar, SIGNAL(sig_protocol(bool)), this, SLOT(on_protocol(bool))); - connect(_trig_bar, SIGNAL(sig_trigger(bool)), this, SLOT(on_trigger(bool))); - connect(_trig_bar, SIGNAL(sig_measure(bool)), this, SLOT(on_measure(bool))); - connect(_trig_bar, SIGNAL(sig_search(bool)), this, SLOT(on_search(bool))); - connect(_trig_bar, SIGNAL(sig_setTheme(QString)), this, SLOT(switchTheme(QString))); - connect(_trig_bar, SIGNAL(sig_show_lissajous(bool)), _view, SLOT(show_lissajous(bool))); - - //file toolbar - connect(_file_bar, SIGNAL(sig_load_file(QString)), this, SLOT(on_load_file(QString))); - connect(_file_bar, SIGNAL(sig_save()), this, SLOT(on_save())); - connect(_file_bar, SIGNAL(sig_export()), this, SLOT(on_export())); - connect(_file_bar, SIGNAL(sig_screenShot()), this, SLOT(on_screenShot()), Qt::QueuedConnection); - connect(_file_bar, SIGNAL(sig_load_session(QString)), this, SLOT(on_load_session(QString))); - connect(_file_bar, SIGNAL(sig_store_session(QString)), this, SLOT(on_store_session(QString))); - - //logobar - connect(_logo_bar, SIGNAL(sig_open_doc()), this, SLOT(on_open_doc())); - - - connect(_protocol_widget, SIGNAL(protocol_updated()), this, SLOT(on_signals_changed())); - - //SamplingBar - connect(_sampling_bar, SIGNAL(sig_device_selected()), this, SLOT(on_device_selected())); - connect(_sampling_bar, SIGNAL(sig_device_updated()), this, SLOT(on_device_updated_reload())); - connect(_sampling_bar, SIGNAL(sig_run_stop()), this, SLOT(on_run_stop())); - connect(_sampling_bar, SIGNAL(sig_instant_stop()), this, SLOT(on_instant_stop())); - connect(_sampling_bar, SIGNAL(sig_duration_changed()), _trigger_widget, SLOT(device_updated())); - connect(_sampling_bar, SIGNAL(sig_duration_changed()), _view, SLOT(timebase_changed())); - connect(_sampling_bar, SIGNAL(sig_show_calibration()), _view, SLOT(show_calibration())); - - connect(_dso_trigger_widget, SIGNAL(set_trig_pos(int)), _view, SLOT(set_trig_pos(int))); - - _logo_bar->set_mainform_callback(this); - - //delay to update device list - QTimer::singleShot(200, this, SLOT(update_device_list())); - -} - - -void MainWindow::retranslateUi() +namespace pv { - _trigger_dock->setWindowTitle(tr("Trigger Setting...")); - _dso_trigger_dock->setWindowTitle(tr("Trigger Setting...")); - _protocol_dock->setWindowTitle(tr("Protocol")); - _measure_dock->setWindowTitle(tr("Measurement")); - _search_dock->setWindowTitle(tr("Search...")); -} - -void MainWindow::on_device_selected() -{ - update_device_list(); -} + MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), + _msg(NULL) + { + _session = AppControl::Instance()->GetSession(); + _session->set_callback(this); + _device_agent = _session->get_device(); + _session->add_msg_listener(this); -void MainWindow::update_device_list() -{ - assert(_sampling_bar); + _bFirstLoad = true; - /* + setup_ui(); - if (_msg) - _msg->close(); + setContextMenuPolicy(Qt::NoContextMenu); + } - AppConfig &app = AppConfig::Instance(); - + void MainWindow::setup_ui() + { + setObjectName(QString::fromUtf8("MainWindow")); + setContentsMargins(0, 0, 0, 0); + layout()->setSpacing(0); - switchLanguage(app._frameOptions.language); - _session->stop_capture(); - _view->reload(); - _trigger_widget->device_updated(); + // Setup the central widget + _central_widget = new QWidget(this); + _vertical_layout = new QVBoxLayout(_central_widget); + _vertical_layout->setSpacing(0); + _vertical_layout->setContentsMargins(0, 0, 0, 0); + setCentralWidget(_central_widget); - _protocol_widget->del_all_protocol(); + // Setup the sampling bar + _sampling_bar = new toolbars::SamplingBar(_session, this); + _sampling_bar->setObjectName("sampling_bar"); + _trig_bar = new toolbars::TrigBar(_session, this); + _trig_bar->setObjectName("trig_bar"); + _file_bar = new toolbars::FileBar(_session, this); + _file_bar->setObjectName("file_bar"); + _logo_bar = new toolbars::LogoBar(_session, this); + _logo_bar->setObjectName("logo_bar"); - _trig_bar->reload(); - - DevInst *selected_device = _device_agent; - _device_manager.add_device(selected_device); - _session->init_signals(); - _sampling_bar->set_device_list(_device_manager.devices(), selected_device); + // trigger dock + _trigger_dock = new QDockWidget(tr("Trigger Setting..."), this); + _trigger_dock->setObjectName("trigger_dock"); + _trigger_dock->setFeatures(QDockWidget::DockWidgetMovable); + _trigger_dock->setAllowedAreas(Qt::RightDockWidgetArea); + _trigger_dock->setVisible(false); + _trigger_widget = new dock::TriggerDock(_trigger_dock, _session); + _trigger_dock->setWidget(_trigger_widget); - File *file_dev = NULL; - if((file_dev = dynamic_cast(selected_device))) { - // check version - if (selected_device->dev_inst()->mode == LOGIC) { - GVariant* gvar = selected_device->get_config(NULL, NULL, SR_CONF_FILE_VERSION); - if (gvar != NULL) { - int16_t version = g_variant_get_int16(gvar); - g_variant_unref(gvar); - if (version == 1) { - show_error(tr("Current loading file has an old format. " - "This will lead to a slow loading speed. " - "Please resave it after loaded.")); + _dso_trigger_dock = new QDockWidget(tr("Trigger Setting..."), this); + _dso_trigger_dock->setObjectName("dso_trigger_dock"); + _dso_trigger_dock->setFeatures(QDockWidget::DockWidgetMovable); + _dso_trigger_dock->setAllowedAreas(Qt::RightDockWidgetArea); + _dso_trigger_dock->setVisible(false); + _dso_trigger_widget = new dock::DsoTriggerDock(_dso_trigger_dock, _session); + _dso_trigger_dock->setWidget(_dso_trigger_widget); + + // Setup _view widget + _view = new pv::view::View(_session, _sampling_bar, this); + _vertical_layout->addWidget(_view); + + setIconSize(QSize(40, 40)); + addToolBar(_sampling_bar); + addToolBar(_trig_bar); + addToolBar(_file_bar); + addToolBar(_logo_bar); + + // Setup the dockWidget + _protocol_dock = new QDockWidget(tr("Protocol"), this); + _protocol_dock->setObjectName("protocol_dock"); + _protocol_dock->setFeatures(QDockWidget::DockWidgetMovable); + _protocol_dock->setAllowedAreas(Qt::RightDockWidgetArea); + _protocol_dock->setVisible(false); + _protocol_widget = new dock::ProtocolDock(_protocol_dock, *_view, _session); + _protocol_dock->setWidget(_protocol_widget); + + // measure dock + _measure_dock = new QDockWidget(tr("Measurement"), this); + _measure_dock->setObjectName("measure_dock"); + _measure_dock->setFeatures(QDockWidget::DockWidgetMovable); + _measure_dock->setAllowedAreas(Qt::RightDockWidgetArea); + _measure_dock->setVisible(false); + _measure_widget = new dock::MeasureDock(_measure_dock, *_view, _session); + _measure_dock->setWidget(_measure_widget); + // search dock + _search_dock = new QDockWidget(tr("Search..."), this); + _search_dock->setObjectName("search_dock"); + _search_dock->setFeatures(QDockWidget::NoDockWidgetFeatures); + _search_dock->setTitleBarWidget(new QWidget(_search_dock)); + _search_dock->setAllowedAreas(Qt::BottomDockWidgetArea); + _search_dock->setVisible(false); + // dock::SearchDock *_search_widget = new dock::SearchDock(_search_dock, *_view, _session); + _search_widget = new dock::SearchDock(_search_dock, *_view, _session); + _search_dock->setWidget(_search_widget); + + addDockWidget(Qt::RightDockWidgetArea, _protocol_dock); + + addDockWidget(Qt::RightDockWidgetArea, _trigger_dock); + addDockWidget(Qt::RightDockWidgetArea, _dso_trigger_dock); + addDockWidget(Qt::RightDockWidgetArea, _measure_dock); + addDockWidget(Qt::BottomDockWidgetArea, _search_dock); + + // Set the title + QString title = QApplication::applicationName() + " v" + QApplication::applicationVersion(); + std::string std_title = title.toStdString(); + setWindowTitle(QApplication::translate("MainWindow", std_title.c_str(), 0)); + + // event filter + _view->installEventFilter(this); + _sampling_bar->installEventFilter(this); + _trig_bar->installEventFilter(this); + _file_bar->installEventFilter(this); + _logo_bar->installEventFilter(this); + _dso_trigger_dock->installEventFilter(this); + _trigger_dock->installEventFilter(this); + _protocol_dock->installEventFilter(this); + _measure_dock->installEventFilter(this); + _search_dock->installEventFilter(this); + + // defaut language + AppConfig &app = AppConfig::Instance(); + switchLanguage(app._frameOptions.language); + switchTheme(app._frameOptions.style); + + // UI initial + _measure_widget->add_dist_measure(); + + retranslateUi(); + + // event + connect(&_event, SIGNAL(capture_state_changed(int)), this, SLOT(on_capture_state_changed(int))); + connect(&_event, SIGNAL(session_error()), this, SLOT(on_session_error())); + connect(&_event, SIGNAL(show_error(QString)), this, SLOT(on_show_error(QString))); + connect(&_event, SIGNAL(signals_changed()), this, SLOT(on_signals_changed())); + connect(&_event, SIGNAL(receive_trigger(quint64)), this, SLOT(on_receive_trigger(quint64))); + connect(&_event, SIGNAL(frame_ended()), this, SLOT(on_frame_ended())); + connect(&_event, SIGNAL(frame_began()), this, SLOT(on_frame_began())); + connect(&_event, SIGNAL(decode_done()), this, SLOT(on_decode_done())); + connect(&_event, SIGNAL(data_updated()), this, SLOT(on_data_updated())); + connect(&_event, SIGNAL(cur_snap_samplerate_changed()), this, SLOT(on_cur_snap_samplerate_changed())); + connect(&_event, SIGNAL(receive_data_len(quint64)), this, SLOT(on_receive_data_len(quint64))); + connect(&_event, SIGNAL(trigger_message(int)), this, SLOT(on_trigger_message(int))); + + // view + connect(_view, SIGNAL(cursor_update()), _measure_widget, SLOT(cursor_update())); + connect(_view, SIGNAL(cursor_moving()), _measure_widget, SLOT(cursor_moving())); + connect(_view, SIGNAL(cursor_moved()), _measure_widget, SLOT(reCalc())); + connect(_view, SIGNAL(prgRate(int)), this, SIGNAL(prgRate(int))); + connect(_view, SIGNAL(auto_trig(int)), _dso_trigger_widget, SLOT(auto_trig(int))); + + // trig_bar + connect(_trig_bar, SIGNAL(sig_protocol(bool)), this, SLOT(on_protocol(bool))); + connect(_trig_bar, SIGNAL(sig_trigger(bool)), this, SLOT(on_trigger(bool))); + connect(_trig_bar, SIGNAL(sig_measure(bool)), this, SLOT(on_measure(bool))); + connect(_trig_bar, SIGNAL(sig_search(bool)), this, SLOT(on_search(bool))); + connect(_trig_bar, SIGNAL(sig_setTheme(QString)), this, SLOT(switchTheme(QString))); + connect(_trig_bar, SIGNAL(sig_show_lissajous(bool)), _view, SLOT(show_lissajous(bool))); + + // file toolbar + connect(_file_bar, SIGNAL(sig_load_file(QString)), this, SLOT(on_load_file(QString))); + connect(_file_bar, SIGNAL(sig_save()), this, SLOT(on_save())); + connect(_file_bar, SIGNAL(sig_export()), this, SLOT(on_export())); + connect(_file_bar, SIGNAL(sig_screenShot()), this, SLOT(on_screenShot()), Qt::QueuedConnection); + connect(_file_bar, SIGNAL(sig_load_session(QString)), this, SLOT(on_load_session(QString))); + connect(_file_bar, SIGNAL(sig_store_session(QString)), this, SLOT(on_store_session(QString))); + + // logobar + connect(_logo_bar, SIGNAL(sig_open_doc()), this, SLOT(on_open_doc())); + + connect(_protocol_widget, SIGNAL(protocol_updated()), this, SLOT(on_signals_changed())); + + // SamplingBar + connect(_dso_trigger_widget, SIGNAL(set_trig_pos(int)), _view, SLOT(set_trig_pos(int))); + + _logo_bar->set_mainform_callback(this); + + _session->set_default_device(); + } + + void MainWindow::retranslateUi() + { + _trigger_dock->setWindowTitle(tr("Trigger Setting...")); + _dso_trigger_dock->setWindowTitle(tr("Trigger Setting...")); + _protocol_dock->setWindowTitle(tr("Protocol")); + _measure_dock->setWindowTitle(tr("Measurement")); + _search_dock->setWindowTitle(tr("Search...")); + } + + void MainWindow::update_device_list() + { + assert(_sampling_bar); + + /* + + if (_msg) + _msg->close(); + + AppConfig &app = AppConfig::Instance(); + + + switchLanguage(app._frameOptions.language); + _session->stop_capture(); + _view->reload(); + _trigger_widget->device_updated(); + + _protocol_widget->del_all_protocol(); + + _trig_bar->reload(); + + DevInst *selected_device = _device_agent; + _device_manager.add_device(selected_device); + _session->init_signals(); + _sampling_bar->set_device_list(_device_manager.devices(), selected_device); + + File *file_dev = NULL; + if((file_dev = dynamic_cast(selected_device))) { + // check version + if (selected_device->dev_inst()->mode == LOGIC) { + GVariant* gvar = selected_device->get_config(NULL, NULL, SR_CONF_FILE_VERSION); + if (gvar != NULL) { + int16_t version = g_variant_get_int16(gvar); + g_variant_unref(gvar); + if (version == 1) { + show_error(tr("Current loading file has an old format. " + "This will lead to a slow loading speed. " + "Please resave it after loaded.")); + } } } + + + // load decoders + StoreSession ss(_session); + bool bFlag = ss.load_decoders(_protocol_widget, file_dev->get_decoders()); + + // load session + load_session_json(file_dev->get_session(), true, !bFlag); + + // load data + const QString errorMessage( + QString(tr("Failed to capture file data!"))); + _session->start_capture(true); + } + + if (!selected_device->name().contains("virtual")) { + _file_bar->set_settings_en(true); + _logo_bar->dsl_connected(true); + #if QT_VERSION >= 0x050400 + QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); + #else + QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); + #endif + if (dir.exists()) { + QString str = dir.absolutePath() + "/"; + QString lang_name = ".ses" + QString::number(app._frameOptions.language); + QString ses_name = str + + selected_device->name() + + QString::number(selected_device->dev_inst()->mode) + + lang_name + ".dsc"; + on_load_session(ses_name); + } + } else { + _file_bar->set_settings_en(false); + _logo_bar->dsl_connected(false); + + QDir dir(GetResourceDir()); + if (dir.exists()) { + QString str = dir.absolutePath() + "/"; + QString ses_name = str + + selected_device->name() + + QString::number(selected_device->dev_inst()->mode) + + ".dsc"; + if (QFileInfo(ses_name).exists()) + on_load_session(ses_name); + } + } + _sampling_bar->reload(); + _view->status_clear(); + _trigger_widget->init(); + _dso_trigger_widget->init(); + _measure_widget->reload(); + + // USB device speed check + if (!selected_device->name().contains("virtual")) { + int usb_speed = LIBUSB_SPEED_HIGH; + GVariant *gvar = selected_device->get_config(NULL, NULL, SR_CONF_USB_SPEED); + if (gvar != NULL) { + usb_speed = g_variant_get_int32(gvar); + g_variant_unref(gvar); + } + + bool usb30_support = false; + gvar = selected_device->get_config(NULL, NULL, SR_CONF_USB30_SUPPORT); + if (gvar != NULL) { + usb30_support = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + + if (usb30_support && usb_speed == LIBUSB_SPEED_HIGH) + show_error(tr("Plug it into a USB 2.0 port will seriously affect its performance." + "Please replug it into a USB 3.0 port.")); + } } - - // load decoders - StoreSession ss(_session); - bool bFlag = ss.load_decoders(_protocol_widget, file_dev->get_decoders()); + _trig_bar->restore_status(); - // load session - load_session_json(file_dev->get_session(), true, !bFlag); + //load specified file name from application startup param + if (_bFirstLoad){ + _bFirstLoad = false; - // load data - const QString errorMessage( - QString(tr("Failed to capture file data!"))); - _session->start_capture(true); - } + QString ldFileName(AppControl::Instance()->_open_file_name.c_str()); - if (!selected_device->name().contains("virtual")) { - _file_bar->set_settings_en(true); - _logo_bar->dsl_connected(true); - #if QT_VERSION >= 0x050400 - QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation)); - #else - QDir dir(QStandardPaths::writableLocation(QStandardPaths::DataLocation)); - #endif - if (dir.exists()) { - QString str = dir.absolutePath() + "/"; - QString lang_name = ".ses" + QString::number(app._frameOptions.language); - QString ses_name = str + - selected_device->name() + - QString::number(selected_device->dev_inst()->mode) + - lang_name + ".dsc"; - on_load_session(ses_name); - } - } else { - _file_bar->set_settings_en(false); - _logo_bar->dsl_connected(false); - - QDir dir(GetResourceDir()); - if (dir.exists()) { - QString str = dir.absolutePath() + "/"; - QString ses_name = str + - selected_device->name() + - QString::number(selected_device->dev_inst()->mode) + - ".dsc"; - if (QFileInfo(ses_name).exists()) - on_load_session(ses_name); - } - } - _sampling_bar->reload(); - _view->status_clear(); - _trigger_widget->init(); - _dso_trigger_widget->init(); - _measure_widget->reload(); - - // USB device speed check - if (!selected_device->name().contains("virtual")) { - int usb_speed = LIBUSB_SPEED_HIGH; - GVariant *gvar = selected_device->get_config(NULL, NULL, SR_CONF_USB_SPEED); - if (gvar != NULL) { - usb_speed = g_variant_get_int32(gvar); - g_variant_unref(gvar); - } - - bool usb30_support = false; - gvar = selected_device->get_config(NULL, NULL, SR_CONF_USB30_SUPPORT); - if (gvar != NULL) { - usb30_support = g_variant_get_boolean(gvar); - g_variant_unref(gvar); - - if (usb30_support && usb_speed == LIBUSB_SPEED_HIGH) - show_error(tr("Plug it into a USB 2.0 port will seriously affect its performance." - "Please replug it into a USB 3.0 port.")); - } - } - - _trig_bar->restore_status(); - - //load specified file name from application startup param - if (_bFirstLoad){ - _bFirstLoad = false; - - QString ldFileName(AppControl::Instance()->_open_file_name.c_str()); - - if (ldFileName != ""){ - if (QFile::exists(ldFileName)){ - dsv_info("auto load file:%s", ldFileName.toUtf8().data()); - on_load_file(ldFileName); + if (ldFileName != ""){ + if (QFile::exists(ldFileName)){ + dsv_info("auto load file:%s", ldFileName.toUtf8().data()); + on_load_file(ldFileName); + } + else{ + dsv_err("file is not exists:%s", ldFileName.toUtf8().data()); + MsgBox::Show(tr("Open file error!"), ldFileName, NULL); + } } - else{ - dsv_err("file is not exists:%s", ldFileName.toUtf8().data()); - MsgBox::Show(tr("Open file error!"), ldFileName, NULL); - } - } - } - */ -} - - -void MainWindow::on_device_updated_reload() -{ - _trigger_widget->device_updated(); - _session->reload(); - _measure_widget->reload(); -} - -void MainWindow::on_load_file(QString file_name) -{ - - try { - if (strncmp(_device_agent->name().toUtf8(), "virtual", 7)) - session_save(); - _session->set_file(file_name); - } catch(QString e) { - show_error(tr("Failed to load ") + file_name); - _session->set_default_device(); + } + */ } - update_device_list(); -} + void MainWindow::on_load_file(QString file_name) + { + try + { + if (strncmp(_device_agent->name().toUtf8(), "virtual", 7)) + session_save(); + _session->set_file(file_name); + } + catch (QString e) + { + show_error(tr("Failed to load ") + file_name); + _session->set_default_device(); + } + } -void MainWindow::show_error(QString error) -{ - _event.show_error(error); //safe call -} - -void MainWindow::on_show_error(QString error) -{ - MsgBox::Show(NULL, error.toStdString().c_str(), this); -} - -void MainWindow::device_attach() -{ - _event.device_attach(); //safe call -} - -void MainWindow::on_device_attach() -{ - /* - - _device_agent->device_updated(); - - _session->set_repeating(false); - _session->stop_capture(); - _sampling_bar->set_sampling(false); - _session->capture_state_changed(SigSession::Stopped); - - struct sr_dev_driver **const drivers = sr_driver_list(); - struct sr_dev_driver **driver; - - for (driver = drivers; *driver; driver++) + void MainWindow::show_error(QString error) { - if (*driver){ - std::list driver_devices; - _device_manager.driver_scan(driver_devices, *driver); - } + _event.show_error(error); // safe call } - _session->set_default_device(); - update_device_list(); - */ -} - -void MainWindow::device_detach(){ - _event.device_detach(); //safe call -} - -void MainWindow::on_device_detach() -{ - /* - - _device_agent->device_updated(); - //_session->stop_hot_plug_proc(); - - _session->set_repeating(false); - _session->stop_capture(); - _sampling_bar->set_sampling(false); - _session->capture_state_changed(SigSession::Stopped); - - session_save(); - _view->hide_calibration(); - - if (_device_agent->get_work_mode() != DSO && - strncmp(_device_agent->name().toUtf8(), "virtual", 7)) { - const auto logic_snapshot = _session->get_snapshot(SR_CHANNEL_LOGIC); - assert(logic_snapshot); - const auto analog_snapshot = _session->get_snapshot(SR_CHANNEL_ANALOG); - assert(analog_snapshot); - - if (!logic_snapshot->empty() || !analog_snapshot->empty()) { - dialogs::DSMessageBox msg(this); - _msg = &msg; - msg.mBox()->setText(tr("Hardware Detached")); - msg.mBox()->setInformativeText(tr("Save captured data?")); - msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole); - msg.mBox()->addButton(tr("Cancel"), QMessageBox::RejectRole); - msg.mBox()->setIcon(QMessageBox::Warning); - if (msg.exec()) - on_save(); - _msg = NULL; - } + void MainWindow::on_show_error(QString error) + { + MsgBox::Show(NULL, error.toStdString().c_str(), this); } - _hot_detach = true; - if (!_session->get_saving()) - device_detach_post(); - */ -} + // void MainWindow::on_device_detach() + //{ + /* -void MainWindow::device_detach_post() -{ - if (!_hot_detach) - return; + _device_agent->device_updated(); + //_session->stop_hot_plug_proc(); - /* - _hot_detach = false; - struct sr_dev_driver **const drivers = sr_driver_list(); - struct sr_dev_driver **driver; - for (driver = drivers; *driver; driver++){ - if (*driver){ - std::list driver_devices; - _device_manager.driver_scan(driver_devices, *driver); - } - } - - _session->set_default_device(); - update_device_list(); - */ -} - -void MainWindow::device_changed(bool close) -{ - if (close) { - _sampling_bar->set_sampling(false); - _session->set_default_device(); - } - - update_device_list(); -} - -void MainWindow::on_run_stop() -{ - switch(_session->get_capture_state()) { - case SigSession::Init: - case SigSession::Stopped: - commit_trigger(false); - _session->start_capture(false); - _view->capture_init(); - break; - - case SigSession::Running: - _session->stop_capture(); - break; - } -} - -void MainWindow::on_instant_stop() -{ - switch(_session->get_capture_state()) { - case SigSession::Init: - case SigSession::Stopped: - commit_trigger(true); - _session->start_capture(true); - _view->capture_init(); - break; - - case SigSession::Running: - _session->stop_capture(); - break; - } -} - -void MainWindow::repeat_resume() -{ - while(_view->session().get_capture_state() == SigSession::Running) - QCoreApplication::processEvents(); - on_run_stop(); -} - -void MainWindow::session_error() -{ - _event.session_error(); -} - -void MainWindow::on_session_error() -{ - QString title; - QString details; - QString ch_status = ""; - uint64_t error_pattern; - - switch(_session->get_error()) { - case SigSession::Hw_err: - _session->set_repeating(false); - _session->stop_capture(); - title = tr("Hardware Operation Failed"); - details = tr("Please replug device to refresh hardware configuration!"); - break; - case SigSession::Malloc_err: - _session->set_repeating(false); - _session->stop_capture(); - title = tr("Malloc Error"); - details = tr("Memory is not enough for this sample!\nPlease reduce the sample depth!"); - break; - case SigSession::Test_data_err: _session->set_repeating(false); _session->stop_capture(); _sampling_bar->set_sampling(false); _session->capture_state_changed(SigSession::Stopped); - title = tr("Data Error"); - error_pattern = _session->get_error_pattern(); - for(int i = 0; i < 16; i++) { - if (error_pattern & 0x01) - ch_status += "X "; - else - ch_status += " "; - ch_status += (i > 9 ? " " : ""); - error_pattern >>= 1; - } - details = tr("the received data are not consist with pre-defined test data!") + "\n" + - tr("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15")+ "\n" + ch_status; - break; - case SigSession::Pkt_data_err: - title = tr("Packet Error"); - details = tr("the content of received packet are not expected!"); - _session->refresh(0); - break; - case SigSession::Data_overflow: - _session->set_repeating(false); - _session->stop_capture(); - title = tr("Data Overflow"); - details = tr("USB bandwidth can not support current sample rate! \nPlease reduce the sample rate!"); - break; - default: - title = tr("Undefined Error"); - details = tr("Not expected error!"); - break; - } - dialogs::DSMessageBox msg(this); - connect(_device_agent, SIGNAL(device_updated()), &msg, SLOT(accept())); - QFont font("Monaco"); - font.setStyleHint(QFont::Monospace); - font.setFixedPitch(true); - msg.mBox()->setFont(font); + session_save(); + _view->hide_calibration(); - msg.mBox()->setText(title); - msg.mBox()->setInformativeText(details); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); + if (_device_agent->get_work_mode() != DSO && + strncmp(_device_agent->name().toUtf8(), "virtual", 7)) { + const auto logic_snapshot = _session->get_snapshot(SR_CHANNEL_LOGIC); + assert(logic_snapshot); + const auto analog_snapshot = _session->get_snapshot(SR_CHANNEL_ANALOG); + assert(analog_snapshot); - _session->clear_error(); -} - -void MainWindow::capture_state_changed(int state) -{ - _event.capture_state_changed(state);//safe call -} - -void MainWindow::on_capture_state_changed(int state) -{ - if (!_session->repeat_check()) { - _file_bar->enable_toggle(state != SigSession::Running); - _sampling_bar->set_sampling(state == SigSession::Running); - _view->on_state_changed(state != SigSession::Running); - - if (_device_agent->get_work_mode() != DSO || - _session->get_instant()) { - _sampling_bar->enable_toggle(state != SigSession::Running); - _trig_bar->enable_toggle(state != SigSession::Running); - //_measure_dock->widget()->setEnabled(state != SigSession::Running); - _measure_widget->refresh(); - } - } - - if (state == SigSession::Stopped) { - prgRate(0); - _view->repeat_unshow(); - } -} - -void MainWindow::session_save() -{ - QDir dir; - #if QT_VERSION >= 0x050400 - QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); - #else - QString path = QStandardPaths::writableLocation(QStandardPaths::DataLocation); - #endif - - if (_device_agent->have_instance() == false){ - dsv_info("%s", "There is no need to save the configuration"); - return; - } - - AppConfig &app = AppConfig::Instance(); - - if(dir.mkpath(path)) { - dir.cd(path); - QString driver_name = _device_agent->name(); - QString mode_name = QString::number(_device_agent->get_work_mode()); - QString lang_name = ".ses" + QString::number(app._frameOptions.language); - QString file_name = dir.absolutePath() + "/" + - driver_name + mode_name + - lang_name + ".dsc"; - if (strncmp(driver_name.toUtf8(), "virtual", 7) && - !file_name.isEmpty()) { - on_store_session(file_name); - } - } - - app._frameOptions.windowState = saveState(); - app.SaveFrame(); -} - -void MainWindow::closeEvent(QCloseEvent *event) -{ - // not used, refer to closeEvent of mainFrame - session_save(); - event->accept(); -} - -void MainWindow::on_protocol(bool visible) -{ - - _protocol_dock->setVisible(visible); - -} - -void MainWindow::on_trigger(bool visible) -{ - if (_device_agent->get_work_mode() != DSO) { - _trigger_widget->init(); - _trigger_dock->setVisible(visible); - _dso_trigger_dock->setVisible(false); - } else { - _dso_trigger_widget->init(); - _trigger_dock->setVisible(false); - _dso_trigger_dock->setVisible(visible); - } - _trig_bar->update_trig_btn(visible); -} - -void MainWindow::commit_trigger(bool instant) -{ - int i = 0; - - AppConfig &app = AppConfig::Instance(); - - if (_device_agent->get_work_mode() != LOGIC || - instant) - return; - - if (!_trigger_widget->commit_trigger()) { - /* simple trigger check trigger_enable */ - for(auto &s : _session->get_signals()) - { - assert(s); - view::LogicSignal *logicSig = NULL; - if ((logicSig = dynamic_cast(s))) { - if (logicSig->commit_trig()) - i++; + if (!logic_snapshot->empty() || !analog_snapshot->empty()) { + dialogs::DSMessageBox msg(this); + _msg = &msg; + msg.mBox()->setText(tr("Hardware Detached")); + msg.mBox()->setInformativeText(tr("Save captured data?")); + msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole); + msg.mBox()->addButton(tr("Cancel"), QMessageBox::RejectRole); + msg.mBox()->setIcon(QMessageBox::Warning); + if (msg.exec()) + on_save(); + _msg = NULL; } } - if (app._appOptions.warnofMultiTrig && i > 1) { - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(tr("Trigger")); - msg.mBox()->setInformativeText(tr("Trigger setted on multiple channels! " - "Capture will Only triggered when all setted channels fullfill at one sample")); - msg.mBox()->setIcon(QMessageBox::Information); - QPushButton *noMoreButton = msg.mBox()->addButton(tr("Not Show Again"), QMessageBox::ActionRole); - QPushButton *cancelButton = msg.mBox()->addButton(tr("Clear Trig"), QMessageBox::ActionRole); - msg.mBox()->addButton(tr("Continue"), QMessageBox::ActionRole); + _hot_detach = true; - msg.exec(); + if (!_session->get_saving()) + device_detach_post(); + */ + // } - if (msg.mBox()->clickedButton() == cancelButton) { - for(auto &s : _session->get_signals()) - { - assert(s); - view::LogicSignal *logicSig = NULL; - if ((logicSig = dynamic_cast(s))) { - logicSig->set_trig(view::LogicSignal::NONTRIG); - logicSig->commit_trig(); - } - } - } - - if (msg.mBox()->clickedButton() == noMoreButton) - { - app._appOptions.warnofMultiTrig = false; - app.SaveApp(); - } - } - } -} - -void MainWindow::on_measure(bool visible) -{ - _measure_dock->setVisible(visible); -} - -void MainWindow::on_search(bool visible) -{ - _search_dock->setVisible(visible); - _view->show_search_cursor(visible); -} - -void MainWindow::on_screenShot() -{ - AppConfig &app = AppConfig::Instance(); - QString default_name = app._userHistory.screenShotPath + "/" + APP_NAME + QDateTime::currentDateTime().toString("-yyMMdd-hhmmss"); - -#ifdef _WIN32 - int x = parentWidget()->pos().x(); - int y = parentWidget()->pos().y(); - int w = parentWidget()->frameGeometry().width(); - int h = parentWidget()->frameGeometry().height(); - QDesktopWidget *desktop = QApplication::desktop(); - QPixmap pixmap = QGuiApplication::primaryScreen()->grabWindow(desktop->winId(), x, y, w, h); -#else - QPixmap pixmap = QGuiApplication::primaryScreen()->grabWindow(winId()); -#endif - - QString format = "png"; - QString fileName = QFileDialog::getSaveFileName( - this, - tr("Save As"), - default_name, - // tr("%1 Files (*.%2);;All Files (*)") - "png file(*.png);;jpeg file(*.jpeg)", - &format); - - if (!fileName.isEmpty()) { - - QStringList list = format.split('.').last().split(')'); - QString suffix = list.first(); - - QFileInfo f(fileName); - if (f.suffix().compare(suffix)) - { - fileName += tr(".") + suffix; - } - - pixmap.save(fileName, suffix.toLatin1()); - - fileName = path::GetDirectoryName(fileName); - - if (app._userHistory.screenShotPath != fileName){ - app._userHistory.screenShotPath = fileName; - app.SaveHistory(); - } - } -} - -//save file -void MainWindow::on_save() -{ - using pv::dialogs::StoreProgress; - - if (_device_agent->have_instance() == false){ - dsv_info("%s", "Have no device, can't to save data."); - return; - } - - _session->set_saving(true); - - StoreProgress *dlg = new StoreProgress(_session, this); - connect(dlg, SIGNAL(save_done()), this, SLOT(device_detach_post())); - dlg->save_run(this); -} - -void MainWindow::on_export() -{ - using pv::dialogs::StoreProgress; - - StoreProgress *dlg = new StoreProgress(_session, this); - dlg->export_run(); -} - -bool MainWindow::on_load_session(QString name) -{ - QFile sessionFile(name); - if (!sessionFile.open(QIODevice::ReadOnly)) { - dsv_warn("%s", "Warning: Couldn't open session file!"); - return false; - } - - QString sessionData = QString::fromUtf8(sessionFile.readAll()); - QJsonDocument sessionDoc = QJsonDocument::fromJson(sessionData.toUtf8()); - - return load_session_json(sessionDoc, false); -} - -bool MainWindow::load_session_json(QJsonDocument json, bool file_dev, bool bDecoder) -{ - QJsonObject sessionObj = json.object(); - - /* - - // check session file version - if (!sessionObj.contains("Version")){ - dsv_dbg("%s", "session file version is not exists!"); - return false; - } - - if (sessionObj["Version"].toInt() < BASE_SESSION_VERSION){ - dsv_err("%s", "session file version is error!"); - return false; - } - - // old version(<= 1.1.2), restore the language - if (sessionObj["Version"].toInt() == BASE_SESSION_VERSION){ - switchLanguage(sessionObj["Language"].toInt()); - } - - - // check device and mode - const sr_dev_inst *const sdi = _device_agent->dev_inst(); - if ((!file_dev && strcmp(sdi->driver->name, sessionObj["Device"].toString().toUtf8()) != 0) || - sdi->mode != sessionObj["DeviceMode"].toDouble()) { - MsgBox::Show(NULL, tr("Session File is not compatible with current device or mode!"), this); - return false; - } - - // clear decoders - if (sdi->mode == LOGIC && !file_dev) + void MainWindow::repeat_resume() { - _protocol_widget->del_all_protocol(); - } - - // load device settings - GVariant *gvar_opts; - gsize num_opts; - if ((sr_config_list(sdi->driver, sdi, NULL, SR_CONF_DEVICE_SESSIONS, &gvar_opts) == SR_OK)) { - const int *const options = (const int32_t *)g_variant_get_fixed_array( - gvar_opts, &num_opts, sizeof(int32_t)); - for (unsigned int i = 0; i < num_opts; i++) { - const struct sr_config_info *const info = - sr_config_info_get(options[i]); - if (!sessionObj.contains(info->name)) - continue; - if (info->datatype == SR_T_BOOL) - _device_agent->set_config(NULL, NULL, info->key, g_variant_new_boolean(sessionObj[info->name].toDouble())); - else if (info->datatype == SR_T_UINT64) - _device_agent->set_config(NULL, NULL, info->key, g_variant_new_uint64(sessionObj[info->name].toString().toULongLong())); - else if (info->datatype == SR_T_UINT8) - _device_agent->set_config(NULL, NULL, info->key, g_variant_new_byte(sessionObj[info->name].toString().toUInt())); - else if (info->datatype == SR_T_FLOAT) - _device_agent->set_config(NULL, NULL, info->key, g_variant_new_double(sessionObj[info->name].toDouble())); - else if (info->datatype == SR_T_CHAR) - _device_agent->set_config(NULL, NULL, info->key, g_variant_new_string(sessionObj[info->name].toString().toUtf8())); - } + while (_view->session().get_capture_state() == SigSession::Running) + QCoreApplication::processEvents(); + _session->stop_capture(); } - // load channel settings - if (file_dev && (sdi->mode == DSO)) { - for (const GSList *l = _device_agent->dev_inst()->channels; l; l = l->next) { - sr_channel *const probe = (sr_channel*)l->data; - assert(probe); - - for (const QJsonValue &value : sessionObj["channel"].toArray()) { - QJsonObject obj = value.toObject(); - if ((strcmp(probe->name, g_strdup(obj["name"].toString().toStdString().c_str())) == 0) && - (probe->type == obj["type"].toDouble())) { - probe->vdiv = obj["vdiv"].toDouble(); - probe->coupling = obj["coupling"].toDouble(); - probe->vfactor = obj["vfactor"].toDouble(); - probe->trig_value = obj["trigValue"].toDouble(); - probe->map_unit = g_strdup(obj["mapUnit"].toString().toStdString().c_str()); - probe->map_min = obj["mapMin"].toDouble(); - probe->map_max = obj["mapMax"].toDouble(); - break; - } - } - } - } else { - for (const GSList *l = _device_agent->dev_inst()->channels; l; l = l->next) { - sr_channel *const probe = (sr_channel*)l->data; - assert(probe); - bool isEnabled = false; - - for (const QJsonValue &value : sessionObj["channel"].toArray()) { - QJsonObject obj = value.toObject(); - if ((probe->index == obj["index"].toDouble()) && - (probe->type == obj["type"].toDouble())) { - isEnabled = true; - probe->enabled = obj["enabled"].toBool(); - probe->name = g_strdup(obj["name"].toString().toStdString().c_str()); - probe->vdiv = obj["vdiv"].toDouble(); - probe->coupling = obj["coupling"].toDouble(); - probe->vfactor = obj["vfactor"].toDouble(); - probe->trig_value = obj["trigValue"].toDouble(); - probe->map_unit = g_strdup(obj["mapUnit"].toString().toStdString().c_str()); - probe->map_min = obj["mapMin"].toDouble(); - probe->map_max = obj["mapMax"].toDouble(); - break; - } - } - if (!isEnabled) - probe->enabled = false; - } + void MainWindow::session_error() + { + _event.session_error(); } - //_session->init_signals(); - _session->reload(); + void MainWindow::on_session_error() + { + QString title; + QString details; + QString ch_status = ""; + uint64_t error_pattern; - // load signal setting - if (file_dev && (sdi->mode == DSO)) { - - for(auto &s : _session->get_signals()) { - for (const QJsonValue &value : sessionObj["channel"].toArray()) { - QJsonObject obj = value.toObject(); - if ((strcmp(s->get_name().toStdString().c_str(), g_strdup(obj["name"].toString().toStdString().c_str())) == 0) && - (s->get_type() == obj["type"].toDouble())) { - s->set_colour(QColor(obj["colour"].toString())); - - view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s))) { - dsoSig->load_settings(); - dsoSig->set_zero_ratio(obj["zeroPos"].toDouble()); - dsoSig->set_trig_ratio(obj["trigValue"].toDouble()); - dsoSig->commit_settings(); - } - break; - } - } - } - } else { - for(auto &s : _session->get_signals()) { - for (const QJsonValue &value : sessionObj["channel"].toArray()) { - QJsonObject obj = value.toObject(); - if ((s->get_index() == obj["index"].toDouble()) && - (s->get_type() == obj["type"].toDouble())) { - s->set_colour(QColor(obj["colour"].toString())); - s->set_name(g_strdup(obj["name"].toString().toUtf8().data())); - - view::LogicSignal *logicSig = NULL; - if ((logicSig = dynamic_cast(s))) { - logicSig->set_trig(obj["strigger"].toDouble()); - } - - view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s))) { - dsoSig->load_settings(); - dsoSig->set_zero_ratio(obj["zeroPos"].toDouble()); - dsoSig->set_trig_ratio(obj["trigValue"].toDouble()); - dsoSig->commit_settings(); - } - - view::AnalogSignal *analogSig = NULL; - if ((analogSig = dynamic_cast(s))) { - analogSig->set_zero_ratio(obj["zeroPos"].toDouble()); - analogSig->commit_settings(); - } - - break; - } - } - } - } - - // update UI settings - _sampling_bar->update_sample_rate_selector(); - _trigger_widget->device_updated(); - _view->header_updated(); - - // load trigger settings - if (sessionObj.contains("trigger")) { - _trigger_widget->set_session(sessionObj["trigger"].toObject()); - } - on_trigger(false); - - - // load decoders - if (bDecoder && sessionObj.contains("decoder")) { - StoreSession ss(_session); - ss.load_decoders(_protocol_widget, sessionObj["decoder"].toArray()); - } - - // load measure - if (sessionObj.contains("measure")) { - _view->get_viewstatus()->load_session(sessionObj["measure"].toArray()); - } - */ - - return true; -} - -bool MainWindow::gen_session_json(QJsonObject &sessionVar) -{ - AppConfig &app = AppConfig::Instance(); - - GVariant *gvar_opts; - GVariant *gvar; - gsize num_opts; - - QJsonArray channelVar; - sessionVar["Version"]= QJsonValue::fromVariant(BASE_SESSION_VERSION); - sessionVar["Device"] = QJsonValue::fromVariant(_device_agent->driver_name()); - sessionVar["DeviceMode"] = QJsonValue::fromVariant(_device_agent->get_work_mode()); - sessionVar["Language"] = QJsonValue::fromVariant(app._frameOptions.language); - - gvar_opts = _device_agent->get_config_list(NULL, SR_CONF_DEVICE_SESSIONS); - if (gvar_opts == NULL){ - dsv_warn("%s", "Device config list is empty. id:SR_CONF_DEVICE_SESSIONS"); - /* Driver supports no device instance sessions. */ - return false; - } - - const int *const options = (const int32_t *)g_variant_get_fixed_array( - gvar_opts, &num_opts, sizeof(int32_t)); - - for (unsigned int i = 0; i < num_opts; i++) { - const struct sr_config_info *const info = _device_agent->get_config_info(options[i]); - gvar = _device_agent->get_config(NULL, NULL, info->key); - if (gvar != NULL) { - if (info->datatype == SR_T_BOOL) - sessionVar[info->name] = QJsonValue::fromVariant(g_variant_get_boolean(gvar)); - else if (info->datatype == SR_T_UINT64) - sessionVar[info->name] = QJsonValue::fromVariant(QString::number(g_variant_get_uint64(gvar))); - else if (info->datatype == SR_T_UINT8) - sessionVar[info->name] = QJsonValue::fromVariant(QString::number(g_variant_get_byte(gvar))); - else if (info->datatype == SR_T_FLOAT) - sessionVar[info->name] = QJsonValue::fromVariant(g_variant_get_double(gvar)); - else if (info->datatype == SR_T_CHAR) - sessionVar[info->name] = QJsonValue::fromVariant(g_variant_get_string(gvar, NULL)); - g_variant_unref(gvar); - } - } - - for(auto &s : _session->get_signals()) { - QJsonObject s_obj; - s_obj["index"] = s->get_index(); - s_obj["type"] = s->get_type(); - s_obj["enabled"] = s->enabled(); - s_obj["name"] = s->get_name(); - if (s->get_colour().isValid()) - s_obj["colour"] = QJsonValue::fromVariant(s->get_colour()); - else - s_obj["colour"] = QJsonValue::fromVariant("default"); - - view::LogicSignal *logicSig = NULL; - if ((logicSig = dynamic_cast(s))) { - s_obj["strigger"] = logicSig->get_trig(); - } - - view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s))) { - s_obj["vdiv"] = QJsonValue::fromVariant(static_cast(dsoSig->get_vDialValue())); - s_obj["vfactor"] = QJsonValue::fromVariant(static_cast(dsoSig->get_factor())); - s_obj["coupling"] = dsoSig->get_acCoupling(); - s_obj["trigValue"] = dsoSig->get_trig_vrate(); - s_obj["zeroPos"] = dsoSig->get_zero_ratio(); - } - - view::AnalogSignal *analogSig = NULL; - if ((analogSig = dynamic_cast(s))) { - s_obj["vdiv"] = QJsonValue::fromVariant(static_cast(analogSig->get_vdiv())); - s_obj["vfactor"] = QJsonValue::fromVariant(static_cast(analogSig->get_factor())); - s_obj["coupling"] = analogSig->get_acCoupling(); - s_obj["zeroPos"] = analogSig->get_zero_ratio(); - s_obj["mapUnit"] = analogSig->get_mapUnit(); - s_obj["mapMin"] = analogSig->get_mapMin(); - s_obj["mapMax"] = analogSig->get_mapMax(); - } - channelVar.append(s_obj); - } - sessionVar["channel"] = channelVar; - - if (_device_agent->get_work_mode() == LOGIC) { - sessionVar["trigger"] = _trigger_widget->get_session(); - } - - StoreSession ss(_session); - QJsonArray decodeJson; - ss.json_decoders(decodeJson); - sessionVar["decoder"] = decodeJson; - - if (_device_agent->get_work_mode() == DSO) { - sessionVar["measure"] = _view->get_viewstatus()->get_session(); - } - - return true; -} - -bool MainWindow::on_store_session(QString name) -{ - QFile sessionFile(name); - if (!sessionFile.open(QIODevice::WriteOnly | QIODevice::Text)) { - dsv_warn("%s", "Warning: Couldn't open session file to write!"); - return false; - } - - QTextStream outStream(&sessionFile); - encoding::set_utf8(outStream); - - QJsonObject sessionVar; - if (!gen_session_json(sessionVar)) - return false; - QJsonDocument sessionDoc(sessionVar); - outStream << QString::fromUtf8(sessionDoc.toJson()); - sessionFile.close(); - return true; -} - -bool MainWindow::genSessionData(std::string &str) -{ - QJsonObject sessionVar; - if (!gen_session_json(sessionVar)) - return false; - QJsonDocument sessionDoc(sessionVar); - QString data = QString::fromUtf8(sessionDoc.toJson()); - str.append(data.toLocal8Bit().data()); - return true; -} - -void MainWindow::restore_dock() -{ - // default dockwidget size - AppConfig &app = AppConfig::Instance(); - QByteArray st = app._frameOptions.windowState; - if (!st.isEmpty()){ - try + switch (_session->get_error()) { - restoreState(st); - } - catch(...) - { - MsgBox::Show(NULL, tr("restore window status error!")); - } - } - - if (_device_agent->get_work_mode() != DSO) { - _dso_trigger_dock->setVisible(false); - _trig_bar->update_trig_btn(_trigger_dock->isVisible()); - } else { - _trigger_dock->setVisible(false); - _trig_bar->update_trig_btn(_dso_trigger_dock->isVisible()); - } - if (_device_agent->get_work_mode() != LOGIC) { - - on_protocol(false); - - } - _trig_bar->update_protocol_btn(_protocol_dock->isVisible()); - _trig_bar->update_measure_btn(_measure_dock->isVisible()); - _trig_bar->update_search_btn(_search_dock->isVisible()); -} - -bool MainWindow::eventFilter(QObject *object, QEvent *event) -{ - (void) object; - - if ( event->type() == QEvent::KeyPress ) - { - const auto &sigs = _session->get_signals(); - QKeyEvent *ke = (QKeyEvent *) event; - switch(ke->key()) { - case Qt::Key_S: - on_run_stop(); + case SigSession::Hw_err: + _session->set_repeating(false); + _session->stop_capture(); + title = tr("Hardware Operation Failed"); + details = tr("Please replug device to refresh hardware configuration!"); break; - case Qt::Key_I: - on_instant_stop(); + case SigSession::Malloc_err: + _session->set_repeating(false); + _session->stop_capture(); + title = tr("Malloc Error"); + details = tr("Memory is not enough for this sample!\nPlease reduce the sample depth!"); break; - case Qt::Key_T: - if (_device_agent->get_work_mode() == DSO) - on_trigger(!_dso_trigger_dock->isVisible()); - else - on_trigger(!_trigger_dock->isVisible()); - break; - - case Qt::Key_D: - on_protocol(!_protocol_dock->isVisible()); - break; - - case Qt::Key_M: - on_measure(!_measure_dock->isVisible()); - break; - case Qt::Key_R: - on_search(!_search_dock->isVisible()); - break; - case Qt::Key_O: - _sampling_bar->on_configure(); - break; - case Qt::Key_PageUp: - _view->set_scale_offset(_view->scale(), - _view->offset() - _view->get_view_width()); - break; - case Qt::Key_PageDown: - _view->set_scale_offset(_view->scale(), - _view->offset() + _view->get_view_width()); - - break; - case Qt::Key_Left: - _view->zoom(1); - break; - case Qt::Key_Right: - _view->zoom(-1); - break; - case Qt::Key_0: - for(auto & s : sigs) { - view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s))) { - if (dsoSig->get_index() == 0) - dsoSig->set_vDialActive(!dsoSig->get_vDialActive()); - else - dsoSig->set_vDialActive(false); - } + case SigSession::Test_data_err: + _session->set_repeating(false); + _session->stop_capture(); + _sampling_bar->set_sampling(false); + _session->capture_state_changed(SigSession::Stopped); + title = tr("Data Error"); + error_pattern = _session->get_error_pattern(); + for (int i = 0; i < 16; i++) + { + if (error_pattern & 0x01) + ch_status += "X "; + else + ch_status += " "; + ch_status += (i > 9 ? " " : ""); + error_pattern >>= 1; } - _view->setFocus(); - update(); + details = tr("the received data are not consist with pre-defined test data!") + "\n" + + tr("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15") + "\n" + ch_status; break; - case Qt::Key_1: - for(auto & s : sigs) { - view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s))) { - if (dsoSig->get_index() == 1) - dsoSig->set_vDialActive(!dsoSig->get_vDialActive()); - else - dsoSig->set_vDialActive(false); - } - } - _view->setFocus(); - update(); + case SigSession::Pkt_data_err: + title = tr("Packet Error"); + details = tr("the content of received packet are not expected!"); + _session->refresh(0); break; - case Qt::Key_Up: - for(auto &s : sigs) { - view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s))) { - if (dsoSig->get_vDialActive()) { - dsoSig->go_vDialNext(true); - update(); - break; - } - } - } - break; - case Qt::Key_Down: - for(auto &s : sigs) { - view::DsoSignal *dsoSig = NULL; - if ((dsoSig = dynamic_cast(s))) { - if (dsoSig->get_vDialActive()) { - dsoSig->go_vDialPre(true); - update(); - break; - } - } - } + case SigSession::Data_overflow: + _session->set_repeating(false); + _session->stop_capture(); + title = tr("Data Overflow"); + details = tr("USB bandwidth can not support current sample rate! \nPlease reduce the sample rate!"); break; default: - QWidget::keyPressEvent((QKeyEvent *)event); + title = tr("Undefined Error"); + details = tr("Not expected error!"); + break; } + + dialogs::DSMessageBox msg(this); + + connect(_device_agent, SIGNAL(device_updated()), &msg, SLOT(accept())); + + QFont font("Monaco"); + font.setStyleHint(QFont::Monospace); + font.setFixedPitch(true); + msg.mBox()->setFont(font); + + msg.mBox()->setText(title); + msg.mBox()->setInformativeText(details); + msg.mBox()->setStandardButtons(QMessageBox::Ok); + msg.mBox()->setIcon(QMessageBox::Warning); + msg.exec(); + + _session->clear_error(); + } + + void MainWindow::capture_state_changed(int state) + { + _event.capture_state_changed(state); // safe call + } + + void MainWindow::on_capture_state_changed(int state) + { + if (!_session->repeat_check()) + { + _file_bar->enable_toggle(state != SigSession::Running); + _sampling_bar->set_sampling(state == SigSession::Running); + _view->on_state_changed(state != SigSession::Running); + + if (_device_agent->get_work_mode() != DSO || + _session->get_instant()) + { + _sampling_bar->enable_toggle(state != SigSession::Running); + _trig_bar->enable_toggle(state != SigSession::Running); + //_measure_dock->widget()->setEnabled(state != SigSession::Running); + _measure_widget->refresh(); + } + } + + if (state == SigSession::Stopped) + { + prgRate(0); + _view->repeat_unshow(); + } + } + + void MainWindow::session_save() + { + QDir dir; +#if QT_VERSION >= 0x050400 + QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation); +#else + QString path = QStandardPaths::writableLocation(QStandardPaths::DataLocation); +#endif + + if (_device_agent->have_instance() == false) + { + dsv_info("%s", "There is no need to save the configuration"); + return; + } + + AppConfig &app = AppConfig::Instance(); + + if (dir.mkpath(path)) + { + dir.cd(path); + QString driver_name = _device_agent->name(); + QString mode_name = QString::number(_device_agent->get_work_mode()); + QString lang_name = ".ses" + QString::number(app._frameOptions.language); + QString file_name = dir.absolutePath() + "/" + + driver_name + mode_name + + lang_name + ".dsc"; + if (strncmp(driver_name.toUtf8(), "virtual", 7) && + !file_name.isEmpty()) + { + on_store_session(file_name); + } + } + + app._frameOptions.windowState = saveState(); + app.SaveFrame(); + } + + void MainWindow::closeEvent(QCloseEvent *event) + { + // not used, refer to closeEvent of mainFrame + session_save(); + event->accept(); + } + + void MainWindow::on_protocol(bool visible) + { + + _protocol_dock->setVisible(visible); + } + + void MainWindow::on_trigger(bool visible) + { + if (_device_agent->get_work_mode() != DSO) + { + _trigger_widget->init(); + _trigger_dock->setVisible(visible); + _dso_trigger_dock->setVisible(false); + } + else + { + _dso_trigger_widget->init(); + _trigger_dock->setVisible(false); + _dso_trigger_dock->setVisible(visible); + } + _trig_bar->update_trig_btn(visible); + } + + void MainWindow::on_measure(bool visible) + { + _measure_dock->setVisible(visible); + } + + void MainWindow::on_search(bool visible) + { + _search_dock->setVisible(visible); + _view->show_search_cursor(visible); + } + + void MainWindow::on_screenShot() + { + AppConfig &app = AppConfig::Instance(); + QString default_name = app._userHistory.screenShotPath + "/" + APP_NAME + QDateTime::currentDateTime().toString("-yyMMdd-hhmmss"); + +#ifdef _WIN32 + int x = parentWidget()->pos().x(); + int y = parentWidget()->pos().y(); + int w = parentWidget()->frameGeometry().width(); + int h = parentWidget()->frameGeometry().height(); + QDesktopWidget *desktop = QApplication::desktop(); + QPixmap pixmap = QGuiApplication::primaryScreen()->grabWindow(desktop->winId(), x, y, w, h); +#else + QPixmap pixmap = QGuiApplication::primaryScreen()->grabWindow(winId()); +#endif + + QString format = "png"; + QString fileName = QFileDialog::getSaveFileName( + this, + tr("Save As"), + default_name, + // tr("%1 Files (*.%2);;All Files (*)") + "png file(*.png);;jpeg file(*.jpeg)", + &format); + + if (!fileName.isEmpty()) + { + + QStringList list = format.split('.').last().split(')'); + QString suffix = list.first(); + + QFileInfo f(fileName); + if (f.suffix().compare(suffix)) + { + fileName += tr(".") + suffix; + } + + pixmap.save(fileName, suffix.toLatin1()); + + fileName = path::GetDirectoryName(fileName); + + if (app._userHistory.screenShotPath != fileName) + { + app._userHistory.screenShotPath = fileName; + app.SaveHistory(); + } + } + } + + // save file + void MainWindow::on_save() + { + using pv::dialogs::StoreProgress; + + if (_device_agent->have_instance() == false) + { + dsv_info("%s", "Have no device, can't to save data."); + return; + } + + _session->set_saving(true); + + StoreProgress *dlg = new StoreProgress(_session, this); + dlg->save_run(this); + } + + void MainWindow::on_export() + { + using pv::dialogs::StoreProgress; + + StoreProgress *dlg = new StoreProgress(_session, this); + dlg->export_run(); + } + + bool MainWindow::on_load_session(QString name) + { + QFile sessionFile(name); + if (!sessionFile.open(QIODevice::ReadOnly)) + { + dsv_warn("%s", "Warning: Couldn't open session file!"); + return false; + } + + QString sessionData = QString::fromUtf8(sessionFile.readAll()); + QJsonDocument sessionDoc = QJsonDocument::fromJson(sessionData.toUtf8()); + + return load_session_json(sessionDoc, false); + } + + bool MainWindow::load_session_json(QJsonDocument json, bool file_dev, bool bDecoder) + { + QJsonObject sessionObj = json.object(); + + /* + + // check session file version + if (!sessionObj.contains("Version")){ + dsv_dbg("%s", "session file version is not exists!"); + return false; + } + + if (sessionObj["Version"].toInt() < BASE_SESSION_VERSION){ + dsv_err("%s", "session file version is error!"); + return false; + } + + // old version(<= 1.1.2), restore the language + if (sessionObj["Version"].toInt() == BASE_SESSION_VERSION){ + switchLanguage(sessionObj["Language"].toInt()); + } + + + // check device and mode + const sr_dev_inst *const sdi = _device_agent->dev_inst(); + if ((!file_dev && strcmp(sdi->driver->name, sessionObj["Device"].toString().toUtf8()) != 0) || + sdi->mode != sessionObj["DeviceMode"].toDouble()) { + MsgBox::Show(NULL, tr("Session File is not compatible with current device or mode!"), this); + return false; + } + + // clear decoders + if (sdi->mode == LOGIC && !file_dev) + { + _protocol_widget->del_all_protocol(); + } + + // load device settings + GVariant *gvar_opts; + gsize num_opts; + if ((sr_config_list(sdi->driver, sdi, NULL, SR_CONF_DEVICE_SESSIONS, &gvar_opts) == SR_OK)) { + const int *const options = (const int32_t *)g_variant_get_fixed_array( + gvar_opts, &num_opts, sizeof(int32_t)); + for (unsigned int i = 0; i < num_opts; i++) { + const struct sr_config_info *const info = + sr_config_info_get(options[i]); + if (!sessionObj.contains(info->name)) + continue; + if (info->datatype == SR_T_BOOL) + _device_agent->set_config(NULL, NULL, info->key, g_variant_new_boolean(sessionObj[info->name].toDouble())); + else if (info->datatype == SR_T_UINT64) + _device_agent->set_config(NULL, NULL, info->key, g_variant_new_uint64(sessionObj[info->name].toString().toULongLong())); + else if (info->datatype == SR_T_UINT8) + _device_agent->set_config(NULL, NULL, info->key, g_variant_new_byte(sessionObj[info->name].toString().toUInt())); + else if (info->datatype == SR_T_FLOAT) + _device_agent->set_config(NULL, NULL, info->key, g_variant_new_double(sessionObj[info->name].toDouble())); + else if (info->datatype == SR_T_CHAR) + _device_agent->set_config(NULL, NULL, info->key, g_variant_new_string(sessionObj[info->name].toString().toUtf8())); + } + } + + // load channel settings + if (file_dev && (sdi->mode == DSO)) { + for (const GSList *l = _device_agent->dev_inst()->channels; l; l = l->next) { + sr_channel *const probe = (sr_channel*)l->data; + assert(probe); + + for (const QJsonValue &value : sessionObj["channel"].toArray()) { + QJsonObject obj = value.toObject(); + if ((strcmp(probe->name, g_strdup(obj["name"].toString().toStdString().c_str())) == 0) && + (probe->type == obj["type"].toDouble())) { + probe->vdiv = obj["vdiv"].toDouble(); + probe->coupling = obj["coupling"].toDouble(); + probe->vfactor = obj["vfactor"].toDouble(); + probe->trig_value = obj["trigValue"].toDouble(); + probe->map_unit = g_strdup(obj["mapUnit"].toString().toStdString().c_str()); + probe->map_min = obj["mapMin"].toDouble(); + probe->map_max = obj["mapMax"].toDouble(); + break; + } + } + } + } else { + for (const GSList *l = _device_agent->dev_inst()->channels; l; l = l->next) { + sr_channel *const probe = (sr_channel*)l->data; + assert(probe); + bool isEnabled = false; + + for (const QJsonValue &value : sessionObj["channel"].toArray()) { + QJsonObject obj = value.toObject(); + if ((probe->index == obj["index"].toDouble()) && + (probe->type == obj["type"].toDouble())) { + isEnabled = true; + probe->enabled = obj["enabled"].toBool(); + probe->name = g_strdup(obj["name"].toString().toStdString().c_str()); + probe->vdiv = obj["vdiv"].toDouble(); + probe->coupling = obj["coupling"].toDouble(); + probe->vfactor = obj["vfactor"].toDouble(); + probe->trig_value = obj["trigValue"].toDouble(); + probe->map_unit = g_strdup(obj["mapUnit"].toString().toStdString().c_str()); + probe->map_min = obj["mapMin"].toDouble(); + probe->map_max = obj["mapMax"].toDouble(); + break; + } + } + if (!isEnabled) + probe->enabled = false; + } + } + + //_session->init_signals(); + _session->reload(); + + // load signal setting + if (file_dev && (sdi->mode == DSO)) { + + for(auto &s : _session->get_signals()) { + for (const QJsonValue &value : sessionObj["channel"].toArray()) { + QJsonObject obj = value.toObject(); + if ((strcmp(s->get_name().toStdString().c_str(), g_strdup(obj["name"].toString().toStdString().c_str())) == 0) && + (s->get_type() == obj["type"].toDouble())) { + s->set_colour(QColor(obj["colour"].toString())); + + view::DsoSignal *dsoSig = NULL; + if ((dsoSig = dynamic_cast(s))) { + dsoSig->load_settings(); + dsoSig->set_zero_ratio(obj["zeroPos"].toDouble()); + dsoSig->set_trig_ratio(obj["trigValue"].toDouble()); + dsoSig->commit_settings(); + } + break; + } + } + } + } else { + for(auto &s : _session->get_signals()) { + for (const QJsonValue &value : sessionObj["channel"].toArray()) { + QJsonObject obj = value.toObject(); + if ((s->get_index() == obj["index"].toDouble()) && + (s->get_type() == obj["type"].toDouble())) { + s->set_colour(QColor(obj["colour"].toString())); + s->set_name(g_strdup(obj["name"].toString().toUtf8().data())); + + view::LogicSignal *logicSig = NULL; + if ((logicSig = dynamic_cast(s))) { + logicSig->set_trig(obj["strigger"].toDouble()); + } + + view::DsoSignal *dsoSig = NULL; + if ((dsoSig = dynamic_cast(s))) { + dsoSig->load_settings(); + dsoSig->set_zero_ratio(obj["zeroPos"].toDouble()); + dsoSig->set_trig_ratio(obj["trigValue"].toDouble()); + dsoSig->commit_settings(); + } + + view::AnalogSignal *analogSig = NULL; + if ((analogSig = dynamic_cast(s))) { + analogSig->set_zero_ratio(obj["zeroPos"].toDouble()); + analogSig->commit_settings(); + } + + break; + } + } + } + } + + // update UI settings + _sampling_bar->update_sample_rate_selector(); + _trigger_widget->device_updated(); + _view->header_updated(); + + // load trigger settings + if (sessionObj.contains("trigger")) { + _trigger_widget->set_session(sessionObj["trigger"].toObject()); + } + on_trigger(false); + + + // load decoders + if (bDecoder && sessionObj.contains("decoder")) { + StoreSession ss(_session); + ss.load_decoders(_protocol_widget, sessionObj["decoder"].toArray()); + } + + // load measure + if (sessionObj.contains("measure")) { + _view->get_viewstatus()->load_session(sessionObj["measure"].toArray()); + } + */ + return true; } - return false; -} - - -void MainWindow::switchLanguage(int language) -{ - if (language == 0) - return; - if (_device_agent->have_instance()) - _device_agent->set_config(NULL, NULL, SR_CONF_LANGUAGE, g_variant_new_int16(language)); - AppConfig &app = AppConfig::Instance(); - - if (app._frameOptions.language != language && language > 0) + bool MainWindow::gen_session_json(QJsonObject &sessionVar) { - app._frameOptions.language = language; - app.SaveFrame(); + AppConfig &app = AppConfig::Instance(); + + GVariant *gvar_opts; + GVariant *gvar; + gsize num_opts; + + QJsonArray channelVar; + sessionVar["Version"] = QJsonValue::fromVariant(BASE_SESSION_VERSION); + sessionVar["Device"] = QJsonValue::fromVariant(_device_agent->driver_name()); + sessionVar["DeviceMode"] = QJsonValue::fromVariant(_device_agent->get_work_mode()); + sessionVar["Language"] = QJsonValue::fromVariant(app._frameOptions.language); + + gvar_opts = _device_agent->get_config_list(NULL, SR_CONF_DEVICE_SESSIONS); + if (gvar_opts == NULL) + { + dsv_warn("%s", "Device config list is empty. id:SR_CONF_DEVICE_SESSIONS"); + /* Driver supports no device instance sessions. */ + return false; + } + + const int *const options = (const int32_t *)g_variant_get_fixed_array( + gvar_opts, &num_opts, sizeof(int32_t)); + + for (unsigned int i = 0; i < num_opts; i++) + { + const struct sr_config_info *const info = _device_agent->get_config_info(options[i]); + gvar = _device_agent->get_config(NULL, NULL, info->key); + if (gvar != NULL) + { + if (info->datatype == SR_T_BOOL) + sessionVar[info->name] = QJsonValue::fromVariant(g_variant_get_boolean(gvar)); + else if (info->datatype == SR_T_UINT64) + sessionVar[info->name] = QJsonValue::fromVariant(QString::number(g_variant_get_uint64(gvar))); + else if (info->datatype == SR_T_UINT8) + sessionVar[info->name] = QJsonValue::fromVariant(QString::number(g_variant_get_byte(gvar))); + else if (info->datatype == SR_T_FLOAT) + sessionVar[info->name] = QJsonValue::fromVariant(g_variant_get_double(gvar)); + else if (info->datatype == SR_T_CHAR) + sessionVar[info->name] = QJsonValue::fromVariant(g_variant_get_string(gvar, NULL)); + g_variant_unref(gvar); + } + } + + for (auto &s : _session->get_signals()) + { + QJsonObject s_obj; + s_obj["index"] = s->get_index(); + s_obj["type"] = s->get_type(); + s_obj["enabled"] = s->enabled(); + s_obj["name"] = s->get_name(); + if (s->get_colour().isValid()) + s_obj["colour"] = QJsonValue::fromVariant(s->get_colour()); + else + s_obj["colour"] = QJsonValue::fromVariant("default"); + + view::LogicSignal *logicSig = NULL; + if ((logicSig = dynamic_cast(s))) + { + s_obj["strigger"] = logicSig->get_trig(); + } + + view::DsoSignal *dsoSig = NULL; + if ((dsoSig = dynamic_cast(s))) + { + s_obj["vdiv"] = QJsonValue::fromVariant(static_cast(dsoSig->get_vDialValue())); + s_obj["vfactor"] = QJsonValue::fromVariant(static_cast(dsoSig->get_factor())); + s_obj["coupling"] = dsoSig->get_acCoupling(); + s_obj["trigValue"] = dsoSig->get_trig_vrate(); + s_obj["zeroPos"] = dsoSig->get_zero_ratio(); + } + + view::AnalogSignal *analogSig = NULL; + if ((analogSig = dynamic_cast(s))) + { + s_obj["vdiv"] = QJsonValue::fromVariant(static_cast(analogSig->get_vdiv())); + s_obj["vfactor"] = QJsonValue::fromVariant(static_cast(analogSig->get_factor())); + s_obj["coupling"] = analogSig->get_acCoupling(); + s_obj["zeroPos"] = analogSig->get_zero_ratio(); + s_obj["mapUnit"] = analogSig->get_mapUnit(); + s_obj["mapMin"] = analogSig->get_mapMin(); + s_obj["mapMax"] = analogSig->get_mapMax(); + } + channelVar.append(s_obj); + } + sessionVar["channel"] = channelVar; + + if (_device_agent->get_work_mode() == LOGIC) + { + sessionVar["trigger"] = _trigger_widget->get_session(); + } + + StoreSession ss(_session); + QJsonArray decodeJson; + ss.json_decoders(decodeJson); + sessionVar["decoder"] = decodeJson; + + if (_device_agent->get_work_mode() == DSO) + { + sessionVar["measure"] = _view->get_viewstatus()->get_session(); + } + + return true; } - if (language == LAN_CN) + bool MainWindow::on_store_session(QString name) { - _qtTrans.load(":/qt_" + QString::number(language)); - qApp->installTranslator(&_qtTrans); - _myTrans.load(":/my_" + QString::number(language)); - qApp->installTranslator(&_myTrans); - retranslateUi(); + QFile sessionFile(name); + if (!sessionFile.open(QIODevice::WriteOnly | QIODevice::Text)) + { + dsv_warn("%s", "Warning: Couldn't open session file to write!"); + return false; + } + + QTextStream outStream(&sessionFile); + encoding::set_utf8(outStream); + + QJsonObject sessionVar; + if (!gen_session_json(sessionVar)) + return false; + QJsonDocument sessionDoc(sessionVar); + outStream << QString::fromUtf8(sessionDoc.toJson()); + sessionFile.close(); + return true; } - else if (language == LAN_EN) + + bool MainWindow::genSessionData(std::string &str) { - qApp->removeTranslator(&_qtTrans); - qApp->removeTranslator(&_myTrans); - retranslateUi(); + QJsonObject sessionVar; + if (!gen_session_json(sessionVar)) + return false; + QJsonDocument sessionDoc(sessionVar); + QString data = QString::fromUtf8(sessionDoc.toJson()); + str.append(data.toLocal8Bit().data()); + return true; } - else{ - dsv_err("%s%d", "Unknown language code:", language); - } -} -void MainWindow::switchTheme(QString style) -{ - AppConfig &app = AppConfig::Instance(); - - if (app._frameOptions.style != style) + void MainWindow::restore_dock() { - app._frameOptions.style = style; - app.SaveFrame(); - } + // default dockwidget size + AppConfig &app = AppConfig::Instance(); + QByteArray st = app._frameOptions.windowState; + if (!st.isEmpty()) + { + try + { + restoreState(st); + } + catch (...) + { + MsgBox::Show(NULL, tr("restore window status error!")); + } + } - QString qssRes = ":/" + style + ".qss"; - QFile qss(qssRes); - qss.open(QFile::ReadOnly | QFile::Text); - qApp->setStyleSheet(qss.readAll()); - qss.close(); + if (_device_agent->get_work_mode() != DSO) + { + _dso_trigger_dock->setVisible(false); + _trig_bar->update_trig_btn(_trigger_dock->isVisible()); + } + else + { + _trigger_dock->setVisible(false); + _trig_bar->update_trig_btn(_dso_trigger_dock->isVisible()); + } + if (_device_agent->get_work_mode() != LOGIC) + { - data_updated(); -} + on_protocol(false); + } + _trig_bar->update_protocol_btn(_protocol_dock->isVisible()); + _trig_bar->update_measure_btn(_measure_dock->isVisible()); + _trig_bar->update_search_btn(_search_dock->isVisible()); + } -void MainWindow::data_updated() -{ - _event.data_updated(); //safe call -} + bool MainWindow::eventFilter(QObject *object, QEvent *event) + { + (void)object; -void MainWindow::on_data_updated(){ - _measure_widget->reCalc(); - _view->data_updated(); -} + if (event->type() == QEvent::KeyPress) + { + const auto &sigs = _session->get_signals(); + QKeyEvent *ke = (QKeyEvent *)event; + switch (ke->key()) + { + case Qt::Key_S: + on_run_stop(); + break; + case Qt::Key_I: + on_instant_stop(); + break; + case Qt::Key_T: + if (_device_agent->get_work_mode() == DSO) + on_trigger(!_dso_trigger_dock->isVisible()); + else + on_trigger(!_trigger_dock->isVisible()); + break; -void MainWindow::on_open_doc(){ - openDoc(); -} + case Qt::Key_D: + on_protocol(!_protocol_dock->isVisible()); + break; -void MainWindow::openDoc() -{ - QDir dir(GetAppDataDir()); - AppConfig &app = AppConfig::Instance(); - int lan = app._frameOptions.language; - QDesktopServices::openUrl( - QUrl("file:///"+dir.absolutePath() + "/ug"+QString::number(lan)+".pdf")); -} + case Qt::Key_M: + on_measure(!_measure_dock->isVisible()); + break; + case Qt::Key_R: + on_search(!_search_dock->isVisible()); + break; + case Qt::Key_O: + _sampling_bar->on_configure(); + break; + case Qt::Key_PageUp: + _view->set_scale_offset(_view->scale(), + _view->offset() - _view->get_view_width()); + break; + case Qt::Key_PageDown: + _view->set_scale_offset(_view->scale(), + _view->offset() + _view->get_view_width()); -void MainWindow::update_capture(){ - _view->update_hori_res(); -} + break; + case Qt::Key_Left: + _view->zoom(1); + break; + case Qt::Key_Right: + _view->zoom(-1); + break; + case Qt::Key_0: + for (auto &s : sigs) + { + view::DsoSignal *dsoSig = NULL; + if ((dsoSig = dynamic_cast(s))) + { + if (dsoSig->get_index() == 0) + dsoSig->set_vDialActive(!dsoSig->get_vDialActive()); + else + dsoSig->set_vDialActive(false); + } + } + _view->setFocus(); + update(); + break; + case Qt::Key_1: + for (auto &s : sigs) + { + view::DsoSignal *dsoSig = NULL; + if ((dsoSig = dynamic_cast(s))) + { + if (dsoSig->get_index() == 1) + dsoSig->set_vDialActive(!dsoSig->get_vDialActive()); + else + dsoSig->set_vDialActive(false); + } + } + _view->setFocus(); + update(); + break; + case Qt::Key_Up: + for (auto &s : sigs) + { + view::DsoSignal *dsoSig = NULL; + if ((dsoSig = dynamic_cast(s))) + { + if (dsoSig->get_vDialActive()) + { + dsoSig->go_vDialNext(true); + update(); + break; + } + } + } + break; + case Qt::Key_Down: + for (auto &s : sigs) + { + view::DsoSignal *dsoSig = NULL; + if ((dsoSig = dynamic_cast(s))) + { + if (dsoSig->get_vDialActive()) + { + dsoSig->go_vDialPre(true); + update(); + break; + } + } + } + break; + default: + QWidget::keyPressEvent((QKeyEvent *)event); + } + return true; + } + return false; + } -void MainWindow::cur_snap_samplerate_changed(){ - _event.cur_snap_samplerate_changed(); //safe call -} + void MainWindow::switchLanguage(int language) + { + if (language == 0) + return; -void MainWindow::on_cur_snap_samplerate_changed() -{ - _measure_widget->cursor_update(); -} + if (_device_agent->have_instance()) + _device_agent->set_config(NULL, NULL, SR_CONF_LANGUAGE, g_variant_new_int16(language)); + AppConfig &app = AppConfig::Instance(); + if (app._frameOptions.language != language && language > 0) + { + app._frameOptions.language = language; + app.SaveFrame(); + } - /*------------------on event end-------*/ + if (language == LAN_CN) + { + _qtTrans.load(":/qt_" + QString::number(language)); + qApp->installTranslator(&_qtTrans); + _myTrans.load(":/my_" + QString::number(language)); + qApp->installTranslator(&_myTrans); + retranslateUi(); + } + else if (language == LAN_EN) + { + qApp->removeTranslator(&_qtTrans); + qApp->removeTranslator(&_myTrans); + retranslateUi(); + } + else + { + dsv_err("%s%d", "Unknown language code:", language); + } + } -void MainWindow::device_setted(){ - _view->set_device(); -} + void MainWindow::switchTheme(QString style) + { + AppConfig &app = AppConfig::Instance(); - void MainWindow::signals_changed() - { - _event.signals_changed(); //safe call - } + if (app._frameOptions.style != style) + { + app._frameOptions.style = style; + app.SaveFrame(); + } - void MainWindow::on_signals_changed() - { - _view->signals_changed(); - } + QString qssRes = ":/" + style + ".qss"; + QFile qss(qssRes); + qss.open(QFile::ReadOnly | QFile::Text); + qApp->setStyleSheet(qss.readAll()); + qss.close(); - void MainWindow::receive_trigger(quint64 trigger_pos) - { - _event.receive_trigger(trigger_pos); //save call - } + data_updated(); + } - void MainWindow::on_receive_trigger(quint64 trigger_pos) - { - _view->receive_trigger(trigger_pos); - } + void MainWindow::data_updated() + { + _event.data_updated(); // safe call + } - void MainWindow::frame_ended() - { - _event.frame_ended(); //save call - } + void MainWindow::on_data_updated() + { + _measure_widget->reCalc(); + _view->data_updated(); + } - void MainWindow::on_frame_ended() - { - _view->receive_end(); - } + void MainWindow::on_open_doc() + { + openDoc(); + } - void MainWindow::frame_began() - { - _event.frame_began(); //save call - } + void MainWindow::openDoc() + { + QDir dir(GetAppDataDir()); + AppConfig &app = AppConfig::Instance(); + int lan = app._frameOptions.language; + QDesktopServices::openUrl( + QUrl("file:///" + dir.absolutePath() + "/ug" + QString::number(lan) + ".pdf")); + } - void MainWindow::on_frame_began() - { - _view->frame_began(); - } + void MainWindow::update_capture() + { + _view->update_hori_res(); + } - void MainWindow::show_region(uint64_t start, uint64_t end, bool keep){ - _view->show_region(start, end, keep); - } + void MainWindow::cur_snap_samplerate_changed() + { + _event.cur_snap_samplerate_changed(); // safe call + } - void MainWindow::show_wait_trigger(){ - _view->show_wait_trigger(); - } + void MainWindow::on_cur_snap_samplerate_changed() + { + _measure_widget->cursor_update(); + } - void MainWindow::repeat_hold(int percent){ - (void)percent; - _view->repeat_show(); - } + /*------------------on event end-------*/ - void MainWindow::decode_done(){ - _event.decode_done(); //safe call - } + void MainWindow::device_setted() + { + _view->set_device(); + } - void MainWindow::on_decode_done(){ - _protocol_widget->update_model(); - } + void MainWindow::signals_changed() + { + _event.signals_changed(); // safe call + } - void MainWindow::receive_data_len(quint64 len){ - _event.receive_data_len(len);//safe call - } + void MainWindow::on_signals_changed() + { + _view->signals_changed(); + } -void MainWindow::on_receive_data_len(quint64 len){ - _view->set_receive_len(len); -} + void MainWindow::receive_trigger(quint64 trigger_pos) + { + _event.receive_trigger(trigger_pos); // save call + } -void MainWindow::receive_header(){ + void MainWindow::on_receive_trigger(quint64 trigger_pos) + { + _view->receive_trigger(trigger_pos); + } -} + void MainWindow::frame_ended() + { + _event.frame_ended(); // save call + } -void MainWindow::data_received(){ + void MainWindow::on_frame_ended() + { + _view->receive_end(); + } -} + void MainWindow::frame_began() + { + _event.frame_began(); // save call + } -void MainWindow::device_list_changed() -{ - _sampling_bar->update_device_list(); -} + void MainWindow::on_frame_began() + { + _view->frame_began(); + } + + void MainWindow::show_region(uint64_t start, uint64_t end, bool keep) + { + _view->show_region(start, end, keep); + } + + void MainWindow::show_wait_trigger() + { + _view->show_wait_trigger(); + } + + void MainWindow::repeat_hold(int percent) + { + (void)percent; + _view->repeat_show(); + } + + void MainWindow::decode_done() + { + _event.decode_done(); // safe call + } + + void MainWindow::on_decode_done() + { + _protocol_widget->update_model(); + } + + void MainWindow::receive_data_len(quint64 len) + { + _event.receive_data_len(len); // safe call + } + + void MainWindow::on_receive_data_len(quint64 len) + { + _view->set_receive_len(len); + } + + void MainWindow::receive_header() + { + } + + void MainWindow::data_received() + { + } + + void MainWindow::trigger_message(int msg) + { + _event.trigger_message(msg); + } + + void MainWindow::on_trigger_message(int msg) + { + _session->broadcast_msg(msg); + } + + void MainWindow::OnMessage(int msg) + { + } } // namespace pv diff --git a/DSView/pv/mainwindow.h b/DSView/pv/mainwindow.h index 463ad304..cf2f6adc 100644 --- a/DSView/pv/mainwindow.h +++ b/DSView/pv/mainwindow.h @@ -77,7 +77,8 @@ using namespace pv::device; //The mainwindow,referenced by MainFrame //TODO: create graph view,toolbar,and show device list -class MainWindow : public QMainWindow, public ISessionCallback, public IMainForm, public ISessionDataGetter +class MainWindow : public QMainWindow, public ISessionCallback, + public IMainForm, public ISessionDataGetter, public IMessageListener { Q_OBJECT @@ -101,14 +102,11 @@ public slots: private slots: void on_load_file(QString file_name); void on_open_doc(); - void on_device_updated_reload(); + void update_device_list(); - - void on_run_stop(); - void on_instant_stop(); + void on_protocol(bool visible); void on_trigger(bool visible); - void commit_trigger(bool instant); void on_measure(bool visible); void on_search(bool visible); @@ -117,15 +115,11 @@ private slots: void on_export(); bool on_load_session(QString name); - bool on_store_session(QString name); - void device_detach_post(); - void device_changed(bool close); - void on_device_selected(); + bool on_store_session(QString name); void on_capture_state_changed(int state); void on_data_updated(); - void on_device_attach(); - void on_device_detach(); + void on_show_error(QString str); void on_session_error(); void on_signals_changed(); @@ -135,6 +129,7 @@ private slots: void on_decode_done(); void on_receive_data_len(quint64 len); void on_cur_snap_samplerate_changed(); + void on_trigger_message(int msg); signals: void prgRate(int progress); @@ -147,17 +142,14 @@ public: public: void session_save(); - //ISessionDataGetter + private: - bool genSessionData(std::string &str); - -//ISessionCallback + private: + //ISessionCallback void show_error(QString error); void session_error(); void capture_state_changed(int state); - void device_attach(); - void device_detach(); void data_updated(); void repeat_resume(); @@ -177,14 +169,17 @@ private: void receive_data_len(quint64 len); void receive_header(); void data_received(); - void device_list_changed(); + void trigger_message(int msg); + + //ISessionDataGetter + bool genSessionData(std::string &str); - //------private bool gen_session_json(QJsonObject &sessionVar); -private: - bool _hot_detach; + //IMessageListener + void OnMessage(int msg); +private: pv::view::View *_view; dialogs::DSMessageBox *_msg; diff --git a/DSView/pv/sigsession.cpp b/DSView/pv/sigsession.cpp index cd4442fe..ca7f460f 100644 --- a/DSView/pv/sigsession.cpp +++ b/DSView/pv/sigsession.cpp @@ -79,14 +79,16 @@ SigSession::SigSession() _repeat_intvl = 1; _run_mode = Single; _error = No_err; - _instant = false; - _capture_state = Init; + _bInstant = false; _noData_cnt = 0; _data_lock = false; _data_updated = false; _active_last_device_flag = false; _bSaving = false; + _bRepeatMode = false; + + this->add_msg_listener(this); _decoder_model = new pv::data::DecoderModel(NULL); @@ -118,12 +120,6 @@ SigSession::SigSession(SigSession &o) SigSession::~SigSession() { } - -SigSession::capture_state SigSession::get_capture_state() -{ - std::lock_guard lock(_sampling_mutex); - return _capture_state; -} uint64_t SigSession::cur_samplelimits() { @@ -201,11 +197,11 @@ void SigSession::set_cur_samplelimits(uint64_t samplelimits) void SigSession::capture_init() { - if (!_instant) + if (!_bInstant) set_repeating(get_run_mode() == Repetitive); // update instant setting - _device_agent.set_config(NULL, NULL, SR_CONF_INSTANT, g_variant_new_boolean(_instant)); + _device_agent.set_config(NULL, NULL, SR_CONF_INSTANT, g_variant_new_boolean(_bInstant)); _callback->update_capture(); set_cur_snap_samplerate(_device_agent.get_sample_rate()); @@ -291,6 +287,14 @@ void SigSession::start_capture(bool instant) return; } + // update setting + if (_device_agent.is_file()) + _bInstant = true; + else + _bInstant = instant; + + _callback->trigger_message(DSV_MSG_COLLECT_START_PREV); + // stop all decode tasks int run_dex = 0; clear_all_decode_task(run_dex); @@ -304,13 +308,7 @@ void SigSession::start_capture(bool instant) view::DsoSignal *dsoSig = NULL; if ((dsoSig = dynamic_cast(s))) dsoSig->set_mValid(false); - } - - // update setting - if (_device_agent.is_file() == false) - _instant = instant; - else - _instant = true; + } capture_init(); @@ -328,15 +326,21 @@ void SigSession::start_capture(bool instant) } void SigSession::stop_capture() -{ +{ + _callback->trigger_message(DSV_MSG_COLLECT_END_PREV); + data_unlock(); - if (_device_agent.is_collecting()){ + if (this->is_running()){ _device_agent.stop(); - // update_collect_status_view(); } } +bool SigSession::is_running() +{ + return _device_agent.is_running(); +} + bool SigSession::get_capture_status(bool &triggered, int &progress) { uint64_t sample_limits = cur_samplelimits(); @@ -383,11 +387,6 @@ std::set SigSession::get_data() return data; } -bool SigSession::get_instant() -{ - return _instant; -} - void SigSession::set_capture_state(capture_state state) { std::lock_guard lock(_sampling_mutex); @@ -400,7 +399,7 @@ void SigSession::check_update() { ds_lock_guard lock(_data_mutex); - if (_capture_state != Running) + if (_device_agent.is_running() == false) return; if (_data_updated) { @@ -831,7 +830,7 @@ void SigSession::feed_in_dso(const sr_datafeed_dso &dso) } // first payload - _dso_data->snapshot()->first_payload(dso, _device_agent.get_sample_limit(), sig_enable, _instant); + _dso_data->snapshot()->first_payload(dso, _device_agent.get_sample_limit(), sig_enable, _bInstant); } else { // Append to the existing data snapshot _dso_data->snapshot()->append_payload(dso); @@ -873,7 +872,7 @@ void SigSession::feed_in_dso(const sr_datafeed_dso &dso) _trigger_ch = dso.trig_ch; receive_data(dso.num_samples); - if (!_instant) + if (!_bInstant) data_lock(); _data_updated = true; @@ -1398,7 +1397,7 @@ bool SigSession::isRepeating() bool SigSession::repeat_check() { - if (get_capture_state() != Stopped || + if (_device_agent.is_running() || get_run_mode() != Repetitive || !isRepeating()) { return false; @@ -1685,10 +1684,12 @@ void SigSession::on_device_lib_event(int event) { if (event == DS_EV_COLLECT_TASK_START){ set_capture_state(Running); + _callback->trigger_message(DSV_MSG_COLLECT_START); return; } if (event == DS_EV_COLLECT_TASK_END){ set_capture_state(Stopped); + _callback->trigger_message(DSV_MSG_COLLECT_END); if (_logic_data->snapshot()->last_ended() == false){ dsv_err("%s", "The collected data is error!"); @@ -1699,12 +1700,13 @@ void SigSession::on_device_lib_event(int event) if (_analog_data->snapshot()->last_ended() == false){ dsv_err("%s", "The collected data is error!"); } + _bInstant = false; return; } if (event == DS_EV_NEW_DEVICE_ATTACH || event == DS_EV_CURRENT_DEVICE_DETACH) { - if (_device_agent.is_collecting()) + if (this->is_running()) _device_agent.stop(); update_collect_status_view(); @@ -1719,7 +1721,7 @@ void SigSession::on_device_lib_event(int event) } } - if (_device_agent.is_collecting()) + if (this->is_running()) _device_agent.stop(); update_collect_status_view(); @@ -1733,7 +1735,7 @@ void SigSession::on_device_lib_event(int event) } else if (_callback != NULL) { - _callback->device_list_changed(); // Update list only. + _callback->trigger_message(DSV_MSG_DEVICE_LIST_UPDATE); // Update list only. } } @@ -1751,7 +1753,7 @@ bool SigSession::set_default_device() { dsv_err("%s", "SigSession::set_default_device, Device list is empty!"); return false; - } + } struct ds_device_info *dev = (array + count - 1); ds_device_handle dev_handle = dev->handle; @@ -1761,7 +1763,7 @@ bool SigSession::set_default_device() bool ret = set_device(dev_handle); if (ret && _callback != NULL){ - _callback->device_list_changed(); + _callback->trigger_message(DSV_MSG_DEVICE_LIST_UPDATE); init_device_view(); } @@ -1778,6 +1780,8 @@ bool SigSession::set_device(ds_device_handle dev_handle) } _device_agent.update(); + init_signals(); + RELEASE_ARRAY(_group_traces); clear_all_decoder(); @@ -1795,6 +1799,7 @@ bool SigSession::set_device(ds_device_handle dev_handle) set_run_mode(Single); _callback->device_setted(); + return true; } bool SigSession::set_file(QString name) @@ -1835,7 +1840,7 @@ bool SigSession::init() ds_set_firmware_resource_dir(res_path.c_str()); if (ds_lib_init() != SR_OK) - { + { dsv_err("%s", "DSView run ERROR: collect lib init failed."); return false; } @@ -1893,5 +1898,25 @@ bool SigSession::init() return NULL; } + void SigSession::add_msg_listener(IMessageListener *ln) + { + _msg_listeners.push_back(ln); + } + + void SigSession::broadcast_msg(int msg) + { + for (IMessageListener *cb : _msg_listeners) + { + cb->OnMessage(msg); + } + } + + void SigSession::OnMessage(int msg) + { + if (msg == DSV_MSG_DEVICE_OPTIONS_UPDATED){ + this->reload(); + } + } + } // namespace pv diff --git a/DSView/pv/sigsession.h b/DSView/pv/sigsession.h index 6cfea1c3..87088f94 100644 --- a/DSView/pv/sigsession.h +++ b/DSView/pv/sigsession.h @@ -85,7 +85,7 @@ using namespace pv::device; using namespace pv::data; //created by MainWindow -class SigSession +class SigSession: public IMessageListener { private: static constexpr float Oversampling = 2.0f; @@ -96,13 +96,7 @@ public: static const int FeedInterval = 50; static const int WaitShowTime = 500; -public: - enum capture_state { - Init, - Stopped, - Running - }; - +public: enum run_mode { Single, Repetitive @@ -135,7 +129,7 @@ public: void close_file(ds_device_handle dev_handle); bool set_default_device(); - capture_state get_capture_state(); + uint64_t cur_samplerate(); uint64_t cur_snap_samplerate(); uint64_t cur_samplelimits(); @@ -177,8 +171,12 @@ public: void add_group(); void del_group(); - uint16_t get_ch_num(int type); - bool get_instant(); + uint16_t get_ch_num(int type); + + inline bool is_instant(){ + return _bInstant; + } + bool get_data_lock(); void data_auto_lock(int lock); void data_auto_unlock(); @@ -260,7 +258,7 @@ public: inline void set_saving(bool flag){ _bSaving = flag; - } + } bool init(); @@ -270,6 +268,7 @@ public: void refresh(int holdtime); void start_capture(bool instant); void stop_capture(); + bool is_running(); void check_update(); void set_repeating(bool repeat); void set_map_zoom(int index); @@ -279,6 +278,9 @@ public: bool have_hardware_data(); struct ds_device_info* get_device_list(int &out_count, int &actived_index); + void add_msg_listener(IMessageListener *ln); + void broadcast_msg(int msg); + private: inline void data_updated(){ _callback->data_updated(); @@ -309,6 +311,9 @@ private: void feed_timeout(); void repeat_update(); + //IMessageListener + void OnMessage(int msg); + private: /** * Attempts to autodetect the format. Failing that @@ -358,7 +363,7 @@ private: volatile bool _bDecodeRunning; capture_state _capture_state; - bool _instant; + bool _bInstant; uint64_t _cur_snap_samplerate; uint64_t _cur_samplelimits; @@ -397,7 +402,6 @@ private: run_mode _run_mode; double _repeat_intvl; - bool _repeating; int _repeat_hold_prg; int _map_zoom; @@ -405,6 +409,8 @@ private: float _stop_scale; bool _bClose; bool _active_last_device_flag; + bool _bRepeatMode; + bool _bRunning; bool _bSaving; uint64_t _save_start; @@ -413,6 +419,7 @@ private: ISessionCallback *_callback; DeviceAgent _device_agent; + std::vector _msg_listeners; private: // TODO: This should not be necessary. Multiple concurrent diff --git a/DSView/pv/toolbars/filebar.cpp b/DSView/pv/toolbars/filebar.cpp index 112b2716..798f6966 100644 --- a/DSView/pv/toolbars/filebar.cpp +++ b/DSView/pv/toolbars/filebar.cpp @@ -154,21 +154,6 @@ void FileBar::on_actionOpen_triggered() } } -void FileBar::session_error( - const QString text, const QString info_text) -{ - QMetaObject::invokeMethod(this, "show_session_error", - Qt::QueuedConnection, Q_ARG(QString, text), - Q_ARG(QString, info_text)); -} - -void FileBar::show_session_error( - const QString text, const QString info_text) -{ - (void)text; - MsgBox::Show(NULL, info_text.toStdString().c_str(), this); -} - void FileBar::on_actionLoad_triggered() { //load session file @@ -257,5 +242,10 @@ void FileBar::set_settings_en(bool enable) _menu_session->setDisabled(!enable); } +void FileBar::OnMessage(int msg) +{ + +} + } // namespace toolbars } // namespace pv diff --git a/DSView/pv/toolbars/filebar.h b/DSView/pv/toolbars/filebar.h index 32cbbe81..243e4501 100644 --- a/DSView/pv/toolbars/filebar.h +++ b/DSView/pv/toolbars/filebar.h @@ -29,13 +29,14 @@ #include #include "../sigsession.h" +#include "../interface/icallbacks.h" namespace pv { namespace toolbars { //toolbar button,referenced by MainWindow //TODO: load session file, sorte session, load log data file, sorte data, export data -class FileBar : public QToolBar +class FileBar : public QToolBar, public IMessageListener { Q_OBJECT @@ -51,11 +52,6 @@ private: void retranslateUi(); void reStyle(); - void session_error( - const QString text, const QString info_text); - void show_session_error( - const QString text, const QString info_text); - signals: void sig_load_file(QString); void sig_save(); @@ -71,6 +67,9 @@ private slots: void on_actionOpen_triggered(); void on_actionCapture_triggered(); + //IMessageListener + void OnMessage(int msg); + private: bool _enable; SigSession* _session; diff --git a/DSView/pv/toolbars/logobar.cpp b/DSView/pv/toolbars/logobar.cpp index 48ff6271..da564cb2 100644 --- a/DSView/pv/toolbars/logobar.cpp +++ b/DSView/pv/toolbars/logobar.cpp @@ -170,25 +170,6 @@ void LogoBar::dsl_connected(bool conn) _logo_button.setIcon(QIcon(iconPath+"/logo_noColor.svg")); } -void LogoBar::session_error( - const QString text, const QString info_text) -{ - QMetaObject::invokeMethod(this, "show_session_error", - Qt::QueuedConnection, Q_ARG(QString, text), - Q_ARG(QString, info_text)); -} - -void LogoBar::show_session_error( - const QString text, const QString info_text) -{ - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(text); - msg.mBox()->setInformativeText(info_text); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); -} - void LogoBar::on_actionEn_triggered() { _language->setIcon(QIcon::fromTheme("file", diff --git a/DSView/pv/toolbars/logobar.h b/DSView/pv/toolbars/logobar.h index 2a9ee401..4637cdac 100644 --- a/DSView/pv/toolbars/logobar.h +++ b/DSView/pv/toolbars/logobar.h @@ -59,11 +59,6 @@ private: void retranslateUi(); void reStyle(); - void session_error( - const QString text, const QString info_text); - void show_session_error( - const QString text, const QString info_text); - signals: //post event message to open user help document, MainWindow class receive it void sig_open_doc(); diff --git a/DSView/pv/toolbars/samplingbar.cpp b/DSView/pv/toolbars/samplingbar.cpp index 0d008702..65527a1e 100644 --- a/DSView/pv/toolbars/samplingbar.cpp +++ b/DSView/pv/toolbars/samplingbar.cpp @@ -65,11 +65,12 @@ SamplingBar::SamplingBar(SigSession *session, QWidget *parent) : _updating_sample_rate = false; _updating_sample_count = false; _sampling = false; - _enable = true; - _instant = false; + _enable = true; + _last_device_handle = NULL_HANDLE; _session = session; _device_agent = _session->get_device(); + _session->add_msg_listener(this); setMovable(false); setContentsMargins(0,0,0,0); @@ -141,10 +142,12 @@ void SamplingBar::retranslateUi() bool bDev = _device_agent->have_instance(); if (bDev) { - if (_device_agent->is_demo()) + if (_device_agent->is_demo()){ _device_type.setText(tr("Demo")); - else if (_device_agent->is_file()) + } + else if (_device_agent->is_file()){ _device_type.setText(tr("File")); + } else { int usb_speed = LIBUSB_SPEED_HIGH; GVariant *gvar = _device_agent->get_config(NULL, NULL, SR_CONF_USB_SPEED); @@ -166,13 +169,14 @@ void SamplingBar::retranslateUi() int mode = _device_agent->get_work_mode(); - if (_instant) { + if (_session->is_instant()) { if (bDev && mode == DSO) _instant_button.setText(_sampling ? tr("Stop") : tr("Single")); else _instant_button.setText(_sampling ? tr("Stop") : tr("Instant")); _run_stop_button.setText(tr("Start")); - } else { + } + else { _run_stop_button.setText(_sampling ? tr("Stop") : tr("Start")); if (bDev && mode == DSO) _instant_button.setText(tr("Single")); @@ -224,20 +228,22 @@ void SamplingBar::reStyle() void SamplingBar::on_configure() { + int ret; + if (_device_agent->have_instance() == false){ dsv_info("%s", "Have no device, can't to set device config."); return; } - sig_hide_calibration(); - int ret; + _session->broadcast_msg(DSV_MSG_BEGIN_DEVICE_OPTIONS); pv::dialogs::DeviceOptions dlg(this); ret = dlg.exec(); if (ret == QDialog::Accepted) - { - sig_device_updated(); + { + _session->broadcast_msg(DSV_MSG_DEVICE_OPTIONS_UPDATED); + update_sample_rate_selector(); int mode = _device_agent->get_work_mode(); @@ -252,17 +258,7 @@ void SamplingBar::on_configure() zero_adj(); return; } - } - - gvar = _device_agent->get_config(NULL, NULL, SR_CONF_CALI); - if (gvar != NULL) { - bool cali = g_variant_get_boolean(gvar); - g_variant_unref(gvar); - if (cali) { - sig_show_calibration(); - return; - } - } + } } gvar = _device_agent->get_config(NULL, NULL, SR_CONF_TEST); if (gvar != NULL) { @@ -279,6 +275,8 @@ void SamplingBar::on_configure() } } } + + _session->broadcast_msg(DSV_MSG_END_DEVICE_OPTIONS); } void SamplingBar::zero_adj() @@ -301,7 +299,8 @@ void SamplingBar::zero_adj() _sample_count.setCurrentIndex(i); commit_hori_res(); - sig_run_stop(); + if (_session->is_running() == false) + _session->start_capture(true); pv::dialogs::WaitingDialog wait(this, _session, SR_CONF_ZERO); if (wait.start() == QDialog::Rejected) { @@ -312,8 +311,8 @@ void SamplingBar::zero_adj() } } - if (_session->get_capture_state() == pv::SigSession::Running) - on_run_stop(); + if (_session->is_running()) + _session->stop_capture(); _sample_count.setCurrentIndex(index_back); commit_hori_res(); @@ -324,11 +323,6 @@ bool SamplingBar::get_sampling() return _sampling; } -bool SamplingBar::get_instant() -{ - return _instant; -} - void SamplingBar::set_sampling(bool sampling) { _sampling = sampling; @@ -336,8 +330,9 @@ void SamplingBar::set_sampling(bool sampling) if (!sampling) { enable_run_stop(true); enable_instant(true); - } else { - if (_instant) + } + else { + if (_session->is_instant()) enable_instant(true); else enable_run_stop(true); @@ -349,11 +344,12 @@ void SamplingBar::set_sampling(bool sampling) if (true) { QString iconPath = GetIconPath(); - if (_instant) { + + if (_session->is_instant()) _instant_button.setIcon(sampling ? QIcon(iconPath+"/stop.svg") : QIcon(iconPath+"/single.svg")); - } else { + else _run_stop_button.setIcon(sampling ? QIcon(iconPath+"/stop.svg") : QIcon(iconPath+"/start.svg")); - } + _mode_button.setIcon(_session->get_run_mode() == pv::SigSession::Single ? QIcon(iconPath+"/modes.svg") : QIcon(iconPath+"/moder.svg")); } @@ -387,6 +383,7 @@ void SamplingBar::update_sample_rate_selector() this, SLOT(on_samplerate_sel(int))); if (_device_agent->have_instance() == false){ + dsv_info("%s", "SamplingBar::update_sample_rate_selector, have no device."); return; } @@ -427,6 +424,7 @@ void SamplingBar::update_sample_rate_selector() g_variant_unref(gvar_dict); update_sample_rate_selector_value(); + connect(&_sample_rate, SIGNAL(currentIndexChanged(int)), this, SLOT(on_samplerate_sel(int))); @@ -677,7 +675,7 @@ void SamplingBar::on_samplecount_sel(int index) if (_device_agent->get_work_mode() == DSO) commit_hori_res(); - sig_duration_changed(); + _session->broadcast_msg(DSV_MSG_DEVICE_DURATION_UPDATED); } double SamplingBar::get_hori_res() @@ -803,9 +801,7 @@ void SamplingBar::on_run_stop() enable_run_stop(false); enable_instant(false); - commit_settings(); - _instant = false; - + commit_settings(); if (_device_agent->get_work_mode() == DSO) { GVariant* gvar = _device_agent->get_config(NULL, NULL, SR_CONF_ZERO); @@ -835,8 +831,7 @@ void SamplingBar::on_run_stop() } } } - - sig_run_stop(); + } void SamplingBar::on_instant_stop() @@ -866,8 +861,7 @@ void SamplingBar::on_instant_stop() enable_run_stop(false); enable_instant(false); - commit_settings(); - _instant = true; + commit_settings(); if (_device_agent->have_instance() == false){ return; @@ -900,9 +894,7 @@ void SamplingBar::on_instant_stop() return; } } - } - - sig_instant_stop(); + } } } @@ -919,10 +911,7 @@ void SamplingBar::on_device_selected() _session->session_save(); ds_device_handle devHandle = (ds_device_handle)_device_selector.currentData().toULongLong(); - - if (_session->set_device(devHandle)){ - sig_device_selected(); - } + _session->set_device(devHandle); } void SamplingBar::enable_toggle(bool enable) @@ -965,17 +954,6 @@ void SamplingBar::enable_instant(bool enable) _instant_button.setDisabled(!enable); } -void SamplingBar::show_session_error( - const QString text, const QString info_text) -{ - dialogs::DSMessageBox msg(this); - msg.mBox()->setText(text); - msg.mBox()->setInformativeText(info_text); - msg.mBox()->setStandardButtons(QMessageBox::Ok); - msg.mBox()->setIcon(QMessageBox::Warning); - msg.exec(); -} - void SamplingBar::reload() { QString iconPath = GetIconPath(); @@ -1029,8 +1007,7 @@ void SamplingBar::on_mode() } void SamplingBar::update_device_list() - { - + { struct ds_device_info *array = NULL; int dev_count = 0; int select_index = 0; @@ -1064,5 +1041,19 @@ void SamplingBar::on_mode() _updating_device_list = false; } + void SamplingBar::OnMessage(int msg) + { + switch (msg) + { + case DSV_MSG_DEVICE_LIST_UPDATE: + update_device_list(); + break; + case DSV_MSG_COLLECT_START: + set_sampling(false); + case DSV_MSG_COLLECT_END: + set_sampling(true); + } + } + } // namespace toolbars } // namespace pv diff --git a/DSView/pv/toolbars/samplingbar.h b/DSView/pv/toolbars/samplingbar.h index bb9416ce..750504b5 100644 --- a/DSView/pv/toolbars/samplingbar.h +++ b/DSView/pv/toolbars/samplingbar.h @@ -33,6 +33,7 @@ #include #include #include "../ui/dscombobox.h" +#include "../interface/icallbacks.h" struct st_dev_inst; class QAction; @@ -58,7 +59,7 @@ namespace pv namespace toolbars { - class SamplingBar : public QToolBar + class SamplingBar : public QToolBar, public IMessageListener { Q_OBJECT @@ -72,39 +73,27 @@ namespace pv static const QString RLEString; static const QString DIVString; static const uint64_t ZeroTimeBase = SR_US(2); + public: SamplingBar(SigSession *session, QWidget *parent); void update_sample_rate_selector(); - - void set_sampling(bool sampling); - bool get_sampling(); - bool get_instant(); + void enable_toggle(bool enable); - void enable_run_stop(bool enable); + void enable_instant(bool enable); double hori_knob(int dir); double commit_hori_res(); - double get_hori_res(); + double get_hori_res(); + void set_sample_rate(uint64_t sample_rate); void update_device_list(); - public slots: - void set_sample_rate(uint64_t sample_rate); - - signals: - void sig_run_stop(); - void sig_instant_stop(); - void sig_device_selected(); - void sig_device_updated(); - void sig_duration_changed(); - void sig_show_calibration(); - void sig_hide_calibration(); - private: + void enable_run_stop(bool enable); void changeEvent(QEvent *event); void retranslateUi(); void reStyle(); @@ -115,6 +104,11 @@ namespace pv void commit_settings(); void setting_adj(); + void set_sampling(bool sampling); + + //IMessageListener + void OnMessage(int msg); + private slots: void on_mode(); void on_run_stop(); @@ -122,11 +116,6 @@ namespace pv void on_device_selected(); void on_samplerate_sel(int index); void on_samplecount_sel(int index); - - void show_session_error( - const QString text, const QString info_text); - - public slots: void on_configure(); void zero_adj(); void reload(); @@ -155,9 +144,9 @@ namespace pv QMenu *_mode_menu; QAction *_action_repeat; QAction *_action_single; - bool _instant; bool _updating_device_list; DeviceAgent *_device_agent; + ds_device_handle _last_device_handle; }; } // namespace toolbars diff --git a/DSView/pv/view/devmode.cpp b/DSView/pv/view/devmode.cpp index 78f85392..cd28ddb0 100644 --- a/DSView/pv/view/devmode.cpp +++ b/DSView/pv/view/devmode.cpp @@ -214,7 +214,8 @@ void DevMode::on_mode_change() _mode_btn->setText(mode_name->_name_cn); else _mode_btn->setText(mode_name->_name_en); - dev_changed(false); + + _session->broadcast_msg(DSV_MSG_DEVICE_MODE_CHANGED); } break; diff --git a/DSView/pv/view/devmode.h b/DSView/pv/view/devmode.h index 53cae8c6..fb259d8c 100644 --- a/DSView/pv/view/devmode.h +++ b/DSView/pv/view/devmode.h @@ -84,8 +84,7 @@ public slots: private slots: -signals: - void dev_changed(bool close); + private: SigSession *_session; diff --git a/DSView/pv/view/view.cpp b/DSView/pv/view/view.cpp index d91f357e..677e5fe0 100644 --- a/DSView/pv/view/view.cpp +++ b/DSView/pv/view/view.cpp @@ -80,7 +80,6 @@ const QColor View::LightRed = QColor(213, 15, 37, 200); View::View(SigSession *session, pv::toolbars::SamplingBar *sampling_bar, QWidget *parent) : QScrollArea(parent), - _session(session), _sampling_bar(sampling_bar), _scale(10), _preScale(1e-6), @@ -97,13 +96,13 @@ View::View(SigSession *session, pv::toolbars::SamplingBar *sampling_bar, QWidget _dso_auto(true), _show_lissajous(false), _back_ready(false) -{ - assert(session); - +{ _trig_cursor = NULL; _search_cursor = NULL; + _session = session; _device_agent = session->get_device(); + session->add_msg_listener(this); setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn); @@ -190,7 +189,6 @@ View::View(SigSession *session, pv::toolbars::SamplingBar *sampling_bar, QWidget connect(_vsplitter, SIGNAL(splitterMoved(int,int)), this, SLOT(splitterMoved(int, int))); - connect(_devmode, SIGNAL(dev_changed(bool)),this, SLOT(dev_changed(bool)), Qt::DirectConnection); connect(_header, SIGNAL(traces_moved()),this, SLOT(on_traces_moved())); connect(_header, SIGNAL(header_updated()),this, SLOT(header_updated())); } @@ -676,15 +674,11 @@ void View::update_scale_offset() viewport_update(); } -void View::dev_changed(bool close) +void View::mode_changed() { - if (!close) { - if (_device_agent->name().contains("virtual")) - _scale = WellSamplesPerPixel * 1.0 / _session->cur_snap_samplerate(); - _scale = max(min(_scale, _maxscale), _minscale); - } - - device_changed(close); + if (_device_agent->name().contains("virtual")) + _scale = WellSamplesPerPixel * 1.0 / _session->cur_snap_samplerate(); + _scale = max(min(_scale, _maxscale), _minscale); } void View::signals_changed() @@ -1363,5 +1357,38 @@ int View::get_cursor_index_by_key(uint64_t key) return -1; } +void View::check_calibration() +{ + if (_device_agent->get_work_mode() == DSO){ + GVariant* gvar = _device_agent->get_config(NULL, NULL, SR_CONF_CALI); + if (gvar != NULL) { + bool cali = g_variant_get_boolean(gvar); + g_variant_unref(gvar); + if (cali) { + show_calibration(); + } + } + } +} + +void View::OnMessage(int msg) +{ + switch (msg) + { + case DSV_MSG_DEVICE_OPTIONS_UPDATED: + check_calibration(); + break; + case DSV_MSG_COLLECT_START_PREV: + capture_init(); + break; + case DSV_MSG_DEVICE_DURATION_UPDATED: + timebase_changed(); + break; + case DSV_MSG_DEVICE_MODE_CHANGED: + mode_changed(); + break; + } +} + } // namespace view } // namespace pv diff --git a/DSView/pv/view/view.h b/DSView/pv/view/view.h index 6479a42a..a82cb117 100644 --- a/DSView/pv/view/view.h +++ b/DSView/pv/view/view.h @@ -42,6 +42,7 @@ #include "signal.h" #include "viewstatus.h" #include "../dsvdef.h" +#include "../interface/icallbacks.h" class DeviceAgent; @@ -68,7 +69,7 @@ class Viewport; class LissajousFigure; //created by MainWindow -class View : public QScrollArea { +class View : public QScrollArea, public IMessageListener { Q_OBJECT private: @@ -259,8 +260,6 @@ signals: void prgRate(int progress); - void device_changed(bool close); - void resize(); void auto_trig(int index); @@ -279,6 +278,9 @@ private: void clear(); void reconstruct(); + //IMessageListener + void OnMessage(int msg); + private: bool eventFilter(QObject *object, QEvent *event); @@ -286,6 +288,8 @@ private: void resizeEvent(QResizeEvent *e); + void check_calibration(); + public slots: void reload(); void set_measure_en(int enable); @@ -340,7 +344,7 @@ private slots: void splitterMoved(int pos, int index); - void dev_changed(bool close); + void mode_changed(); public: void show_wait_trigger(); diff --git a/libsigrok4DSL/lib_main.c b/libsigrok4DSL/lib_main.c index 1026db4f..1acbc82f 100644 --- a/libsigrok4DSL/lib_main.c +++ b/libsigrok4DSL/lib_main.c @@ -68,6 +68,7 @@ static int open_device_instance(struct sr_dev_inst *dev); static void collect_run_proc(); static void post_event_async(int event); static void send_event(int event); +static void make_demo_device_to_list(); static struct sr_lib_context lib_ctx = { .event_callback = NULL, @@ -129,6 +130,8 @@ SR_API int ds_lib_init() } pthread_mutex_init(&lib_ctx.mutext, NULL); // init locker + make_demo_device_to_list(); + lib_ctx.sr_ctx->hotplug_tv.tv_sec = 0; lib_ctx.sr_ctx->hotplug_tv.tv_usec = 0; @@ -154,10 +157,8 @@ SR_API int ds_lib_exit() sr_info("Uninit %s.", SR_LIB_NAME); - if (lib_ctx.collect_thread != NULL) - { + if (ds_is_collecting()) ds_stop_collect(); // stop collect. - } sr_close_hotplug(lib_ctx.sr_ctx); @@ -247,7 +248,7 @@ SR_API int ds_get_device_list(struct ds_device_info **out_list, int *out_count) int num; struct ds_device_info *array = NULL; struct ds_device_info *p = NULL; - GList *l; + GSList *l; struct sr_dev_inst *dev; if (out_list == NULL) @@ -309,7 +310,7 @@ SR_API int ds_get_device_list(struct ds_device_info **out_list, int *out_count) */ SR_API int ds_active_device(ds_device_handle handle) { - GList *l; + GSList *l; struct sr_dev_inst *dev; int bFind = 0; int ret; @@ -322,7 +323,7 @@ SR_API int ds_active_device(ds_device_handle handle) sr_info("%s", "Begin set current device."); - if (lib_ctx.collect_thread != NULL) + if (ds_is_collecting()) { sr_err("%s", "One device is collecting, switch device error."); return SR_ERR_CALL_STATUS; @@ -389,7 +390,7 @@ SR_API int ds_active_device(ds_device_handle handle) */ SR_API int ds_active_device_by_index(int index) { - GList *l; + GSList *l; struct sr_dev_inst *dev; ds_device_handle handle = NULL; ds_device_handle lst_handle = NULL; @@ -432,7 +433,7 @@ SR_API int ds_active_device_by_index(int index) SR_API int ds_get_actived_device_index() { int dex = -1; - GList *l; + GSList *l; int i = 0; if (lib_ctx.actived_device_instance == NULL) @@ -481,7 +482,7 @@ SR_API int ds_device_from_file(const char *file_path) */ SR_API const GSList *ds_get_actived_device_mode_list() { - GList *l; + GSList *l; struct sr_dev_inst *dev; dev = lib_ctx.actived_device_instance ; @@ -489,7 +490,7 @@ SR_API const GSList *ds_get_actived_device_mode_list() if (dev == NULL){ sr_err("%s", "Have no actived device."); } - if (dev->driver == NULL || dev->driver->dev_mode_list){ + if (dev->driver == NULL || dev->driver->dev_mode_list == NULL){ sr_err("%s", "Module not implemented."); return NULL; } @@ -503,7 +504,7 @@ SR_API const GSList *ds_get_actived_device_mode_list() */ SR_API int ds_remove_device(ds_device_handle handle) { - GList *l; + GSList *l; struct sr_dev_inst *dev; int bFind = 0; @@ -626,7 +627,7 @@ SR_API int ds_start_collect() sr_info("%s", "Start collect."); - if (lib_ctx.collect_thread != NULL) + if (ds_is_collecting()) { sr_err("%s", "Error,it's collecting!"); return SR_ERR_CALL_STATUS; @@ -717,7 +718,7 @@ SR_API int ds_stop_collect() sr_info("%s", "Stop collect."); - if (lib_ctx.collect_thread == NULL) + if (!ds_is_collecting()) { sr_err("%s", "It's not collecting now."); return SR_ERR_CALL_STATUS; @@ -728,7 +729,9 @@ SR_API int ds_stop_collect() // Stop current session. sr_session_stop(); - g_thread_join(lib_ctx.collect_thread); // Wait the collect thread ends. + // Wait the collect thread ends. + if (lib_ctx.collect_thread != NULL) + g_thread_join(lib_ctx.collect_thread); lib_ctx.collect_thread = NULL; close_device_instance(di); @@ -923,7 +926,7 @@ GSList* ds_get_actived_device_channels() */ SR_PRIV int sr_usb_device_is_exists(libusb_device *usb_dev) { - GList *l; + GSList *l; struct sr_dev_inst *dev; int bFind = 0; @@ -1004,7 +1007,7 @@ SR_API int ds_is_collecting() static int update_device_handle(struct libusb_device *old_dev, struct libusb_device *new_dev) { - GList *l; + GSList *l; struct sr_dev_inst *dev; struct sr_usb_dev_inst *usb_dev_info; uint8_t bus; @@ -1128,8 +1131,7 @@ static void process_attach_event() { struct sr_dev_driver **drivers; GList *dev_list; - GSList *l; - GList *cur_list; + GSList *l; struct sr_dev_driver *dr; int num = 0; @@ -1155,15 +1157,11 @@ static void process_attach_event() sr_info("Get new device list by driver \"%s\"", dr->name); pthread_mutex_lock(&lib_ctx.mutext); - cur_list = lib_ctx.device_list; - for (l = dev_list; l; l = l->next) - { - cur_list = g_slist_append(cur_list, l->data); + for (l = dev_list; l; l = l->next){ + lib_ctx.device_list = g_slist_append(lib_ctx.device_list, l->data); num++; } - - lib_ctx.device_list = cur_list; pthread_mutex_unlock(&lib_ctx.mutext); g_slist_free(dev_list); } @@ -1184,7 +1182,7 @@ static void process_attach_event() static void process_detach_event() { - GList *l; + GSList *l; struct sr_dev_inst *dev; struct sr_dev_driver *driver_ins; libusb_device *ev_dev; @@ -1284,6 +1282,35 @@ static void usb_hotplug_process_proc() sr_info("%s", "Hotplug thread end!"); } +static void make_demo_device_to_list() +{ + struct sr_dev_driver **drivers; + struct sr_dev_driver *dr; + GList *dev_list; + GSList *l; + + drivers = sr_driver_list(); + + while (*drivers) + { + dr = *drivers; + + if (dr->driver_type == DRIVER_TYPE_DEMO) + { + dev_list = dr->scan(NULL); + + if (dev_list != NULL){ + + for (l = dev_list; l; l = l->next){ + lib_ctx.device_list = g_slist_append(lib_ctx.device_list, l->data); + } + g_slist_free(dev_list); + } + } + drivers++; + } +} + static void destroy_device_instance(struct sr_dev_inst *dev) { if (dev == NULL || dev->driver == NULL)