forked from Ivasoft/DSView
v0.97 initial update, compile pass, run error
This commit is contained in:
@@ -62,6 +62,7 @@ endif()
|
||||
list(APPEND PKGDEPS
|
||||
"libsigrok4DSL >= 0.2.0"
|
||||
"libusb-1.0 >= 1.0.16"
|
||||
"libzip >= 0.10"
|
||||
)
|
||||
if(ENABLE_DECODE)
|
||||
list(APPEND PKGDEPS "libsigrokdecode>=0.3.0")
|
||||
@@ -93,6 +94,7 @@ find_package(Threads)
|
||||
|
||||
find_package(Boost 1.42 COMPONENTS filesystem system thread REQUIRED)
|
||||
find_package(libusb-1.0 REQUIRED)
|
||||
find_package(libzip REQUIRED)
|
||||
find_package(FFTW REQUIRED)
|
||||
|
||||
#===============================================================================
|
||||
@@ -104,7 +106,7 @@ set(DS_DESCRIPTION "A GUI for instruments of DreamSourceLab")
|
||||
|
||||
set(DS_VERSION_MAJOR 0)
|
||||
set(DS_VERSION_MINOR 9)
|
||||
set(DS_VERSION_MICRO 6)
|
||||
set(DS_VERSION_MICRO 7)
|
||||
set(DS_VERSION_STRING
|
||||
${DS_VERSION_MAJOR}.${DS_VERSION_MINOR}.${DS_VERSION_MICRO}
|
||||
)
|
||||
@@ -202,6 +204,7 @@ set(DSView_SOURCES
|
||||
pv/dialogs/dsmessagebox.cpp
|
||||
pv/dialogs/shadow.cpp
|
||||
pv/dialogs/dsdialog.cpp
|
||||
pv/dialogs/interval.cpp
|
||||
)
|
||||
|
||||
set(DSView_HEADERS
|
||||
@@ -257,6 +260,7 @@ set(DSView_HEADERS
|
||||
pv/dialogs/dsmessagebox.h
|
||||
pv/dialogs/shadow.h
|
||||
pv/dialogs/dsdialog.h
|
||||
pv/dialogs/interval.h
|
||||
)
|
||||
|
||||
set(DSView_FORMS
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
[Desktop Entry]
|
||||
Version=0.96
|
||||
Exec=/usr/local/bin/DSView
|
||||
Name=DSView
|
||||
Comment=GUI Program for DreamSourceLab USB-based Instruments
|
||||
Icon=/usr/local/share/DSView/logo.png
|
||||
Type=Application
|
||||
Terminal=false
|
||||
Categories=Development
|
||||
@@ -10,8 +10,6 @@
|
||||
<file>stylesheet.qss</file>
|
||||
<file>icons/down-arrow.png</file>
|
||||
<file>icons/slider-handle.png</file>
|
||||
<file>icons/add.png</file>
|
||||
<file>icons/del.png</file>
|
||||
<file>icons/trigger.png</file>
|
||||
<file>icons/measure.png</file>
|
||||
<file>icons/search-bar.png</file>
|
||||
@@ -55,5 +53,16 @@
|
||||
<file>icons/maximize.png</file>
|
||||
<file>icons/minimize.png</file>
|
||||
<file>icons/restore.png</file>
|
||||
<file>icons/nav.png</file>
|
||||
<file>icons/oneloop.png</file>
|
||||
<file>icons/repeat.png</file>
|
||||
<file>icons/moder.png</file>
|
||||
<file>icons/moder_dis.png</file>
|
||||
<file>icons/modes.png</file>
|
||||
<file>icons/modes_dis.png</file>
|
||||
<file>icons/add.png</file>
|
||||
<file>icons/del.png</file>
|
||||
<file>icons/add_dis.png</file>
|
||||
<file>icons/del_dis.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
@@ -65,7 +65,7 @@ QWidget:item:selected
|
||||
|
||||
QCheckBox
|
||||
{
|
||||
spacing: 5px;
|
||||
spacing: 0px;
|
||||
outline: none;
|
||||
color: #bbb;
|
||||
margin-bottom: 2px;
|
||||
@@ -635,7 +635,7 @@ QComboBox::drop-down
|
||||
{
|
||||
subcontrol-origin: padding;
|
||||
subcontrol-position: top right;
|
||||
width: 15px;
|
||||
width: 10px;
|
||||
|
||||
border-left-width: 0px;
|
||||
border-left-color: darkgray;
|
||||
|
||||
@@ -34,15 +34,15 @@ bool DSApplication::notify(QObject *receiver_, QEvent *event_)
|
||||
return QApplication::notify(receiver_, event_);
|
||||
} catch ( std::exception& e ) {
|
||||
QMessageBox msg(NULL);
|
||||
msg.setText("Application Error");
|
||||
msg.setText(tr("Application Error"));
|
||||
msg.setInformativeText(e.what());
|
||||
msg.setStandardButtons(QMessageBox::Ok);
|
||||
msg.setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
} catch (...) {
|
||||
QMessageBox msg(NULL);
|
||||
msg.setText("Application Error");
|
||||
msg.setInformativeText("An unexpected error occurred");
|
||||
msg.setText(tr("Application Error"));
|
||||
msg.setInformativeText(tr("An unexpected error occurred"));
|
||||
msg.setStandardButtons(QMessageBox::Ok);
|
||||
msg.setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
|
||||
BIN
DSView/icons/add.png
Normal file → Executable file
BIN
DSView/icons/add.png
Normal file → Executable file
Binary file not shown.
|
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 399 B |
BIN
DSView/icons/del.png
Normal file → Executable file
BIN
DSView/icons/del.png
Normal file → Executable file
Binary file not shown.
|
Before Width: | Height: | Size: 624 B After Width: | Height: | Size: 714 B |
@@ -34,7 +34,7 @@
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QIcon>
|
||||
#include <QTranslator>
|
||||
|
||||
#include "dsapplication.h"
|
||||
#include "pv/devicemanager.h"
|
||||
@@ -143,9 +143,10 @@ int main(int argc, char *argv[])
|
||||
a.setStyleSheet(qss.readAll());
|
||||
qss.close();
|
||||
w.show();
|
||||
w.readSettings();
|
||||
|
||||
// Run the application
|
||||
ret = a.exec();
|
||||
ret = a.exec();
|
||||
|
||||
} catch(std::exception e) {
|
||||
qDebug() << e.what();
|
||||
|
||||
@@ -91,14 +91,20 @@ void AnalogSnapshot::clear()
|
||||
init();
|
||||
}
|
||||
|
||||
void AnalogSnapshot::first_payload(const sr_datafeed_analog &analog, uint64_t total_sample_count, unsigned int channel_num)
|
||||
void AnalogSnapshot::first_payload(const sr_datafeed_analog &analog, uint64_t total_sample_count, GSList *channels)
|
||||
{
|
||||
_total_sample_count = total_sample_count;
|
||||
_channel_num = channel_num;
|
||||
_unit_size = sizeof(uint16_t)*channel_num;
|
||||
_channel_num = 0;
|
||||
for (const GSList *l = channels; l; l = l->next) {
|
||||
sr_channel *const probe = (sr_channel*)l->data;
|
||||
assert(probe);
|
||||
if (probe->type == SR_CHANNEL_ANALOG && probe->enabled) {
|
||||
_channel_num ++;
|
||||
}
|
||||
}
|
||||
|
||||
bool isOk = true;
|
||||
uint64_t size = _total_sample_count * _unit_size + sizeof(uint64_t);
|
||||
uint64_t size = _total_sample_count * _channel_num * BytesPerSample + sizeof(uint64_t);
|
||||
if (size != _capacity) {
|
||||
free_data();
|
||||
_data = malloc(size);
|
||||
@@ -125,6 +131,13 @@ void AnalogSnapshot::first_payload(const sr_datafeed_analog &analog, uint64_t to
|
||||
}
|
||||
|
||||
if (isOk) {
|
||||
for (const GSList *l = channels; l; l = l->next) {
|
||||
sr_channel *const probe = (sr_channel*)l->data;
|
||||
assert(probe);
|
||||
if (probe->type == SR_CHANNEL_ANALOG && probe->enabled) {
|
||||
_ch_index.push_back(probe->index);
|
||||
}
|
||||
}
|
||||
_capacity = size;
|
||||
_memory_failed = false;
|
||||
append_payload(analog);
|
||||
@@ -132,7 +145,6 @@ void AnalogSnapshot::first_payload(const sr_datafeed_analog &analog, uint64_t to
|
||||
} else {
|
||||
free_data();
|
||||
free_envelop();
|
||||
_capacity = 0;
|
||||
_memory_failed = true;
|
||||
}
|
||||
}
|
||||
@@ -147,6 +159,27 @@ void AnalogSnapshot::append_payload(
|
||||
append_payload_to_envelope_levels();
|
||||
}
|
||||
|
||||
void AnalogSnapshot::append_data(void *data, uint64_t samples)
|
||||
{
|
||||
int unit_bytes = BytesPerSample * _channel_num;
|
||||
if (_sample_count + samples < _total_sample_count)
|
||||
_sample_count += samples;
|
||||
else
|
||||
_sample_count = _total_sample_count;
|
||||
|
||||
if (_ring_sample_count + samples > _total_sample_count) {
|
||||
memcpy((uint8_t*)_data + _ring_sample_count * unit_bytes,
|
||||
data, (_total_sample_count - _ring_sample_count) * unit_bytes);
|
||||
_ring_sample_count = (samples + _ring_sample_count - _total_sample_count) % _total_sample_count;
|
||||
memcpy((uint8_t*)_data,
|
||||
data, _ring_sample_count * unit_bytes);
|
||||
} else {
|
||||
memcpy((uint8_t*)_data + _ring_sample_count * unit_bytes,
|
||||
data, samples * unit_bytes);
|
||||
_ring_sample_count += samples;
|
||||
}
|
||||
}
|
||||
|
||||
const uint16_t* AnalogSnapshot::get_samples(
|
||||
int64_t start_sample, int64_t end_sample) const
|
||||
{
|
||||
@@ -303,5 +336,20 @@ void AnalogSnapshot::append_payload_to_envelope_levels()
|
||||
}
|
||||
}
|
||||
|
||||
int AnalogSnapshot::get_ch_order(int sig_index)
|
||||
{
|
||||
int order = 0;
|
||||
for (auto& iter:_ch_index) {
|
||||
if (iter == sig_index)
|
||||
break;
|
||||
order++;
|
||||
}
|
||||
|
||||
if (order >= _ch_index.size())
|
||||
return -1;
|
||||
else
|
||||
return order;
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace pv
|
||||
|
||||
@@ -68,6 +68,8 @@ private:
|
||||
static const float LogEnvelopeScaleFactor;
|
||||
static const uint64_t EnvelopeDataUnit;
|
||||
|
||||
static const int BytesPerSample = 2;
|
||||
|
||||
public:
|
||||
AnalogSnapshot();
|
||||
|
||||
@@ -76,7 +78,8 @@ public:
|
||||
void clear();
|
||||
void init();
|
||||
|
||||
void first_payload(const sr_datafeed_analog &analog, uint64_t total_sample_count, unsigned int channel_num);
|
||||
void first_payload(const sr_datafeed_analog &analog,
|
||||
uint64_t total_sample_count, GSList *channels);
|
||||
|
||||
void append_payload(const sr_datafeed_analog &analog);
|
||||
|
||||
@@ -86,11 +89,16 @@ public:
|
||||
void get_envelope_section(EnvelopeSection &s,
|
||||
uint64_t start, uint64_t end, float min_length, int probe_index) const;
|
||||
|
||||
int get_ch_order(int sig_index);
|
||||
|
||||
private:
|
||||
void append_data(void *data, uint64_t samples);
|
||||
void free_envelop();
|
||||
void reallocate_envelope(Envelope &l);
|
||||
void append_payload_to_envelope_levels();
|
||||
|
||||
|
||||
|
||||
private:
|
||||
struct Envelope _envelope_levels[2*DS_MAX_ANALOG_PROBES_NUM][ScaleStepCount];
|
||||
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
#include "decoder.h"
|
||||
|
||||
#include <pv/view/logicsignal.h>
|
||||
|
||||
using boost::shared_ptr;
|
||||
using std::set;
|
||||
using std::map;
|
||||
@@ -44,10 +42,6 @@ Decoder::Decoder(const srd_decoder *const dec) :
|
||||
|
||||
Decoder::~Decoder()
|
||||
{
|
||||
for (map<string, GVariant*>::const_iterator i = _options.begin();
|
||||
i != _options.end(); i++)
|
||||
g_variant_unref((*i).second);
|
||||
|
||||
for (map<string, GVariant*>::const_iterator i = _options_back.begin();
|
||||
i != _options_back.end(); i++)
|
||||
g_variant_unref((*i).second);
|
||||
@@ -68,14 +62,13 @@ void Decoder::show(bool show)
|
||||
_shown = show;
|
||||
}
|
||||
|
||||
const map<const srd_channel*, shared_ptr<view::LogicSignal> >&
|
||||
const map<const srd_channel*, int>&
|
||||
Decoder::channels() const
|
||||
{
|
||||
return _probes;
|
||||
}
|
||||
|
||||
void Decoder::set_probes(std::map<const srd_channel*,
|
||||
boost::shared_ptr<view::LogicSignal> > probes)
|
||||
void Decoder::set_probes(std::map<const srd_channel *, int> probes)
|
||||
{
|
||||
_probes_back = probes;
|
||||
_setted = true;
|
||||
@@ -89,6 +82,7 @@ const std::map<std::string, GVariant*>& Decoder::options() const
|
||||
void Decoder::set_option(const char *id, GVariant *value)
|
||||
{
|
||||
assert(value);
|
||||
g_variant_unref(_options_back[id]);
|
||||
g_variant_ref(value);
|
||||
_options_back[id] = value;
|
||||
_setted = true;
|
||||
@@ -139,24 +133,8 @@ bool Decoder::have_required_probes() const
|
||||
return true;
|
||||
}
|
||||
|
||||
set< shared_ptr<pv::data::Logic> > Decoder::get_data()
|
||||
srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session) const
|
||||
{
|
||||
set< shared_ptr<pv::data::Logic> > data;
|
||||
for(map<const srd_channel*, shared_ptr<view::LogicSignal> >::
|
||||
const_iterator i = _probes.begin();
|
||||
i != _probes.end(); i++)
|
||||
{
|
||||
shared_ptr<view::LogicSignal> signal((*i).second);
|
||||
assert(signal);
|
||||
data.insert(signal->logic_data());
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session, int unit_size) const
|
||||
{
|
||||
(void)unit_size;
|
||||
GHashTable *const opt_hash = g_hash_table_new_full(g_str_hash,
|
||||
g_str_equal, g_free, (GDestroyNotify)g_variant_unref);
|
||||
|
||||
@@ -180,13 +158,11 @@ srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session, int unit_si
|
||||
GHashTable *const probes = g_hash_table_new_full(g_str_hash,
|
||||
g_str_equal, g_free, (GDestroyNotify)g_variant_unref);
|
||||
|
||||
for(map<const srd_channel*, shared_ptr<view::LogicSignal> >::
|
||||
for(map<const srd_channel*, int>::
|
||||
const_iterator i = _probes.begin();
|
||||
i != _probes.end(); i++)
|
||||
{
|
||||
shared_ptr<view::LogicSignal> signal((*i).second);
|
||||
GVariant *const gvar = g_variant_new_int32(
|
||||
signal->probe()->index);
|
||||
GVariant *const gvar = g_variant_new_int32((*i).second);
|
||||
g_variant_ref_sink(gvar);
|
||||
g_hash_table_insert(probes, (*i).first->id, gvar);
|
||||
}
|
||||
@@ -196,6 +172,11 @@ srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session, int unit_si
|
||||
return decoder_inst;
|
||||
}
|
||||
|
||||
int Decoder::get_channel_type(const srd_channel *ch)
|
||||
{
|
||||
return ch->type;
|
||||
}
|
||||
|
||||
} // decode
|
||||
} // data
|
||||
} // pv
|
||||
|
||||
@@ -35,15 +35,7 @@ struct srd_channel;
|
||||
struct srd_session;
|
||||
|
||||
namespace pv {
|
||||
|
||||
namespace view {
|
||||
class LogicSignal;
|
||||
}
|
||||
|
||||
namespace data {
|
||||
|
||||
class Logic;
|
||||
|
||||
namespace decode {
|
||||
|
||||
class Decoder
|
||||
@@ -58,10 +50,8 @@ public:
|
||||
bool shown() const;
|
||||
void show(bool show = true);
|
||||
|
||||
const std::map<const srd_channel*,
|
||||
boost::shared_ptr<view::LogicSignal> >& channels() const;
|
||||
void set_probes(std::map<const srd_channel*,
|
||||
boost::shared_ptr<view::LogicSignal> > probes);
|
||||
const std::map<const srd_channel*, int>& channels() const;
|
||||
void set_probes(std::map<const srd_channel*, int> probes);
|
||||
|
||||
const std::map<std::string, GVariant*>& options() const;
|
||||
|
||||
@@ -69,10 +59,7 @@ public:
|
||||
|
||||
bool have_required_probes() const;
|
||||
|
||||
srd_decoder_inst* create_decoder_inst(
|
||||
srd_session *session, int unit_size) const;
|
||||
|
||||
std::set< boost::shared_ptr<pv::data::Logic> > get_data();
|
||||
srd_decoder_inst* create_decoder_inst(srd_session *session) const;
|
||||
|
||||
void set_decode_region(uint64_t start, uint64_t end);
|
||||
uint64_t decode_start() const;
|
||||
@@ -80,17 +67,17 @@ public:
|
||||
|
||||
bool commit();
|
||||
|
||||
int get_channel_type(const srd_channel* ch);
|
||||
|
||||
private:
|
||||
const srd_decoder *const _decoder;
|
||||
|
||||
bool _shown;
|
||||
|
||||
std::map<const srd_channel*, boost::shared_ptr<pv::view::LogicSignal> >
|
||||
_probes;
|
||||
std::map<const srd_channel*, int> _probes;
|
||||
std::map<std::string, GVariant*> _options;
|
||||
|
||||
std::map<const srd_channel*, boost::shared_ptr<pv::view::LogicSignal> >
|
||||
_probes_back;
|
||||
std::map<const srd_channel*, int> _probes_back;
|
||||
std::map<std::string, GVariant*> _options_back;
|
||||
|
||||
uint64_t _decode_start, _decode_end;
|
||||
|
||||
@@ -38,6 +38,11 @@ RowData::RowData() :
|
||||
}
|
||||
|
||||
RowData::~RowData()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
void RowData::clear()
|
||||
{
|
||||
_annotations.clear();
|
||||
}
|
||||
@@ -56,7 +61,10 @@ uint64_t RowData::get_max_annotation() const
|
||||
|
||||
uint64_t RowData::get_min_annotation() const
|
||||
{
|
||||
return _min_annotation;
|
||||
if (_min_annotation == UINT64_MAX)
|
||||
return 10;
|
||||
else
|
||||
return _min_annotation;
|
||||
}
|
||||
|
||||
void RowData::get_annotation_subset(
|
||||
@@ -70,6 +78,18 @@ void RowData::get_annotation_subset(
|
||||
dest.push_back(*i);
|
||||
}
|
||||
|
||||
uint64_t RowData::get_annotation_index(uint64_t start_sample) const
|
||||
{
|
||||
uint64_t index = 0;
|
||||
for (vector<Annotation>::const_iterator i = _annotations.begin();
|
||||
i != _annotations.end(); i++) {
|
||||
if ((*i).start_sample() > start_sample)
|
||||
break;
|
||||
index++;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
bool RowData::push_annotation(const Annotation &a)
|
||||
{
|
||||
try {
|
||||
|
||||
@@ -47,6 +47,8 @@ public:
|
||||
std::vector<pv::data::decode::Annotation> &dest,
|
||||
uint64_t start_sample, uint64_t end_sample) const;
|
||||
|
||||
uint64_t get_annotation_index(uint64_t start_sample) const;
|
||||
|
||||
bool push_annotation(const Annotation &a);
|
||||
|
||||
uint64_t get_annotation_size() const;
|
||||
@@ -54,6 +56,8 @@ public:
|
||||
bool get_annotation(pv::data::decode::Annotation &ann,
|
||||
uint64_t index) const;
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
uint64_t _max_annotation;
|
||||
uint64_t _min_annotation;
|
||||
|
||||
@@ -35,19 +35,8 @@
|
||||
#include <pv/sigsession.h>
|
||||
#include <pv/view/logicsignal.h>
|
||||
|
||||
using boost::lock_guard;
|
||||
using boost::mutex;
|
||||
using boost::optional;
|
||||
using boost::shared_ptr;
|
||||
using boost::unique_lock;
|
||||
using std::deque;
|
||||
using std::make_pair;
|
||||
using std::max;
|
||||
using std::min;
|
||||
using std::list;
|
||||
using std::map;
|
||||
using std::pair;
|
||||
using std::vector;
|
||||
using namespace boost;
|
||||
using namespace std;
|
||||
|
||||
using namespace pv::data::decode;
|
||||
|
||||
@@ -70,7 +59,8 @@ DecoderStack::DecoderStack(pv::SigSession &session,
|
||||
_samples_decoded(0),
|
||||
_decode_state(Stopped),
|
||||
_options_changed(false),
|
||||
_no_memory(false)
|
||||
_no_memory(false),
|
||||
_mark_index(-1)
|
||||
{
|
||||
connect(&_session, SIGNAL(frame_began()),
|
||||
this, SLOT(on_new_frame()));
|
||||
@@ -79,7 +69,7 @@ DecoderStack::DecoderStack(pv::SigSession &session,
|
||||
connect(&_session, SIGNAL(frame_ended()),
|
||||
this, SLOT(on_frame_ended()));
|
||||
|
||||
_stack.push_back(shared_ptr<decode::Decoder>(
|
||||
_stack.push_back(boost::shared_ptr<decode::Decoder>(
|
||||
new decode::Decoder(dec)));
|
||||
|
||||
build_row();
|
||||
@@ -116,7 +106,7 @@ void DecoderStack::push(boost::shared_ptr<decode::Decoder> decoder)
|
||||
void DecoderStack::remove(boost::shared_ptr<Decoder> &decoder)
|
||||
{
|
||||
// Find the decoder in the stack
|
||||
list< shared_ptr<Decoder> >::iterator iter = _stack.begin();
|
||||
list< boost::shared_ptr<Decoder> >::iterator iter = _stack.begin();
|
||||
for(unsigned int i = 0; i < _stack.size(); i++, iter++)
|
||||
if ((*iter) == decoder)
|
||||
break;
|
||||
@@ -133,7 +123,7 @@ void DecoderStack::build_row()
|
||||
{
|
||||
_rows.clear();
|
||||
// Add classes
|
||||
BOOST_FOREACH (const shared_ptr<decode::Decoder> &dec, _stack)
|
||||
BOOST_FOREACH (const boost::shared_ptr<decode::Decoder> &dec, _stack)
|
||||
{
|
||||
assert(dec);
|
||||
const srd_decoder *const decc = dec->decoder();
|
||||
@@ -206,6 +196,21 @@ void DecoderStack::get_annotation_subset(
|
||||
start_sample, end_sample);
|
||||
}
|
||||
|
||||
|
||||
uint64_t DecoderStack::get_annotation_index(
|
||||
const Row &row, uint64_t start_sample) const
|
||||
{
|
||||
//lock_guard<mutex> lock(_output_mutex);
|
||||
|
||||
uint64_t index = 0;
|
||||
std::map<const Row, decode::RowData>::const_iterator iter =
|
||||
_rows.find(row);
|
||||
if (iter != _rows.end())
|
||||
index = (*iter).second.get_annotation_index(start_sample);
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
uint64_t DecoderStack::get_max_annotation(const Row &row)
|
||||
{
|
||||
//lock_guard<mutex> lock(_output_mutex);
|
||||
@@ -353,84 +358,77 @@ QString DecoderStack::error_message()
|
||||
|
||||
void DecoderStack::clear()
|
||||
{
|
||||
//lock_guard<boost::recursive_mutex> decode_lock(_output_mutex);
|
||||
_sample_count = 0;
|
||||
_frame_complete = false;
|
||||
_samples_decoded = 0;
|
||||
new_decode_data();
|
||||
_error_message = QString();
|
||||
for (map<const Row, RowData>::iterator i = _rows.begin();
|
||||
i != _rows.end(); i++)
|
||||
_rows[(*i).first] = decode::RowData();
|
||||
// _rows.clear();
|
||||
// _rows_gshow.clear();
|
||||
// _rows_lshow.clear();
|
||||
// _class_rows.clear();
|
||||
_no_memory = false;
|
||||
init();
|
||||
}
|
||||
|
||||
void DecoderStack::init()
|
||||
{
|
||||
clear();
|
||||
_sample_count = 0;
|
||||
_frame_complete = false;
|
||||
_samples_decoded = 0;
|
||||
_error_message = QString();
|
||||
_no_memory = false;
|
||||
for (map<const Row, RowData>::iterator i = _rows.begin();
|
||||
i != _rows.end(); i++) {
|
||||
//_rows[(*i).first] = decode::RowData();
|
||||
(*i).second.clear();
|
||||
}
|
||||
set_mark_index(-1);
|
||||
}
|
||||
|
||||
void DecoderStack::stop_decode()
|
||||
{
|
||||
//_snapshot.reset();
|
||||
|
||||
if(_decode_state == Stopped) {
|
||||
clear();
|
||||
return;
|
||||
if(_decode_state != Stopped) {
|
||||
if (_decode_thread.get()) {
|
||||
_decode_thread->interrupt();
|
||||
_decode_thread->join();
|
||||
_decode_state = Stopped;
|
||||
}
|
||||
_decode_thread.reset();
|
||||
}
|
||||
|
||||
if (_decode_thread.get()) {
|
||||
_decode_thread->interrupt();
|
||||
_decode_thread->join();
|
||||
_decode_state = Stopped;
|
||||
}
|
||||
_decode_thread.reset();
|
||||
clear();
|
||||
}
|
||||
|
||||
void DecoderStack::begin_decode()
|
||||
{
|
||||
shared_ptr<pv::view::LogicSignal> logic_signal;
|
||||
shared_ptr<pv::data::Logic> data;
|
||||
boost::shared_ptr<pv::view::LogicSignal> logic_signal;
|
||||
boost::shared_ptr<pv::data::Logic> data;
|
||||
|
||||
if (!_options_changed)
|
||||
return;
|
||||
_options_changed = false;
|
||||
// if (_decode_thread.joinable()) {
|
||||
// _decode_thread.interrupt();
|
||||
// _decode_thread.join();
|
||||
// }
|
||||
stop_decode();
|
||||
init();
|
||||
|
||||
// Check that all decoders have the required channels
|
||||
BOOST_FOREACH(const shared_ptr<decode::Decoder> &dec, _stack)
|
||||
BOOST_FOREACH(const boost::shared_ptr<decode::Decoder> &dec, _stack)
|
||||
if (!dec->have_required_probes()) {
|
||||
_error_message = tr("One or more required channels "
|
||||
"have not been specified");
|
||||
return;
|
||||
}
|
||||
|
||||
// // Build rows
|
||||
// build_row();
|
||||
|
||||
// We get the logic data of the first channel in the list.
|
||||
// This works because we are currently assuming all
|
||||
// LogicSignals have the same data/snapshot
|
||||
BOOST_FOREACH (const shared_ptr<decode::Decoder> &dec, _stack)
|
||||
if (dec && !dec->channels().empty() &&
|
||||
((logic_signal = (*dec->channels().begin()).second)) &&
|
||||
((data = logic_signal->logic_data())))
|
||||
break;
|
||||
BOOST_FOREACH (const boost::shared_ptr<decode::Decoder> &dec, _stack) {
|
||||
if (dec && !dec->channels().empty()) {
|
||||
BOOST_FOREACH(boost::shared_ptr<view::Signal> sig, _session.get_signals()) {
|
||||
if((sig->get_index() == (*dec->channels().begin()).second) &&
|
||||
(logic_signal = dynamic_pointer_cast<view::LogicSignal>(sig)) &&
|
||||
(data = logic_signal->logic_data()))
|
||||
break;
|
||||
}
|
||||
if (data)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
// Check we have a snapshot of data
|
||||
const deque< shared_ptr<pv::data::LogicSnapshot> > &snapshots =
|
||||
const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
|
||||
data->get_snapshots();
|
||||
if (snapshots.empty())
|
||||
return;
|
||||
@@ -438,8 +436,7 @@ void DecoderStack::begin_decode()
|
||||
if (_snapshot->empty())
|
||||
return;
|
||||
|
||||
// Get the samplerate and start time
|
||||
_start_time = data->get_start_time();
|
||||
// Get the samplerate
|
||||
_samplerate = data->samplerate();
|
||||
if (_samplerate == 0.0)
|
||||
return;
|
||||
@@ -474,13 +471,11 @@ boost::optional<uint64_t> DecoderStack::wait_for_data() const
|
||||
|
||||
void DecoderStack::decode_data(
|
||||
const uint64_t decode_start, const uint64_t decode_end,
|
||||
const unsigned int unit_size, srd_session *const session)
|
||||
srd_session *const session)
|
||||
{
|
||||
uint8_t *chunk = NULL;
|
||||
//uint8_t *chunk = NULL;
|
||||
uint64_t last_cnt = 0;
|
||||
uint64_t notify_cnt = (decode_end - decode_start + 1)/100;
|
||||
const uint64_t chunk_sample_count =
|
||||
DecodeChunkLength / _snapshot->unit_size();
|
||||
srd_decoder_inst *logic_di = NULL;
|
||||
// find the first level decoder instant
|
||||
for (GSList *d = session->di_list; d; d = d->next) {
|
||||
@@ -501,41 +496,63 @@ void DecoderStack::decode_data(
|
||||
i < decode_end && !_no_memory)
|
||||
{
|
||||
//lock_guard<mutex> decode_lock(_global_decode_mutex);
|
||||
std::vector<const uint8_t *> chunk;
|
||||
std::vector<uint8_t> chunk_const;
|
||||
uint64_t chunk_end = decode_end;
|
||||
for (int j =0 ; j < logic_di->dec_num_channels; j++) {
|
||||
int sig_index = logic_di->dec_channelmap[j];
|
||||
if (sig_index == -1) {
|
||||
chunk.push_back(NULL);
|
||||
} else {
|
||||
if (_snapshot->has_data(sig_index)) {
|
||||
chunk.push_back(_snapshot->get_samples(i, chunk_end, sig_index));
|
||||
chunk_const.push_back(_snapshot->get_sample(i, sig_index));
|
||||
} else {
|
||||
_error_message = tr("At least one of selected channels are not enabled.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (chunk_end - i > MaxChunkSize)
|
||||
chunk_end = i + MaxChunkSize;
|
||||
|
||||
const uint64_t chunk_end = min(
|
||||
i + chunk_sample_count, decode_end);
|
||||
chunk = _snapshot->get_samples(i, chunk_end);
|
||||
|
||||
if (srd_session_send(session, chunk_type, i, chunk_end, chunk,
|
||||
(chunk_end - i) * unit_size, unit_size, &error) != SRD_OK) {
|
||||
if (srd_session_send(session, chunk_type, i, chunk_end,
|
||||
chunk.data(), chunk_const.data(), &error) != SRD_OK) {
|
||||
_error_message = QString::fromLocal8Bit(error);
|
||||
break;
|
||||
}
|
||||
|
||||
if (logic_di && logic_di->logic_mask != 0) {
|
||||
if (logic_di && logic_di->logic_mask != 0 && logic_di->cur_pos < decode_end) {
|
||||
uint64_t cur_pos = logic_di->cur_pos;
|
||||
assert(cur_pos < _snapshot->get_sample_count());
|
||||
uint64_t sample = _snapshot->get_sample(cur_pos) & logic_di->logic_mask;
|
||||
uint64_t sample;
|
||||
if (logic_di->edge_index == -1) {
|
||||
std::vector<uint64_t> pos_vector;
|
||||
cur_pos++;
|
||||
for (int j =0 ; j < logic_di->dec_num_channels; j++) {
|
||||
int index = logic_di->dec_channelmap[j];
|
||||
if (index != -1 && (logic_di->logic_mask & (1 << index))) {
|
||||
bool last_sample = (sample & (1 << index)) ? 1 : 0;
|
||||
if (index != -1 && (logic_di->logic_mask & (1 << j))) {
|
||||
bool last_sample = _snapshot->get_sample(cur_pos - 1, index);
|
||||
pos_vector.push_back(cur_pos);
|
||||
_snapshot->get_nxt_edge(pos_vector.back(), last_sample, decode_end, 1, index);
|
||||
}
|
||||
}
|
||||
cur_pos = *std::min_element(pos_vector.begin(), pos_vector.end());
|
||||
} else {
|
||||
bool last_sample = (sample & (1 << logic_di->edge_index)) ? 1 : 0;
|
||||
bool last_sample = _snapshot->get_sample(cur_pos, logic_di->edge_index);
|
||||
do {
|
||||
sample = 0;
|
||||
cur_pos++;
|
||||
if (!_snapshot->get_nxt_edge(cur_pos, last_sample, decode_end, 1, logic_di->edge_index))
|
||||
break;
|
||||
sample = _snapshot->get_sample(cur_pos) & logic_di->logic_mask;
|
||||
last_sample = (sample & (1 << logic_di->edge_index)) ? 1 : 0;
|
||||
for (int j =0 ; j < logic_di->dec_num_channels; j++) {
|
||||
if (logic_di->logic_mask & (1 << j)) {
|
||||
int index = logic_di->dec_channelmap[j];
|
||||
bool index_sample = _snapshot->get_sample(cur_pos, index);
|
||||
sample += index_sample << j;
|
||||
if (index == logic_di->edge_index)
|
||||
last_sample = index_sample;
|
||||
}
|
||||
}
|
||||
} while(sample != logic_di->exp_logic);
|
||||
}
|
||||
|
||||
@@ -544,7 +561,7 @@ void DecoderStack::decode_data(
|
||||
i = decode_end;
|
||||
chunk_type = 0;
|
||||
} else {
|
||||
i += chunk_sample_count;
|
||||
i = chunk_end + 1;
|
||||
chunk_type = 1;
|
||||
}
|
||||
|
||||
@@ -582,18 +599,16 @@ void DecoderStack::decode_proc()
|
||||
|
||||
_decode_state = Running;
|
||||
|
||||
// Create the decoders
|
||||
const unsigned int unit_size = _snapshot->unit_size();
|
||||
|
||||
// Get the intial sample count
|
||||
{
|
||||
//unique_lock<mutex> input_lock(_input_mutex);
|
||||
sample_count = _sample_count = _snapshot->get_sample_count();
|
||||
}
|
||||
|
||||
BOOST_FOREACH(const shared_ptr<decode::Decoder> &dec, _stack)
|
||||
// Create the decoders
|
||||
BOOST_FOREACH(const boost::shared_ptr<decode::Decoder> &dec, _stack)
|
||||
{
|
||||
srd_decoder_inst *const di = dec->create_decoder_inst(session, unit_size);
|
||||
srd_decoder_inst *const di = dec->create_decoder_inst(session);
|
||||
|
||||
if (!di)
|
||||
{
|
||||
@@ -619,7 +634,7 @@ void DecoderStack::decode_proc()
|
||||
|
||||
char *error = NULL;
|
||||
if (srd_session_start(session, &error) == SRD_OK)
|
||||
decode_data(decode_start, decode_end, unit_size, session);
|
||||
decode_data(decode_start, decode_end, session);
|
||||
else
|
||||
_error_message = QString::fromLocal8Bit(error);
|
||||
|
||||
@@ -747,5 +762,15 @@ bool DecoderStack::out_of_memory() const
|
||||
return _no_memory;
|
||||
}
|
||||
|
||||
void DecoderStack::set_mark_index(int64_t index)
|
||||
{
|
||||
_mark_index = index;
|
||||
}
|
||||
|
||||
int64_t DecoderStack::get_mark_index() const
|
||||
{
|
||||
return _mark_index;
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace pv
|
||||
|
||||
@@ -68,6 +68,7 @@ private:
|
||||
static const double DecodeThreshold;
|
||||
static const int64_t DecodeChunkLength;
|
||||
static const unsigned int DecodeNotifyPeriod;
|
||||
static const uint64_t MaxChunkSize = 1024 * 16;
|
||||
|
||||
public:
|
||||
enum decode_state {
|
||||
@@ -96,6 +97,9 @@ public:
|
||||
const decode::Row &row, uint64_t start_sample,
|
||||
uint64_t end_sample) const;
|
||||
|
||||
uint64_t get_annotation_index(
|
||||
const decode::Row &row, uint64_t start_sample) const;
|
||||
|
||||
uint64_t get_max_annotation(const decode::Row &row);
|
||||
uint64_t get_min_annotation(const decode::Row &row); // except instant(end=start) annotation
|
||||
|
||||
@@ -137,14 +141,13 @@ public:
|
||||
|
||||
bool out_of_memory() const;
|
||||
|
||||
void set_mark_index(int64_t index);
|
||||
int64_t get_mark_index() const;
|
||||
|
||||
private:
|
||||
boost::optional<uint64_t> wait_for_data() const;
|
||||
|
||||
// void decode_data(const uint64_t sample_count,
|
||||
// const unsigned int unit_size, srd_session *const session);
|
||||
|
||||
void decode_data(const uint64_t decode_start, const uint64_t decode_end,
|
||||
const unsigned int unit_size, srd_session *const session);
|
||||
void decode_data(const uint64_t decode_start, const uint64_t decode_end, srd_session *const session);
|
||||
|
||||
void decode_proc();
|
||||
|
||||
@@ -199,6 +202,8 @@ private:
|
||||
bool _options_changed;
|
||||
bool _no_memory;
|
||||
|
||||
int64_t _mark_index;
|
||||
|
||||
friend class DecoderStackTest::TwoDecoderStack;
|
||||
};
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ void DsoSnapshot::init()
|
||||
_memory_failed = false;
|
||||
_last_ended = true;
|
||||
_envelope_done = false;
|
||||
_ch_enable.clear();
|
||||
for (unsigned int i = 0; i < _channel_num; i++) {
|
||||
for (unsigned int level = 0; level < ScaleStepCount; level++) {
|
||||
_envelope_levels[i][level].length = 0;
|
||||
@@ -96,15 +97,29 @@ void DsoSnapshot::clear()
|
||||
init();
|
||||
}
|
||||
|
||||
void DsoSnapshot::first_payload(const sr_datafeed_dso &dso, uint64_t total_sample_count, unsigned int channel_num, bool instant)
|
||||
void DsoSnapshot::first_payload(const sr_datafeed_dso &dso, uint64_t total_sample_count,
|
||||
std::map<int, bool> ch_enable, bool instant)
|
||||
{
|
||||
bool re_alloc = false;
|
||||
unsigned int channel_num = 0;
|
||||
for (auto& iter:ch_enable) {
|
||||
if (iter.second)
|
||||
channel_num++;
|
||||
}
|
||||
assert(channel_num != 0);
|
||||
|
||||
if (total_sample_count != _total_sample_count ||
|
||||
channel_num != _channel_num)
|
||||
re_alloc = true;
|
||||
|
||||
_total_sample_count = total_sample_count;
|
||||
_channel_num = channel_num;
|
||||
_instant = instant;
|
||||
_ch_enable = ch_enable;
|
||||
|
||||
bool isOk = true;
|
||||
uint64_t size = _total_sample_count * _unit_size + sizeof(uint64_t);
|
||||
if (size != _capacity) {
|
||||
uint64_t size = _total_sample_count * _channel_num + sizeof(uint64_t);
|
||||
if (re_alloc || size != _capacity) {
|
||||
free_data();
|
||||
_data = malloc(size);
|
||||
if (_data) {
|
||||
@@ -137,7 +152,6 @@ void DsoSnapshot::first_payload(const sr_datafeed_dso &dso, uint64_t total_sampl
|
||||
} else {
|
||||
free_data();
|
||||
free_envelop();
|
||||
_capacity = 0;
|
||||
_memory_failed = true;
|
||||
}
|
||||
}
|
||||
@@ -147,7 +161,7 @@ void DsoSnapshot::append_payload(const sr_datafeed_dso &dso)
|
||||
boost::lock_guard<boost::recursive_mutex> lock(_mutex);
|
||||
|
||||
if (_channel_num > 0 && dso.num_samples != 0) {
|
||||
refill_data(dso.data, dso.num_samples, _instant);
|
||||
append_data(dso.data, dso.num_samples, _instant);
|
||||
|
||||
// Generate the first mip-map from the data
|
||||
if (_envelope_en)
|
||||
@@ -155,6 +169,18 @@ void DsoSnapshot::append_payload(const sr_datafeed_dso &dso)
|
||||
}
|
||||
}
|
||||
|
||||
void DsoSnapshot::append_data(void *data, uint64_t samples, bool instant)
|
||||
{
|
||||
if (instant) {
|
||||
memcpy((uint8_t*)_data + _sample_count * _channel_num, data, samples*_channel_num);
|
||||
_sample_count = (_sample_count + samples) % (_total_sample_count + 1);
|
||||
} else {
|
||||
memcpy((uint8_t*)_data, data, samples*_channel_num);
|
||||
_sample_count = samples;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DsoSnapshot::enable_envelope(bool enable)
|
||||
{
|
||||
boost::lock_guard<boost::recursive_mutex> lock(_mutex);
|
||||
@@ -382,5 +408,13 @@ double DsoSnapshot::cal_vmean(int index) const
|
||||
return vmean;
|
||||
}
|
||||
|
||||
bool DsoSnapshot::has_data(int index)
|
||||
{
|
||||
if (_ch_enable.find(index) != _ch_enable.end())
|
||||
return _ch_enable[index];
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace pv
|
||||
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
void clear();
|
||||
void init();
|
||||
|
||||
void first_payload(const sr_datafeed_dso &dso, uint64_t total_sample_count, unsigned int channel_num, bool instant);
|
||||
void first_payload(const sr_datafeed_dso &dso, uint64_t total_sample_count, std::map<int, bool> ch_enable, bool instant);
|
||||
|
||||
void append_payload(const sr_datafeed_dso &dso);
|
||||
|
||||
@@ -92,7 +92,10 @@ public:
|
||||
double cal_vrms(double zero_off, int index) const;
|
||||
double cal_vmean(int index) const;
|
||||
|
||||
bool has_data(int index);
|
||||
|
||||
private:
|
||||
void append_data(void *data, uint64_t samples, bool instant);
|
||||
void free_envelop();
|
||||
void reallocate_envelope(Envelope &l);
|
||||
void append_payload_to_envelope_levels(bool header);
|
||||
@@ -102,6 +105,7 @@ private:
|
||||
bool _envelope_en;
|
||||
bool _envelope_done;
|
||||
bool _instant;
|
||||
std::map<int, bool> _ch_enable;
|
||||
|
||||
friend class DsoSnapshotTest::Basic;
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,6 +26,8 @@
|
||||
|
||||
#include "snapshot.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -43,19 +45,30 @@ namespace data {
|
||||
class LogicSnapshot : public Snapshot
|
||||
{
|
||||
private:
|
||||
struct MipMapLevel
|
||||
{
|
||||
uint64_t length;
|
||||
uint64_t data_length;
|
||||
void *data;
|
||||
};
|
||||
static const int ScaleLevel = 4;
|
||||
static const int ScalePower = 6;
|
||||
static const uint64_t Scale = 1 << ScalePower;
|
||||
static const int ScaleSize = Scale / 8;
|
||||
static const int RootScalePower = ScalePower;
|
||||
static const uint64_t RootScale = 1 << RootScalePower;
|
||||
static const uint64_t LeafBlockSpace = (Scale + Scale*Scale +
|
||||
Scale*Scale*Scale + Scale*Scale*Scale*Scale) / 8;
|
||||
static const uint64_t LeafBlockSamples = 1 << ScaleLevel*ScalePower;
|
||||
static const uint64_t LeafBlockPower = ScaleLevel*ScalePower;
|
||||
static const uint64_t RootNodeSamples = LeafBlockSamples*RootScale;
|
||||
|
||||
static const uint64_t RootMask = ~(~0ULL << RootScalePower) << ScaleLevel*ScalePower;
|
||||
static const uint64_t LeafMask = ~(~0ULL << ScaleLevel*ScalePower);
|
||||
static const uint64_t LevelMask[ScaleLevel];
|
||||
static const uint64_t LevelOffset[ScaleLevel];
|
||||
|
||||
private:
|
||||
static const unsigned int ScaleStepCount = 10;
|
||||
static const int MipMapScalePower;
|
||||
static const int MipMapScaleFactor;
|
||||
static const float LogMipMapScaleFactor;
|
||||
static const uint64_t MipMapDataUnit;
|
||||
struct RootNode
|
||||
{
|
||||
uint64_t tog;
|
||||
uint64_t value;
|
||||
void *lbp[Scale];
|
||||
};
|
||||
|
||||
public:
|
||||
typedef std::pair<uint64_t, bool> EdgePair;
|
||||
@@ -64,50 +77,116 @@ public:
|
||||
LogicSnapshot();
|
||||
|
||||
virtual ~LogicSnapshot();
|
||||
|
||||
void free_data();
|
||||
void clear();
|
||||
void init();
|
||||
|
||||
void first_payload(const sr_datafeed_logic &logic, uint64_t total_sample_count, unsigned int channel_num);
|
||||
void first_payload(const sr_datafeed_logic &logic, uint64_t total_sample_count, GSList *channels);
|
||||
|
||||
void append_payload(const sr_datafeed_logic &logic);
|
||||
|
||||
uint8_t * get_samples(int64_t start_sample, int64_t end_sample) const;
|
||||
const uint8_t * get_samples(uint64_t start_sample, uint64_t& end_sample, int sig_index);
|
||||
|
||||
private:
|
||||
void free_mipmap();
|
||||
void reallocate_mipmap_level(MipMapLevel &m);
|
||||
void append_payload_to_mipmap();
|
||||
bool get_sample(uint64_t index, int sig_index);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Parses a logic data snapshot to generate a list of transitions
|
||||
* in a time interval to a given level of detail.
|
||||
* @param[out] edges The vector to place the edges into.
|
||||
* @param[in] start The start sample index.
|
||||
* @param[in] end The end sample index.
|
||||
* @param[in] min_length The minimum number of samples that
|
||||
* can be resolved at this level of detail.
|
||||
* @param[in] sig_index The index of the signal.
|
||||
**/
|
||||
void get_subsampled_edges(std::vector<EdgePair> &edges,
|
||||
uint64_t start, uint64_t end,
|
||||
float min_length, int sig_index);
|
||||
void capture_ended();
|
||||
|
||||
bool get_display_edges(std::vector<std::pair<bool, bool>> &edges,
|
||||
std::vector<std::pair<uint16_t, bool>> &togs,
|
||||
uint64_t start, uint64_t end, uint16_t width,
|
||||
uint16_t max_togs, double pixels_offset,
|
||||
double min_length, uint16_t sig_index);
|
||||
|
||||
bool get_nxt_edge(uint64_t &index, bool last_sample, uint64_t end,
|
||||
float min_length, int sig_index);
|
||||
double min_length, int sig_index);
|
||||
|
||||
bool get_pre_edge(uint64_t &index, bool last_sample,
|
||||
float min_length, int sig_index);
|
||||
double min_length, int sig_index);
|
||||
|
||||
bool has_data(int sig_index);
|
||||
int get_block_num();
|
||||
uint64_t get_block_size(int block_index);
|
||||
uint8_t *get_block_buf(int block_index, int sig_index, bool &sample);
|
||||
|
||||
bool pattern_search(int64_t start, int64_t end, bool nxt, int64_t& index,
|
||||
std::map<uint16_t, QString> pattern);
|
||||
|
||||
private:
|
||||
uint64_t get_subsample(int level, uint64_t offset) const;
|
||||
int get_ch_order(int sig_index);
|
||||
void calc_mipmap(unsigned int order, uint8_t index0, uint8_t index1, uint64_t samples);
|
||||
|
||||
static uint64_t pow2_ceil(uint64_t x, unsigned int power);
|
||||
void append_cross_payload(const sr_datafeed_logic &logic);
|
||||
void append_split_payload(const sr_datafeed_logic &logic);
|
||||
|
||||
bool block_nxt_edge(uint64_t *lbp, uint64_t &index, uint64_t block_end, bool last_sample,
|
||||
unsigned int min_level);
|
||||
|
||||
bool block_pre_edge(uint64_t *lbp, uint64_t &index, bool last_sample,
|
||||
unsigned int min_level, int sig_index);
|
||||
|
||||
inline uint64_t bsf_folded (uint64_t bb)
|
||||
{
|
||||
static const int lsb_64_table[64] = {
|
||||
63, 30, 3, 32, 59, 14, 11, 33,
|
||||
60, 24, 50, 9, 55, 19, 21, 34,
|
||||
61, 29, 2, 53, 51, 23, 41, 18,
|
||||
56, 28, 1, 43, 46, 27, 0, 35,
|
||||
62, 31, 58, 4, 5, 49, 54, 6,
|
||||
15, 52, 12, 40, 7, 42, 45, 16,
|
||||
25, 57, 48, 13, 10, 39, 8, 44,
|
||||
20, 47, 38, 22, 17, 37, 36, 26
|
||||
};
|
||||
unsigned int folded;
|
||||
bb ^= bb - 1;
|
||||
folded = (int) bb ^ (bb >> 32);
|
||||
return lsb_64_table[folded * 0x78291ACF >> 26];
|
||||
}
|
||||
|
||||
inline int bsr32(uint32_t bb)
|
||||
{
|
||||
static const char msb_256_table[256] = {
|
||||
0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 4, 4, 4, 4,4, 4, 4, 4,4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
|
||||
};
|
||||
int result = 0;
|
||||
|
||||
if (bb > 0xFFFF) {
|
||||
bb >>= 16;
|
||||
result += 16;
|
||||
}
|
||||
if (bb > 0xFF) {
|
||||
bb >>= 8;
|
||||
result += 8;
|
||||
}
|
||||
|
||||
return (result + msb_256_table[bb]);
|
||||
}
|
||||
|
||||
inline uint64_t bsr64(uint64_t bb)
|
||||
{
|
||||
const uint32_t hb = bb >> 32;
|
||||
return hb ? 32 + bsr32((uint32_t)hb) : bsr32((uint32_t)bb);
|
||||
}
|
||||
|
||||
private:
|
||||
struct MipMapLevel _mip_map[ScaleStepCount];
|
||||
uint64_t _last_append_sample;
|
||||
std::vector<std::vector<struct RootNode>> _ch_data;
|
||||
uint64_t _block_num;
|
||||
uint8_t _byte_fraction;
|
||||
uint16_t _ch_fraction;
|
||||
void *_src_ptr;
|
||||
void *_dest_ptr;
|
||||
|
||||
std::vector<uint64_t> _sample_cnt;
|
||||
std::vector<uint64_t> _block_cnt;
|
||||
std::vector<uint64_t> _ring_sample_cnt;
|
||||
std::vector<uint64_t> _last_sample;
|
||||
|
||||
friend class LogicSnapshotTest::Pow2;
|
||||
friend class LogicSnapshotTest::Basic;
|
||||
|
||||
@@ -193,14 +193,13 @@ void MathStack::calc_fft()
|
||||
if (_snapshot->get_sample_count() < _sample_num*_sample_interval)
|
||||
return;
|
||||
|
||||
// Get the samplerate and start time
|
||||
_start_time = data->get_start_time();
|
||||
// Get the samplerate
|
||||
_samplerate = data->samplerate();
|
||||
if (_samplerate == 0.0)
|
||||
_samplerate = 1.0;
|
||||
|
||||
// prepare _xn data
|
||||
const double offset = dsoSig->get_zero_value();
|
||||
const double offset = dsoSig->get_hw_offset();
|
||||
const double vscale = dsoSig->get_vDialValue() * dsoSig->get_factor() * DS_CONF_DSO_VDIVS / (1000*255.0);
|
||||
const uint16_t step = _snapshot->get_channel_num() * _sample_interval;
|
||||
const uint8_t *const samples = _snapshot->get_samples(0, _sample_num*_sample_interval-1, _index);
|
||||
|
||||
@@ -28,8 +28,7 @@ namespace pv {
|
||||
namespace data {
|
||||
|
||||
SignalData::SignalData() :
|
||||
_samplerate(0),
|
||||
_start_time(0)
|
||||
_samplerate(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -44,10 +43,5 @@ void SignalData::set_samplerate(double samplerate)
|
||||
_samplerate = samplerate;
|
||||
}
|
||||
|
||||
double SignalData::get_start_time() const
|
||||
{
|
||||
return _start_time;
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace pv
|
||||
|
||||
@@ -42,11 +42,8 @@ public:
|
||||
|
||||
virtual void init() = 0;
|
||||
|
||||
double get_start_time() const;
|
||||
|
||||
protected:
|
||||
double _samplerate;
|
||||
double _start_time;
|
||||
};
|
||||
|
||||
} // namespace data
|
||||
|
||||
@@ -59,7 +59,9 @@ void Snapshot::free_data()
|
||||
free(_data);
|
||||
_data = NULL;
|
||||
_capacity = 0;
|
||||
_sample_count = 0;
|
||||
}
|
||||
_ch_index.clear();
|
||||
}
|
||||
|
||||
bool Snapshot::memory_failed() const
|
||||
@@ -69,7 +71,7 @@ bool Snapshot::memory_failed() const
|
||||
|
||||
bool Snapshot::empty() const
|
||||
{
|
||||
if (get_sample_count() == 0 || _memory_failed || !_data)
|
||||
if (get_sample_count() == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
@@ -106,46 +108,9 @@ unsigned int Snapshot::get_channel_num() const
|
||||
return _channel_num;
|
||||
}
|
||||
|
||||
uint64_t Snapshot::get_sample(uint64_t index) const
|
||||
void Snapshot::capture_ended()
|
||||
{
|
||||
assert(_data);
|
||||
assert(index < get_sample_count());
|
||||
|
||||
return *(uint64_t*)((uint8_t*)_data + index * _unit_size);
|
||||
}
|
||||
|
||||
void Snapshot::append_data(void *data, uint64_t samples)
|
||||
{
|
||||
// _data = realloc(_data, (_sample_count + samples) * _unit_size +
|
||||
// sizeof(uint64_t));
|
||||
if (_sample_count + samples < _total_sample_count)
|
||||
_sample_count += samples;
|
||||
else
|
||||
_sample_count = _total_sample_count;
|
||||
|
||||
if (_ring_sample_count + samples > _total_sample_count) {
|
||||
memcpy((uint8_t*)_data + _ring_sample_count * _unit_size,
|
||||
data, (_total_sample_count - _ring_sample_count) * _unit_size);
|
||||
_ring_sample_count = (samples + _ring_sample_count - _total_sample_count) % _total_sample_count;
|
||||
memcpy((uint8_t*)_data,
|
||||
data, _ring_sample_count * _unit_size);
|
||||
} else {
|
||||
memcpy((uint8_t*)_data + _ring_sample_count * _unit_size,
|
||||
data, samples * _unit_size);
|
||||
_ring_sample_count += samples;
|
||||
}
|
||||
}
|
||||
|
||||
void Snapshot::refill_data(void *data, uint64_t samples, bool instant)
|
||||
{
|
||||
if (instant) {
|
||||
memcpy((uint8_t*)_data + _sample_count * _channel_num, data, samples*_channel_num);
|
||||
_sample_count = (_sample_count + samples) % (_total_sample_count + 1);
|
||||
} else {
|
||||
memcpy((uint8_t*)_data, data, samples*_channel_num);
|
||||
_sample_count = samples;
|
||||
}
|
||||
|
||||
set_last_ended(true);
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
|
||||
@@ -55,17 +55,18 @@ public:
|
||||
|
||||
unsigned int get_channel_num() const;
|
||||
|
||||
uint64_t get_sample(uint64_t index) const;
|
||||
virtual void capture_ended();
|
||||
|
||||
protected:
|
||||
void append_data(void *data, uint64_t samples);
|
||||
void refill_data(void *data, uint64_t samples, bool instant);
|
||||
void free_data();
|
||||
virtual void free_data();
|
||||
|
||||
protected:
|
||||
mutable boost::recursive_mutex _mutex;
|
||||
|
||||
//std::vector<uint8_t> _data;
|
||||
void* _data;
|
||||
std::vector<uint16_t> _ch_index;
|
||||
|
||||
uint64_t _capacity;
|
||||
unsigned int _channel_num;
|
||||
uint64_t _sample_count;
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace pv {
|
||||
namespace device {
|
||||
|
||||
Device::Device(sr_dev_inst *sdi) :
|
||||
_sdi(sdi)
|
||||
_sdi(sdi)
|
||||
{
|
||||
assert(_sdi);
|
||||
}
|
||||
@@ -50,6 +50,7 @@ void Device::use(SigSession *owner) throw(QString)
|
||||
|
||||
assert(_sdi);
|
||||
sr_dev_open(_sdi);
|
||||
_usable = (_sdi->status == SR_ST_ACTIVE);
|
||||
if (sr_session_dev_add(_sdi) != SR_OK)
|
||||
throw QString(tr("Failed to use device."));
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ public:
|
||||
|
||||
sr_dev_inst* dev_inst() const;
|
||||
|
||||
void use(SigSession *owner) throw(QString);
|
||||
void use(SigSession *owner) throw(QString);
|
||||
|
||||
void release();
|
||||
|
||||
|
||||
@@ -33,7 +33,8 @@ namespace pv {
|
||||
namespace device {
|
||||
|
||||
DevInst::DevInst() :
|
||||
_owner(NULL)
|
||||
_owner(NULL),
|
||||
_usable(true)
|
||||
{
|
||||
_id = malloc(1);
|
||||
}
|
||||
@@ -206,5 +207,10 @@ void DevInst::run()
|
||||
sr_session_run();
|
||||
}
|
||||
|
||||
bool DevInst::is_usable() const
|
||||
{
|
||||
return _usable;
|
||||
}
|
||||
|
||||
} // device
|
||||
} // pv
|
||||
|
||||
@@ -118,6 +118,8 @@ public:
|
||||
|
||||
virtual bool is_trigger_enabled() const;
|
||||
|
||||
bool is_usable() const;
|
||||
|
||||
public:
|
||||
virtual void start();
|
||||
|
||||
@@ -132,6 +134,7 @@ signals:
|
||||
protected:
|
||||
SigSession *_owner;
|
||||
void *_id;
|
||||
bool _usable;
|
||||
};
|
||||
|
||||
} // device
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
#include <zip.h>
|
||||
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
#include <libsigrok4DSL/libsigrok.h>
|
||||
@@ -63,7 +65,35 @@ File* File::create(QString name)
|
||||
}
|
||||
}
|
||||
|
||||
return new InputFile(name);
|
||||
return new InputFile(name);
|
||||
}
|
||||
|
||||
QJsonArray File::get_decoders()
|
||||
{
|
||||
struct zip *archive;
|
||||
struct zip_file *zf;
|
||||
struct zip_stat zs;
|
||||
int ret;
|
||||
char *dec_file;
|
||||
QJsonArray dec_array;
|
||||
QJsonParseError error;
|
||||
|
||||
if (archive = zip_open(_path.toLocal8Bit().data(), 0, &ret)) {
|
||||
/* read "decoders" */
|
||||
if (zip_stat(archive, "decoders", 0, &zs) != -1) {
|
||||
if (dec_file = (char *)g_try_malloc(zs.size)) {
|
||||
zf = zip_fopen_index(archive, zs.index, 0);
|
||||
zip_fread(zf, dec_file, zs.size);
|
||||
zip_fclose(zf);
|
||||
|
||||
//QString sessionData = QString::fromUtf8(dec_file);
|
||||
QJsonDocument sessionDoc = QJsonDocument::fromJson(QByteArray::fromRawData(dec_file, zs.size), &error);
|
||||
dec_array = sessionDoc.array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return dec_array;
|
||||
}
|
||||
|
||||
} // device
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include "devinst.h"
|
||||
|
||||
namespace pv {
|
||||
@@ -37,6 +40,8 @@ protected:
|
||||
public:
|
||||
static File* create(QString name);
|
||||
|
||||
QJsonArray get_decoders();
|
||||
|
||||
public:
|
||||
QString format_device_title() const;
|
||||
|
||||
|
||||
@@ -50,13 +50,18 @@ void InputFile::use(SigSession *owner) throw(QString)
|
||||
{
|
||||
assert(!_input);
|
||||
|
||||
_input = load_input_file_format(_path, NULL);
|
||||
File::use(owner);
|
||||
// only *.dsl file is valid
|
||||
// don't allow other types of file input
|
||||
throw tr("Not a valid DSView data file.");
|
||||
return;
|
||||
|
||||
sr_session_new();
|
||||
// _input = load_input_file_format(_path, NULL);
|
||||
// File::use(owner);
|
||||
|
||||
if (sr_session_dev_add(_input->sdi) != SR_OK)
|
||||
throw tr("Failed to add session device.");
|
||||
// sr_session_new();
|
||||
|
||||
// if (sr_session_dev_add(_input->sdi) != SR_OK)
|
||||
// throw tr("Failed to add session device.");
|
||||
}
|
||||
|
||||
void InputFile::release()
|
||||
@@ -78,7 +83,7 @@ sr_input_format* InputFile::determine_input_file_format(const QString filename)
|
||||
/* If there are no input formats, return NULL right away. */
|
||||
sr_input_format *const *const inputs = sr_input_list();
|
||||
if (!inputs) {
|
||||
g_critical("No supported input formats available.");
|
||||
g_critical("No supported input formats available.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -90,7 +95,7 @@ sr_input_format* InputFile::determine_input_file_format(const QString filename)
|
||||
|
||||
/* Return NULL if no input module wanted to touch this. */
|
||||
if (!inputs[i]) {
|
||||
g_critical("Error: no matching input module found.");
|
||||
g_critical("Error: no matching input module found.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "sessionfile.h"
|
||||
|
||||
#include <libsigrok4DSL//libsigrok.h>
|
||||
#include <libsigrok4DSL/libsigrok.h>
|
||||
|
||||
namespace pv {
|
||||
namespace device {
|
||||
|
||||
@@ -45,6 +45,10 @@ const QString Calibration::VOFF = QT_TR_NOOP(" VOFF");
|
||||
Calibration::Calibration(QWidget *parent) :
|
||||
DSDialog(parent)
|
||||
{
|
||||
#ifdef Q_OS_OSX
|
||||
Qt::WindowFlags flags = windowFlags();
|
||||
this->setWindowFlags(flags | Qt::Tool);
|
||||
#endif
|
||||
this->setFixedSize(400, 250);
|
||||
this->setWindowOpacity(0.7);
|
||||
this->setModal(false);
|
||||
@@ -125,7 +129,7 @@ void Calibration::set_device(boost::shared_ptr<device::DevInst> dev_inst)
|
||||
gain_slider->setRange(-vgain_range/2, vgain_range/2);
|
||||
gain_slider->setValue(vgain - vgain_default);
|
||||
gain_slider->setObjectName(VGAIN+probe->index);
|
||||
QString gain_string = "Channel" + QString::number(probe->index) + VGAIN;
|
||||
QString gain_string = tr("Channel") + QString::number(probe->index) + VGAIN;
|
||||
QLabel *gain_label = new QLabel(gain_string, this);
|
||||
_flayout->addRow(gain_label, gain_slider);
|
||||
_slider_list.push_back(gain_slider);
|
||||
@@ -147,7 +151,7 @@ void Calibration::set_device(boost::shared_ptr<device::DevInst> dev_inst)
|
||||
off_slider->setRange(0, voff_range);
|
||||
off_slider->setValue(voff);
|
||||
off_slider->setObjectName(VOFF+probe->index);
|
||||
QString off_string = "Channel" + QString::number(probe->index) + VOFF;
|
||||
QString off_string = tr("Channel") + QString::number(probe->index) + VOFF;
|
||||
QLabel *off_label = new QLabel(off_string, this);
|
||||
_flayout->addRow(off_label, off_slider);
|
||||
_slider_list.push_back(off_slider);
|
||||
@@ -213,7 +217,8 @@ void Calibration::on_save()
|
||||
QProgressDialog dlg(tr("Save Calibration Result... It can take a while."),
|
||||
tr("Cancel"),0,0,this,flags);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
dlg.setCancelButton(NULL);
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
@@ -239,7 +244,8 @@ void Calibration::on_reset()
|
||||
QProgressDialog dlg(tr("Reset Calibration Result... It can take a while."),
|
||||
tr("Cancel"),0,0,this,flags);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
dlg.setCancelButton(NULL);
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
|
||||
@@ -54,7 +54,7 @@ DeviceOptions::DeviceOptions(QWidget *parent, boost::shared_ptr<pv::device::DevI
|
||||
_probes_box->setLayout(&_probes_box_layout);
|
||||
_layout.addWidget(_probes_box);
|
||||
} else if (_dev_inst->name().contains("DSCope")){
|
||||
_config_button = new QPushButton(tr("Zero Adjustment"), this);
|
||||
_config_button = new QPushButton(tr("Auto Calibration"), this);
|
||||
_layout.addWidget(_config_button);
|
||||
connect(_config_button, SIGNAL(clicked()), this, SLOT(zero_adj()));
|
||||
|
||||
@@ -86,8 +86,7 @@ DeviceOptions::DeviceOptions(QWidget *parent, boost::shared_ptr<pv::device::DevI
|
||||
void DeviceOptions::accept()
|
||||
{
|
||||
using namespace Qt;
|
||||
|
||||
QDialog::accept();
|
||||
bool hasEnabled = false;
|
||||
|
||||
// Commit the properties
|
||||
const vector< boost::shared_ptr<pv::prop::Property> > &properties =
|
||||
@@ -103,10 +102,24 @@ void DeviceOptions::accept()
|
||||
for (const GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) {
|
||||
sr_channel *const probe = (sr_channel*)l->data;
|
||||
assert(probe);
|
||||
|
||||
probe->enabled = (_probes_checkBox_list.at(index)->checkState() == Qt::Checked);
|
||||
index++;
|
||||
if (probe->enabled)
|
||||
hasEnabled = true;
|
||||
}
|
||||
} else {
|
||||
hasEnabled = true;
|
||||
}
|
||||
|
||||
if (hasEnabled) {
|
||||
QDialog::accept();
|
||||
} else {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Attention"));
|
||||
msg.mBox()->setInformativeText(tr("All channel disabled! Please enable at least one channel."));
|
||||
msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +160,8 @@ void DeviceOptions::setup_probes()
|
||||
int row0 = 0, row1 = 0, col = 0;
|
||||
int index = 0;
|
||||
QString ch_mode;
|
||||
int vld_ch_num = 0;
|
||||
int cur_ch_num = 0;
|
||||
|
||||
while(_probes_box_layout.count() > 0)
|
||||
{
|
||||
@@ -182,10 +197,22 @@ void DeviceOptions::setup_probes()
|
||||
}
|
||||
}
|
||||
|
||||
GVariant *gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_VLD_CH_NUM);
|
||||
if (gvar != NULL) {
|
||||
vld_ch_num = g_variant_get_int16(gvar);
|
||||
g_variant_unref(gvar);
|
||||
}
|
||||
|
||||
for (const GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) {
|
||||
sr_channel *const probe = (sr_channel*)l->data;
|
||||
assert(probe);
|
||||
|
||||
if (probe->enabled)
|
||||
cur_ch_num++;
|
||||
|
||||
if (cur_ch_num > vld_ch_num)
|
||||
probe->enabled = false;
|
||||
|
||||
QLabel *probe_label = new QLabel(QString::number(probe->index), this);
|
||||
QCheckBox *probe_checkBox = new QCheckBox(this);
|
||||
probe_checkBox->setCheckState(probe->enabled ? Qt::Checked : Qt::Unchecked);
|
||||
@@ -197,6 +224,8 @@ void DeviceOptions::setup_probes()
|
||||
index++;
|
||||
col = index % 8;
|
||||
row1 = index / 8;
|
||||
|
||||
connect(probe_checkBox, SIGNAL(released()), this, SLOT(channel_enable()));
|
||||
}
|
||||
|
||||
QPushButton *_enable_all_probes = new QPushButton(tr("Enable All"), this);
|
||||
@@ -220,8 +249,45 @@ void DeviceOptions::set_all_probes(bool set)
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceOptions::enable_max_probes() {
|
||||
int cur_ch_num = 0;
|
||||
QVector<QCheckBox *>::iterator iter = _probes_checkBox_list.begin();
|
||||
while(iter != _probes_checkBox_list.end()) {
|
||||
if ((*iter)->isChecked())
|
||||
cur_ch_num++;
|
||||
iter++;
|
||||
}
|
||||
|
||||
GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_VLD_CH_NUM);
|
||||
if (gvar == NULL)
|
||||
return;
|
||||
|
||||
int vld_ch_num = g_variant_get_int16(gvar);
|
||||
g_variant_unref(gvar);
|
||||
iter = _probes_checkBox_list.begin();
|
||||
while(cur_ch_num < vld_ch_num &&
|
||||
iter != _probes_checkBox_list.end()) {
|
||||
if (!(*iter)->isChecked()) {
|
||||
(*iter)->setChecked(true);
|
||||
cur_ch_num++;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
|
||||
void DeviceOptions::enable_all_probes()
|
||||
{
|
||||
GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_STREAM);
|
||||
if (gvar != NULL) {
|
||||
bool stream_mode = g_variant_get_boolean(gvar);
|
||||
g_variant_unref(gvar);
|
||||
|
||||
if (stream_mode) {
|
||||
enable_max_probes();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
set_all_probes(true);
|
||||
}
|
||||
|
||||
@@ -237,7 +303,7 @@ void DeviceOptions::zero_adj()
|
||||
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Information"));
|
||||
msg.mBox()->setInformativeText(tr("Zero adjustment program will be started. Please keep all channels out of singal input. It can take a while!"));
|
||||
msg.mBox()->setInformativeText(tr("Auto Calibration program will be started. Please keep all channels out of singal input. It can take a while!"));
|
||||
//msg.mBox()->setStandardButtons(QMessageBox::);
|
||||
msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole);
|
||||
msg.mBox()->addButton(tr("Cancel"), QMessageBox::RejectRole);
|
||||
@@ -293,5 +359,47 @@ void DeviceOptions::channel_check()
|
||||
setup_probes();
|
||||
}
|
||||
|
||||
void DeviceOptions::channel_enable()
|
||||
{
|
||||
QCheckBox* sc=dynamic_cast<QCheckBox*>(sender());
|
||||
if (sc == NULL || !sc->isChecked())
|
||||
return;
|
||||
|
||||
GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_STREAM);
|
||||
if (gvar == NULL)
|
||||
return;
|
||||
|
||||
bool stream_mode = g_variant_get_boolean(gvar);
|
||||
g_variant_unref(gvar);
|
||||
|
||||
if (!stream_mode)
|
||||
return;
|
||||
|
||||
int cur_ch_num = 0;
|
||||
QVector<QCheckBox *>::iterator i = _probes_checkBox_list.begin();
|
||||
while(i != _probes_checkBox_list.end()) {
|
||||
if ((*i)->isChecked())
|
||||
cur_ch_num++;
|
||||
i++;
|
||||
}
|
||||
|
||||
gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_VLD_CH_NUM);
|
||||
if (gvar == NULL)
|
||||
return;
|
||||
|
||||
int vld_ch_num = g_variant_get_int16(gvar);
|
||||
g_variant_unref(gvar);
|
||||
if (cur_ch_num > vld_ch_num) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Information"));
|
||||
msg.mBox()->setInformativeText(tr("Current mode only suppport max ") + QString::number(vld_ch_num) + tr(" channels!"));
|
||||
msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole);
|
||||
msg.mBox()->setIcon(QMessageBox::Information);
|
||||
msg.exec();
|
||||
|
||||
sc->setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dialogs
|
||||
} // namespace pv
|
||||
|
||||
@@ -66,6 +66,7 @@ private:
|
||||
void setup_probes();
|
||||
|
||||
void set_all_probes(bool set);
|
||||
void enable_max_probes();
|
||||
|
||||
private slots:
|
||||
void enable_all_probes();
|
||||
@@ -74,6 +75,7 @@ private slots:
|
||||
void mode_check();
|
||||
void channel_check();
|
||||
void on_calibration();
|
||||
void channel_enable();
|
||||
|
||||
private:
|
||||
boost::shared_ptr<pv::device::DevInst> _dev_inst;
|
||||
|
||||
@@ -36,7 +36,8 @@ DSDialog::DSDialog(QWidget *parent, bool hasClose) :
|
||||
QDialog(parent),
|
||||
_moving(false)
|
||||
{
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
|
||||
build_main(hasClose);
|
||||
|
||||
@@ -36,7 +36,8 @@ DSMessageBox::DSMessageBox(QWidget *parent) :
|
||||
QDialog(parent),
|
||||
_moving(false)
|
||||
{
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog);
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
_main = new QWidget(this);
|
||||
QVBoxLayout *mlayout = new QVBoxLayout(_main);
|
||||
@@ -50,7 +51,8 @@ DSMessageBox::DSMessageBox(QWidget *parent) :
|
||||
_main->setGraphicsEffect(bodyShadow);
|
||||
|
||||
_msg = new QMessageBox(this);
|
||||
_msg->setWindowFlags(Qt::FramelessWindowHint | Qt::Widget);
|
||||
_msg->setWindowFlags(Qt::FramelessWindowHint | Qt::Widget | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
|
||||
_titlebar = new toolbars::TitleBar(false, this);
|
||||
_titlebar->setTitle(tr("Message"));
|
||||
|
||||
@@ -152,7 +152,7 @@ void ProtocolExp::accept()
|
||||
break;
|
||||
}
|
||||
}
|
||||
out << QString("%1;%2;%3\n")
|
||||
out << QString("%1,%2,%3\n")
|
||||
.arg("ID")
|
||||
.arg("Time[s]")
|
||||
.arg(title);
|
||||
@@ -180,7 +180,7 @@ void ProtocolExp::accept()
|
||||
0, decoder_stack->sample_count()-1);
|
||||
if (!annotations.empty()) {
|
||||
BOOST_FOREACH(const Annotation &a, annotations) {
|
||||
out << QString("%1;%2;%3\n")
|
||||
out << QString("%1,%2,%3\n")
|
||||
.arg(QString::number(exported))
|
||||
.arg(QString::number(a.start_sample()*time_pre_samples))
|
||||
.arg(a.annotations().at(0));
|
||||
@@ -195,7 +195,8 @@ void ProtocolExp::accept()
|
||||
QProgressDialog dlg(tr("Export Protocol List Result... It can take a while."),
|
||||
tr("Cancel"),0,100,this,flags);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel()));
|
||||
|
||||
@@ -47,6 +47,15 @@ ProtocolList::ProtocolList(QWidget *parent, SigSession &session) :
|
||||
{
|
||||
pv::data::DecoderModel* decoder_model = _session.get_decoder_model();
|
||||
|
||||
_map_zoom_combobox = new QComboBox(this);
|
||||
_map_zoom_combobox->addItem(tr("Fit to Window"));
|
||||
_map_zoom_combobox->addItem(tr("Fixed"));
|
||||
int cur_map_zoom = _session.get_map_zoom();
|
||||
if (cur_map_zoom >= _map_zoom_combobox->count())
|
||||
_map_zoom_combobox->setCurrentIndex(0);
|
||||
else
|
||||
_map_zoom_combobox->setCurrentIndex(cur_map_zoom);
|
||||
connect(_map_zoom_combobox, SIGNAL(currentIndexChanged(int)), &_session, SLOT(set_map_zoom(int)));
|
||||
|
||||
_protocol_combobox = new QComboBox(this);
|
||||
const std::vector< boost::shared_ptr<pv::view::DecodeTrace> > decode_sigs(
|
||||
@@ -67,6 +76,7 @@ ProtocolList::ProtocolList(QWidget *parent, SigSession &session) :
|
||||
_flayout->setFormAlignment(Qt::AlignLeft);
|
||||
_flayout->setLabelAlignment(Qt::AlignLeft);
|
||||
_flayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow);
|
||||
_flayout->addRow(new QLabel(tr("Map Zoom: "), this), _map_zoom_combobox);
|
||||
_flayout->addRow(new QLabel(tr("Decoded Protocols: "), this), _protocol_combobox);
|
||||
|
||||
_layout = new QVBoxLayout();
|
||||
@@ -185,6 +195,5 @@ void ProtocolList::on_row_check(bool show)
|
||||
|
||||
_session.get_decoder_model()->setDecoderStack(decoder_stack);
|
||||
}
|
||||
|
||||
} // namespace dialogs
|
||||
} // namespace pv
|
||||
|
||||
@@ -62,6 +62,7 @@ private:
|
||||
SigSession &_session;
|
||||
|
||||
toolbars::TitleBar *_titlebar;
|
||||
QComboBox *_map_zoom_combobox;
|
||||
QComboBox *_protocol_combobox;
|
||||
std::list<QCheckBox *> _show_checkbox_list;
|
||||
std::list<QLabel *> _show_label_list;
|
||||
|
||||
@@ -21,53 +21,73 @@
|
||||
|
||||
|
||||
#include "search.h"
|
||||
#include "../view/logicsignal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <QRegExpValidator>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
namespace pv {
|
||||
namespace dialogs {
|
||||
|
||||
Search::Search(QWidget *parent, boost::shared_ptr<device::DevInst> dev_inst, QString pattern) :
|
||||
Search::Search(QWidget *parent, SigSession &session, std::map<uint16_t, QString> pattern) :
|
||||
DSDialog(parent),
|
||||
_dev_inst(dev_inst)
|
||||
_session(session)
|
||||
{
|
||||
assert(_dev_inst);
|
||||
|
||||
QFont font("Monaco");
|
||||
font.setStyleHint(QFont::Monospace);
|
||||
font.setFixedPitch(true);
|
||||
//this->setMinimumWidth(350);
|
||||
|
||||
QRegExp value_rx("[10XRFCxrfc ]+");
|
||||
QRegExp value_rx("[10XRFCxrfc]+");
|
||||
QValidator *value_validator = new QRegExpValidator(value_rx, this);
|
||||
|
||||
|
||||
search_lineEdit.setText(pattern);
|
||||
search_lineEdit.setValidator(value_validator);
|
||||
search_lineEdit.setMaxLength(16 * 2 - 1);
|
||||
search_lineEdit.setInputMask("X X X X X X X X X X X X X X X X");
|
||||
search_lineEdit.setFont(font);
|
||||
|
||||
QLabel *search_label = new QLabel("1 1 1 1 1 1\n5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0");
|
||||
search_label->setFont(font);
|
||||
|
||||
search_buttonBox.addButton(QDialogButtonBox::Ok);
|
||||
search_buttonBox.addButton(QDialogButtonBox::Cancel);
|
||||
|
||||
QGridLayout *search_layout = new QGridLayout();
|
||||
search_layout->setVerticalSpacing(5);
|
||||
search_layout->addWidget(search_label, 1, 1);
|
||||
search_layout->addWidget(new QLabel(tr("Search Value: ")), 2,0, Qt::AlignRight);
|
||||
search_layout->addWidget(&search_lineEdit, 2, 1);
|
||||
search_layout->addWidget(new QLabel(" "), 3,0);
|
||||
search_layout->addWidget(new QLabel(tr("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge")), 4, 0);
|
||||
search_layout->addWidget(&search_buttonBox, 5, 2);
|
||||
search_layout->setVerticalSpacing(0);
|
||||
|
||||
int index = 0;
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::Signal> sig,
|
||||
_session.get_signals()) {
|
||||
assert(sig);
|
||||
boost::shared_ptr<view::LogicSignal> logic_sig;
|
||||
if (logic_sig = boost::dynamic_pointer_cast<view::LogicSignal>(sig)) {
|
||||
QLineEdit *search_lineEdit = new QLineEdit(this);
|
||||
if (pattern.find(index) != pattern.end())
|
||||
search_lineEdit->setText(pattern[index]);
|
||||
else
|
||||
search_lineEdit->setText("X");
|
||||
search_lineEdit->setValidator(value_validator);
|
||||
search_lineEdit->setMaxLength(1);
|
||||
search_lineEdit->setInputMask("X");
|
||||
search_lineEdit->setFont(font);
|
||||
_search_lineEdit_vec.push_back(search_lineEdit);
|
||||
|
||||
search_layout->addWidget(new QLabel(logic_sig->get_name()+":"), index, 0, Qt::AlignRight);
|
||||
search_layout->addWidget(new QLabel(QString::number(logic_sig->get_index())), index, 1, Qt::AlignRight);
|
||||
search_layout->addWidget(search_lineEdit, index, 2);
|
||||
|
||||
connect(search_lineEdit, SIGNAL(editingFinished()), this, SLOT(format()));
|
||||
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
search_layout->addWidget(new QLabel(" "), index,0);
|
||||
search_layout->addWidget(new QLabel(tr("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge")), 0, 3, index, 1);
|
||||
search_layout->addWidget(&search_buttonBox, index+1, 3);
|
||||
search_layout->setColumnStretch(3, 100);
|
||||
|
||||
layout()->addLayout(search_layout);
|
||||
setTitle(tr("Search Options"));
|
||||
|
||||
connect(&search_buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||
connect(&search_buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
connect(_dev_inst.get(), SIGNAL(device_updated()), this, SLOT(reject()));
|
||||
connect(_session.get_device().get(), SIGNAL(device_updated()), this, SLOT(reject()));
|
||||
}
|
||||
|
||||
Search::~Search()
|
||||
@@ -81,10 +101,27 @@ void Search::accept()
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
QString Search::get_pattern()
|
||||
void Search::format()
|
||||
{
|
||||
QString pattern = search_lineEdit.text();
|
||||
//pattern.remove(QChar('/r'), Qt::CaseInsensitive);
|
||||
QLineEdit *sc = qobject_cast<QLineEdit *>(sender());
|
||||
sc->setText(sc->text().toUpper());
|
||||
}
|
||||
|
||||
std::map<uint16_t, QString> Search::get_pattern()
|
||||
{
|
||||
std::map<uint16_t, QString> pattern;
|
||||
|
||||
int index = 0;
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::Signal> sig,
|
||||
_session.get_signals()) {
|
||||
assert(sig);
|
||||
boost::shared_ptr<view::LogicSignal> logic_sig;
|
||||
if (logic_sig = boost::dynamic_pointer_cast<view::LogicSignal>(sig)) {
|
||||
pattern[index] = _search_lineEdit_vec[index]->text();
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
return pattern;
|
||||
}
|
||||
|
||||
|
||||
@@ -45,23 +45,25 @@ class Search : public DSDialog
|
||||
|
||||
public:
|
||||
|
||||
Search(QWidget *parent = 0, boost::shared_ptr<pv::device::DevInst> dev_inst = 0, QString pattern = "");
|
||||
Search(QWidget *parent, SigSession &session, std::map<uint16_t, QString> pattern);
|
||||
~Search();
|
||||
|
||||
QString get_pattern();
|
||||
std::map<uint16_t, QString> get_pattern();
|
||||
|
||||
protected:
|
||||
void accept();
|
||||
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
private slots:
|
||||
void format();
|
||||
|
||||
private:
|
||||
SigSession &_session;
|
||||
|
||||
toolbars::TitleBar *_titlebar;
|
||||
QLineEdit search_lineEdit;
|
||||
QVector<QLineEdit *> _search_lineEdit_vec;
|
||||
QDialogButtonBox search_buttonBox;
|
||||
boost::shared_ptr<pv::device::DevInst> _dev_inst;
|
||||
};
|
||||
|
||||
} // namespace decoder
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* This file is part of the PulseView project.
|
||||
*
|
||||
* Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
* Copyright (C) 2016 DreamSourceLab <support@dreamsourcelab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -21,62 +22,113 @@
|
||||
#include "storeprogress.h"
|
||||
#include "dsmessagebox.h"
|
||||
|
||||
#include "QVBoxLayout"
|
||||
|
||||
namespace pv {
|
||||
namespace dialogs {
|
||||
|
||||
StoreProgress::StoreProgress(const QString &file_name,
|
||||
SigSession &session, QWidget *parent) :
|
||||
QProgressDialog(tr("Saving..."), tr("Cancel"), 0, 0, parent),
|
||||
_session(file_name.toStdString(), session)
|
||||
StoreProgress::StoreProgress(SigSession &session, QWidget *parent) :
|
||||
DSDialog(parent),
|
||||
_store_session(session),
|
||||
_button_box(QDialogButtonBox::Cancel, Qt::Horizontal, this),
|
||||
_done(false)
|
||||
{
|
||||
connect(&_session, SIGNAL(progress_updated()),
|
||||
this, SLOT(on_progress_updated()));
|
||||
this->setModal(true);
|
||||
|
||||
_info.setText("...");
|
||||
_progress.setValue(0);
|
||||
_progress.setMaximum(0);
|
||||
|
||||
QVBoxLayout* add_layout = new QVBoxLayout(this);
|
||||
add_layout->addWidget(&_info, 0, Qt::AlignCenter);
|
||||
add_layout->addWidget(&_progress);
|
||||
add_layout->addWidget(&_button_box);
|
||||
layout()->addLayout(add_layout);
|
||||
|
||||
connect(&_button_box, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
connect(&_store_session, SIGNAL(progress_updated()),
|
||||
this, SLOT(on_progress_updated()), Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
StoreProgress::~StoreProgress()
|
||||
{
|
||||
_session.wait();
|
||||
_store_session.wait();
|
||||
}
|
||||
|
||||
void StoreProgress::run()
|
||||
void StoreProgress::reject()
|
||||
{
|
||||
if (_session.start())
|
||||
show();
|
||||
else
|
||||
using namespace Qt;
|
||||
_store_session.cancel();
|
||||
QDialog::reject();
|
||||
}
|
||||
|
||||
void StoreProgress::timeout()
|
||||
{
|
||||
if (_done)
|
||||
close();
|
||||
else
|
||||
QTimer::singleShot(100, this, SLOT(timeout()));
|
||||
}
|
||||
|
||||
void StoreProgress::save_run()
|
||||
{
|
||||
_info.setText("Saving...");
|
||||
if (_store_session.save_start())
|
||||
show();
|
||||
else
|
||||
show_error();
|
||||
|
||||
QTimer::singleShot(100, this, SLOT(timeout()));
|
||||
}
|
||||
|
||||
void StoreProgress::export_run()
|
||||
{
|
||||
_info.setText("Exporting...");
|
||||
if (_store_session.export_start())
|
||||
show();
|
||||
else
|
||||
show_error();
|
||||
|
||||
QTimer::singleShot(100, this, SLOT(timeout()));
|
||||
}
|
||||
|
||||
void StoreProgress::show_error()
|
||||
{
|
||||
dialogs::DSMessageBox msg(parentWidget());
|
||||
msg.mBox()->setText(tr("Failed to save session."));
|
||||
msg.mBox()->setInformativeText(_session.error());
|
||||
msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
if (!_store_session.error().isEmpty()) {
|
||||
dialogs::DSMessageBox msg(parentWidget());
|
||||
msg.mBox()->setText(tr("Failed to save data."));
|
||||
msg.mBox()->setInformativeText(_store_session.error());
|
||||
msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
}
|
||||
}
|
||||
|
||||
void StoreProgress::closeEvent(QCloseEvent*)
|
||||
void StoreProgress::closeEvent(QCloseEvent* e)
|
||||
{
|
||||
_session.cancel();
|
||||
_store_session.cancel();
|
||||
DSDialog::closeEvent(e);
|
||||
}
|
||||
|
||||
void StoreProgress::on_progress_updated()
|
||||
{
|
||||
const std::pair<uint64_t, uint64_t> p = _session.progress();
|
||||
const std::pair<uint64_t, uint64_t> p = _store_session.progress();
|
||||
assert(p.first <= p.second);
|
||||
|
||||
setValue(p.first);
|
||||
setMaximum(p.second);
|
||||
_progress.setValue(p.first);
|
||||
_progress.setMaximum(p.second);
|
||||
|
||||
const QString err = _session.error();
|
||||
const QString err = _store_session.error();
|
||||
if (!err.isEmpty()) {
|
||||
show_error();
|
||||
close();
|
||||
//close();
|
||||
_done = true;
|
||||
}
|
||||
|
||||
if (p.first == p.second)
|
||||
close();
|
||||
if (p.first == p.second) {
|
||||
//close();
|
||||
_done = true;
|
||||
}
|
||||
}
|
||||
|
||||
} // dialogs
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* This file is part of the PulseView project.
|
||||
*
|
||||
* Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
* Copyright (C) 2016 DreamSourceLab <support@dreamsourcelab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -25,9 +26,13 @@
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <QProgressDialog>
|
||||
#include <QLabel>
|
||||
#include <QProgressBar>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QTimer>
|
||||
|
||||
#include <pv/storesession.h>
|
||||
#include "../storesession.h"
|
||||
#include "../dialogs/dsdialog.h"
|
||||
#include "../toolbars/titlebar.h"
|
||||
|
||||
namespace pv {
|
||||
@@ -36,30 +41,43 @@ class SigSession;
|
||||
|
||||
namespace dialogs {
|
||||
|
||||
class StoreProgress : public QProgressDialog
|
||||
class StoreProgress : public DSDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
StoreProgress(const QString &file_name, SigSession &session,
|
||||
StoreProgress(SigSession &session,
|
||||
QWidget *parent = 0);
|
||||
|
||||
virtual ~StoreProgress();
|
||||
|
||||
void run();
|
||||
|
||||
|
||||
protected:
|
||||
void reject();
|
||||
|
||||
private:
|
||||
void show_error();
|
||||
void closeEvent(QCloseEvent* e);
|
||||
|
||||
void closeEvent(QCloseEvent*);
|
||||
public slots:
|
||||
void save_run();
|
||||
void export_run();
|
||||
|
||||
private slots:
|
||||
void on_progress_updated();
|
||||
void timeout();
|
||||
|
||||
private:
|
||||
pv::StoreSession _session;
|
||||
pv::StoreSession _store_session;
|
||||
|
||||
QLabel _info;
|
||||
QProgressBar _progress;
|
||||
QDialogButtonBox _button_box;
|
||||
|
||||
toolbars::TitleBar *_titlebar;
|
||||
|
||||
bool _done;
|
||||
};
|
||||
|
||||
} // dialogs
|
||||
|
||||
@@ -79,7 +79,7 @@ WaitingDialog::WaitingDialog(QWidget *parent, boost::shared_ptr<pv::device::DevI
|
||||
mlayout->addWidget(&_button_box);
|
||||
|
||||
layout()->addLayout(mlayout);
|
||||
setTitle(tr("Zero Adjustment"));
|
||||
setTitle(tr("Auto Calibration"));
|
||||
}
|
||||
|
||||
void WaitingDialog::accept()
|
||||
@@ -100,7 +100,8 @@ void WaitingDialog::accept()
|
||||
QProgressDialog dlg(tr("Save Auto Zero Result... It can take a while."),
|
||||
tr("Cancel"),0,0,this,flags);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
dlg.setCancelButton(NULL);
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
@@ -130,7 +131,8 @@ void WaitingDialog::reject()
|
||||
QProgressDialog dlg(tr("Load Current Setting... It can take a while."),
|
||||
tr("Cancel"),0,0,this,flags);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
dlg.setCancelButton(NULL);
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
|
||||
@@ -34,14 +34,17 @@
|
||||
#include "../devicemanager.h"
|
||||
#include "../device/device.h"
|
||||
#include "../device/file.h"
|
||||
#include "../dialogs/dsdialog.h"
|
||||
#include "../dialogs/dsmessagebox.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QPainter>
|
||||
#include <QRegExpValidator>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "libsigrok4DSL/libsigrok.h"
|
||||
|
||||
using boost::shared_ptr;
|
||||
using namespace boost;
|
||||
|
||||
namespace pv {
|
||||
namespace dock {
|
||||
@@ -51,7 +54,11 @@ using namespace pv::view;
|
||||
MeasureDock::MeasureDock(QWidget *parent, View &view, SigSession &session) :
|
||||
QScrollArea(parent),
|
||||
_session(session),
|
||||
_view(view)
|
||||
_view(view),
|
||||
_icon_add(":/icons/add.png"),
|
||||
_icon_add_dis(":/icons/add_dis.png"),
|
||||
_icon_del(":/icons/del.png"),
|
||||
_icon_del_dis(":/icons/del_dis.png")
|
||||
{
|
||||
|
||||
_widget = new QWidget(this);
|
||||
@@ -67,76 +74,74 @@ MeasureDock::MeasureDock(QWidget *parent, View &view, SigSession &session) :
|
||||
|
||||
_mouse_layout = new QGridLayout();
|
||||
_mouse_layout->setVerticalSpacing(5);
|
||||
_mouse_layout->addWidget(_fen_checkBox, 0, 0, 1, 4);
|
||||
_mouse_layout->addWidget(_fen_checkBox, 0, 0, 1, 6);
|
||||
_mouse_layout->addWidget(new QLabel(tr("W: "), _widget), 1, 0);
|
||||
_mouse_layout->addWidget(_width_label, 1, 1);
|
||||
_mouse_layout->addWidget(new QLabel(tr("P: "), _widget), 1, 2);
|
||||
_mouse_layout->addWidget(_period_label, 1, 3);
|
||||
_mouse_layout->addWidget(new QLabel(tr("F: "), _widget), 2, 2);
|
||||
_mouse_layout->addWidget(_freq_label, 2, 3);
|
||||
_mouse_layout->addWidget(new QLabel(tr("P: "), _widget), 1, 4);
|
||||
_mouse_layout->addWidget(_period_label, 1, 5);
|
||||
_mouse_layout->addWidget(new QLabel(tr("F: "), _widget), 2, 4);
|
||||
_mouse_layout->addWidget(_freq_label, 2, 5);
|
||||
_mouse_layout->addWidget(new QLabel(tr("D: "), _widget), 2, 0);
|
||||
_mouse_layout->addWidget(_duty_label, 2, 1);
|
||||
_mouse_layout->addWidget(new QLabel(_widget), 0, 4);
|
||||
_mouse_layout->addWidget(new QLabel(_widget), 1, 4);
|
||||
_mouse_layout->addWidget(new QLabel(_widget), 2, 4);
|
||||
_mouse_layout->addWidget(new QLabel(_widget), 0, 6);
|
||||
_mouse_layout->addWidget(new QLabel(_widget), 1, 6);
|
||||
_mouse_layout->addWidget(new QLabel(_widget), 2, 6);
|
||||
_mouse_layout->setColumnStretch(5, 1);
|
||||
_mouse_groupBox->setLayout(_mouse_layout);
|
||||
|
||||
/* cursor distance group */
|
||||
_dist_groupBox = new QGroupBox(tr("Cursor Distance"), _widget);
|
||||
_dist_groupBox->setMinimumWidth(300);
|
||||
_dist_add_btn = new QToolButton(_widget);
|
||||
_dist_add_btn->setIcon(_icon_add);
|
||||
connect(_dist_add_btn, SIGNAL(clicked()), this, SLOT(add_dist_measure()));
|
||||
|
||||
_cursor_groupBox = new QGroupBox(tr("Cursor measurement"), _widget);
|
||||
_t1_comboBox = new QComboBox(_widget);
|
||||
_t2_comboBox = new QComboBox(_widget);
|
||||
_t3_comboBox = new QComboBox(_widget);
|
||||
_delta_label_t1t2 = new QLabel("##########/##########", _widget);
|
||||
_delta_label_t2t3 = new QLabel("##########/##########", _widget);
|
||||
_delta_label_t1t3 = new QLabel("##########/##########", _widget);
|
||||
_t1_last_index = 0;
|
||||
_t2_last_index = 0;
|
||||
_t3_last_index = 0;
|
||||
_t1_comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
_t2_comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
_t3_comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
|
||||
_dist_layout = new QGridLayout(_widget);
|
||||
_dist_layout->setVerticalSpacing(5);
|
||||
_dist_layout->addWidget(_dist_add_btn, 0, 0);
|
||||
_dist_layout->addWidget(new QLabel(_widget), 0, 1, 1, 3);
|
||||
_dist_layout->addWidget(new QLabel(tr("Time/Samples"), _widget), 0, 4);
|
||||
_dist_layout->addWidget(new QLabel(_widget), 0, 5, 1, 2);
|
||||
_dist_layout->setColumnStretch(1, 50);
|
||||
_dist_layout->setColumnStretch(6, 100);
|
||||
add_dist_measure();
|
||||
_dist_groupBox->setLayout(_dist_layout);
|
||||
|
||||
/* cursor edges group */
|
||||
_edge_groupBox = new QGroupBox(tr("Edges"), _widget);
|
||||
_edge_groupBox->setMinimumWidth(300);
|
||||
_edge_add_btn = new QToolButton(_widget);
|
||||
_edge_add_btn->setIcon(_icon_add);
|
||||
connect(_edge_add_btn, SIGNAL(clicked()), this, SLOT(add_edge_measure()));
|
||||
|
||||
_edge_layout = new QGridLayout(_widget);
|
||||
_edge_layout->setVerticalSpacing(5);
|
||||
_edge_layout->addWidget(_edge_add_btn, 0, 0);
|
||||
_edge_layout->addWidget(new QLabel(_widget), 0, 1, 1, 4);
|
||||
_edge_layout->addWidget(new QLabel(tr("Channel"), _widget), 0, 5);
|
||||
_edge_layout->addWidget(new QLabel(tr("Rising/Falling/Edges"), _widget), 0, 6);
|
||||
_edge_layout->setColumnStretch(1, 50);
|
||||
//_edge_layout->setColumnStretch(6, 100);
|
||||
//add_edge_measure();
|
||||
_edge_groupBox->setLayout(_edge_layout);
|
||||
|
||||
/* cursors group */
|
||||
_cursor_groupBox = new QGroupBox(tr("Cursors"), _widget);
|
||||
_cursor_layout = new QGridLayout(_widget);
|
||||
_cursor_layout->setVerticalSpacing(5);
|
||||
_cursor_layout->addWidget(new QLabel(tr("T1: "), _widget), 0, 0);
|
||||
_cursor_layout->addWidget(_t1_comboBox, 0, 1);
|
||||
_cursor_layout->addWidget(new QLabel(tr("T2: "), _widget), 1, 0);
|
||||
_cursor_layout->addWidget(_t2_comboBox, 1, 1);
|
||||
_cursor_layout->addWidget(new QLabel(tr("T3: "), _widget), 2, 0);
|
||||
_cursor_layout->addWidget(_t3_comboBox, 2, 1);
|
||||
|
||||
_cursor_layout->addWidget(new QLabel(tr("Time/Samples"), _widget), 3, 1, 1, 2);
|
||||
_cursor_layout->addWidget(new QLabel(tr("|T2 - T1|: "), _widget), 4, 0);
|
||||
_cursor_layout->addWidget(_delta_label_t1t2, 4, 1, 1, 2);
|
||||
|
||||
_cursor_layout->addWidget(new QLabel(tr("|T3 - T2|: "), _widget), 5, 0);
|
||||
_cursor_layout->addWidget(_delta_label_t2t3, 5, 1, 1, 2);
|
||||
|
||||
_cursor_layout->addWidget(new QLabel(tr("|T3 - T1|: "), _widget), 6, 0);
|
||||
_cursor_layout->addWidget(_delta_label_t1t3, 6, 1, 1, 2);
|
||||
|
||||
_cursor_layout->addWidget(new QLabel(_widget), 7, 0);
|
||||
_cursor_layout->addWidget(new QLabel(tr("Cursors"), _widget), 8, 0);
|
||||
_cursor_layout->addWidget(new QLabel(tr("Time/Samples"), _widget), 8, 1, 1, 2);
|
||||
|
||||
_cursor_layout->addWidget(new QLabel(_widget), 0, 2);
|
||||
_cursor_layout->addWidget(new QLabel(_widget), 1, 2);
|
||||
_cursor_layout->addWidget(new QLabel(_widget), 2, 2);
|
||||
_cursor_layout->setColumnStretch(2, 1);
|
||||
_cursor_layout->addWidget(new QLabel(tr("Time/Samples"), _widget), 0, 2);
|
||||
_cursor_layout->addWidget(new QLabel(_widget), 0, 3);
|
||||
_cursor_layout->setColumnStretch(3, 1);
|
||||
|
||||
_cursor_groupBox->setLayout(_cursor_layout);
|
||||
|
||||
QVBoxLayout *layout = new QVBoxLayout(_widget);
|
||||
layout->addWidget(_mouse_groupBox);
|
||||
layout->addWidget(_dist_groupBox);
|
||||
layout->addWidget(_edge_groupBox);
|
||||
layout->addWidget(_cursor_groupBox);
|
||||
layout->addStretch(1);
|
||||
_widget->setLayout(layout);
|
||||
|
||||
connect(_t1_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(delta_update()));
|
||||
connect(_t2_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(delta_update()));
|
||||
connect(_t3_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(delta_update()));
|
||||
|
||||
connect(_fen_checkBox, SIGNAL(stateChanged(int)), &_view, SLOT(set_measure_en(int)));
|
||||
connect(&_view, SIGNAL(measure_updated()), this, SLOT(measure_updated()));
|
||||
|
||||
@@ -157,73 +162,70 @@ void MeasureDock::paintEvent(QPaintEvent *)
|
||||
// style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
|
||||
}
|
||||
|
||||
void MeasureDock::refresh()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MeasureDock::reload()
|
||||
{
|
||||
for (QVector <QComboBox *>::const_iterator i = _edge_ch_cmb_vec.begin();
|
||||
i != _edge_ch_cmb_vec.end(); i++) {
|
||||
update_probe_selector(*i);
|
||||
}
|
||||
reCalc();
|
||||
}
|
||||
|
||||
void MeasureDock::cursor_update()
|
||||
{
|
||||
using namespace pv::data;
|
||||
|
||||
int index = 1;
|
||||
|
||||
disconnect(_t1_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(delta_update()));
|
||||
disconnect(_t2_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(delta_update()));
|
||||
disconnect(_t3_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(delta_update()));
|
||||
_t1_comboBox->clear();
|
||||
_t2_comboBox->clear();
|
||||
_t3_comboBox->clear();
|
||||
|
||||
if (!_cursor_pushButton_list.empty()) {
|
||||
for (QVector <QToolButton *>::const_iterator i = _cursor_del_btn_vec.begin();
|
||||
i != _cursor_del_btn_vec.end(); i++)
|
||||
delete (*i);
|
||||
for (QVector<QPushButton *>::Iterator i = _cursor_pushButton_list.begin();
|
||||
i != _cursor_pushButton_list.end(); i++)
|
||||
delete (*i);
|
||||
for (QVector<QLabel *>::Iterator i = _curpos_label_list.begin();
|
||||
i != _curpos_label_list.end(); i++)
|
||||
delete (*i);
|
||||
for (QVector<QLabel *>::Iterator i = _space_label_list.begin();
|
||||
i != _space_label_list.end(); i++)
|
||||
delete (*i);
|
||||
|
||||
_cursor_del_btn_vec.clear();
|
||||
_cursor_pushButton_list.clear();
|
||||
_curpos_label_list.clear();
|
||||
_space_label_list.clear();
|
||||
}
|
||||
|
||||
update_dist();
|
||||
update_edge();
|
||||
|
||||
int index = 1;
|
||||
for(std::list<Cursor*>::iterator i = _view.get_cursorList().begin();
|
||||
i != _view.get_cursorList().end(); i++) {
|
||||
QString curCursor = tr("Cursor ")+QString::number(index);
|
||||
_t1_comboBox->addItem(curCursor);
|
||||
_t2_comboBox->addItem(curCursor);
|
||||
_t3_comboBox->addItem(curCursor);
|
||||
QString curCursor = QString::number(index);
|
||||
|
||||
QToolButton *del_btn = new QToolButton(_widget);
|
||||
del_btn->setIcon(QIcon::fromTheme("measure",
|
||||
QIcon(":/icons/del.png")));
|
||||
del_btn->setCheckable(true);
|
||||
QPushButton *_cursor_pushButton = new QPushButton(curCursor, _widget);
|
||||
set_cursor_btn_color(_cursor_pushButton);
|
||||
QString _cur_text = _view.get_cm_time(index - 1) + "/" + QString::number(_view.get_cursor_samples(index - 1));
|
||||
QLabel *_curpos_label = new QLabel(_cur_text, _widget);
|
||||
QLabel *_space_label = new QLabel(_widget);
|
||||
_cursor_del_btn_vec.push_back(del_btn);
|
||||
_cursor_pushButton_list.push_back(_cursor_pushButton);
|
||||
_curpos_label_list.push_back(_curpos_label);
|
||||
_space_label_list.push_back(_space_label);
|
||||
|
||||
_cursor_layout->addWidget(_cursor_pushButton, 8 + index, 0);
|
||||
_cursor_layout->addWidget(_curpos_label, 8 + index, 1, 1, 2);
|
||||
_cursor_layout->addWidget(del_btn, 1+index, 0);
|
||||
_cursor_layout->addWidget(_cursor_pushButton, 1 + index, 1);
|
||||
_cursor_layout->addWidget(_curpos_label, 1 + index, 2);
|
||||
|
||||
connect(del_btn, SIGNAL(clicked()), this, SLOT(del_cursor()));
|
||||
connect(_cursor_pushButton, SIGNAL(clicked()), this, SLOT(goto_cursor()));
|
||||
|
||||
index++;
|
||||
}
|
||||
_t1_comboBox->setMinimumWidth(_t1_comboBox->sizeHint().width()+30);
|
||||
_t2_comboBox->setMinimumWidth(_t2_comboBox->sizeHint().width()+30);
|
||||
_t3_comboBox->setMinimumWidth(_t3_comboBox->sizeHint().width()+30);
|
||||
|
||||
if (_t1_last_index < _t1_comboBox->count())
|
||||
_t1_comboBox->setCurrentIndex(_t1_last_index);
|
||||
if (_t2_last_index < _t2_comboBox->count())
|
||||
_t2_comboBox->setCurrentIndex(_t2_last_index);
|
||||
if (_t3_last_index < _t3_comboBox->count())
|
||||
_t3_comboBox->setCurrentIndex(_t3_last_index);
|
||||
|
||||
connect(_t1_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(delta_update()));
|
||||
connect(_t2_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(delta_update()));
|
||||
connect(_t3_comboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(delta_update()));
|
||||
|
||||
delta_update();
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -235,7 +237,7 @@ void MeasureDock::measure_updated()
|
||||
_duty_label->setText(_view.get_measure("duty"));
|
||||
}
|
||||
|
||||
void MeasureDock::cursor_moved()
|
||||
void MeasureDock::cursor_moving()
|
||||
{
|
||||
//TimeMarker* grabbed_marker = _view.get_ruler()->get_grabbed_cursor();
|
||||
if (_view.cursors_shown()) {
|
||||
@@ -248,38 +250,13 @@ void MeasureDock::cursor_moved()
|
||||
index++;
|
||||
}
|
||||
}
|
||||
delta_update();
|
||||
|
||||
update_dist();
|
||||
}
|
||||
|
||||
void MeasureDock::delta_update()
|
||||
void MeasureDock::reCalc()
|
||||
{
|
||||
QString delta_text;
|
||||
_t1_last_index = std::max(_t1_comboBox->currentIndex(), 0);
|
||||
_t2_last_index = std::max(_t2_comboBox->currentIndex(), 0);
|
||||
_t3_last_index = std::max(_t3_comboBox->currentIndex(), 0);
|
||||
if (_t1_comboBox->count() != 0 && _t2_comboBox->count() != 0) {
|
||||
uint64_t delta = abs(_view.get_cursor_samples(_t1_last_index) -
|
||||
_view.get_cursor_samples(_t2_last_index));
|
||||
delta_text = _view.get_cm_delta(_t1_last_index, _t2_last_index) +
|
||||
"/" + QString::number(delta);
|
||||
_delta_label_t1t2->setText(delta_text);
|
||||
}
|
||||
|
||||
if (_t2_comboBox->count() != 0 && _t2_comboBox->count() != 0) {
|
||||
uint64_t delta = abs(_view.get_cursor_samples(_t2_last_index) -
|
||||
_view.get_cursor_samples(_t3_last_index));
|
||||
delta_text = _view.get_cm_delta(_t2_last_index, _t3_last_index) +
|
||||
"/" + QString::number(delta);
|
||||
_delta_label_t2t3->setText(delta_text);
|
||||
}
|
||||
|
||||
if (_t1_comboBox->count() != 0 && _t3_comboBox->count() != 0) {
|
||||
uint64_t delta = abs(_view.get_cursor_samples(_t1_last_index) -
|
||||
_view.get_cursor_samples(_t3_last_index));
|
||||
delta_text = _view.get_cm_delta(_t1_last_index, _t3_last_index) +
|
||||
"/" + QString::number(delta);
|
||||
_delta_label_t1t3->setText(delta_text);
|
||||
}
|
||||
update_edge();
|
||||
}
|
||||
|
||||
void MeasureDock::goto_cursor()
|
||||
@@ -297,5 +274,387 @@ void MeasureDock::goto_cursor()
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureDock::add_dist_measure()
|
||||
{
|
||||
if (_dist_row_widget_vec.size() > Max_Measure_Limits)
|
||||
return;
|
||||
|
||||
QWidget *row_widget = new QWidget(_widget);
|
||||
row_widget->setContentsMargins(0,0,0,0);
|
||||
QHBoxLayout *row_layout = new QHBoxLayout(row_widget);
|
||||
row_layout->setContentsMargins(0,0,0,0);
|
||||
row_layout->setSpacing(0);
|
||||
row_widget->setLayout(row_layout);
|
||||
_dist_row_widget_vec.push_back(row_widget);
|
||||
|
||||
QToolButton *del_btn = new QToolButton(row_widget);
|
||||
del_btn->setIcon(QIcon::fromTheme("measure",
|
||||
QIcon(":/icons/del.png")));
|
||||
del_btn->setCheckable(true);
|
||||
QPushButton *s_btn = new QPushButton(tr(" "), row_widget);
|
||||
s_btn->setObjectName("dist");
|
||||
QPushButton *e_btn = new QPushButton(tr(" "), row_widget);
|
||||
e_btn->setObjectName("dist");
|
||||
QLabel *r_label = new QLabel(row_widget);
|
||||
QLabel *g_label = new QLabel(tr("-"), row_widget);
|
||||
g_label->setContentsMargins(0,0,0,0);
|
||||
_dist_del_btn_vec.push_back(del_btn);
|
||||
_dist_s_btn_vec.push_back(s_btn);
|
||||
_dist_e_btn_vec.push_back(e_btn);
|
||||
_dist_r_label_vec.push_back(r_label);
|
||||
|
||||
connect(del_btn, SIGNAL(clicked()), this, SLOT(del_dist_measure()));
|
||||
connect(s_btn, SIGNAL(clicked()), this, SLOT(show_all_coursor()));
|
||||
connect(e_btn, SIGNAL(clicked()), this, SLOT(show_all_coursor()));
|
||||
|
||||
row_layout->addWidget(del_btn);
|
||||
row_layout->addSpacing(5);
|
||||
row_layout->addWidget(s_btn);
|
||||
row_layout->addWidget(g_label);
|
||||
row_layout->addWidget(e_btn);
|
||||
row_layout->addSpacing(5);
|
||||
row_layout->addWidget(r_label, 100);
|
||||
|
||||
_dist_layout->addWidget(row_widget, _dist_row_widget_vec.size(), 0, 1, 7);
|
||||
|
||||
}
|
||||
|
||||
void MeasureDock::del_dist_measure()
|
||||
{
|
||||
int del_index = 0;
|
||||
for (QVector <QToolButton *>::const_iterator i = _dist_del_btn_vec.begin();
|
||||
i != _dist_del_btn_vec.end(); i++) {
|
||||
if ((*i)->isChecked()) {
|
||||
_dist_layout->removeWidget(_dist_row_widget_vec.at(del_index));
|
||||
|
||||
delete _dist_del_btn_vec.at(del_index);
|
||||
delete _dist_s_btn_vec.at(del_index);
|
||||
delete _dist_e_btn_vec.at(del_index);
|
||||
delete _dist_r_label_vec.at(del_index);
|
||||
delete _dist_row_widget_vec.at(del_index);
|
||||
|
||||
_dist_del_btn_vec.remove(del_index);
|
||||
_dist_s_btn_vec.remove(del_index);
|
||||
_dist_e_btn_vec.remove(del_index);
|
||||
_dist_r_label_vec.remove(del_index);
|
||||
_dist_row_widget_vec.remove(del_index);
|
||||
|
||||
break;
|
||||
}
|
||||
del_index++;
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureDock::add_edge_measure()
|
||||
{
|
||||
if (_edge_row_widget_vec.size() > Max_Measure_Limits)
|
||||
return;
|
||||
|
||||
QWidget *row_widget = new QWidget(_widget);
|
||||
row_widget->setContentsMargins(0,0,0,0);
|
||||
QHBoxLayout *row_layout = new QHBoxLayout(row_widget);
|
||||
row_layout->setContentsMargins(0,0,0,0);
|
||||
row_layout->setSpacing(0);
|
||||
row_widget->setLayout(row_layout);
|
||||
_edge_row_widget_vec.push_back(row_widget);
|
||||
|
||||
QToolButton *del_btn = new QToolButton(row_widget);
|
||||
del_btn->setIcon(QIcon::fromTheme("measure",
|
||||
QIcon(":/icons/del.png")));
|
||||
del_btn->setCheckable(true);
|
||||
QPushButton *s_btn = new QPushButton(tr(" "), row_widget);
|
||||
s_btn->setObjectName("edge");
|
||||
QPushButton *e_btn = new QPushButton(tr(" "), row_widget);
|
||||
e_btn->setObjectName("edge");
|
||||
QLabel *r_label = new QLabel(row_widget);
|
||||
QLabel *g_label = new QLabel(tr("-"), row_widget);
|
||||
g_label->setContentsMargins(0,0,0,0);
|
||||
QLabel *a_label = new QLabel(tr("@"), row_widget);
|
||||
a_label->setContentsMargins(0,0,0,0);
|
||||
QComboBox *ch_cmb = create_probe_selector(row_widget);
|
||||
_edge_del_btn_vec.push_back(del_btn);
|
||||
_edge_s_btn_vec.push_back(s_btn);
|
||||
_edge_e_btn_vec.push_back(e_btn);
|
||||
_edge_ch_cmb_vec.push_back(ch_cmb);
|
||||
_edge_r_label_vec.push_back(r_label);
|
||||
|
||||
connect(del_btn, SIGNAL(clicked()), this, SLOT(del_edge_measure()));
|
||||
connect(s_btn, SIGNAL(clicked()), this, SLOT(show_all_coursor()));
|
||||
connect(e_btn, SIGNAL(clicked()), this, SLOT(show_all_coursor()));
|
||||
connect(ch_cmb, SIGNAL(currentIndexChanged(int)), this, SLOT(update_edge()));
|
||||
|
||||
row_layout->addWidget(del_btn);
|
||||
row_layout->addSpacing(5);
|
||||
row_layout->addWidget(s_btn);
|
||||
row_layout->addWidget(g_label);
|
||||
row_layout->addWidget(e_btn);
|
||||
row_layout->addWidget(a_label);
|
||||
row_layout->addWidget(ch_cmb);
|
||||
row_layout->addSpacing(5);
|
||||
row_layout->addWidget(r_label, 100);
|
||||
|
||||
_edge_layout->addWidget(row_widget, _edge_row_widget_vec.size(), 0, 1, 7);
|
||||
|
||||
}
|
||||
|
||||
void MeasureDock::del_edge_measure()
|
||||
{
|
||||
int del_index = 0;
|
||||
for (QVector <QToolButton *>::const_iterator i = _edge_del_btn_vec.begin();
|
||||
i != _edge_del_btn_vec.end(); i++) {
|
||||
if ((*i)->isChecked()) {
|
||||
_edge_layout->removeWidget(_edge_row_widget_vec.at(del_index));
|
||||
|
||||
delete _edge_del_btn_vec.at(del_index);
|
||||
delete _edge_s_btn_vec.at(del_index);
|
||||
delete _edge_e_btn_vec.at(del_index);
|
||||
delete _edge_r_label_vec.at(del_index);
|
||||
delete _edge_ch_cmb_vec.at(del_index);
|
||||
delete _edge_row_widget_vec.at(del_index);
|
||||
|
||||
_edge_del_btn_vec.remove(del_index);
|
||||
_edge_s_btn_vec.remove(del_index);
|
||||
_edge_e_btn_vec.remove(del_index);
|
||||
_edge_r_label_vec.remove(del_index);
|
||||
_edge_ch_cmb_vec.remove(del_index);
|
||||
_edge_row_widget_vec.remove(del_index);
|
||||
|
||||
break;
|
||||
}
|
||||
del_index++;
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureDock::show_all_coursor()
|
||||
{
|
||||
if (_view.get_cursorList().empty()) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Information"));
|
||||
msg.mBox()->setInformativeText(tr("Please insert cursor before using cursor measure."));
|
||||
msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole);
|
||||
msg.mBox()->setIcon(QMessageBox::Information);
|
||||
msg.exec();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
_sel_btn = qobject_cast<QPushButton *>(sender());
|
||||
|
||||
//dialogs::DSDialog cursor_dlg(_widget);
|
||||
QDialog cursor_dlg(_widget);
|
||||
cursor_dlg.setWindowFlags(Qt::FramelessWindowHint | Qt::Popup | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
int index = 0;
|
||||
QHBoxLayout *hlayout;
|
||||
QVBoxLayout *vlayout = new QVBoxLayout(&cursor_dlg);
|
||||
for(std::list<Cursor*>::iterator i = _view.get_cursorList().begin();
|
||||
i != _view.get_cursorList().end(); i++) {
|
||||
QPushButton *cursor_btn = new QPushButton(QString::number(index+1), &cursor_dlg);
|
||||
set_cursor_btn_color(cursor_btn);
|
||||
if ((index % 4) == 0) {
|
||||
hlayout = new QHBoxLayout(&cursor_dlg);
|
||||
vlayout->addLayout(hlayout);
|
||||
//cursor_dlg.layout()->addLayout(hlayout);
|
||||
}
|
||||
hlayout->addWidget(cursor_btn);
|
||||
connect(cursor_btn, SIGNAL(clicked()), &cursor_dlg, SLOT(accept()));
|
||||
connect(cursor_btn, SIGNAL(clicked()), this, SLOT(set_se_cursor()));
|
||||
index++;
|
||||
}
|
||||
while((index++ % 4) != 0)
|
||||
hlayout->addWidget(new QLabel(&cursor_dlg));
|
||||
|
||||
cursor_dlg.setLayout(vlayout);
|
||||
QRect sel_btn_rect = _sel_btn->geometry();
|
||||
sel_btn_rect.moveTopLeft(_sel_btn->parentWidget()->mapToGlobal(sel_btn_rect.topLeft()));
|
||||
cursor_dlg.setGeometry(sel_btn_rect.left(), sel_btn_rect.bottom()+10,
|
||||
cursor_dlg.width(), cursor_dlg.height());
|
||||
cursor_dlg.exec();
|
||||
}
|
||||
|
||||
void MeasureDock::set_se_cursor()
|
||||
{
|
||||
QPushButton *sc = qobject_cast<QPushButton *>(sender());
|
||||
if (_sel_btn)
|
||||
_sel_btn->setText(sc->text());
|
||||
|
||||
set_cursor_btn_color(_sel_btn);
|
||||
|
||||
if (_sel_btn->objectName() == "dist")
|
||||
update_dist();
|
||||
else if (_sel_btn->objectName() == "edge")
|
||||
update_edge();
|
||||
}
|
||||
|
||||
const view::Cursor* MeasureDock::find_cousor(int index)
|
||||
{
|
||||
int cur_index = 1;
|
||||
for(std::list<Cursor*>::iterator i = _view.get_cursorList().begin();
|
||||
i != _view.get_cursorList().end(); i++) {
|
||||
if (cur_index == index) {
|
||||
return (*i);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void MeasureDock::update_dist()
|
||||
{
|
||||
int dist_index = 0;
|
||||
for (QVector<QPushButton *>::Iterator i = _dist_s_btn_vec.begin();
|
||||
i != _dist_s_btn_vec.end(); i++) {
|
||||
bool start_ret, end_ret;
|
||||
const unsigned int start = (*i)->text().toInt(&start_ret) - 1;
|
||||
const unsigned int end = _dist_e_btn_vec[dist_index]->text().toInt(&end_ret) - 1;
|
||||
|
||||
if (start_ret) {
|
||||
if (start + 1 > _view.get_cursorList().size()) {
|
||||
(*i)->setText(" ");
|
||||
set_cursor_btn_color((*i));
|
||||
start_ret = false;
|
||||
}
|
||||
}
|
||||
if (end_ret) {
|
||||
if (end + 1 > _view.get_cursorList().size()) {
|
||||
_dist_e_btn_vec[dist_index]->setText(" ");
|
||||
set_cursor_btn_color(_dist_e_btn_vec[dist_index]);
|
||||
end_ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (start_ret && end_ret) {
|
||||
int64_t delta = _view.get_cursor_samples(start) -
|
||||
_view.get_cursor_samples(end);
|
||||
QString delta_text = _view.get_cm_delta(start, end) +
|
||||
"/" + QString::number(delta);
|
||||
if (delta < 0)
|
||||
delta_text.replace('+', '-');
|
||||
_dist_r_label_vec[dist_index]->setText(delta_text);
|
||||
} else {
|
||||
_dist_r_label_vec[dist_index]->setText(" ");
|
||||
}
|
||||
|
||||
dist_index++;
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureDock::update_edge()
|
||||
{
|
||||
int edge_index = 0;
|
||||
for (QVector<QPushButton *>::Iterator i = _edge_s_btn_vec.begin();
|
||||
i != _edge_s_btn_vec.end(); i++) {
|
||||
bool start_ret, end_ret;
|
||||
const unsigned int start = (*i)->text().toInt(&start_ret) - 1;
|
||||
const unsigned int end = _edge_e_btn_vec[edge_index]->text().toInt(&end_ret) - 1;
|
||||
|
||||
if (start_ret) {
|
||||
if (start + 1 > _view.get_cursorList().size()) {
|
||||
(*i)->setText(" ");
|
||||
set_cursor_btn_color((*i));
|
||||
start_ret = false;
|
||||
}
|
||||
}
|
||||
if (end_ret) {
|
||||
if (end + 1 > _view.get_cursorList().size()) {
|
||||
_edge_e_btn_vec[edge_index]->setText(" ");
|
||||
set_cursor_btn_color(_edge_e_btn_vec[edge_index]);
|
||||
end_ret = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool mValid = false;
|
||||
if (start_ret && end_ret) {
|
||||
uint64_t rising_edges;
|
||||
uint64_t falling_edges;
|
||||
const std::vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
|
||||
for(size_t i = 0; i < sigs.size(); i++) {
|
||||
const boost::shared_ptr<view::Signal> s(sigs[i]);
|
||||
boost::shared_ptr<view::LogicSignal> logicSig;
|
||||
assert(s);
|
||||
if ((logicSig = dynamic_pointer_cast<view::LogicSignal>(s)) &&
|
||||
(logicSig->enabled()) &&
|
||||
(logicSig->get_index() == _edge_ch_cmb_vec[edge_index]->currentText().toInt())){
|
||||
if (logicSig->edges(_view.get_cursor_samples(end), _view.get_cursor_samples(start), rising_edges, falling_edges)) {
|
||||
QString delta_text = QString::number(rising_edges) + "/" +
|
||||
QString::number(falling_edges) + "/" +
|
||||
QString::number(rising_edges + falling_edges);
|
||||
_edge_r_label_vec[edge_index]->setText(delta_text);
|
||||
mValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!mValid)
|
||||
_edge_r_label_vec[edge_index]->setText("-/-/-");
|
||||
|
||||
edge_index++;
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureDock::set_cursor_btn_color(QPushButton *btn)
|
||||
{
|
||||
bool ret;
|
||||
const unsigned int start = btn->text().toInt(&ret) - 1;
|
||||
QColor cursor_color = ret ? view::Ruler::CursorColor[start%8] : QColor("#302F2F");
|
||||
QString border_width = ret ? "0px" : "1px";
|
||||
QString normal = "{background-color:" + cursor_color.name() +
|
||||
"; color:black" + "; border-width:" + border_width + ";}";
|
||||
QString hover = "{background-color:" + cursor_color.darker().name() +
|
||||
"; color:black" + "; border-width:" + border_width + ";}";
|
||||
QString style = "QPushButton:hover" + hover +
|
||||
"QPushButton" + normal;
|
||||
btn->setStyleSheet(style);
|
||||
}
|
||||
|
||||
QComboBox* MeasureDock::create_probe_selector(QWidget *parent)
|
||||
{
|
||||
QComboBox *selector = new QComboBox(parent);
|
||||
update_probe_selector(selector);
|
||||
return selector;
|
||||
}
|
||||
|
||||
void MeasureDock::update_probe_selector(QComboBox *selector)
|
||||
{
|
||||
selector->clear();
|
||||
const std::vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
|
||||
for(size_t i = 0; i < sigs.size(); i++) {
|
||||
const boost::shared_ptr<view::Signal> s(sigs[i]);
|
||||
assert(s);
|
||||
|
||||
if (dynamic_pointer_cast<LogicSignal>(s) && s->enabled())
|
||||
{
|
||||
selector->addItem(QString::number(s->get_index()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MeasureDock::del_cursor()
|
||||
{
|
||||
int del_index = 0;
|
||||
Cursor* cursor;
|
||||
for (QVector <QToolButton *>::const_iterator i = _cursor_del_btn_vec.begin();
|
||||
i != _cursor_del_btn_vec.end(); i++) {
|
||||
if ((*i)->isChecked()) {
|
||||
int cur_index = 0;
|
||||
std::list<Cursor*>::iterator ite = _view.get_cursorList().begin();
|
||||
while (cur_index++ != del_index)
|
||||
ite++;
|
||||
cursor = *ite;
|
||||
break;
|
||||
}
|
||||
del_index++;
|
||||
}
|
||||
|
||||
_view.del_cursor(cursor);
|
||||
if (_view.get_cursorList().empty())
|
||||
_view.show_cursors(false);
|
||||
|
||||
cursor_update();
|
||||
_view.update();
|
||||
}
|
||||
|
||||
} // namespace dock
|
||||
} // namespace pv
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace pv {
|
||||
class SigSession;
|
||||
|
||||
namespace view {
|
||||
class Cursor;
|
||||
class View;
|
||||
}
|
||||
|
||||
@@ -59,21 +60,42 @@ class MeasureDock : public QScrollArea
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
static const int Max_Measure_Limits = 16;
|
||||
|
||||
public:
|
||||
MeasureDock(QWidget *parent, pv::view::View &view, SigSession &session);
|
||||
~MeasureDock();
|
||||
|
||||
void paintEvent(QPaintEvent *);
|
||||
void reload();
|
||||
private:
|
||||
QComboBox* create_probe_selector(QWidget *parent);
|
||||
void update_probe_selector(QComboBox *selector);
|
||||
|
||||
signals:
|
||||
|
||||
private slots:
|
||||
void delta_update();
|
||||
void goto_cursor();
|
||||
|
||||
void add_dist_measure();
|
||||
void del_dist_measure();
|
||||
void add_edge_measure();
|
||||
void del_edge_measure();
|
||||
void show_all_coursor();
|
||||
void set_se_cursor();
|
||||
const view::Cursor* find_cousor(int index);
|
||||
void update_dist();
|
||||
void update_edge();
|
||||
void set_cursor_btn_color(QPushButton *btn);
|
||||
void del_cursor();
|
||||
|
||||
public slots:
|
||||
void cursor_update();
|
||||
void cursor_moved();
|
||||
void cursor_moving();
|
||||
void reCalc();
|
||||
void measure_updated();
|
||||
void refresh();
|
||||
|
||||
private:
|
||||
SigSession &_session;
|
||||
@@ -88,24 +110,37 @@ private:
|
||||
QLabel *_freq_label;
|
||||
QLabel *_duty_label;
|
||||
|
||||
QGridLayout *_dist_layout;
|
||||
QGroupBox *_dist_groupBox;
|
||||
QToolButton *_dist_add_btn;
|
||||
QVector<QWidget *> _dist_row_widget_vec;
|
||||
QVector<QToolButton *> _dist_del_btn_vec;
|
||||
QVector<QPushButton *> _dist_s_btn_vec;
|
||||
QVector<QPushButton *> _dist_e_btn_vec;
|
||||
QVector<QLabel *> _dist_r_label_vec;
|
||||
|
||||
QGridLayout *_edge_layout;
|
||||
QGroupBox *_edge_groupBox;
|
||||
QToolButton *_edge_add_btn;
|
||||
QVector<QWidget *> _edge_row_widget_vec;
|
||||
QVector<QToolButton *> _edge_del_btn_vec;
|
||||
QVector<QPushButton *> _edge_s_btn_vec;
|
||||
QVector<QPushButton *> _edge_e_btn_vec;
|
||||
QVector<QComboBox *> _edge_ch_cmb_vec;
|
||||
QVector<QLabel *> _edge_r_label_vec;
|
||||
|
||||
QPushButton *_sel_btn;
|
||||
|
||||
QGridLayout *_cursor_layout;
|
||||
QGroupBox *_cursor_groupBox;
|
||||
QComboBox *_t1_comboBox;
|
||||
QComboBox *_t2_comboBox;
|
||||
QComboBox *_t3_comboBox;
|
||||
QLabel *_delta_label_t1t2;
|
||||
QLabel *_cnt_label_t1t2;
|
||||
QLabel *_delta_label_t2t3;
|
||||
QLabel *_cnt_label_t2t3;
|
||||
QLabel *_delta_label_t1t3;
|
||||
QLabel *_cnt_label_t1t3;
|
||||
int _t1_last_index;
|
||||
int _t2_last_index;
|
||||
int _t3_last_index;
|
||||
|
||||
QVector<QToolButton *> _cursor_del_btn_vec;
|
||||
QVector <QPushButton *> _cursor_pushButton_list;
|
||||
QVector <QLabel *> _curpos_label_list;
|
||||
QVector <QLabel *> _space_label_list;
|
||||
|
||||
QIcon _icon_add;
|
||||
QIcon _icon_add_dis;
|
||||
QIcon _icon_del;
|
||||
QIcon _icon_del_dis;
|
||||
};
|
||||
|
||||
} // namespace dock
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "../dialogs/protocollist.h"
|
||||
#include "../dialogs/protocolexp.h"
|
||||
#include "../dialogs/dsmessagebox.h"
|
||||
#include "../view/view.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QHBoxLayout>
|
||||
@@ -52,12 +53,14 @@
|
||||
namespace pv {
|
||||
namespace dock {
|
||||
|
||||
ProtocolDock::ProtocolDock(QWidget *parent, SigSession &session) :
|
||||
ProtocolDock::ProtocolDock(QWidget *parent, view::View &view, SigSession &session) :
|
||||
QScrollArea(parent),
|
||||
_session(session),
|
||||
_view(view),
|
||||
_cur_search_index(-1),
|
||||
_search_edited(false),
|
||||
_searching(false)
|
||||
_searching(false),
|
||||
_add_silent(false)
|
||||
{
|
||||
_up_widget = new QWidget(this);
|
||||
|
||||
@@ -125,11 +128,19 @@ ProtocolDock::ProtocolDock(QWidget *parent, SigSession &session) :
|
||||
connect(_dn_save_button, SIGNAL(clicked()),
|
||||
this, SLOT(export_table_view()));
|
||||
|
||||
_dn_nav_button = new QPushButton(_dn_widget);
|
||||
_dn_nav_button->setFlat(true);
|
||||
_dn_nav_button->setIcon(QIcon::fromTheme("protocol",
|
||||
QIcon(":/icons/nav.png")));
|
||||
connect(_dn_nav_button, SIGNAL(clicked()),
|
||||
this, SLOT(nav_table_view()));
|
||||
|
||||
QHBoxLayout *dn_title_layout = new QHBoxLayout();
|
||||
dn_title_layout->addWidget(_dn_set_button, 0, Qt::AlignLeft);
|
||||
dn_title_layout->addWidget(_dn_save_button, 0, Qt::AlignLeft);
|
||||
dn_title_layout->addWidget(new QLabel(tr("Protocol List Viewer"), _dn_widget), 1, Qt::AlignLeft);
|
||||
dn_title_layout->addStretch(1);
|
||||
dn_title_layout->addWidget(_dn_nav_button, 0, Qt::AlignRight);
|
||||
//dn_title_layout->addStretch(1);
|
||||
|
||||
_table_view = new QTableView(_dn_widget);
|
||||
_table_view->setModel(_session.get_decoder_model());
|
||||
@@ -237,7 +248,38 @@ int ProtocolDock::decoder_name_cmp(const void *a, const void *b)
|
||||
((const srd_decoder*)b)->name);
|
||||
}
|
||||
|
||||
bool ProtocolDock::sel_protocol(QString id)
|
||||
{
|
||||
QString name;
|
||||
GSList *l = g_slist_sort(g_slist_copy(
|
||||
(GSList*)srd_decoder_list()), decoder_name_cmp);
|
||||
for(; l; l = l->next)
|
||||
{
|
||||
const srd_decoder *const d = (srd_decoder*)l->data;
|
||||
assert(d);
|
||||
|
||||
const bool have_probes = (d->channels || d->opt_channels) != 0;
|
||||
if (true == have_probes &&
|
||||
QString::fromUtf8(d->id) == id) {
|
||||
name = QString::fromUtf8(d->name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_slist_free(l);
|
||||
|
||||
_protocol_combobox->setCurrentText(name);
|
||||
if (_protocol_combobox->currentText() == name)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void ProtocolDock::add_protocol()
|
||||
{
|
||||
add_protocol(false);
|
||||
}
|
||||
|
||||
void ProtocolDock::add_protocol(bool silent)
|
||||
{
|
||||
if (_session.get_device()->dev_inst()->mode != LOGIC) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
@@ -249,7 +291,7 @@ void ProtocolDock::add_protocol()
|
||||
} else {
|
||||
srd_decoder *const decoder =
|
||||
(srd_decoder*)(_protocol_combobox->itemData(_protocol_combobox->currentIndex())).value<void*>();
|
||||
if (_session.add_decoder(decoder)) {
|
||||
if (_session.add_decoder(decoder, silent)) {
|
||||
//std::list <int > _sel_probes = dlg.get_sel_probes();
|
||||
//QMap <QString, QVariant>& _options = dlg.get_options();
|
||||
//QMap <QString, int> _options_index = dlg.get_options_index();
|
||||
@@ -442,6 +484,13 @@ void ProtocolDock::set_model()
|
||||
resize_table_view(_session.get_decoder_model());
|
||||
_model_proxy.setSourceModel(_session.get_decoder_model());
|
||||
search_done();
|
||||
|
||||
// clear mark_index of all DecoderStacks
|
||||
const std::vector< boost::shared_ptr<pv::view::DecodeTrace> > decode_sigs(
|
||||
_session.get_decode_signals());
|
||||
BOOST_FOREACH(boost::shared_ptr<pv::view::DecodeTrace> d, decode_sigs) {
|
||||
d->decoder()->set_mark_index(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolDock::update_model()
|
||||
@@ -494,7 +543,13 @@ void ProtocolDock::item_clicked(const QModelIndex &index)
|
||||
if (decoder_stack) {
|
||||
pv::data::decode::Annotation ann;
|
||||
if (decoder_stack->list_annotation(ann, index.column(), index.row())) {
|
||||
_session.show_region(ann.start_sample(), ann.end_sample());
|
||||
const std::vector< boost::shared_ptr<pv::view::DecodeTrace> > decode_sigs(
|
||||
_session.get_decode_signals());
|
||||
BOOST_FOREACH(boost::shared_ptr<pv::view::DecodeTrace> d, decode_sigs) {
|
||||
d->decoder()->set_mark_index(-1);
|
||||
}
|
||||
decoder_stack->set_mark_index((ann.start_sample()+ann.end_sample())/2);
|
||||
_session.show_region(ann.start_sample(), ann.end_sample(), false);
|
||||
}
|
||||
}
|
||||
_table_view->resizeRowToContents(index.row());
|
||||
@@ -558,6 +613,41 @@ void ProtocolDock::export_table_view()
|
||||
protocolexp_dlg->exec();
|
||||
}
|
||||
|
||||
void ProtocolDock::nav_table_view()
|
||||
{
|
||||
uint64_t row_index;
|
||||
pv::data::DecoderModel *decoder_model = _session.get_decoder_model();
|
||||
boost::shared_ptr<pv::data::DecoderStack> decoder_stack = decoder_model->getDecoderStack();
|
||||
if (decoder_stack) {
|
||||
uint64_t offset = _view.offset() * (decoder_stack->samplerate() * _view.scale());
|
||||
std::map<const pv::data::decode::Row, bool> rows = decoder_stack->get_rows_lshow();
|
||||
int column = _model_proxy.filterKeyColumn();
|
||||
for (std::map<const pv::data::decode::Row, bool>::const_iterator i = rows.begin();
|
||||
i != rows.end(); i++) {
|
||||
if ((*i).second && column-- == 0) {
|
||||
row_index = decoder_stack->get_annotation_index((*i).first, offset);
|
||||
break;
|
||||
}
|
||||
}
|
||||
QModelIndex index = _model_proxy.mapToSource(_model_proxy.index(row_index, _model_proxy.filterKeyColumn()));
|
||||
if(index.isValid()){
|
||||
_table_view->scrollTo(index);
|
||||
_table_view->setCurrentIndex(index);
|
||||
|
||||
pv::data::decode::Annotation ann;
|
||||
decoder_stack->list_annotation(ann, index.column(), index.row());
|
||||
const std::vector< boost::shared_ptr<pv::view::DecodeTrace> > decode_sigs(
|
||||
_session.get_decode_signals());
|
||||
BOOST_FOREACH(boost::shared_ptr<pv::view::DecodeTrace> d, decode_sigs) {
|
||||
d->decoder()->set_mark_index(-1);
|
||||
}
|
||||
decoder_stack->set_mark_index((ann.start_sample()+ann.end_sample())/2);
|
||||
_view.set_all_update(true);
|
||||
_view.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProtocolDock::search_pre()
|
||||
{
|
||||
search_update();
|
||||
@@ -707,7 +797,8 @@ void ProtocolDock::search_update()
|
||||
QProgressDialog dlg(tr("Searching..."),
|
||||
tr("Cancel"),0,0,this,flags);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
dlg.setCancelButton(NULL);
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
|
||||
@@ -52,6 +52,10 @@ namespace data {
|
||||
class DecoderModel;
|
||||
}
|
||||
|
||||
namespace view {
|
||||
class View;
|
||||
}
|
||||
|
||||
namespace dock {
|
||||
|
||||
class ProtocolDock : public QScrollArea
|
||||
@@ -62,10 +66,12 @@ public:
|
||||
static const uint64_t ProgressRows = 100000;
|
||||
|
||||
public:
|
||||
ProtocolDock(QWidget *parent, SigSession &session);
|
||||
ProtocolDock(QWidget *parent, view::View &view, SigSession &session);
|
||||
~ProtocolDock();
|
||||
|
||||
void del_all_protocol();
|
||||
bool sel_protocol(QString name);
|
||||
void add_protocol(bool silent);
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
@@ -82,6 +88,7 @@ private slots:
|
||||
void set_model();
|
||||
void update_model();
|
||||
void export_table_view();
|
||||
void nav_table_view();
|
||||
void item_clicked(const QModelIndex &index);
|
||||
void column_resize(int index, int old_size, int new_size);
|
||||
void search_pre();
|
||||
@@ -96,6 +103,7 @@ private:
|
||||
|
||||
private:
|
||||
SigSession &_session;
|
||||
view::View &_view;
|
||||
QSortFilterProxyModel _model_proxy;
|
||||
double _cur_search_index;
|
||||
QStringList _str_list;
|
||||
@@ -124,10 +132,13 @@ private:
|
||||
|
||||
QPushButton *_dn_set_button;
|
||||
QPushButton *_dn_save_button;
|
||||
QPushButton *_dn_nav_button;
|
||||
|
||||
mutable boost::mutex _search_mutex;
|
||||
bool _search_edited;
|
||||
bool _searching;
|
||||
|
||||
bool _add_silent;
|
||||
};
|
||||
|
||||
} // namespace dock
|
||||
|
||||
@@ -55,8 +55,6 @@ SearchDock::SearchDock(QWidget *parent, View &view, SigSession &session) :
|
||||
_session(session),
|
||||
_view(view)
|
||||
{
|
||||
_pattern = "X X X X X X X X X X X X X X X X";
|
||||
|
||||
connect(&_pre_button, SIGNAL(clicked()),
|
||||
this, SLOT(on_previous()));
|
||||
connect(&_nxt_button, SIGNAL(clicked()),
|
||||
@@ -113,14 +111,25 @@ void SearchDock::paintEvent(QPaintEvent *)
|
||||
void SearchDock::on_previous()
|
||||
{
|
||||
bool ret;
|
||||
uint64_t last_pos;
|
||||
uint8_t *data;
|
||||
int unit_size;
|
||||
uint64_t length;
|
||||
QString value = _search_value->text();
|
||||
search_previous(value);
|
||||
int64_t last_pos;
|
||||
bool last_hit;
|
||||
const boost::shared_ptr<data::Snapshot> snapshot(_session.get_snapshot(SR_CHANNEL_LOGIC));
|
||||
assert(snapshot);
|
||||
const boost::shared_ptr<data::LogicSnapshot> logic_snapshot = boost::dynamic_pointer_cast<data::LogicSnapshot>(snapshot);
|
||||
|
||||
if (!logic_snapshot || logic_snapshot->empty()) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Search"));
|
||||
msg.mBox()->setInformativeText(tr("No Sample data!"));
|
||||
msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
const int64_t end = logic_snapshot->get_sample_count() - 1;
|
||||
last_pos = _view.get_search_pos();
|
||||
last_hit = _view.get_search_hit();
|
||||
if (last_pos == 0) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Search"));
|
||||
@@ -130,43 +139,34 @@ void SearchDock::on_previous()
|
||||
msg.exec();
|
||||
return;
|
||||
} else {
|
||||
data = (uint8_t*)_session.get_buf(unit_size, length);
|
||||
if (data == NULL) {
|
||||
QFuture<void> future;
|
||||
future = QtConcurrent::run([&]{
|
||||
last_pos -= last_hit;
|
||||
ret = logic_snapshot->pattern_search(0, end, false, last_pos, _pattern);
|
||||
});
|
||||
Qt::WindowFlags flags = Qt::CustomizeWindowHint;
|
||||
QProgressDialog dlg(tr("Search Previous..."),
|
||||
tr("Cancel"),0,0,this,flags);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
dlg.setCancelButton(NULL);
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel()));
|
||||
watcher.setFuture(future);
|
||||
dlg.exec();
|
||||
|
||||
if (!ret) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Search"));
|
||||
msg.mBox()->setInformativeText(tr("No Sample data!"));
|
||||
msg.mBox()->setInformativeText(tr("Pattern not found!"));
|
||||
msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
return;
|
||||
} else {
|
||||
QFuture<void> future;
|
||||
future = QtConcurrent::run([&]{
|
||||
ret = search_value(data, unit_size, length, last_pos, 1, value);
|
||||
});
|
||||
Qt::WindowFlags flags = Qt::CustomizeWindowHint;
|
||||
QProgressDialog dlg(tr("Search Previous..."),
|
||||
tr("Cancel"),0,0,this,flags);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
|
||||
dlg.setCancelButton(NULL);
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel()));
|
||||
watcher.setFuture(future);
|
||||
dlg.exec();
|
||||
|
||||
if (!ret) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Search"));
|
||||
msg.mBox()->setInformativeText(tr("Pattern ") + value + tr(" not found!"));
|
||||
msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
return;
|
||||
} else {
|
||||
_view.set_search_pos(last_pos);
|
||||
}
|
||||
_view.set_search_pos(last_pos, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -174,15 +174,24 @@ void SearchDock::on_previous()
|
||||
void SearchDock::on_next()
|
||||
{
|
||||
bool ret;
|
||||
uint64_t last_pos;
|
||||
int unit_size;
|
||||
uint64_t length;
|
||||
uint8_t *data = (uint8_t*)_session.get_buf(unit_size, length);
|
||||
QString value = _search_value->text();
|
||||
search_previous(value);
|
||||
int64_t last_pos;
|
||||
const boost::shared_ptr<data::Snapshot> snapshot(_session.get_snapshot(SR_CHANNEL_LOGIC));
|
||||
assert(snapshot);
|
||||
const boost::shared_ptr<data::LogicSnapshot> logic_snapshot = boost::dynamic_pointer_cast<data::LogicSnapshot>(snapshot);
|
||||
|
||||
last_pos = _view.get_search_pos();
|
||||
if (last_pos == length - 1) {
|
||||
if (!logic_snapshot || logic_snapshot->empty()) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Search"));
|
||||
msg.mBox()->setInformativeText(tr("No Sample data!"));
|
||||
msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
return;
|
||||
}
|
||||
|
||||
const int64_t end = logic_snapshot->get_sample_count() - 1;
|
||||
last_pos = _view.get_search_pos() + _view.get_search_hit();
|
||||
if (last_pos >= end) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Search"));
|
||||
msg.mBox()->setInformativeText(tr("Search cursor at the end position!"));
|
||||
@@ -191,180 +200,58 @@ void SearchDock::on_next()
|
||||
msg.exec();
|
||||
return;
|
||||
} else {
|
||||
if (data == NULL) {
|
||||
QFuture<void> future;
|
||||
future = QtConcurrent::run([&]{
|
||||
ret = logic_snapshot->pattern_search(0, end, true, last_pos, _pattern);
|
||||
});
|
||||
Qt::WindowFlags flags = Qt::CustomizeWindowHint;
|
||||
QProgressDialog dlg(tr("Search Next..."),
|
||||
tr("Cancel"),0,0,this,flags);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
dlg.setCancelButton(NULL);
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel()));
|
||||
watcher.setFuture(future);
|
||||
dlg.exec();
|
||||
|
||||
if (!ret) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Search"));
|
||||
msg.mBox()->setInformativeText(tr("No Sample data!"));
|
||||
msg.mBox()->setInformativeText(tr("Pattern not found!"));
|
||||
msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
return;
|
||||
} else {
|
||||
QFuture<void> future;
|
||||
future = QtConcurrent::run([&]{
|
||||
ret = search_value(data, unit_size, length, last_pos, 0, value);
|
||||
});
|
||||
Qt::WindowFlags flags = Qt::CustomizeWindowHint;
|
||||
QProgressDialog dlg(tr("Search Next..."),
|
||||
tr("Cancel"),0,0,this,flags);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
|
||||
dlg.setCancelButton(NULL);
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel()));
|
||||
watcher.setFuture(future);
|
||||
dlg.exec();
|
||||
|
||||
if (!ret) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Search"));
|
||||
msg.mBox()->setInformativeText(tr("Pattern ") + value + tr(" not found!"));
|
||||
msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
return;
|
||||
} else {
|
||||
_view.set_search_pos(last_pos);
|
||||
}
|
||||
_view.set_search_pos(last_pos, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SearchDock::on_set()
|
||||
{
|
||||
dialogs::Search dlg(this, _session.get_device(), _pattern);
|
||||
dialogs::Search dlg(this, _session, _pattern);
|
||||
if (dlg.exec()) {
|
||||
_pattern = dlg.get_pattern();
|
||||
_pattern.remove(QChar(' '), Qt::CaseInsensitive);
|
||||
_pattern = _pattern.toUpper();
|
||||
_search_value->setText(_pattern);
|
||||
|
||||
QFontMetrics fm = this->fontMetrics();
|
||||
_search_value->setFixedWidth(fm.width(_pattern)+_search_button->width()+20);
|
||||
}
|
||||
}
|
||||
|
||||
bool SearchDock::search_value(const uint8_t *data, int unit_size, uint64_t length, uint64_t& pos, bool left, QString value)
|
||||
{
|
||||
QByteArray pattern = value.toUtf8();
|
||||
int i = 0;
|
||||
uint64_t match_pos = left ? pos - 1 : pos + 1;
|
||||
bool part_match = false;
|
||||
int match_bits = unit_size * 8 - 1;
|
||||
bool unmatch = false;
|
||||
|
||||
while(i <= match_bits) {
|
||||
unmatch = false;
|
||||
uint64_t pattern_mask = 1ULL << i;
|
||||
|
||||
if (pattern[match_bits - i] == 'X') {
|
||||
part_match = true;
|
||||
} else if (pattern[match_bits - i] == '0') {
|
||||
//while((match_pos >= 0 && left) || (match_pos < length && !left)) {
|
||||
while(left || (match_pos < length && !left)) {
|
||||
if (0 == ((*(uint64_t *)(data + match_pos * unit_size) & pattern_mask) != 0)) {
|
||||
part_match = true;
|
||||
break;
|
||||
} else if ((match_pos == 0 && left) || (match_pos == length - 1 && !left)) {
|
||||
unmatch = true;
|
||||
part_match = false;
|
||||
break;
|
||||
} else if (part_match) {
|
||||
unmatch = true;
|
||||
match_pos = left ? match_pos - 1 : match_pos + 1;
|
||||
i = 0;
|
||||
break;
|
||||
} else if (!part_match) {
|
||||
match_pos = left ? match_pos - 1 : match_pos + 1;
|
||||
}
|
||||
}
|
||||
} else if (pattern[match_bits - i] == '1') {
|
||||
//while((match_pos >= 0 && left) || (match_pos < length && !left)) {
|
||||
while(left || (match_pos < length && !left)) {
|
||||
if (1 == ((*(uint64_t *)(data + match_pos * unit_size) & pattern_mask) != 0)) {
|
||||
part_match = true;
|
||||
break;
|
||||
} else if ((match_pos == 0 && left) || (match_pos == length - 1 && !left)) {
|
||||
unmatch = true;
|
||||
part_match = false;
|
||||
break;
|
||||
} else if (part_match) {
|
||||
unmatch = true;
|
||||
match_pos = left ? match_pos - 1 : match_pos + 1;
|
||||
i = 0;
|
||||
break;
|
||||
} else if (!part_match) {
|
||||
match_pos = left ? match_pos - 1 : match_pos + 1;
|
||||
}
|
||||
}
|
||||
}else if (pattern[match_bits - i] == 'R') {
|
||||
while((match_pos > 0 && left) || (match_pos < length && !left)) {
|
||||
if (1 == ((*(uint64_t *)(data + match_pos * unit_size) & pattern_mask) != 0) &&
|
||||
0 == ((*(uint64_t *)(data + (match_pos - 1) * unit_size) & pattern_mask) != 0)) {
|
||||
part_match = true;
|
||||
break;
|
||||
} else if ((match_pos == 1 && left) || (match_pos == length - 1 && !left)) {
|
||||
unmatch = true;
|
||||
part_match = false;
|
||||
break;
|
||||
} else if (part_match) {
|
||||
unmatch = true;
|
||||
match_pos = left ? match_pos - 1 : match_pos + 1;
|
||||
i = 0;
|
||||
break;
|
||||
} else if (!part_match) {
|
||||
match_pos = left ? match_pos - 1 : match_pos + 1;
|
||||
}
|
||||
}
|
||||
} else if (pattern[match_bits - i] == 'F') {
|
||||
while((match_pos > 0 && left) || (match_pos < length && !left)) {
|
||||
if (0 == ((*(uint64_t *)(data + match_pos * unit_size) & pattern_mask) != 0) &&
|
||||
1 == ((*(uint64_t *)(data + (match_pos - 1) * unit_size) & pattern_mask) != 0)) {
|
||||
part_match = true;
|
||||
break;
|
||||
} else if ((match_pos == 1 && left) || (match_pos == length - 1 && !left)) {
|
||||
unmatch = true;
|
||||
part_match = false;
|
||||
break;
|
||||
} else if (part_match) {
|
||||
unmatch = true;
|
||||
match_pos = left ? match_pos - 1 : match_pos + 1;
|
||||
i = 0;
|
||||
break;
|
||||
} else if (!part_match) {
|
||||
match_pos = left ? match_pos - 1 : match_pos + 1;
|
||||
}
|
||||
}
|
||||
} else if (pattern[match_bits - i] == 'C') {
|
||||
while((match_pos > 0 && left) || (match_pos < length && !left)) {
|
||||
if (((*(uint64_t *)(data + match_pos * unit_size) & pattern_mask) != 0) !=
|
||||
((*(uint64_t *)(data + (match_pos - 1) * unit_size) & pattern_mask) != 0)) {
|
||||
part_match = true;
|
||||
break;
|
||||
} else if ((match_pos == 1 && left) || (match_pos == length - 1 && !left)) {
|
||||
unmatch = true;
|
||||
part_match = false;
|
||||
break;
|
||||
} else if (part_match) {
|
||||
unmatch = true;
|
||||
match_pos = left ? match_pos - 1 : match_pos + 1;
|
||||
i = 0;
|
||||
break;
|
||||
} else if (!part_match) {
|
||||
match_pos = left ? match_pos - 1 : match_pos + 1;
|
||||
}
|
||||
}
|
||||
QString search_label;
|
||||
for (auto& iter:_pattern) {
|
||||
iter.second.remove(QChar(' '), Qt::CaseInsensitive);
|
||||
iter.second = iter.second.toUpper();
|
||||
search_label.push_back(iter.second);
|
||||
// if (iter.second != "XXXXXXXXXXXXXXXX") {
|
||||
// search_label.push_back(QString::number(iter.first));
|
||||
// search_label.push_back("/");
|
||||
// }
|
||||
}
|
||||
|
||||
if (unmatch && !part_match)
|
||||
break;
|
||||
else if ((!unmatch && part_match) || !part_match)
|
||||
i++;
|
||||
_search_value->setText(search_label);
|
||||
QFontMetrics fm = this->fontMetrics();
|
||||
_search_value->setFixedWidth(fm.width(search_label)+_search_button->width()+20);
|
||||
}
|
||||
|
||||
pos = match_pos;
|
||||
return !unmatch;
|
||||
}
|
||||
|
||||
} // namespace dock
|
||||
|
||||
@@ -70,22 +70,15 @@ public:
|
||||
|
||||
void paintEvent(QPaintEvent *);
|
||||
|
||||
signals:
|
||||
void search_previous(QString);
|
||||
void search_next(QString);
|
||||
|
||||
public slots:
|
||||
void on_previous();
|
||||
void on_next();
|
||||
void on_set();
|
||||
private:
|
||||
bool search_value(const uint8_t* data, int unit_size, uint64_t length,
|
||||
uint64_t& pos, bool left, QString value);
|
||||
|
||||
private:
|
||||
SigSession &_session;
|
||||
view::View &_view;
|
||||
QString _pattern;
|
||||
std::map<uint16_t, QString> _pattern;
|
||||
|
||||
QPushButton _pre_button;
|
||||
QPushButton _nxt_button;
|
||||
|
||||
@@ -57,10 +57,10 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) :
|
||||
|
||||
position_label = new QLabel(tr("Trigger Position: "), _widget);
|
||||
position_spinBox = new QSpinBox(_widget);
|
||||
position_spinBox->setRange(MinTrigPosition, 99);
|
||||
position_spinBox->setRange(MinTrigPosition, DS_MAX_TRIG_PERCENT);
|
||||
position_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
|
||||
position_slider = new QSlider(Qt::Horizontal, _widget);
|
||||
position_slider->setRange(MinTrigPosition, 99);
|
||||
position_slider->setRange(MinTrigPosition, DS_MAX_TRIG_PERCENT);
|
||||
connect(position_slider, SIGNAL(valueChanged(int)), position_spinBox, SLOT(setValue(int)));
|
||||
connect(position_spinBox, SIGNAL(valueChanged(int)), position_slider, SLOT(setValue(int)));
|
||||
|
||||
@@ -93,10 +93,10 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) :
|
||||
_value0_lineEdit->setInputMask("X X X X X X X X X X X X X X X X");
|
||||
_value0_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
_value0_lineEdit_list.push_back(_value0_lineEdit);
|
||||
QSpinBox *_count0_spinBox = new QSpinBox(_widget);
|
||||
_count0_spinBox->setRange(1, INT32_MAX);
|
||||
_count0_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
|
||||
_count0_spinBox_list.push_back(_count0_spinBox);
|
||||
QSpinBox *_count_spinBox = new QSpinBox(_widget);
|
||||
_count_spinBox->setRange(1, INT32_MAX);
|
||||
_count_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
|
||||
_count_spinBox_list.push_back(_count_spinBox);
|
||||
QComboBox *_inv0_comboBox = new QComboBox(_widget);
|
||||
_inv0_comboBox->addItem(tr("=="));
|
||||
_inv0_comboBox->addItem(tr("!="));
|
||||
@@ -109,33 +109,38 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) :
|
||||
_value1_lineEdit->setInputMask("X X X X X X X X X X X X X X X X");
|
||||
_value1_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
_value1_lineEdit_list.push_back(_value1_lineEdit);
|
||||
QSpinBox *_count1_spinBox = new QSpinBox(_widget);
|
||||
_count1_spinBox->setRange(1, INT32_MAX);
|
||||
_count1_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
|
||||
_count1_spinBox_list.push_back(_count1_spinBox);
|
||||
QComboBox *_inv1_comboBox = new QComboBox(_widget);
|
||||
_inv1_comboBox->addItem(tr("=="));
|
||||
_inv1_comboBox->addItem(tr("!="));
|
||||
_inv1_comboBox_list.push_back(_inv1_comboBox);
|
||||
|
||||
QCheckBox *_contiguous_checkbox = new QCheckBox(_widget);
|
||||
_contiguous_checkbox_list.push_back(_contiguous_checkbox);
|
||||
|
||||
QLabel *value_exp_label = new QLabel("1 1 1 1 1 1\n5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 ", _widget);
|
||||
QLabel *inv_exp_label = new QLabel("Inv", _widget);
|
||||
QLabel *count_exp_label = new QLabel("Counter", _widget);
|
||||
QLabel *inv_exp_label = new QLabel(tr("Inv"), _widget);
|
||||
QLabel *count_exp_label = new QLabel(tr("Counter"), _widget);
|
||||
value_exp_label->setFont(font);
|
||||
|
||||
QVBoxLayout *stage_layout = new QVBoxLayout();
|
||||
QGridLayout *stage_glayout = new QGridLayout();
|
||||
stage_glayout->setVerticalSpacing(5);
|
||||
|
||||
stage_glayout->addWidget(value_exp_label, 1, 0);
|
||||
stage_glayout->addWidget(inv_exp_label, 1, 1);
|
||||
stage_glayout->addWidget(count_exp_label, 1, 2);
|
||||
stage_glayout->addWidget(_value0_lineEdit, 2, 0);
|
||||
stage_glayout->addWidget(_inv0_comboBox, 2, 1);
|
||||
stage_glayout->addWidget(_count0_spinBox, 2, 2);
|
||||
stage_glayout->addWidget(_logic_comboBox, 2, 3);
|
||||
stage_glayout->addWidget(_logic_comboBox, 2, 2);
|
||||
stage_glayout->addWidget(_value1_lineEdit, 3, 0);
|
||||
stage_glayout->addWidget(_inv1_comboBox, 3, 1);
|
||||
stage_glayout->addWidget(_count1_spinBox, 3, 2);
|
||||
|
||||
stage_glayout->addWidget(new QLabel(_widget), 4, 0);
|
||||
|
||||
stage_glayout->addWidget(new QLabel(tr("Contiguous")), 5, 1, 1, 2);
|
||||
stage_glayout->addWidget(_contiguous_checkbox, 5, 0, 1, 1, Qt::AlignRight);
|
||||
stage_glayout->addWidget(count_exp_label, 6, 1, 1, 2);
|
||||
stage_glayout->addWidget(_count_spinBox, 6, 0);
|
||||
|
||||
stage_layout->addLayout(stage_glayout);
|
||||
stage_layout->addSpacing(20);
|
||||
stage_layout->addWidget(new QLabel(tr("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge")));
|
||||
@@ -189,9 +194,9 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) :
|
||||
_serial_value_lineEdit->setInputMask("X X X X X X X X X X X X X X X X");
|
||||
_serial_value_lineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
|
||||
_serial_vcnt_spinBox = new QSpinBox(_widget);
|
||||
_serial_vcnt_spinBox->setRange(1, INT32_MAX);
|
||||
_serial_vcnt_spinBox->setButtonSymbols(QAbstractSpinBox::NoButtons);
|
||||
_serial_bits_comboBox = new QComboBox(_widget);
|
||||
for(i = 1; i <= 16; i++)
|
||||
_serial_bits_comboBox->addItem(QString::number(i));
|
||||
|
||||
QLabel *serial_value_exp_label = new QLabel("1 1 1 1 1 1\n5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0", _widget);
|
||||
serial_value_exp_label->setFont(font);
|
||||
@@ -211,11 +216,11 @@ TriggerDock::TriggerDock(QWidget *parent, SigSession &session) :
|
||||
serial_glayout->addWidget(new QLabel(_widget), 5, 0, 1, 5);
|
||||
serial_glayout->addWidget(_serial_data_lable, 6, 0);
|
||||
serial_glayout->addWidget(_serial_data_comboBox, 6, 1);
|
||||
serial_glayout->addWidget(new QLabel(tr("counter"), _widget), 6, 4);
|
||||
serial_glayout->addWidget(_serial_value_lable, 7, 0);
|
||||
serial_glayout->addWidget(_serial_value_lineEdit, 7, 1, 1, 3);
|
||||
serial_glayout->addWidget(_serial_vcnt_spinBox, 7, 4);
|
||||
serial_glayout->addWidget(new QLabel(_widget), 7, 5);
|
||||
serial_glayout->addWidget(new QLabel(tr("Data Bits"), _widget), 7, 0);
|
||||
serial_glayout->addWidget(_serial_bits_comboBox, 7, 1);
|
||||
serial_glayout->addWidget(_serial_value_lable, 8, 0);
|
||||
serial_glayout->addWidget(_serial_value_lineEdit, 8, 1, 1, 3);
|
||||
|
||||
serial_layout->addLayout(serial_glayout);
|
||||
serial_layout->addSpacing(20);
|
||||
serial_layout->addWidget(new QLabel(tr("X: Don't care\n0: Low level\n1: High level\nR: Rising edge\nF: Falling edge\nC: Rising/Falling edge")));
|
||||
@@ -343,27 +348,18 @@ void TriggerDock::value_changed()
|
||||
sc->setText(sc->text().toUpper());
|
||||
}
|
||||
|
||||
void TriggerDock::device_change()
|
||||
void TriggerDock::device_updated()
|
||||
{
|
||||
uint64_t max_hd_depth;
|
||||
uint64_t hw_depth;
|
||||
bool stream = false;
|
||||
uint8_t maxRange;
|
||||
uint64_t sample_limits;
|
||||
GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_MAX_LOGIC_SAMPLELIMITS);
|
||||
GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_HW_DEPTH);
|
||||
if (gvar != NULL) {
|
||||
max_hd_depth = g_variant_get_uint64(gvar);
|
||||
hw_depth = g_variant_get_uint64(gvar);
|
||||
g_variant_unref(gvar);
|
||||
|
||||
if (_session.get_device()->dev_inst()->mode == LOGIC) {
|
||||
sample_limits = _session.get_device()->get_sample_limit();
|
||||
if (max_hd_depth >= sample_limits)
|
||||
maxRange = 99;
|
||||
else
|
||||
maxRange = max_hd_depth*70 / sample_limits;
|
||||
position_spinBox->setRange(MinTrigPosition, maxRange);
|
||||
position_slider->setRange(MinTrigPosition, maxRange);
|
||||
|
||||
|
||||
|
||||
gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_STREAM);
|
||||
if (gvar != NULL) {
|
||||
@@ -371,6 +367,16 @@ void TriggerDock::device_change()
|
||||
g_variant_unref(gvar);
|
||||
}
|
||||
|
||||
sample_limits = _session.get_device()->get_sample_limit();
|
||||
if (stream)
|
||||
maxRange = 1;
|
||||
else if (hw_depth >= sample_limits)
|
||||
maxRange = DS_MAX_TRIG_PERCENT;
|
||||
else
|
||||
maxRange = ceil(hw_depth * DS_MAX_TRIG_PERCENT / sample_limits);
|
||||
position_spinBox->setRange(MinTrigPosition, maxRange);
|
||||
position_slider->setRange(MinTrigPosition, maxRange);
|
||||
|
||||
if (_session.get_device()->name().contains("virtual") ||
|
||||
stream) {
|
||||
simple_radioButton->setChecked(true);
|
||||
@@ -397,7 +403,7 @@ bool TriggerDock::commit_trigger()
|
||||
ds_trigger_set_mode(SERIAL_TRIGGER);
|
||||
|
||||
// trigger stage update
|
||||
ds_trigger_set_stage(stages_comboBox->currentText().toInt());
|
||||
ds_trigger_set_stage(stages_comboBox->currentText().toInt() - 1);
|
||||
|
||||
int i;
|
||||
// trigger value update
|
||||
@@ -410,36 +416,36 @@ bool TriggerDock::commit_trigger()
|
||||
} else if(_adv_tabWidget->currentIndex() == 1){
|
||||
ds_trigger_stage_set_value(0, TriggerProbes,
|
||||
_serial_start_lineEdit->text().toLocal8Bit().data(),
|
||||
_value1_lineEdit_list.at(0)->text().toLocal8Bit().data());
|
||||
_serial_stop_lineEdit->text().toLocal8Bit().data());
|
||||
ds_trigger_stage_set_value(1, TriggerProbes,
|
||||
_serial_stop_lineEdit->text().toLocal8Bit().data(),
|
||||
_value1_lineEdit_list.at(1)->text().toLocal8Bit().data());
|
||||
ds_trigger_stage_set_value(2, TriggerProbes,
|
||||
_serial_edge_lineEdit->text().toLocal8Bit().data(),
|
||||
_value1_lineEdit_list.at(2)->text().toLocal8Bit().data());
|
||||
_value1_lineEdit_list.at(1)->text().toLocal8Bit().data());
|
||||
|
||||
//_serial_data_comboBox
|
||||
const int data_channel = _serial_data_comboBox->currentText().toInt();
|
||||
char channel[31];
|
||||
for(i = 0; i < 31; i++){
|
||||
if (i == (30 - 2*data_channel))
|
||||
channel[i] = '1';
|
||||
else if (i%2 == 0)
|
||||
channel[i] = '0';
|
||||
else if (i%2 == 0)
|
||||
channel[i] = 'X';
|
||||
else
|
||||
channel[i] = ' ';
|
||||
}
|
||||
ds_trigger_stage_set_value(3, TriggerProbes,
|
||||
ds_trigger_stage_set_value(2, TriggerProbes,
|
||||
channel,
|
||||
_value1_lineEdit_list.at(3)->text().toLocal8Bit().data());
|
||||
ds_trigger_stage_set_value(4, TriggerProbes,
|
||||
_value1_lineEdit_list.at(2)->text().toLocal8Bit().data());
|
||||
ds_trigger_stage_set_value(STriggerDataStage, TriggerProbes,
|
||||
_serial_value_lineEdit->text().toLocal8Bit().data(),
|
||||
_value1_lineEdit_list.at(4)->text().toLocal8Bit().data());
|
||||
_value1_lineEdit_list.at(3)->text().toLocal8Bit().data());
|
||||
}
|
||||
|
||||
// trigger logic update
|
||||
for (i = 0; i < stages_comboBox->currentText().toInt(); i++) {
|
||||
const char logic = (_contiguous_checkbox_list.at(i)->isChecked() << 1) +
|
||||
_logic_comboBox_list.at(i)->currentIndex();
|
||||
ds_trigger_stage_set_logic(i, TriggerProbes,
|
||||
_logic_comboBox_list.at(i)->currentIndex());
|
||||
logic);
|
||||
}
|
||||
|
||||
// trigger inv update
|
||||
@@ -453,12 +459,15 @@ bool TriggerDock::commit_trigger()
|
||||
if (_adv_tabWidget->currentIndex() == 0) {
|
||||
for (i = 0; i < stages_comboBox->currentText().toInt(); i++) {
|
||||
ds_trigger_stage_set_count(i, TriggerProbes,
|
||||
_count0_spinBox_list.at(i)->value() - 1,
|
||||
_count1_spinBox_list.at(i)->value() - 1);
|
||||
_count_spinBox_list.at(i)->value(),
|
||||
0);
|
||||
}
|
||||
} else if(_adv_tabWidget->currentIndex() == 1){
|
||||
ds_trigger_stage_set_count(4, TriggerProbes,
|
||||
_serial_vcnt_spinBox->value() - 1,
|
||||
ds_trigger_stage_set_count(1, TriggerProbes,
|
||||
1,
|
||||
0);
|
||||
ds_trigger_stage_set_count(3, TriggerProbes,
|
||||
_serial_bits_comboBox->currentText().toInt() - 1,
|
||||
0);
|
||||
}
|
||||
return 1;
|
||||
@@ -475,34 +484,37 @@ void TriggerDock::init()
|
||||
QJsonObject TriggerDock::get_session()
|
||||
{
|
||||
QJsonObject trigSes;
|
||||
trigSes["triggerMode"] = adv_radioButton->isChecked() ? 1 : 0;
|
||||
trigSes["advTriggerMode"] = adv_radioButton->isChecked();
|
||||
trigSes["triggerPos"] = position_slider->value();
|
||||
trigSes["triggerStages"] = stages_comboBox->currentIndex();
|
||||
trigSes["triggerSerial"] = _adv_tabWidget->currentIndex();
|
||||
trigSes["triggerTab"] = _adv_tabWidget->currentIndex();
|
||||
|
||||
for (int i = 0; i < stages_comboBox->count(); i++) {
|
||||
QString value0_str = "triggerValue0" + QString::number(i);
|
||||
QString inv0_str = "triggerInv0" + QString::number(i);
|
||||
QString count0_str = "triggerCount0" + QString::number(i);
|
||||
QString value1_str = "triggerValue1" + QString::number(i);
|
||||
QString inv1_str = "triggerInv1" + QString::number(i);
|
||||
QString count1_str = "triggerCount1" + QString::number(i);
|
||||
QString logic_str = "triggerLogic" + QString::number(i);
|
||||
QString value0_str = "stageTriggerValue0" + QString::number(i);
|
||||
QString inv0_str = "stageTriggerInv0" + QString::number(i);
|
||||
QString value1_str = "stageTriggerValue1" + QString::number(i);
|
||||
QString inv1_str = "stageTriggerInv1" + QString::number(i);
|
||||
|
||||
QString logic_str = "stageTriggerLogic" + QString::number(i);
|
||||
QString count_str = "stageTriggerCount" + QString::number(i);
|
||||
QString conti_str = "stageTriggerContiguous" + QString::number(i);
|
||||
|
||||
trigSes[value0_str] = _value0_lineEdit_list.at(i)->text();
|
||||
trigSes[value1_str] = _value1_lineEdit_list.at(i)->text();
|
||||
trigSes[inv0_str] = _inv0_comboBox_list.at(i)->currentIndex();
|
||||
trigSes[inv1_str] = _inv1_comboBox_list.at(i)->currentIndex();
|
||||
trigSes[count0_str] = _count0_spinBox_list.at(i)->value();
|
||||
trigSes[count1_str] = _count1_spinBox_list.at(i)->value();
|
||||
|
||||
trigSes[logic_str] = _logic_comboBox_list.at(i)->currentIndex();
|
||||
trigSes[count_str] = _count_spinBox_list.at(i)->value();
|
||||
trigSes[conti_str] = _contiguous_checkbox_list.at(i)->isChecked();
|
||||
}
|
||||
|
||||
trigSes["triggerStart"] = _serial_start_lineEdit->text();
|
||||
trigSes["triggerStop"] = _serial_stop_lineEdit->text();
|
||||
trigSes["triggerClock"] = _serial_edge_lineEdit->text();
|
||||
trigSes["triggerChannel"] = _serial_data_comboBox->currentIndex();
|
||||
trigSes["triggerData"] = _serial_value_lineEdit->text();
|
||||
trigSes["triggerVcnt"] = _serial_vcnt_spinBox->value();
|
||||
trigSes["serialTriggerStart"] = _serial_start_lineEdit->text();
|
||||
trigSes["serialTriggerStop"] = _serial_stop_lineEdit->text();
|
||||
trigSes["serialTriggerClock"] = _serial_edge_lineEdit->text();
|
||||
trigSes["serialTriggerChannel"] = _serial_data_comboBox->currentIndex();
|
||||
trigSes["serialTriggerData"] = _serial_value_lineEdit->text();
|
||||
trigSes["serialTriggerBits"] = _serial_bits_comboBox->currentIndex();
|
||||
|
||||
return trigSes;
|
||||
}
|
||||
@@ -511,35 +523,38 @@ void TriggerDock::set_session(QJsonObject ses)
|
||||
{
|
||||
position_slider->setValue(ses["triggerPos"].toDouble());
|
||||
stages_comboBox->setCurrentIndex(ses["triggerStages"].toDouble());
|
||||
_adv_tabWidget->setCurrentIndex(ses["triggerSerial"].toDouble());
|
||||
if (ses["triggerMode"].toDouble() == 0)
|
||||
simple_radioButton->click();
|
||||
else
|
||||
_adv_tabWidget->setCurrentIndex(ses["triggerTab"].toDouble());
|
||||
if (ses["advTriggerMode"].toBool())
|
||||
adv_radioButton->click();
|
||||
else
|
||||
simple_radioButton->click();
|
||||
|
||||
for (int i = 0; i < stages_comboBox->count(); i++) {
|
||||
QString value0_str = "triggerValue0" + QString::number(i);
|
||||
QString inv0_str = "triggerInv0" + QString::number(i);
|
||||
QString count0_str = "triggerCount0" + QString::number(i);
|
||||
QString value1_str = "triggerValue1" + QString::number(i);
|
||||
QString inv1_str = "triggerInv1" + QString::number(i);
|
||||
QString count1_str = "triggerCount1" + QString::number(i);
|
||||
QString logic_str = "triggerLogic" + QString::number(i);
|
||||
QString value0_str = "stageTriggerValue0" + QString::number(i);
|
||||
QString inv0_str = "stageTriggerInv0" + QString::number(i);
|
||||
QString value1_str = "stageTriggerValue1" + QString::number(i);
|
||||
QString inv1_str = "stageTriggerInv1" + QString::number(i);
|
||||
|
||||
QString logic_str = "stageTriggerLogic" + QString::number(i);
|
||||
QString count_str = "stageTriggerCount" + QString::number(i);
|
||||
QString conti_str = "stageTriggerContiguous" + QString::number(i);
|
||||
|
||||
_value0_lineEdit_list.at(i)->setText(ses[value0_str].toString());
|
||||
_value1_lineEdit_list.at(i)->setText(ses[value1_str].toString());
|
||||
_inv0_comboBox_list.at(i)->setCurrentIndex(ses[inv0_str].toDouble());
|
||||
_inv1_comboBox_list.at(i)->setCurrentIndex(ses[inv1_str].toDouble());
|
||||
_count0_spinBox_list.at(i)->setValue(ses[count0_str].toDouble());
|
||||
_count1_spinBox_list.at(i)->setValue(ses[count1_str].toDouble());
|
||||
|
||||
_logic_comboBox_list.at(i)->setCurrentIndex(ses[logic_str].toDouble());
|
||||
_count_spinBox_list.at(i)->setValue(ses[count_str].toDouble());
|
||||
_contiguous_checkbox_list.at(i)->setChecked(ses[conti_str].toBool());
|
||||
}
|
||||
|
||||
_serial_start_lineEdit->setText(ses["triggerStart"].toString());
|
||||
_serial_stop_lineEdit->setText(ses["triggerStop"].toString());
|
||||
_serial_edge_lineEdit->setText(ses["triggerClock"].toString());
|
||||
_serial_data_comboBox->setCurrentIndex(ses["triggerChannel"].toDouble());
|
||||
_serial_value_lineEdit->setText(ses["triggerData"].toString());
|
||||
_serial_vcnt_spinBox->setValue(ses["triggerVcnt"].toDouble());
|
||||
_serial_start_lineEdit->setText(ses["serialTriggerStart"].toString());
|
||||
_serial_stop_lineEdit->setText(ses["serialTriggerStop"].toString());
|
||||
_serial_edge_lineEdit->setText(ses["serialTriggerClock"].toString());
|
||||
_serial_data_comboBox->setCurrentIndex(ses["serialTriggerChannel"].toDouble());
|
||||
_serial_value_lineEdit->setText(ses["serialTriggerData"].toString());
|
||||
_serial_bits_comboBox->setCurrentIndex(ses["serialTriggerBits"].toDouble());
|
||||
}
|
||||
|
||||
} // namespace dock
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <QLineEdit>
|
||||
#include <QSpinBox>
|
||||
#include <QGroupBox>
|
||||
#include <QCheckBox>
|
||||
#include <QTableWidget>
|
||||
#include <QJsonObject>
|
||||
|
||||
@@ -84,7 +85,7 @@ public slots:
|
||||
|
||||
void value_changed();
|
||||
|
||||
void device_change();
|
||||
void device_updated();
|
||||
|
||||
private:
|
||||
|
||||
@@ -109,11 +110,11 @@ private:
|
||||
QVector <QLabel *> _mu_label_list;
|
||||
QVector <QComboBox *> _logic_comboBox_list;
|
||||
QVector <QLineEdit *> _value0_lineEdit_list;
|
||||
QVector <QSpinBox *> _count0_spinBox_list;
|
||||
QVector <QSpinBox *> _count_spinBox_list;
|
||||
QVector <QComboBox *> _inv0_comboBox_list;
|
||||
QVector <QLineEdit *> _value1_lineEdit_list;
|
||||
QVector <QSpinBox *> _count1_spinBox_list;
|
||||
QVector <QComboBox *> _inv1_comboBox_list;
|
||||
QVector <QCheckBox *> _contiguous_checkbox_list;
|
||||
|
||||
QTabWidget *_adv_tabWidget;
|
||||
QGroupBox *_serial_groupBox;
|
||||
@@ -128,7 +129,7 @@ private:
|
||||
QLabel *_serial_value_lable;
|
||||
QLineEdit *_serial_value_lineEdit;
|
||||
QLabel *_serial_vcnt_lable;
|
||||
QSpinBox *_serial_vcnt_spinBox;
|
||||
QComboBox *_serial_bits_comboBox;
|
||||
};
|
||||
|
||||
} // namespace dock
|
||||
|
||||
@@ -46,7 +46,8 @@ MainFrame::MainFrame(DeviceManager &device_manager,
|
||||
setAttribute(Qt::WA_TranslucentBackground);
|
||||
// Make this a borderless window which can't
|
||||
// be resized or moved via the window system
|
||||
setWindowFlags(Qt::FramelessWindowHint);
|
||||
setWindowFlags(Qt::FramelessWindowHint | Qt::WindowSystemMenuHint |
|
||||
Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint);
|
||||
setMinimumHeight(680);
|
||||
setMinimumWidth(800);
|
||||
//resize(1024, 768);
|
||||
@@ -58,6 +59,7 @@ MainFrame::MainFrame(DeviceManager &device_manager,
|
||||
setWindowIcon(icon);
|
||||
|
||||
_moving = false;
|
||||
_draging = false;
|
||||
_startPos = None;
|
||||
_freezing = false;
|
||||
_minimized = false;
|
||||
@@ -118,24 +120,24 @@ MainFrame::MainFrame(DeviceManager &device_manager,
|
||||
_layout->addWidget(_bottom_right, 2, 2);
|
||||
|
||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(unfreezing()));
|
||||
readSettings();
|
||||
connect(_mainWindow, SIGNAL(prgRate(int)), this, SLOT(setTaskbarProgress(int)));
|
||||
//readSettings();
|
||||
}
|
||||
|
||||
void MainFrame::changeEvent(QEvent* event)
|
||||
{
|
||||
QFrame::changeEvent(event);
|
||||
QWindowStateChangeEvent* win_event = static_cast< QWindowStateChangeEvent* >(event);
|
||||
if(win_event->type() == QEvent::WindowStateChange) {
|
||||
if (win_event->oldState() & Qt::WindowMinimized) {
|
||||
if (_minimized) {
|
||||
readSettings();
|
||||
_minimized = false;
|
||||
}
|
||||
QWindowStateChangeEvent* win_event = static_cast< QWindowStateChangeEvent* >(event);
|
||||
if(win_event->type() == QEvent::WindowStateChange) {
|
||||
if (win_event->oldState() & Qt::WindowMinimized) {
|
||||
if (_minimized) {
|
||||
readSettings();
|
||||
_minimized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MainFrame::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QFrame::resizeEvent(event);
|
||||
@@ -346,6 +348,7 @@ void MainFrame::writeSettings()
|
||||
QSettings settings;
|
||||
|
||||
settings.beginGroup("MainFrame");
|
||||
settings.setValue("isMax", isMaximized());
|
||||
settings.setValue("size", size());
|
||||
settings.setValue("pos", pos() +
|
||||
QPoint(geometry().left() - frameGeometry().left(), frameGeometry().right() - geometry().right()));
|
||||
@@ -357,13 +360,28 @@ void MainFrame::readSettings()
|
||||
QSettings settings;
|
||||
QDesktopWidget* desktopWidget = QApplication::desktop();
|
||||
QRect deskRect = desktopWidget->availableGeometry();
|
||||
QPoint default_upleft = QPoint((deskRect.width() - minWidth)/2, (deskRect.height() - minHeight)/2);
|
||||
QSize default_size = QSize(minWidth, minHeight);
|
||||
|
||||
settings.beginGroup("MainFrame");
|
||||
QSize size = settings.value("size", QSize(minWidth, minHeight)).toSize();
|
||||
QPoint pos = settings.value("pos", QPoint((deskRect.width() - minWidth)/2, (deskRect.height() - minHeight)/2)).toPoint();
|
||||
bool isMax = settings.value("isMax", false).toBool();
|
||||
QSize size = settings.value("size", default_size).toSize();
|
||||
QPoint pos = settings.value("pos", default_upleft).toPoint();
|
||||
settings.endGroup();
|
||||
|
||||
if (size == deskRect.size()) {
|
||||
// check the restored position is vavlid or not
|
||||
int i = 0;
|
||||
for (; i < desktopWidget->screenCount(); i++) {
|
||||
deskRect = desktopWidget->availableGeometry(i);
|
||||
if (deskRect.contains(pos))
|
||||
break;
|
||||
}
|
||||
if (i >= desktopWidget->screenCount())
|
||||
pos = default_upleft;
|
||||
|
||||
if (isMax) {
|
||||
resize(default_size);
|
||||
move(default_upleft);
|
||||
_titleBar->showMaxRestore();
|
||||
} else {
|
||||
resize(size);
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
MainFrame(DeviceManager &device_manager,
|
||||
const char *open_file_name = NULL);
|
||||
|
||||
void showMaxRestore();
|
||||
void readSettings();
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent* event);
|
||||
@@ -83,7 +83,6 @@ private:
|
||||
void show_border();
|
||||
|
||||
void writeSettings();
|
||||
void readSettings();
|
||||
|
||||
private:
|
||||
toolbars::TitleBar *_titleBar;
|
||||
|
||||
@@ -106,9 +106,6 @@ MainWindow::MainWindow(DeviceManager &device_manager,
|
||||
Qt::QueuedConnection,
|
||||
Q_ARG(QString, s));
|
||||
}
|
||||
test_timer_linked = false;
|
||||
test_timer.stop();
|
||||
test_timer.setSingleShot(true);
|
||||
}
|
||||
|
||||
void MainWindow::setup_ui()
|
||||
@@ -140,8 +137,10 @@ void MainWindow::setup_ui()
|
||||
SLOT(on_search(bool)));
|
||||
connect(_file_bar, SIGNAL(load_file(QString)), this,
|
||||
SLOT(load_file(QString)));
|
||||
connect(_file_bar, SIGNAL(save()), this,
|
||||
connect(_file_bar, SIGNAL(on_save()), this,
|
||||
SLOT(on_save()));
|
||||
connect(_file_bar, SIGNAL(on_export()), this,
|
||||
SLOT(on_export()));
|
||||
connect(_file_bar, SIGNAL(on_screenShot()), this,
|
||||
SLOT(on_screenShot()), Qt::QueuedConnection);
|
||||
connect(_file_bar, SIGNAL(load_session(QString)), this,
|
||||
@@ -149,17 +148,6 @@ void MainWindow::setup_ui()
|
||||
connect(_file_bar, SIGNAL(store_session(QString)), this,
|
||||
SLOT(store_session(QString)));
|
||||
|
||||
#ifdef ENABLE_DECODE
|
||||
// protocol dock
|
||||
_protocol_dock=new QDockWidget(tr("Protocol"),this);
|
||||
_protocol_dock->setFeatures(QDockWidget::DockWidgetMovable);
|
||||
_protocol_dock->setAllowedAreas(Qt::RightDockWidgetArea);
|
||||
_protocol_dock->setVisible(false);
|
||||
//dock::ProtocolDock *_protocol_widget = new dock::ProtocolDock(_protocol_dock, _session);
|
||||
_protocol_widget = new dock::ProtocolDock(_protocol_dock, _session);
|
||||
_protocol_dock->setWidget(_protocol_widget);
|
||||
qDebug() << "Protocol decoder enabled!\n";
|
||||
#endif
|
||||
// trigger dock
|
||||
_trigger_dock=new QDockWidget(tr("Trigger Setting..."),this);
|
||||
_trigger_dock->setFeatures(QDockWidget::DockWidgetMovable);
|
||||
@@ -189,14 +177,13 @@ void MainWindow::setup_ui()
|
||||
connect(_sampling_bar, SIGNAL(instant_stop()), this,
|
||||
SLOT(instant_stop()));
|
||||
connect(_sampling_bar, SIGNAL(sample_count_changed()), _trigger_widget,
|
||||
SLOT(device_change()));
|
||||
SLOT(device_updated()));
|
||||
connect(_sampling_bar, SIGNAL(show_calibration()), _view,
|
||||
SLOT(show_calibration()));
|
||||
connect(_sampling_bar, SIGNAL(hide_calibration()), _view,
|
||||
SLOT(hide_calibration()));
|
||||
connect(_dso_trigger_widget, SIGNAL(set_trig_pos(int)), _view,
|
||||
SLOT(set_trig_pos(int)));
|
||||
connect(_protocol_widget, SIGNAL(protocol_updated()), _view, SLOT(signals_changed()));
|
||||
|
||||
setIconSize(QSize(40,40));
|
||||
addToolBar(_sampling_bar);
|
||||
@@ -205,6 +192,19 @@ void MainWindow::setup_ui()
|
||||
addToolBar(_logo_bar);
|
||||
|
||||
// Setup the dockWidget
|
||||
#ifdef ENABLE_DECODE
|
||||
// protocol dock
|
||||
_protocol_dock=new QDockWidget(tr("Protocol"),this);
|
||||
_protocol_dock->setFeatures(QDockWidget::DockWidgetMovable);
|
||||
_protocol_dock->setAllowedAreas(Qt::RightDockWidgetArea);
|
||||
_protocol_dock->setVisible(false);
|
||||
//dock::ProtocolDock *_protocol_widget = new dock::ProtocolDock(_protocol_dock, _session);
|
||||
_protocol_widget = new dock::ProtocolDock(_protocol_dock, *_view, _session);
|
||||
_protocol_dock->setWidget(_protocol_widget);
|
||||
qDebug() << "Protocol decoder enabled!\n";
|
||||
|
||||
connect(_protocol_widget, SIGNAL(protocol_updated()), _view, SLOT(signals_changed()));
|
||||
#endif
|
||||
// measure dock
|
||||
_measure_dock=new QDockWidget(tr("Measurement"),this);
|
||||
_measure_dock->setFeatures(QDockWidget::DockWidgetMovable);
|
||||
@@ -242,19 +242,24 @@ void MainWindow::setup_ui()
|
||||
SLOT(device_attach()), Qt::QueuedConnection);
|
||||
connect(&_session, SIGNAL(device_detach()), this,
|
||||
SLOT(device_detach()), Qt::QueuedConnection);
|
||||
connect(&_session, SIGNAL(test_data_error()), this,
|
||||
SLOT(test_data_error()));
|
||||
connect(&_session, SIGNAL(malloc_error()), this,
|
||||
SLOT(malloc_error()));
|
||||
connect(&_session, SIGNAL(hardware_connect_failed()), this,
|
||||
SLOT(hardware_connect_failed()));
|
||||
connect(&_session, SIGNAL(on_mode_change()), this,
|
||||
connect(&_session, SIGNAL(session_error()), this,
|
||||
SLOT(show_error()), Qt::QueuedConnection);
|
||||
connect(&_session, SIGNAL(session_save()), this,
|
||||
SLOT(session_save()));
|
||||
connect(&_session, SIGNAL(data_updated()), _measure_widget,
|
||||
SLOT(reCalc()));
|
||||
connect(&_session, SIGNAL(repeat_resume()), this,
|
||||
SLOT(repeat_resume()));
|
||||
|
||||
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(cursor_moved()));
|
||||
SLOT(reCalc()));
|
||||
connect(_view, SIGNAL(prgRate(int)), this, SIGNAL(prgRate(int)));
|
||||
connect(_view, SIGNAL(update_device_list()),
|
||||
this, SLOT(update_device_list()), Qt::DirectConnection);
|
||||
|
||||
// event filter
|
||||
_view->installEventFilter(this);
|
||||
@@ -272,10 +277,10 @@ void MainWindow::setup_ui()
|
||||
|
||||
// Populate the device list and select the initially selected device
|
||||
_session.set_default_device(boost::bind(&MainWindow::session_error, this,
|
||||
QString("Set Default Device failed"), _1));
|
||||
QString(tr("Set Default Device failed")), _1));
|
||||
update_device_list();
|
||||
_session.start_hotplug_proc(boost::bind(&MainWindow::session_error, this,
|
||||
QString("Hotplug failed"), _1));
|
||||
QString(tr("Hotplug failed")), _1));
|
||||
}
|
||||
|
||||
void MainWindow::session_error(
|
||||
@@ -292,24 +297,45 @@ void MainWindow::update_device_list()
|
||||
|
||||
_session.stop_capture();
|
||||
_view->reload();
|
||||
_trigger_widget->device_change();
|
||||
_trigger_widget->device_updated();
|
||||
#ifdef ENABLE_DECODE
|
||||
_protocol_widget->del_all_protocol();
|
||||
#endif
|
||||
_trig_bar->reload();
|
||||
_sampling_bar->reload();
|
||||
|
||||
shared_ptr<pv::device::DevInst> selected_device = _session.get_device();
|
||||
_device_manager.add_device(selected_device);
|
||||
_sampling_bar->set_device_list(_device_manager.devices(), selected_device);
|
||||
_session.init_signals();
|
||||
|
||||
if(dynamic_pointer_cast<pv::device::File>(selected_device)) {
|
||||
shared_ptr<pv::device::File> file_dev;
|
||||
if(file_dev = dynamic_pointer_cast<pv::device::File>(selected_device)) {
|
||||
#ifdef ENABLE_DECODE
|
||||
// load decoders
|
||||
StoreSession ss(_session);
|
||||
ss.load_decoders(_protocol_widget, file_dev->get_decoders());
|
||||
#endif
|
||||
|
||||
// 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_session_error(tr("Attension"),
|
||||
tr("Current loading file has an old format. "
|
||||
"This will lead to a slow loading speed. "
|
||||
"Please resave it after loaded."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// load data
|
||||
const QString errorMessage(
|
||||
QString("Failed to capture file data!"));
|
||||
const QString infoMessage;
|
||||
QString(tr("Failed to capture file data!")));
|
||||
_session.start_capture(true, boost::bind(&MainWindow::session_error, this,
|
||||
errorMessage, infoMessage));
|
||||
errorMessage, _1));
|
||||
}
|
||||
|
||||
if (!selected_device->name().contains("virtual")) {
|
||||
@@ -332,31 +358,30 @@ void MainWindow::update_device_list()
|
||||
_file_bar->set_settings_en(false);
|
||||
_logo_bar->dsl_connected(false);
|
||||
}
|
||||
_sampling_bar->reload();
|
||||
_view->status_clear();
|
||||
_trigger_widget->init();
|
||||
_dso_trigger_widget->init();
|
||||
_measure_widget->reload();
|
||||
}
|
||||
|
||||
void MainWindow::reload()
|
||||
{
|
||||
_trigger_widget->device_change();
|
||||
_trigger_widget->device_updated();
|
||||
_session.reload();
|
||||
}
|
||||
|
||||
void MainWindow::mode_changed()
|
||||
{
|
||||
update_device_list();
|
||||
_measure_widget->reload();
|
||||
}
|
||||
|
||||
void MainWindow::load_file(QString file_name)
|
||||
{
|
||||
try {
|
||||
//_session.set_file(file_name.toStdString());
|
||||
if (strncmp(_session.get_device()->name().toLocal8Bit(), "virtual", 7))
|
||||
session_save();
|
||||
_session.set_file(file_name);
|
||||
} catch(QString e) {
|
||||
show_session_error(tr("Failed to load ") + file_name, e);
|
||||
_session.set_default_device(boost::bind(&MainWindow::session_error, this,
|
||||
QString("Set Default Device failed"), _1));
|
||||
QString(tr("Set Default Device failed")), _1));
|
||||
update_device_list();
|
||||
return;
|
||||
}
|
||||
@@ -380,8 +405,10 @@ void MainWindow::device_attach()
|
||||
_session.get_device()->device_updated();
|
||||
//_session.stop_hot_plug_proc();
|
||||
|
||||
if (_session.get_capture_state() == SigSession::Running)
|
||||
_session.stop_capture();
|
||||
_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;
|
||||
@@ -390,8 +417,9 @@ void MainWindow::device_attach()
|
||||
_device_manager.driver_scan(*driver);
|
||||
|
||||
_session.set_default_device(boost::bind(&MainWindow::session_error, this,
|
||||
QString("Set Default Device failed"), _1));
|
||||
QString(tr("Set Default Device failed")), _1));
|
||||
update_device_list();
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::device_detach()
|
||||
@@ -399,8 +427,10 @@ void MainWindow::device_detach()
|
||||
_session.get_device()->device_updated();
|
||||
//_session.stop_hot_plug_proc();
|
||||
|
||||
if (_session.get_capture_state() == SigSession::Running)
|
||||
_session.stop_capture();
|
||||
_session.set_repeating(false);
|
||||
_session.stop_capture();
|
||||
_sampling_bar->set_sampling(false);
|
||||
_session.capture_state_changed(SigSession::Stopped);
|
||||
|
||||
session_save();
|
||||
_view->hide_calibration();
|
||||
@@ -412,120 +442,143 @@ void MainWindow::device_detach()
|
||||
_device_manager.driver_scan(*driver);
|
||||
|
||||
_session.set_default_device(boost::bind(&MainWindow::session_error, this,
|
||||
QString("Set Default Device failed"), _1));
|
||||
QString(tr("Set Default Device failed")), _1));
|
||||
update_device_list();
|
||||
}
|
||||
|
||||
void MainWindow::run_stop()
|
||||
{
|
||||
#ifdef TEST_MODE
|
||||
if (!test_timer_linked) {
|
||||
connect(&test_timer, SIGNAL(timeout()),
|
||||
this, SLOT(run_stop()));
|
||||
test_timer_linked = true;
|
||||
}
|
||||
#endif
|
||||
switch(_session.get_capture_state()) {
|
||||
case SigSession::Init:
|
||||
case SigSession::Stopped:
|
||||
if (_session.get_device()->dev_inst()->mode == DSO)
|
||||
_view->show_trig_cursor(true);
|
||||
else
|
||||
_view->show_trig_cursor(false);
|
||||
_view->update_sample(false);
|
||||
commit_trigger(false);
|
||||
_session.start_capture(false,
|
||||
boost::bind(&MainWindow::session_error, this,
|
||||
QString("Capture failed"), _1));
|
||||
break;
|
||||
|
||||
case SigSession::Running:
|
||||
_session.stop_capture();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::instant_stop()
|
||||
{
|
||||
#ifdef TEST_MODE
|
||||
if (!test_timer_linked) {
|
||||
connect(&test_timer, SIGNAL(timeout()),
|
||||
this, SLOT(instant_stop()));
|
||||
test_timer_linked = true;
|
||||
}
|
||||
#endif
|
||||
switch(_session.get_capture_state()) {
|
||||
case SigSession::Init:
|
||||
case SigSession::Stopped:
|
||||
if (_session.get_device()->dev_inst()->mode == DSO)
|
||||
_view->show_trig_cursor(true);
|
||||
else
|
||||
_view->show_trig_cursor(false);
|
||||
_view->update_sample(true);
|
||||
commit_trigger(true);
|
||||
_session.start_capture(true,
|
||||
_view->capture_init(false);
|
||||
commit_trigger(false);
|
||||
_session.start_capture(false,
|
||||
boost::bind(&MainWindow::session_error, this,
|
||||
QString("Capture failed"), _1));
|
||||
QString(tr("Capture failed")), _1));
|
||||
break;
|
||||
|
||||
case SigSession::Running:
|
||||
_session.stop_capture();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::test_data_error()
|
||||
void MainWindow::instant_stop()
|
||||
{
|
||||
switch(_session.get_capture_state()) {
|
||||
case SigSession::Init:
|
||||
case SigSession::Stopped:
|
||||
_view->capture_init(true);
|
||||
commit_trigger(true);
|
||||
_session.start_capture(true,
|
||||
boost::bind(&MainWindow::session_error, this,
|
||||
QString(tr("Capture failed")), _1));
|
||||
break;
|
||||
|
||||
case SigSession::Running:
|
||||
_session.stop_capture();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::repeat_resume()
|
||||
{
|
||||
while(_view->session().get_capture_state() == SigSession::Running)
|
||||
QCoreApplication::processEvents();
|
||||
run_stop();
|
||||
}
|
||||
|
||||
void MainWindow::show_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;
|
||||
}
|
||||
|
||||
_session.stop_capture();
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Data Error"));
|
||||
msg.mBox()->setInformativeText(tr("the receive data are not consist with pre-defined test data"));
|
||||
connect(_session.get_device().get(), 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();
|
||||
}
|
||||
|
||||
void MainWindow::malloc_error()
|
||||
{
|
||||
_session.stop_capture();
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Malloc Error"));
|
||||
msg.mBox()->setInformativeText(tr("Memory is not enough for this sample!\nPlease reduce the sample depth!"));
|
||||
msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
}
|
||||
|
||||
void MainWindow::hardware_connect_failed()
|
||||
{
|
||||
_session.stop_capture();
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Hardware Connect Failed"));
|
||||
msg.mBox()->setInformativeText(tr("Please check hardware connection!"));
|
||||
msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
_session.clear_error();
|
||||
}
|
||||
|
||||
void MainWindow::capture_state_changed(int state)
|
||||
{
|
||||
_file_bar->enable_toggle(state != SigSession::Running);
|
||||
_sampling_bar->set_sampling(state == SigSession::Running);
|
||||
_view->on_state_changed(state != SigSession::Running);
|
||||
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 (_session.get_device()->dev_inst()->mode != DSO) {
|
||||
_sampling_bar->enable_toggle(state != SigSession::Running);
|
||||
_trig_bar->enable_toggle(state != SigSession::Running);
|
||||
_measure_dock->widget()->setEnabled(state != SigSession::Running);
|
||||
if (_session.get_device()->dev_inst()->mode != DSO) {
|
||||
_sampling_bar->enable_toggle(state != SigSession::Running);
|
||||
_trig_bar->enable_toggle(state != SigSession::Running);
|
||||
//_measure_dock->widget()->setEnabled(state != SigSession::Running);
|
||||
_measure_widget->refresh();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TEST_MODE
|
||||
if (state == SigSession::Stopped) {
|
||||
test_timer.start(qrand()%1000);
|
||||
prgRate(0);
|
||||
_view->repeat_unshow();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::session_save()
|
||||
@@ -542,8 +595,9 @@ void MainWindow::session_save()
|
||||
QString mode_name = QString::number(_session.get_device()->dev_inst()->mode);
|
||||
QString file_name = dir.absolutePath() + "/" + driver_name + mode_name + ".dsc";
|
||||
if (strncmp(driver_name.toLocal8Bit(), "virtual", 7) &&
|
||||
!file_name.isEmpty())
|
||||
!file_name.isEmpty()) {
|
||||
store_session(file_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -629,35 +683,21 @@ void MainWindow::on_screenShot()
|
||||
void MainWindow::on_save()
|
||||
{
|
||||
using pv::dialogs::StoreProgress;
|
||||
StoreProgress *dlg = new StoreProgress(_session, this);
|
||||
dlg->save_run();
|
||||
}
|
||||
|
||||
const QString DIR_KEY("SavePath");
|
||||
QSettings settings;
|
||||
|
||||
// Stop any currently running capture session
|
||||
_session.stop_capture();
|
||||
|
||||
// Show the dialog
|
||||
const QString file_name = QFileDialog::getSaveFileName(
|
||||
this, tr("Save File"), settings.value(DIR_KEY).toString(), tr("DSView Data (*.dsl)"));
|
||||
|
||||
if (file_name.isEmpty())
|
||||
return;
|
||||
QDir CurrentDir;
|
||||
settings.setValue(DIR_KEY, CurrentDir.absoluteFilePath(file_name));
|
||||
StoreProgress *dlg = new StoreProgress(file_name, _session, this);
|
||||
dlg->run();
|
||||
void MainWindow::on_export()
|
||||
{
|
||||
using pv::dialogs::StoreProgress;
|
||||
StoreProgress *dlg = new StoreProgress(_session, this);
|
||||
dlg->export_run();
|
||||
}
|
||||
|
||||
bool MainWindow::load_session(QString name)
|
||||
{
|
||||
QFile sessionFile(name);
|
||||
if (!sessionFile.open(QIODevice::ReadOnly)) {
|
||||
// dialogs::DSMessageBox msg(this);
|
||||
// msg.mBox()->setText(tr("File Error"));
|
||||
// msg.mBox()->setInformativeText(tr("Couldn't open session file!"));
|
||||
// msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
// msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
// msg.exec();
|
||||
qDebug("Warning: Couldn't open session file!");
|
||||
return false;
|
||||
}
|
||||
@@ -666,6 +706,11 @@ bool MainWindow::load_session(QString name)
|
||||
QJsonDocument sessionDoc = QJsonDocument::fromJson(sessionData.toUtf8());
|
||||
QJsonObject sessionObj = sessionDoc.object();
|
||||
|
||||
// check session file version
|
||||
if (!sessionObj.contains("Version") ||
|
||||
sessionObj["Version"].toInt() != Session_Version)
|
||||
return false;
|
||||
|
||||
// check device and mode
|
||||
const sr_dev_inst *const sdi = _session.get_device()->dev_inst();
|
||||
if (strcmp(sdi->driver->name, sessionObj["Device"].toString().toLocal8Bit()) != 0 ||
|
||||
@@ -729,6 +774,9 @@ bool MainWindow::load_session(QString name)
|
||||
if (!isEnabled)
|
||||
probe->enabled = false;
|
||||
}
|
||||
_sampling_bar->update_record_length();
|
||||
_trigger_widget->device_updated();
|
||||
|
||||
//_session.init_signals();
|
||||
_session.reload();
|
||||
|
||||
@@ -749,7 +797,7 @@ bool MainWindow::load_session(QString name)
|
||||
boost::shared_ptr<view::DsoSignal> dsoSig;
|
||||
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(s)) {
|
||||
dsoSig->load_settings();
|
||||
dsoSig->set_zero_vrate(obj["zeroPos"].toDouble());
|
||||
dsoSig->set_zero_vrate(obj["zeroPos"].toDouble(), true);
|
||||
dsoSig->set_trig_vrate(obj["trigValue"].toDouble());
|
||||
dsoSig->commit_settings();
|
||||
}
|
||||
@@ -763,6 +811,14 @@ bool MainWindow::load_session(QString name)
|
||||
_trigger_widget->set_session(sessionObj["trigger"].toObject());
|
||||
}
|
||||
on_trigger(false);
|
||||
|
||||
#ifdef ENABLE_DECODE
|
||||
// load decoders
|
||||
if (sessionObj.contains("decoder")) {
|
||||
StoreSession ss(_session);
|
||||
ss.load_decoders(_protocol_widget, sessionObj["decoder"].toArray());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MainWindow::store_session(QString name)
|
||||
@@ -787,8 +843,8 @@ bool MainWindow::store_session(QString name)
|
||||
gsize num_opts;
|
||||
const sr_dev_inst *const sdi = _session.get_device()->dev_inst();
|
||||
QJsonObject sessionVar;
|
||||
QJsonObject triggerVar;
|
||||
QJsonArray channelVar;
|
||||
sessionVar["Version"]= QJsonValue::fromVariant(Session_Version);
|
||||
sessionVar["Device"] = QJsonValue::fromVariant(sdi->driver->name);
|
||||
sessionVar["DeviceMode"] = QJsonValue::fromVariant(sdi->mode);
|
||||
|
||||
@@ -844,6 +900,10 @@ bool MainWindow::store_session(QString name)
|
||||
sessionVar["trigger"] = _trigger_widget->get_session();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_DECODE
|
||||
StoreSession ss(_session);
|
||||
sessionVar["decoder"] = ss.json_decoders();
|
||||
#endif
|
||||
|
||||
QJsonDocument sessionDoc(sessionVar);
|
||||
//sessionFile.write(QString::fromUtf8(sessionDoc.toJson()));
|
||||
@@ -888,11 +948,11 @@ bool MainWindow::eventFilter(QObject *object, QEvent *event)
|
||||
break;
|
||||
case Qt::Key_PageUp:
|
||||
_view->set_scale_offset(_view->scale(),
|
||||
_view->offset() - _view->scale()*_view->get_view_width());
|
||||
_view->offset() - _view->get_view_width());
|
||||
break;
|
||||
case Qt::Key_PageDown:
|
||||
_view->set_scale_offset(_view->scale(),
|
||||
_view->offset() + _view->scale()*_view->get_view_width());
|
||||
_view->offset() + _view->get_view_width());
|
||||
|
||||
break;
|
||||
case Qt::Key_Left:
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <list>
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QTimer>
|
||||
|
||||
#include "sigsession.h"
|
||||
|
||||
@@ -59,10 +58,6 @@ class MeasureDock;
|
||||
class SearchDock;
|
||||
}
|
||||
|
||||
namespace dialogs{
|
||||
class Calibration;
|
||||
}
|
||||
|
||||
namespace view {
|
||||
class View;
|
||||
}
|
||||
@@ -71,6 +66,9 @@ class MainWindow : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
static constexpr int Session_Version = 2;
|
||||
|
||||
public:
|
||||
explicit MainWindow(DeviceManager &device_manager,
|
||||
const char *open_file_name = NULL,
|
||||
@@ -100,8 +98,6 @@ private slots:
|
||||
*/
|
||||
void update_device_list();
|
||||
|
||||
void mode_changed();
|
||||
|
||||
void reload();
|
||||
|
||||
void show_session_error(
|
||||
@@ -111,10 +107,6 @@ private slots:
|
||||
|
||||
void instant_stop();
|
||||
|
||||
void test_data_error();
|
||||
|
||||
void malloc_error();
|
||||
|
||||
void capture_state_changed(int state);
|
||||
|
||||
void on_protocol(bool visible);
|
||||
@@ -131,9 +123,16 @@ private slots:
|
||||
|
||||
void on_save();
|
||||
|
||||
void on_export();
|
||||
|
||||
bool load_session(QString name);
|
||||
bool store_session(QString name);
|
||||
|
||||
/*
|
||||
* repeat
|
||||
*/
|
||||
void repeat_resume();
|
||||
|
||||
/*
|
||||
* hotplug slot function
|
||||
*/
|
||||
@@ -143,7 +142,9 @@ private slots:
|
||||
/*
|
||||
* errors
|
||||
*/
|
||||
void hardware_connect_failed();
|
||||
void show_error();
|
||||
signals:
|
||||
void prgRate(int progress);
|
||||
|
||||
private:
|
||||
DeviceManager &_device_manager;
|
||||
@@ -187,9 +188,6 @@ private:
|
||||
dock::MeasureDock *_measure_widget;
|
||||
QDockWidget *_search_dock;
|
||||
dock::SearchDock * _search_widget;
|
||||
|
||||
QTimer test_timer;
|
||||
bool test_timer_linked;
|
||||
};
|
||||
|
||||
} // namespace pv
|
||||
|
||||
@@ -79,6 +79,18 @@ QWidget* Binding::get_property_form(QWidget *parent,
|
||||
return form;
|
||||
}
|
||||
|
||||
std::map< boost::shared_ptr<Property>,
|
||||
GVariant* >& Binding::get_property_value() const
|
||||
{
|
||||
std::map < boost::shared_ptr<Property>,
|
||||
GVariant* > pvalue;
|
||||
BOOST_FOREACH(shared_ptr<pv::prop::Property> p, _properties)
|
||||
{
|
||||
assert(p);
|
||||
pvalue[p] = p->get_value();
|
||||
}
|
||||
}
|
||||
|
||||
QString Binding::print_gvariant(GVariant *const gvar)
|
||||
{
|
||||
QString s;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <glib.h>
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include <QString>
|
||||
@@ -54,6 +55,9 @@ public:
|
||||
QWidget* get_property_form(QWidget *parent,
|
||||
bool auto_commit = false) const;
|
||||
|
||||
std::map< boost::shared_ptr<Property>,
|
||||
GVariant* >& get_property_value() const;
|
||||
|
||||
static QString print_gvariant(GVariant *const gvar);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -87,6 +87,7 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) :
|
||||
case SR_CONF_COUPLING:
|
||||
case SR_CONF_EN_CH:
|
||||
case SR_CONF_OPERATION_MODE:
|
||||
case SR_CONF_BUFFER_OPTIONS:
|
||||
case SR_CONF_THRESHOLD:
|
||||
case SR_CONF_ZERO:
|
||||
case SR_CONF_STREAM:
|
||||
|
||||
@@ -45,14 +45,16 @@ public:
|
||||
DecoderOptions(boost::shared_ptr<pv::data::DecoderStack> decoder_stack,
|
||||
boost::shared_ptr<pv::data::decode::Decoder> decoder);
|
||||
|
||||
GVariant* getter(const char *id);
|
||||
|
||||
void setter(const char *id, GVariant *value);
|
||||
|
||||
private:
|
||||
static boost::shared_ptr<Property> bind_enum(const QString &name,
|
||||
const srd_decoder_option *option,
|
||||
Property::Getter getter, Property::Setter setter);
|
||||
|
||||
GVariant* getter(const char *id);
|
||||
|
||||
void setter(const char *id, GVariant *value);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<pv::data::DecoderStack> _decoder_stack;
|
||||
|
||||
@@ -69,6 +69,13 @@ bool Bool::labeled_widget() const
|
||||
return true;
|
||||
}
|
||||
|
||||
GVariant* Bool::get_value() const
|
||||
{
|
||||
GVariant *const value = _getter ? _getter() : NULL;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void Bool::commit()
|
||||
{
|
||||
assert(_setter);
|
||||
|
||||
@@ -42,6 +42,8 @@ public:
|
||||
QWidget* get_widget(QWidget *parent, bool auto_commit);
|
||||
bool labeled_widget() const;
|
||||
|
||||
GVariant* get_value() const;
|
||||
|
||||
void commit();
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -42,5 +42,10 @@ bool Property::labeled_widget() const
|
||||
return false;
|
||||
}
|
||||
|
||||
GVariant* Property::get_value() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
} // prop
|
||||
} // pv
|
||||
|
||||
@@ -53,6 +53,8 @@ public:
|
||||
bool auto_commit = false) = 0;
|
||||
virtual bool labeled_widget() const;
|
||||
|
||||
virtual GVariant* get_value() const;
|
||||
|
||||
virtual void commit() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
@@ -89,7 +89,13 @@ SigSession* SigSession::_session = NULL;
|
||||
SigSession::SigSession(DeviceManager &device_manager) :
|
||||
_device_manager(device_manager),
|
||||
_capture_state(Init),
|
||||
_instant(false)
|
||||
_instant(false),
|
||||
_error(No_err),
|
||||
_run_mode(Single),
|
||||
_repeat_intvl(1),
|
||||
_repeating(false),
|
||||
_repeat_hold_prg(0),
|
||||
_map_zoom(0)
|
||||
{
|
||||
// TODO: This should not be necessary
|
||||
_session = this;
|
||||
@@ -99,11 +105,11 @@ SigSession::SigSession(DeviceManager &device_manager) :
|
||||
register_hotplug_callback();
|
||||
_view_timer.stop();
|
||||
_noData_cnt = 0;
|
||||
_refresh_timer.stop();
|
||||
_refresh_timer.setSingleShot(true);
|
||||
_data_lock = false;
|
||||
_data_updated = false;
|
||||
#ifdef ENABLE_DECODE
|
||||
_decoder_model = new pv::data::DecoderModel(this);
|
||||
#endif
|
||||
|
||||
// Create snapshots & data containers
|
||||
_cur_logic_snapshot.reset(new data::LogicSnapshot());
|
||||
@@ -119,12 +125,6 @@ SigSession::SigSession(DeviceManager &device_manager) :
|
||||
_group_cnt = 0;
|
||||
|
||||
connect(&_view_timer, SIGNAL(timeout()), this, SLOT(check_update()));
|
||||
connect(&_refresh_timer, SIGNAL(timeout()), this, SLOT(data_unlock()));
|
||||
|
||||
#ifdef TEST_MODE
|
||||
_test_timer.setSingleShot(true);
|
||||
connect(&_test_timer, SIGNAL(timeout()), this, SLOT(stop_capture()));
|
||||
#endif
|
||||
}
|
||||
|
||||
SigSession::~SigSession()
|
||||
@@ -172,6 +172,11 @@ void SigSession::set_device(boost::shared_ptr<device::DevInst> dev_inst) throw(Q
|
||||
_dev_inst->use(this);
|
||||
_cur_samplerate = _dev_inst->get_sample_rate();
|
||||
_cur_samplelimits = _dev_inst->get_sample_limit();
|
||||
|
||||
if (_dev_inst->dev_inst()->mode == DSO)
|
||||
set_run_mode(Repetitive);
|
||||
else
|
||||
set_run_mode(Single);
|
||||
} catch(const QString e) {
|
||||
throw(e);
|
||||
return;
|
||||
@@ -200,222 +205,6 @@ void SigSession::set_file(QString name) throw(QString)
|
||||
}
|
||||
}
|
||||
|
||||
void SigSession::save_file(const QString name, QWidget* parent, int type){
|
||||
unsigned char* data;
|
||||
int unit_size;
|
||||
uint64_t sample_count;
|
||||
if (type == ANALOG) {
|
||||
const deque< boost::shared_ptr<pv::data::AnalogSnapshot> > &snapshots =
|
||||
_analog_data->get_snapshots();
|
||||
if (snapshots.empty())
|
||||
return;
|
||||
const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot =
|
||||
snapshots.front();
|
||||
data = (unsigned char*)snapshot->get_data();
|
||||
unit_size = snapshot->unit_size();
|
||||
sample_count = snapshot->get_sample_count();
|
||||
} else if (type == DSO) {
|
||||
const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
|
||||
_dso_data->get_snapshots();
|
||||
if (snapshots.empty())
|
||||
return;
|
||||
const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot =
|
||||
snapshots.front();
|
||||
data = (unsigned char*)snapshot->get_data();
|
||||
// snapshot->unit_size() is not valid for dso, replaced by enabled channel number
|
||||
unit_size = get_ch_num(SR_CHANNEL_DSO);
|
||||
sample_count = snapshot->get_sample_count();
|
||||
} else {
|
||||
const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
|
||||
_logic_data->get_snapshots();
|
||||
if (snapshots.empty())
|
||||
return;
|
||||
const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
|
||||
snapshots.front();
|
||||
data = (unsigned char*)snapshot->get_data();
|
||||
unit_size = snapshot->unit_size();
|
||||
sample_count = snapshot->get_sample_count();
|
||||
}
|
||||
|
||||
QFuture<void> future;
|
||||
future = QtConcurrent::run([&]{
|
||||
sr_session_save(name.toLocal8Bit().data(), _dev_inst->dev_inst(),
|
||||
data, unit_size, sample_count, _trigger_time.toMSecsSinceEpoch(), _trigger_pos);
|
||||
});
|
||||
Qt::WindowFlags flags = Qt::CustomizeWindowHint;
|
||||
QProgressDialog dlg(tr("Save Capture to File... It can take a while."),
|
||||
tr("Cancel"),0,0,parent,flags);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
|
||||
dlg.setCancelButton(NULL);
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
watcher.setFuture(future);
|
||||
connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel()));
|
||||
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
QList<QString> SigSession::getSuportedExportFormats(){
|
||||
const struct sr_output_module** supportedModules = sr_output_list();
|
||||
QList<QString> list;
|
||||
while(*supportedModules){
|
||||
if(*supportedModules == NULL)
|
||||
break;
|
||||
if (_dev_inst->dev_inst()->mode == DSO && strcmp((*supportedModules)->id, "csv"))
|
||||
break;
|
||||
QString format((*supportedModules)->desc);
|
||||
format.append(" (*.");
|
||||
format.append((*supportedModules)->id);
|
||||
format.append(")");
|
||||
list.append(format);
|
||||
supportedModules++;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void SigSession::cancelSaveFile(){
|
||||
saveFileThreadRunning = false;
|
||||
}
|
||||
|
||||
void SigSession::export_file(const QString name, QWidget* parent, const QString ext){
|
||||
boost::shared_ptr<pv::data::Snapshot> snapshot;
|
||||
int channel_type;
|
||||
|
||||
if (_dev_inst->dev_inst()->mode == LOGIC) {
|
||||
const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
|
||||
_logic_data->get_snapshots();
|
||||
if(snapshots.empty())
|
||||
return;
|
||||
snapshot = snapshots.front();
|
||||
channel_type = SR_CHANNEL_LOGIC;
|
||||
} else if (_dev_inst->dev_inst()->mode == DSO) {
|
||||
const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
|
||||
_dso_data->get_snapshots();
|
||||
if(snapshots.empty())
|
||||
return;
|
||||
snapshot = snapshots.front();
|
||||
channel_type = SR_CHANNEL_DSO;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
const struct sr_output_module** supportedModules = sr_output_list();
|
||||
const struct sr_output_module* outModule = NULL;
|
||||
while(*supportedModules){
|
||||
if(*supportedModules == NULL)
|
||||
break;
|
||||
if(!strcmp((*supportedModules)->id, ext.toLocal8Bit().data())){
|
||||
outModule = *supportedModules;
|
||||
break;
|
||||
}
|
||||
supportedModules++;
|
||||
}
|
||||
if(outModule == NULL)
|
||||
return;
|
||||
|
||||
|
||||
GHashTable *params = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
GVariant* filenameGVariant = g_variant_new_bytestring(name.toLocal8Bit().data());
|
||||
g_hash_table_insert(params, (char*)"filename", filenameGVariant);
|
||||
GVariant* typeGVariant = g_variant_new_int16(channel_type);
|
||||
g_hash_table_insert(params, (char*)"type", typeGVariant);
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _signals) {
|
||||
boost::shared_ptr<view::DsoSignal> dsoSig;
|
||||
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(s)) {
|
||||
GVariant* timebaseGVariant = g_variant_new_uint64(dsoSig->get_hDialValue());
|
||||
g_hash_table_insert(params, (char*)"timebase", timebaseGVariant);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct sr_output output;
|
||||
output.module = (sr_output_module*) outModule;
|
||||
output.sdi = _dev_inst->dev_inst();
|
||||
output.param = NULL;
|
||||
if(outModule->init)
|
||||
outModule->init(&output, params);
|
||||
QFile file(name);
|
||||
file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
QTextStream out(&file);
|
||||
out.setCodec("UTF-8");
|
||||
out.setGenerateByteOrderMark(true);
|
||||
QFuture<void> future;
|
||||
if (_dev_inst->dev_inst()->mode == LOGIC) {
|
||||
future = QtConcurrent::run([&]{
|
||||
saveFileThreadRunning = true;
|
||||
unsigned char* datat = (unsigned char*)snapshot->get_data();
|
||||
unsigned int numsamples = snapshot->get_sample_count()*snapshot->unit_size();
|
||||
GString *data_out;
|
||||
unsigned int usize = 8192;
|
||||
unsigned int size = usize;
|
||||
struct sr_datafeed_logic lp;
|
||||
struct sr_datafeed_packet p;
|
||||
for(uint64_t i = 0; i < numsamples; i+=usize){
|
||||
if(numsamples - i < usize)
|
||||
size = numsamples - i;
|
||||
lp.data = &datat[i];
|
||||
lp.length = size;
|
||||
lp.unitsize = snapshot->unit_size();
|
||||
p.type = SR_DF_LOGIC;
|
||||
p.payload = &lp;
|
||||
outModule->receive(&output, &p, &data_out);
|
||||
if(data_out){
|
||||
out << QString::fromUtf8((char*) data_out->str);
|
||||
g_string_free(data_out,TRUE);
|
||||
}
|
||||
emit progressSaveFileValueChanged(i*100/numsamples);
|
||||
if(!saveFileThreadRunning)
|
||||
break;
|
||||
}
|
||||
});
|
||||
} else if (_dev_inst->dev_inst()->mode == DSO) {
|
||||
future = QtConcurrent::run([&]{
|
||||
saveFileThreadRunning = true;
|
||||
unsigned char* datat = (unsigned char*)snapshot->get_data();
|
||||
unsigned int numsamples = snapshot->get_sample_count();
|
||||
GString *data_out;
|
||||
unsigned int usize = 8192;
|
||||
unsigned int size = usize;
|
||||
struct sr_datafeed_dso dp;
|
||||
struct sr_datafeed_packet p;
|
||||
for(uint64_t i = 0; i < numsamples; i+=usize){
|
||||
if(numsamples - i < usize)
|
||||
size = numsamples - i;
|
||||
dp.data = &datat[i*snapshot->get_channel_num()];
|
||||
dp.num_samples = size;
|
||||
p.type = SR_DF_DSO;
|
||||
p.payload = &dp;
|
||||
outModule->receive(&output, &p, &data_out);
|
||||
if(data_out){
|
||||
out << (char*) data_out->str;
|
||||
g_string_free(data_out,TRUE);
|
||||
}
|
||||
emit progressSaveFileValueChanged(i*100/numsamples);
|
||||
if(!saveFileThreadRunning)
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
QFutureWatcher<void> watcher;
|
||||
Qt::WindowFlags flags = Qt::CustomizeWindowHint;
|
||||
QProgressDialog dlg(tr("Exporting data... It can take a while."),
|
||||
tr("Cancel"),0,100,parent,flags);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
watcher.setFuture(future);
|
||||
connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel()));
|
||||
connect(this,SIGNAL(progressSaveFileValueChanged(int)),&dlg,SLOT(setValue(int)));
|
||||
connect(&dlg,SIGNAL(canceled()),this,SLOT(cancelSaveFile()));
|
||||
dlg.exec();
|
||||
future.waitForFinished();
|
||||
// optional, as QFile destructor will already do it:
|
||||
file.close();
|
||||
outModule->cleanup(&output);
|
||||
g_hash_table_destroy(params);
|
||||
g_variant_unref(filenameGVariant);
|
||||
}
|
||||
|
||||
void SigSession::set_default_device(boost::function<void (const QString)> error_handler)
|
||||
{
|
||||
boost::shared_ptr<pv::device::DevInst> default_device;
|
||||
@@ -511,9 +300,13 @@ void SigSession::set_cur_samplelimits(uint64_t samplelimits)
|
||||
|
||||
void SigSession::capture_init()
|
||||
{
|
||||
if (!_instant)
|
||||
set_repeating(get_run_mode() == Repetitive);
|
||||
_cur_samplerate = _dev_inst->get_sample_rate();
|
||||
_cur_samplelimits = _dev_inst->get_sample_limit();
|
||||
_data_updated = false;
|
||||
_trigger_flag = false;
|
||||
_hw_replied = false;
|
||||
if (_dev_inst->dev_inst()->mode != LOGIC)
|
||||
_view_timer.start(ViewTime);
|
||||
else
|
||||
@@ -522,11 +315,7 @@ void SigSession::capture_init()
|
||||
data_unlock();
|
||||
|
||||
// Init and Set sample rate for all SignalData
|
||||
// Logic/Analog/Dso
|
||||
if (_logic_data) {
|
||||
_logic_data->init();
|
||||
_logic_data->set_samplerate(_cur_samplerate);
|
||||
}
|
||||
// Analog/Dso
|
||||
if (_analog_data) {
|
||||
_analog_data->init();
|
||||
_analog_data->set_samplerate(_cur_samplerate);
|
||||
@@ -535,12 +324,42 @@ void SigSession::capture_init()
|
||||
_dso_data->init();
|
||||
_dso_data->set_samplerate(_cur_samplerate);
|
||||
}
|
||||
|
||||
// MathStack
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::MathTrace> m, _math_traces)
|
||||
{
|
||||
assert(m);
|
||||
m->get_math_stack()->init();
|
||||
m->get_math_stack()->set_samplerate(_cur_samplerate);
|
||||
}
|
||||
|
||||
// update current hw offset
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _signals)
|
||||
{
|
||||
assert(s);
|
||||
boost::shared_ptr<view::DsoSignal> dsoSig;
|
||||
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(s)) {
|
||||
dsoSig->set_zero_vrate(dsoSig->get_zero_vrate(), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SigSession::logic_init()
|
||||
{
|
||||
// Logic
|
||||
if (_logic_data) {
|
||||
_logic_data->init();
|
||||
_logic_data->set_samplerate(_cur_samplerate);
|
||||
}
|
||||
// Group
|
||||
if (_group_data) {
|
||||
_group_data->init();
|
||||
_group_data->set_samplerate(_cur_samplerate);
|
||||
}
|
||||
#ifdef ENABLE_DECODE
|
||||
// DecoderModel
|
||||
pv::data::DecoderModel *decoder_model = get_decoder_model();
|
||||
decoder_model->setDecoderStack(NULL);
|
||||
// DecoderStack
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::DecodeTrace> d, _decode_traces)
|
||||
{
|
||||
@@ -549,29 +368,36 @@ void SigSession::capture_init()
|
||||
d->decoder()->set_samplerate(_cur_samplerate);
|
||||
}
|
||||
#endif
|
||||
// MathStack
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::MathTrace> m, _math_traces)
|
||||
{
|
||||
assert(m);
|
||||
m->get_math_stack()->init();
|
||||
m->get_math_stack()->set_samplerate(_cur_samplerate);
|
||||
}
|
||||
}
|
||||
|
||||
void SigSession::start_capture(bool instant,
|
||||
boost::function<void (const QString)> error_handler)
|
||||
{
|
||||
stop_capture();
|
||||
capture_init();
|
||||
|
||||
// Check that a device instance has been selected.
|
||||
// Check that a device instance has been selected.
|
||||
if (!_dev_inst) {
|
||||
qDebug() << "No device selected";
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "No device selected";
|
||||
capture_state_changed(SigSession::Stopped);
|
||||
return;
|
||||
}
|
||||
assert(_dev_inst->dev_inst());
|
||||
|
||||
if (!_dev_inst->is_usable()) {
|
||||
_error = Hw_err;
|
||||
session_error();
|
||||
capture_state_changed(SigSession::Stopped);
|
||||
return;
|
||||
}
|
||||
|
||||
// stop previous capture
|
||||
stop_capture();
|
||||
|
||||
// update setting
|
||||
if (_dev_inst->name() != "virtual-session")
|
||||
_instant = instant;
|
||||
else
|
||||
_instant = true;
|
||||
capture_init();
|
||||
|
||||
// Check that at least one probe is enabled
|
||||
const GSList *l;
|
||||
for (l = _dev_inst->dev_inst()->channels; l; l = l->next) {
|
||||
@@ -583,16 +409,11 @@ void SigSession::start_capture(bool instant,
|
||||
if (!l) {
|
||||
error_handler(tr("No probes enabled."));
|
||||
data_updated();
|
||||
set_repeating(false);
|
||||
capture_state_changed(SigSession::Stopped);
|
||||
return;
|
||||
}
|
||||
|
||||
// update setting
|
||||
if (_dev_inst->name() != "virtual-session")
|
||||
_instant = instant;
|
||||
else
|
||||
_instant = true;
|
||||
|
||||
// Begin the session
|
||||
_sampling_thread.reset(new boost::thread(
|
||||
&SigSession::sample_thread_proc, this, _dev_inst,
|
||||
@@ -619,6 +440,30 @@ void SigSession::stop_capture()
|
||||
_sampling_thread.reset();
|
||||
}
|
||||
|
||||
bool SigSession::get_capture_status(bool &triggered, int &progress)
|
||||
{
|
||||
uint64_t sample_limits = cur_samplelimits();
|
||||
sr_status status;
|
||||
if (sr_status_get(_dev_inst->dev_inst(), &status, SR_STATUS_TRIG_BEGIN, SR_STATUS_TRIG_END) == SR_OK){
|
||||
triggered = status.trig_hit & 0x01;
|
||||
const bool captured_cnt_dec = status.trig_hit & 0x02;
|
||||
uint64_t captured_cnt = status.trig_hit >> 2;
|
||||
captured_cnt = ((uint64_t)status.captured_cnt0 +
|
||||
((uint64_t)status.captured_cnt1 << 8) +
|
||||
((uint64_t)status.captured_cnt2 << 16) +
|
||||
((uint64_t)status.captured_cnt3 << 24) +
|
||||
(captured_cnt << 32));
|
||||
if (_dev_inst->dev_inst()->mode == DSO)
|
||||
captured_cnt = captured_cnt * _signals.size() / get_ch_num(SR_CHANNEL_DSO);
|
||||
if (captured_cnt_dec)
|
||||
progress = (sample_limits - captured_cnt) * 100.0 / sample_limits;
|
||||
else
|
||||
progress = captured_cnt * 100.0 / sample_limits;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
vector< boost::shared_ptr<view::Signal> > SigSession::get_signals()
|
||||
{
|
||||
//boost::lock_guard<boost::mutex> lock(_signals_mutex);
|
||||
@@ -648,47 +493,6 @@ bool SigSession::get_instant()
|
||||
return _instant;
|
||||
}
|
||||
|
||||
const void* SigSession::get_buf(int& unit_size, uint64_t &length)
|
||||
{
|
||||
if (_dev_inst->dev_inst()->mode == LOGIC) {
|
||||
const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
|
||||
_logic_data->get_snapshots();
|
||||
if (snapshots.empty())
|
||||
return NULL;
|
||||
|
||||
const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
|
||||
snapshots.front();
|
||||
|
||||
unit_size = snapshot->unit_size();
|
||||
length = snapshot->get_sample_count();
|
||||
return snapshot->get_data();
|
||||
} else if (_dev_inst->dev_inst()->mode == DSO) {
|
||||
const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
|
||||
_dso_data->get_snapshots();
|
||||
if (snapshots.empty())
|
||||
return NULL;
|
||||
|
||||
const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot =
|
||||
snapshots.front();
|
||||
|
||||
unit_size = snapshot->unit_size();
|
||||
length = snapshot->get_sample_count();
|
||||
return snapshot->get_data();
|
||||
} else {
|
||||
const deque< boost::shared_ptr<pv::data::AnalogSnapshot> > &snapshots =
|
||||
_analog_data->get_snapshots();
|
||||
if (snapshots.empty())
|
||||
return NULL;
|
||||
|
||||
const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot =
|
||||
snapshots.front();
|
||||
|
||||
unit_size = snapshot->unit_size();
|
||||
length = snapshot->get_sample_count();
|
||||
return snapshot->get_data();
|
||||
}
|
||||
}
|
||||
|
||||
void SigSession::set_capture_state(capture_state state)
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(_sampling_mutex);
|
||||
@@ -733,10 +537,6 @@ void SigSession::check_update()
|
||||
data_updated();
|
||||
_data_updated = false;
|
||||
_noData_cnt = 0;
|
||||
#ifdef TEST_MODE
|
||||
if (!_test_timer.isActive())
|
||||
_test_timer.start(qrand()%5000);
|
||||
#endif
|
||||
} else {
|
||||
if (++_noData_cnt >= (WaitShowTime/ViewTime))
|
||||
nodata_timeout();
|
||||
@@ -947,24 +747,26 @@ void SigSession::reload()
|
||||
}
|
||||
break;
|
||||
|
||||
case SR_CHANNEL_DSO:
|
||||
signal = boost::shared_ptr<view::Signal>(
|
||||
new view::DsoSignal(_dev_inst,_dso_data, probe));
|
||||
break;
|
||||
// case SR_CHANNEL_DSO:
|
||||
// signal = boost::shared_ptr<view::Signal>(
|
||||
// new view::DsoSignal(_dev_inst,_dso_data, probe));
|
||||
// break;
|
||||
|
||||
case SR_CHANNEL_ANALOG:
|
||||
if (probe->enabled)
|
||||
signal = boost::shared_ptr<view::Signal>(
|
||||
new view::AnalogSignal(_dev_inst, _analog_data, probe));
|
||||
break;
|
||||
// case SR_CHANNEL_ANALOG:
|
||||
// if (probe->enabled)
|
||||
// signal = boost::shared_ptr<view::Signal>(
|
||||
// new view::AnalogSignal(_dev_inst, _analog_data, probe));
|
||||
// break;
|
||||
}
|
||||
if (signal.get())
|
||||
sigs.push_back(signal);
|
||||
}
|
||||
|
||||
_signals.clear();
|
||||
vector< boost::shared_ptr<view::Signal> >().swap(_signals);
|
||||
_signals = sigs;
|
||||
if (!sigs.empty()) {
|
||||
_signals.clear();
|
||||
vector< boost::shared_ptr<view::Signal> >().swap(_signals);
|
||||
_signals = sigs;
|
||||
}
|
||||
}
|
||||
|
||||
mathTraces_rebuild();
|
||||
@@ -975,7 +777,7 @@ void SigSession::refresh(int holdtime)
|
||||
boost::lock_guard<boost::mutex> lock(_data_mutex);
|
||||
|
||||
_data_lock = true;
|
||||
_refresh_timer.start(holdtime);
|
||||
QTimer::singleShot(holdtime, this, SLOT(data_unlock()));
|
||||
|
||||
if (_logic_data) {
|
||||
_logic_data->init();
|
||||
@@ -1057,9 +859,12 @@ void SigSession::feed_in_meta(const sr_dev_inst *sdi,
|
||||
|
||||
void SigSession::feed_in_trigger(const ds_trigger_pos &trigger_pos)
|
||||
{
|
||||
_hw_replied = true;
|
||||
if (_dev_inst->dev_inst()->mode != DSO) {
|
||||
_trigger_pos = trigger_pos.real_pos;
|
||||
receive_trigger(_trigger_pos);
|
||||
if (_trigger_flag = (trigger_pos.status & 0x01)) {
|
||||
_trigger_pos = trigger_pos.real_pos;
|
||||
receive_trigger(_trigger_pos);
|
||||
}
|
||||
if (_dev_inst->name() != "virtual-session") {
|
||||
const double time = trigger_pos.real_pos * 1.0 / _cur_samplerate;
|
||||
_trigger_time = QDateTime::currentDateTime();
|
||||
@@ -1092,15 +897,14 @@ void SigSession::feed_in_logic(const sr_datafeed_logic &logic)
|
||||
}
|
||||
|
||||
if (logic.data_error == 1) {
|
||||
test_data_error();
|
||||
_error = Test_data_err;
|
||||
_error_pattern = logic.error_pattern;
|
||||
session_error();
|
||||
}
|
||||
|
||||
if (_cur_logic_snapshot->last_ended()) {
|
||||
_cur_logic_snapshot->first_payload(logic, _dev_inst->get_sample_limit(), 1);
|
||||
if (_cur_logic_snapshot->memory_failed()) {
|
||||
malloc_error();
|
||||
return;
|
||||
}
|
||||
logic_init();
|
||||
_cur_logic_snapshot->first_payload(logic, _dev_inst->get_sample_limit(), _dev_inst->dev_inst()->channels);
|
||||
// @todo Putting this here means that only listeners querying
|
||||
// for logic will be notified. Currently the only user of
|
||||
// frame_began is DecoderStack, but in future we need to signal
|
||||
@@ -1111,7 +915,13 @@ void SigSession::feed_in_logic(const sr_datafeed_logic &logic)
|
||||
_cur_logic_snapshot->append_payload(logic);
|
||||
}
|
||||
|
||||
emit receive_data(logic.length/logic.unitsize);
|
||||
if (_cur_logic_snapshot->memory_failed()) {
|
||||
_error = Malloc_err;
|
||||
session_error();
|
||||
return;
|
||||
}
|
||||
|
||||
emit receive_data(logic.length * 8 / get_ch_num(SR_CHANNEL_LOGIC));
|
||||
data_received();
|
||||
//data_updated();
|
||||
_data_updated = true;
|
||||
@@ -1129,25 +939,30 @@ void SigSession::feed_in_dso(const sr_datafeed_dso &dso)
|
||||
|
||||
if (_cur_dso_snapshot->last_ended())
|
||||
{
|
||||
std::map<int, bool> sig_enable;
|
||||
// reset scale of dso signal
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _signals)
|
||||
{
|
||||
assert(s);
|
||||
boost::shared_ptr<view::DsoSignal> dsoSig;
|
||||
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(s))
|
||||
dsoSig->set_scale(dsoSig->get_view_rect().height() / 256.0f);
|
||||
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(s)) {
|
||||
dsoSig->set_scale(dsoSig->get_view_rect().height());
|
||||
sig_enable[dsoSig->get_index()] = dsoSig->enabled();
|
||||
}
|
||||
}
|
||||
|
||||
// first payload
|
||||
_cur_dso_snapshot->first_payload(dso, _dev_inst->get_sample_limit(), get_ch_num(SR_CHANNEL_DSO), _instant);
|
||||
if (_cur_dso_snapshot->memory_failed()) {
|
||||
malloc_error();
|
||||
return;
|
||||
}
|
||||
_cur_dso_snapshot->first_payload(dso, _dev_inst->get_sample_limit(), sig_enable, _instant);
|
||||
} else {
|
||||
// Append to the existing data snapshot
|
||||
_cur_dso_snapshot->append_payload(dso);
|
||||
}
|
||||
if (_cur_dso_snapshot->memory_failed()) {
|
||||
_error = Malloc_err;
|
||||
session_error();
|
||||
return;
|
||||
}
|
||||
|
||||
// calculate related math results
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::MathTrace> m, _math_traces)
|
||||
{
|
||||
@@ -1175,16 +990,18 @@ void SigSession::feed_in_analog(const sr_datafeed_analog &analog)
|
||||
if (_cur_analog_snapshot->last_ended())
|
||||
{
|
||||
// first payload
|
||||
_cur_analog_snapshot->first_payload(analog, _dev_inst->get_sample_limit(), get_ch_num(SR_CHANNEL_ANALOG));
|
||||
if (_cur_analog_snapshot->memory_failed()) {
|
||||
malloc_error();
|
||||
return;
|
||||
}
|
||||
_cur_analog_snapshot->first_payload(analog, _dev_inst->get_sample_limit(), _dev_inst->dev_inst()->channels);
|
||||
} else {
|
||||
// Append to the existing data snapshot
|
||||
_cur_analog_snapshot->append_payload(analog);
|
||||
}
|
||||
|
||||
if (_cur_analog_snapshot->memory_failed()) {
|
||||
_error = Malloc_err;
|
||||
session_error();
|
||||
return;
|
||||
}
|
||||
|
||||
receive_data(analog.num_samples);
|
||||
//data_updated();
|
||||
_data_updated = true;
|
||||
@@ -1200,6 +1017,12 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
|
||||
|
||||
if (_data_lock)
|
||||
return;
|
||||
if (packet->type != SR_DF_END &&
|
||||
packet->status != SR_PKT_OK) {
|
||||
_error = Pkt_data_err;
|
||||
session_error();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (packet->type) {
|
||||
case SR_DF_HEADER:
|
||||
@@ -1232,6 +1055,12 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
|
||||
feed_in_analog(*(const sr_datafeed_analog*)packet->payload);
|
||||
break;
|
||||
|
||||
case SR_DF_OVERFLOW:
|
||||
{
|
||||
_error = Data_overflow;
|
||||
session_error();
|
||||
break;
|
||||
}
|
||||
case SR_DF_END:
|
||||
{
|
||||
{
|
||||
@@ -1247,14 +1076,22 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
|
||||
_cur_group_snapshot.reset();
|
||||
}
|
||||
}
|
||||
_cur_logic_snapshot->set_last_ended(true);
|
||||
_cur_dso_snapshot->set_last_ended(true);
|
||||
_cur_analog_snapshot->set_last_ended(true);
|
||||
if (!_cur_logic_snapshot->last_ended())
|
||||
_cur_logic_snapshot->capture_ended();
|
||||
else if (get_run_mode() != SigSession::Repetitive)
|
||||
logic_init();
|
||||
_cur_dso_snapshot->capture_ended();
|
||||
_cur_analog_snapshot->capture_ended();
|
||||
#ifdef ENABLE_DECODE
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::DecodeTrace> d, _decode_traces)
|
||||
d->frame_ended();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (packet->status != SR_PKT_OK) {
|
||||
_error = Pkt_data_err;
|
||||
session_error();
|
||||
}
|
||||
frame_ended();
|
||||
break;
|
||||
}
|
||||
@@ -1403,14 +1240,13 @@ uint16_t SigSession::get_ch_num(int type)
|
||||
}
|
||||
|
||||
#ifdef ENABLE_DECODE
|
||||
bool SigSession::add_decoder(srd_decoder *const dec)
|
||||
bool SigSession::add_decoder(srd_decoder *const dec, bool silent)
|
||||
{
|
||||
bool ret = false;
|
||||
map<const srd_channel*, boost::shared_ptr<view::LogicSignal> > probes;
|
||||
map<const srd_channel*, int> probes;
|
||||
boost::shared_ptr<data::DecoderStack> decoder_stack;
|
||||
|
||||
try
|
||||
{
|
||||
try {
|
||||
//lock_guard<mutex> lock(_signals_mutex);
|
||||
|
||||
// Create the decoder
|
||||
@@ -1440,13 +1276,14 @@ bool SigSession::add_decoder(srd_decoder *const dec)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (d->create_popup()) {
|
||||
if (silent) {
|
||||
_decode_traces.push_back(d);
|
||||
ret = true;
|
||||
} else if (d->create_popup()) {
|
||||
_decode_traces.push_back(d);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
catch(std::runtime_error e)
|
||||
{
|
||||
} catch(std::runtime_error e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1604,4 +1441,117 @@ void SigSession::nodata_timeout()
|
||||
}
|
||||
}
|
||||
|
||||
boost::shared_ptr<data::Snapshot> SigSession::get_snapshot(int type)
|
||||
{
|
||||
if (type == SR_CHANNEL_LOGIC)
|
||||
return _cur_logic_snapshot;
|
||||
else if (type == SR_CHANNEL_ANALOG)
|
||||
return _cur_analog_snapshot;
|
||||
else if (type == SR_CHANNEL_DSO)
|
||||
return _cur_dso_snapshot;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SigSession::error_state SigSession::get_error() const
|
||||
{
|
||||
return _error;
|
||||
}
|
||||
|
||||
void SigSession::set_error(error_state state)
|
||||
{
|
||||
_error = state;
|
||||
}
|
||||
|
||||
void SigSession::clear_error()
|
||||
{
|
||||
_error_pattern = 0;
|
||||
_error = No_err;
|
||||
}
|
||||
|
||||
uint64_t SigSession::get_error_pattern() const
|
||||
{
|
||||
return _error_pattern;
|
||||
}
|
||||
|
||||
SigSession::run_mode SigSession::get_run_mode() const
|
||||
{
|
||||
return _run_mode;
|
||||
}
|
||||
|
||||
void SigSession::set_run_mode(run_mode mode)
|
||||
{
|
||||
_run_mode = mode;
|
||||
}
|
||||
|
||||
int SigSession::get_repeat_intvl() const
|
||||
{
|
||||
return _repeat_intvl;
|
||||
}
|
||||
|
||||
void SigSession::set_repeat_intvl(int interval)
|
||||
{
|
||||
_repeat_intvl = interval;
|
||||
}
|
||||
|
||||
void SigSession::set_repeating(bool repeat)
|
||||
{
|
||||
_repeating = repeat;
|
||||
if (!_repeating)
|
||||
_repeat_hold_prg = 0;
|
||||
}
|
||||
|
||||
bool SigSession::isRepeating() const
|
||||
{
|
||||
return _repeating;
|
||||
}
|
||||
|
||||
bool SigSession::repeat_check()
|
||||
{
|
||||
if (get_capture_state() != Stopped ||
|
||||
get_run_mode() != Repetitive ||
|
||||
!isRepeating()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_dev_inst->dev_inst()->mode == LOGIC) {
|
||||
_repeat_hold_prg = 100;
|
||||
repeat_hold(_repeat_hold_prg);
|
||||
QTimer::singleShot(_repeat_intvl*1000/RepeatHoldDiv, this, SLOT(repeat_update()));
|
||||
return true;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void SigSession::repeat_update()
|
||||
{
|
||||
if (isRepeating()) {
|
||||
_repeat_hold_prg -= 100/RepeatHoldDiv;
|
||||
if (_repeat_hold_prg != 0)
|
||||
QTimer::singleShot(_repeat_intvl*1000/RepeatHoldDiv, this, SLOT(repeat_update()));
|
||||
repeat_hold(_repeat_hold_prg);
|
||||
if (_repeat_hold_prg == 0)
|
||||
repeat_resume();
|
||||
}
|
||||
}
|
||||
|
||||
int SigSession::get_repeat_hold() const
|
||||
{
|
||||
if (isRepeating())
|
||||
return _repeat_hold_prg;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SigSession::set_map_zoom(int index)
|
||||
{
|
||||
_map_zoom = index;
|
||||
}
|
||||
|
||||
int SigSession::get_map_zoom() const
|
||||
{
|
||||
return _map_zoom;
|
||||
}
|
||||
|
||||
} // namespace pv
|
||||
|
||||
@@ -59,6 +59,7 @@ class DeviceManager;
|
||||
|
||||
namespace data {
|
||||
class SignalData;
|
||||
class Snapshot;
|
||||
class Analog;
|
||||
class AnalogSnapshot;
|
||||
class Dso;
|
||||
@@ -93,7 +94,7 @@ class SigSession : public QObject
|
||||
private:
|
||||
static constexpr float Oversampling = 2.0f;
|
||||
static const int RefreshTime = 500;
|
||||
bool saveFileThreadRunning = false;
|
||||
static const int RepeatHoldDiv = 20;
|
||||
|
||||
public:
|
||||
static const int ViewTime = 50;
|
||||
@@ -106,6 +107,21 @@ public:
|
||||
Running
|
||||
};
|
||||
|
||||
enum run_mode {
|
||||
Single,
|
||||
Repetitive
|
||||
};
|
||||
|
||||
enum error_state {
|
||||
No_err,
|
||||
Hw_err,
|
||||
Malloc_err,
|
||||
Test_data_err,
|
||||
Test_timeout_err,
|
||||
Pkt_data_err,
|
||||
Data_overflow
|
||||
};
|
||||
|
||||
public:
|
||||
SigSession(DeviceManager &device_manager);
|
||||
|
||||
@@ -122,10 +138,7 @@ public:
|
||||
void set_file(QString name)
|
||||
throw(QString);
|
||||
|
||||
void save_file(const QString name, QWidget* parent, int type);
|
||||
|
||||
void set_default_device(boost::function<void (const QString)> error_handler);
|
||||
void export_file(const QString name, QWidget* parent, const QString ext);
|
||||
|
||||
void release_device(device::DevInst *dev_inst);
|
||||
|
||||
@@ -142,6 +155,8 @@ public:
|
||||
void start_capture(bool instant,
|
||||
boost::function<void (const QString)> error_handler);
|
||||
void capture_init();
|
||||
bool get_capture_status(bool &triggered, int &progress);
|
||||
void logic_init();
|
||||
|
||||
std::set< boost::shared_ptr<data::SignalData> > get_data() const;
|
||||
|
||||
@@ -150,10 +165,9 @@ public:
|
||||
|
||||
std::vector< boost::shared_ptr<view::GroupSignal> >
|
||||
get_group_signals();
|
||||
QList<QString> getSuportedExportFormats();
|
||||
|
||||
#ifdef ENABLE_DECODE
|
||||
bool add_decoder(srd_decoder *const dec);
|
||||
bool add_decoder(srd_decoder *const dec, bool silent);
|
||||
|
||||
std::vector< boost::shared_ptr<view::DecodeTrace> >
|
||||
get_decode_signals() const;
|
||||
@@ -167,20 +181,17 @@ public:
|
||||
void rst_decoder(view::DecodeTrace *signal);
|
||||
|
||||
pv::data::DecoderModel* get_decoder_model() const;
|
||||
#endif
|
||||
|
||||
std::vector< boost::shared_ptr<view::MathTrace> >
|
||||
get_math_signals();
|
||||
|
||||
#endif
|
||||
|
||||
void init_signals();
|
||||
|
||||
void add_group();
|
||||
|
||||
void del_group();
|
||||
|
||||
const void* get_buf(int& unit_size, uint64_t& length);
|
||||
|
||||
void start_hotplug_proc(boost::function<void (const QString)> error_handler);
|
||||
void stop_hotplug_proc();
|
||||
void register_hotplug_callback();
|
||||
@@ -195,6 +206,23 @@ public:
|
||||
|
||||
bool trigd() const;
|
||||
|
||||
boost::shared_ptr<data::Snapshot> get_snapshot(int type);
|
||||
|
||||
error_state get_error() const;
|
||||
void set_error(error_state state);
|
||||
void clear_error();
|
||||
uint64_t get_error_pattern() const;
|
||||
|
||||
run_mode get_run_mode() const;
|
||||
void set_run_mode(run_mode mode);
|
||||
int get_repeat_intvl() const;
|
||||
void set_repeat_intvl(int interval);
|
||||
bool isRepeating() const;
|
||||
bool repeat_check();
|
||||
int get_repeat_hold() const;
|
||||
|
||||
int get_map_zoom() const;
|
||||
|
||||
private:
|
||||
void set_capture_state(capture_state state);
|
||||
|
||||
@@ -278,17 +306,23 @@ private:
|
||||
|
||||
QTimer _view_timer;
|
||||
int _noData_cnt;
|
||||
QTimer _refresh_timer;
|
||||
bool _data_lock;
|
||||
bool _data_updated;
|
||||
|
||||
#ifdef TEST_MODE
|
||||
QTimer _test_timer;
|
||||
#endif
|
||||
|
||||
QDateTime _trigger_time;
|
||||
uint64_t _trigger_pos;
|
||||
bool _trigger_flag;
|
||||
bool _hw_replied;
|
||||
|
||||
error_state _error;
|
||||
uint64_t _error_pattern;
|
||||
|
||||
run_mode _run_mode;
|
||||
int _repeat_intvl;
|
||||
bool _repeating;
|
||||
int _repeat_hold_prg;
|
||||
|
||||
int _map_zoom;
|
||||
|
||||
signals:
|
||||
void capture_state_changed(int state);
|
||||
@@ -297,15 +331,11 @@ signals:
|
||||
|
||||
void data_updated();
|
||||
|
||||
void start_timer(int);
|
||||
|
||||
void receive_data(quint64 length);
|
||||
|
||||
void device_attach();
|
||||
void device_detach();
|
||||
|
||||
void test_data_error();
|
||||
|
||||
void receive_trigger(quint64 trigger_pos);
|
||||
|
||||
void receive_header();
|
||||
@@ -320,31 +350,35 @@ signals:
|
||||
|
||||
void device_setted();
|
||||
|
||||
void malloc_error();
|
||||
|
||||
void zero_adj();
|
||||
void progressSaveFileValueChanged(int percent);
|
||||
|
||||
void decode_done();
|
||||
|
||||
void show_region(uint64_t start, uint64_t end);
|
||||
|
||||
void hardware_connect_failed();
|
||||
void show_region(uint64_t start, uint64_t end, bool keep);
|
||||
|
||||
void show_wait_trigger();
|
||||
|
||||
void on_mode_change();
|
||||
void session_save();
|
||||
|
||||
void session_error();
|
||||
|
||||
void repeat_hold(int percent);
|
||||
void repeat_resume();
|
||||
|
||||
public slots:
|
||||
void reload();
|
||||
void refresh(int holdtime);
|
||||
void stop_capture();
|
||||
// repeat
|
||||
void set_repeating(bool repeat);
|
||||
void set_map_zoom(int index);
|
||||
|
||||
private slots:
|
||||
void cancelSaveFile();
|
||||
void data_unlock();
|
||||
void check_update();
|
||||
void nodata_timeout();
|
||||
void repeat_update();
|
||||
|
||||
private:
|
||||
// TODO: This should not be necessary. Multiple concurrent
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* This file is part of the PulseView project.
|
||||
*
|
||||
* Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
* Copyright (C) 2016 DreamSourceLab <support@dreamsourcelab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -23,10 +24,22 @@
|
||||
#include <pv/sigsession.h>
|
||||
#include <pv/data/logic.h>
|
||||
#include <pv/data/logicsnapshot.h>
|
||||
#include <pv/data/dsosnapshot.h>
|
||||
#include <pv/data/decoderstack.h>
|
||||
#include <pv/data/decode/decoder.h>
|
||||
#include <pv/data/decode/row.h>
|
||||
#include <pv/view/trace.h>
|
||||
#include <pv/view/signal.h>
|
||||
#include <pv/view/logicsignal.h>
|
||||
#include <pv/view/dsosignal.h>
|
||||
#include <pv/view/decodetrace.h>
|
||||
#include <pv/device/devinst.h>
|
||||
#include <pv/dock/protocoldock.h>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
using boost::dynamic_pointer_cast;
|
||||
using boost::mutex;
|
||||
using boost::shared_ptr;
|
||||
@@ -42,14 +55,12 @@ using std::vector;
|
||||
|
||||
namespace pv {
|
||||
|
||||
const size_t StoreSession::BlockSize = 1024 * 1024;
|
||||
|
||||
StoreSession::StoreSession(const std::string &file_name,
|
||||
SigSession &session) :
|
||||
_file_name(file_name),
|
||||
StoreSession::StoreSession(SigSession &session) :
|
||||
_session(session),
|
||||
_outModule(NULL),
|
||||
_units_stored(0),
|
||||
_unit_count(0)
|
||||
_unit_count(0),
|
||||
_has_error(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -70,132 +81,791 @@ const QString& StoreSession::error() const
|
||||
return _error;
|
||||
}
|
||||
|
||||
bool StoreSession::start()
|
||||
{
|
||||
const vector< shared_ptr<view::Signal> > sigs(_session.get_signals());
|
||||
set< boost::shared_ptr<data::SignalData> > data_set;
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::Signal> sig, sigs) {
|
||||
assert(sig);
|
||||
data_set.insert(sig->data());
|
||||
}
|
||||
|
||||
// Check we have logic data
|
||||
if (data_set.empty() || sigs.empty()) {
|
||||
_error = tr("No data to save.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (data_set.size() > 1) {
|
||||
_error = tr("DSView currently only has support for "
|
||||
"storing a single data stream.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the logic data
|
||||
//shared_ptr<data::SignalData
|
||||
shared_ptr<data::Logic> data;
|
||||
if (!(data = dynamic_pointer_cast<data::Logic>(*data_set.begin()))) {
|
||||
_error = tr("DSView currently only has support for "
|
||||
"storing a logic data.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the snapshot
|
||||
const deque< shared_ptr<data::LogicSnapshot> > &snapshots =
|
||||
data->get_snapshots();
|
||||
|
||||
if (snapshots.empty()) {
|
||||
_error = tr("No snapshots to save.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const shared_ptr<data::LogicSnapshot> snapshot(snapshots.front());
|
||||
assert(snapshot);
|
||||
|
||||
// Make a list of probes
|
||||
char **const probes = new char*[sigs.size() + 1];
|
||||
for (size_t i = 0; i < sigs.size(); i++) {
|
||||
shared_ptr<view::Signal> sig(sigs[i]);
|
||||
assert(sig);
|
||||
probes[i] = strdup(sig->get_name().toUtf8().constData());
|
||||
}
|
||||
probes[sigs.size()] = NULL;
|
||||
|
||||
// Begin storing
|
||||
if (sr_session_save_init(_file_name.c_str(),
|
||||
data->samplerate(), probes) != SR_OK) {
|
||||
_error = tr("Error while saving.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Delete the probes array
|
||||
for (size_t i = 0; i <= sigs.size(); i++)
|
||||
free(probes[i]);
|
||||
delete[] probes;
|
||||
|
||||
_thread = boost::thread(&StoreSession::store_proc, this, snapshot);
|
||||
return true;
|
||||
}
|
||||
|
||||
void StoreSession::wait()
|
||||
{
|
||||
if (_thread.joinable())
|
||||
_thread.join();
|
||||
if (_thread.joinable())
|
||||
_thread.join();
|
||||
}
|
||||
|
||||
void StoreSession::cancel()
|
||||
{
|
||||
_thread.interrupt();
|
||||
_thread.interrupt();
|
||||
}
|
||||
|
||||
void StoreSession::store_proc(shared_ptr<data::LogicSnapshot> snapshot)
|
||||
QList<QString> StoreSession::getSuportedExportFormats(){
|
||||
const struct sr_output_module** supportedModules = sr_output_list();
|
||||
QList<QString> list;
|
||||
while(*supportedModules){
|
||||
if(*supportedModules == NULL)
|
||||
break;
|
||||
if (_session.get_device()->dev_inst()->mode == DSO && strcmp((*supportedModules)->id, "csv"))
|
||||
break;
|
||||
QString format((*supportedModules)->desc);
|
||||
format.append(" (*.");
|
||||
format.append((*supportedModules)->id);
|
||||
format.append(")");
|
||||
list.append(format);
|
||||
supportedModules++;
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
bool StoreSession::save_start()
|
||||
{
|
||||
std::set<int> type_set;
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::Signal> sig, _session.get_signals()) {
|
||||
assert(sig);
|
||||
type_set.insert(sig->get_type());
|
||||
}
|
||||
|
||||
if (type_set.size() > 1) {
|
||||
_error = tr("DSView does not currently support"
|
||||
"file saving for multiple data types.");
|
||||
return false;
|
||||
} else if (type_set.size() == 0) {
|
||||
_error = tr("No data to save.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const boost::shared_ptr<data::Snapshot> snapshot(_session.get_snapshot(*type_set.begin()));
|
||||
assert(snapshot);
|
||||
// Check we have data
|
||||
if (snapshot->empty()) {
|
||||
_error = tr("No data to save.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString DIR_KEY("SavePath");
|
||||
QSettings settings;
|
||||
|
||||
// Show the dialog
|
||||
_file_name = QFileDialog::getSaveFileName(
|
||||
NULL, tr("Save File"), settings.value(DIR_KEY).toString(),
|
||||
tr("DSView Data (*.dsl)"));
|
||||
|
||||
if (!_file_name.isEmpty()) {
|
||||
QFileInfo f(_file_name);
|
||||
if(f.suffix().compare("dsl"))
|
||||
_file_name.append(tr(".dsl"));
|
||||
QDir CurrentDir;
|
||||
settings.setValue(DIR_KEY, CurrentDir.absoluteFilePath(_file_name));
|
||||
|
||||
QString meta_file = meta_gen(snapshot);
|
||||
#ifdef ENABLE_DECODE
|
||||
QString decoders_file = decoders_gen();
|
||||
#else
|
||||
QString decoders_file = NULL;
|
||||
#endif
|
||||
if (meta_file == NULL) {
|
||||
_error = tr("Generate temp file failed.");
|
||||
return false;
|
||||
} else {
|
||||
sr_session_save_init(_file_name.toLocal8Bit().data(),
|
||||
meta_file.toLocal8Bit().data(),
|
||||
decoders_file.toLocal8Bit().data());
|
||||
_thread = boost::thread(&StoreSession::save_proc, this, snapshot);
|
||||
return !_has_error;
|
||||
}
|
||||
}
|
||||
|
||||
_error.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
void StoreSession::save_proc(shared_ptr<data::Snapshot> snapshot)
|
||||
{
|
||||
assert(snapshot);
|
||||
|
||||
uint64_t start_sample = 0;
|
||||
shared_ptr<data::LogicSnapshot> logic_snapshot;
|
||||
shared_ptr<data::AnalogSnapshot> analog_snapshot;
|
||||
shared_ptr<data::DsoSnapshot> dso_snapshot;
|
||||
|
||||
/// TODO: Wrap this in a std::unique_ptr when we transition to C++11
|
||||
uint8_t *data = NULL;
|
||||
//uint8_t *const data = new uint8_t[BlockSize];
|
||||
//assert(data);
|
||||
if (logic_snapshot = boost::dynamic_pointer_cast<data::LogicSnapshot>(snapshot)) {
|
||||
uint16_t to_save_probes = 0;
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _session.get_signals()) {
|
||||
if (s->enabled() && logic_snapshot->has_data(s->get_index()))
|
||||
to_save_probes++;
|
||||
}
|
||||
_unit_count = logic_snapshot->get_sample_count() / 8 * to_save_probes;
|
||||
int num = logic_snapshot->get_block_num();
|
||||
bool sample;
|
||||
|
||||
const int unit_size = snapshot->unit_size();
|
||||
assert(unit_size != 0);
|
||||
|
||||
{
|
||||
//lock_guard<mutex> lock(_mutex);
|
||||
_unit_count = snapshot->get_sample_count();
|
||||
}
|
||||
|
||||
const unsigned int samples_per_block = BlockSize / unit_size;
|
||||
|
||||
while (!boost::this_thread::interruption_requested() &&
|
||||
start_sample < _unit_count)
|
||||
{
|
||||
progress_updated();
|
||||
|
||||
const uint64_t end_sample = min(
|
||||
start_sample + samples_per_block, _unit_count);
|
||||
data = snapshot->get_samples(start_sample, end_sample);
|
||||
|
||||
if(sr_session_append(_file_name.c_str(), data, unit_size,
|
||||
end_sample - start_sample) != SR_OK)
|
||||
{
|
||||
_error = tr("Error while saving.");
|
||||
break;
|
||||
}
|
||||
|
||||
start_sample = end_sample;
|
||||
|
||||
{
|
||||
//lock_guard<mutex> lock(_mutex);
|
||||
_units_stored = start_sample;
|
||||
}
|
||||
}
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _session.get_signals()) {
|
||||
int ch_type = s->get_type();
|
||||
if (ch_type == SR_CHANNEL_LOGIC) {
|
||||
int ch_index = s->get_index();
|
||||
if (!s->enabled() || !logic_snapshot->has_data(ch_index))
|
||||
continue;
|
||||
for (int i = 0; !boost::this_thread::interruption_requested() && i < num; i++) {
|
||||
uint8_t *buf = logic_snapshot->get_block_buf(i, ch_index, sample);
|
||||
uint64_t size = logic_snapshot->get_block_size(i);
|
||||
bool need_malloc = (buf == NULL);
|
||||
if (need_malloc) {
|
||||
buf = (uint8_t *)malloc(size);
|
||||
if (buf == NULL) {
|
||||
_has_error = true;
|
||||
_error = tr("Malloc failed.");
|
||||
return;
|
||||
}
|
||||
memset(buf, sample ? 0xff : 0x0, size);
|
||||
}
|
||||
sr_session_append(_file_name.toLocal8Bit().data(), buf, size,
|
||||
i, ch_index, ch_type, File_Version);
|
||||
_units_stored += size;
|
||||
if (need_malloc)
|
||||
free(buf);
|
||||
progress_updated();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int ch_type;
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _session.get_signals()) {
|
||||
ch_type = s->get_type();
|
||||
break;
|
||||
}
|
||||
uint64_t size = snapshot->get_sample_count() * snapshot->get_channel_num();
|
||||
uint8_t *buf = (uint8_t *)snapshot->get_data();
|
||||
sr_session_append(_file_name.toLocal8Bit().data(), buf, size,
|
||||
0, 0, ch_type, 1);
|
||||
}
|
||||
|
||||
progress_updated();
|
||||
}
|
||||
|
||||
//delete[] data;
|
||||
QString StoreSession::meta_gen(boost::shared_ptr<data::Snapshot> snapshot)
|
||||
{
|
||||
GSList *l;
|
||||
GVariant *gvar;
|
||||
FILE *meta;
|
||||
struct sr_channel *probe;
|
||||
int probecnt;
|
||||
char *s;
|
||||
struct sr_status status;
|
||||
QString metafile;
|
||||
|
||||
/* init "metadata" */
|
||||
QDir dir;
|
||||
#if QT_VERSION >= 0x050400
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
||||
#else
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
||||
#endif
|
||||
if(dir.mkpath(path)) {
|
||||
dir.cd(path);
|
||||
metafile = dir.absolutePath() + "/DSView-meta-XXXXXX";
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const sr_dev_inst *sdi = _session.get_device()->dev_inst();
|
||||
meta = fopen(metafile.toLocal8Bit().data(), "wb");
|
||||
fprintf(meta, "[version]\n");
|
||||
if (sdi->mode == DSO)
|
||||
fprintf(meta, "version = %d\n", 1); // should be updated in next version
|
||||
else
|
||||
fprintf(meta, "version = %d\n", File_Version);
|
||||
|
||||
/* metadata */
|
||||
|
||||
fprintf(meta, "[header]\n");
|
||||
if (sdi->driver) {
|
||||
fprintf(meta, "driver = %s\n", sdi->driver->name);
|
||||
fprintf(meta, "device mode = %d\n", sdi->mode);
|
||||
}
|
||||
|
||||
/* metadata */
|
||||
fprintf(meta, "capturefile = data\n");
|
||||
fprintf(meta, "total samples = %llu\n", snapshot->get_sample_count());
|
||||
|
||||
if (sdi->mode == DSO)
|
||||
fprintf(meta, "total probes = %d\n", g_slist_length(sdi->channels));
|
||||
|
||||
shared_ptr<data::LogicSnapshot> logic_snapshot;
|
||||
if (logic_snapshot = dynamic_pointer_cast<data::LogicSnapshot>(snapshot)) {
|
||||
uint16_t to_save_probes = 0;
|
||||
for (l = sdi->channels; l; l = l->next) {
|
||||
probe = (struct sr_channel *)l->data;
|
||||
if (probe->enabled && logic_snapshot->has_data(probe->index))
|
||||
to_save_probes++;
|
||||
}
|
||||
fprintf(meta, "total probes = %d\n", to_save_probes);
|
||||
fprintf(meta, "total blocks = %d\n", logic_snapshot->get_block_num());
|
||||
}
|
||||
|
||||
s = sr_samplerate_string(_session.cur_samplerate());
|
||||
fprintf(meta, "samplerate = %s\n", s);
|
||||
|
||||
if (sdi->mode == DSO) {
|
||||
gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_TIMEBASE);
|
||||
if (gvar != NULL) {
|
||||
uint64_t tmp_u64 = g_variant_get_uint64(gvar);
|
||||
fprintf(meta, "hDiv = %llu\n", tmp_u64);
|
||||
g_variant_unref(gvar);
|
||||
}
|
||||
gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_DSO_BITS);
|
||||
if (gvar != NULL) {
|
||||
uint8_t tmp_u8 = g_variant_get_byte(gvar);
|
||||
fprintf(meta, "bits = %d\n", tmp_u8);
|
||||
g_variant_unref(gvar);
|
||||
}
|
||||
} else if (sdi->mode == LOGIC) {
|
||||
fprintf(meta, "trigger time = %lld\n", _session.get_trigger_time().toMSecsSinceEpoch());
|
||||
}
|
||||
fprintf(meta, "trigger pos = %llu\n", _session.get_trigger_pos());
|
||||
|
||||
probecnt = 1;
|
||||
for (l = sdi->channels; l; l = l->next) {
|
||||
probe = (struct sr_channel *)l->data;
|
||||
if (probe->enabled || sdi->mode == DSO) {
|
||||
if (probe->name)
|
||||
fprintf(meta, "probe%d = %s\n", probe->index, probe->name);
|
||||
if (probe->trigger)
|
||||
fprintf(meta, " trigger%d = %s\n", probe->index, probe->trigger);
|
||||
if (sdi->mode == DSO) {
|
||||
fprintf(meta, " enable%d = %d\n", probe->index, probe->enabled);
|
||||
fprintf(meta, " coupling%d = %d\n", probe->index, probe->coupling);
|
||||
fprintf(meta, " vDiv%d = %d\n", probe->index, probe->vdiv);
|
||||
fprintf(meta, " vFactor%d = %d\n", probe->index, probe->vfactor);
|
||||
fprintf(meta, " vPos%d = %lf\n", probe->index, probe->vpos);
|
||||
fprintf(meta, " vTrig%d = %d\n", probe->index, probe->trig_value);
|
||||
if (sr_status_get(sdi, &status, 0, 0) == SR_OK) {
|
||||
if (probe->index == 0) {
|
||||
fprintf(meta, " period%d = %llu\n", probe->index, status.ch0_period);
|
||||
fprintf(meta, " pcnt%d = %lu\n", probe->index, status.ch0_pcnt);
|
||||
fprintf(meta, " max%d = %d\n", probe->index, status.ch0_max);
|
||||
fprintf(meta, " min%d = %d\n", probe->index, status.ch0_min);
|
||||
} else {
|
||||
fprintf(meta, " period%d = %llu\n", probe->index, status.ch1_period);
|
||||
fprintf(meta, " pcnt%d = %lu\n", probe->index, status.ch1_pcnt);
|
||||
fprintf(meta, " max%d = %d\n", probe->index, status.ch1_max);
|
||||
fprintf(meta, " min%d = %d\n", probe->index, status.ch1_min);
|
||||
}
|
||||
}
|
||||
}
|
||||
probecnt++;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(meta);
|
||||
|
||||
return metafile;
|
||||
}
|
||||
|
||||
bool StoreSession::export_start()
|
||||
{
|
||||
std::set<int> type_set;
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::Signal> sig, _session.get_signals()) {
|
||||
assert(sig);
|
||||
type_set.insert(sig->get_type());
|
||||
}
|
||||
|
||||
if (type_set.size() > 1) {
|
||||
_error = tr("DSView does not currently support"
|
||||
"file export for multiple data types.");
|
||||
return false;
|
||||
} else if (type_set.size() == 0) {
|
||||
_error = tr("No data to save.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const boost::shared_ptr<data::Snapshot> snapshot(_session.get_snapshot(*type_set.begin()));
|
||||
assert(snapshot);
|
||||
// Check we have data
|
||||
if (snapshot->empty()) {
|
||||
_error = tr("No data to save.");
|
||||
return false;
|
||||
}
|
||||
|
||||
const QString DIR_KEY("ExportPath");
|
||||
QSettings settings;
|
||||
|
||||
// Show the dialog
|
||||
QList<QString> supportedFormats = getSuportedExportFormats();
|
||||
QString filter;
|
||||
for(int i = 0; i < supportedFormats.count();i++){
|
||||
filter.append(supportedFormats[i]);
|
||||
if(i < supportedFormats.count() - 1)
|
||||
filter.append(";;");
|
||||
}
|
||||
_file_name = QFileDialog::getSaveFileName(
|
||||
NULL, tr("Export Data"), settings.value(DIR_KEY).toString(),filter,&filter);
|
||||
if (!_file_name.isEmpty()) {
|
||||
QFileInfo f(_file_name);
|
||||
QStringList list = filter.split('.').last().split(')');
|
||||
_suffix = list.first();
|
||||
if(f.suffix().compare(_suffix))
|
||||
_file_name += tr(".") + _suffix;
|
||||
QDir CurrentDir;
|
||||
settings.setValue(DIR_KEY, CurrentDir.absoluteFilePath(_file_name));
|
||||
|
||||
const struct sr_output_module** supportedModules = sr_output_list();
|
||||
while(*supportedModules){
|
||||
if(*supportedModules == NULL)
|
||||
break;
|
||||
if(!strcmp((*supportedModules)->id, _suffix.toLocal8Bit().data())){
|
||||
_outModule = *supportedModules;
|
||||
break;
|
||||
}
|
||||
supportedModules++;
|
||||
}
|
||||
|
||||
if(_outModule == NULL) {
|
||||
_error = tr("Invalid export format.");
|
||||
} else {
|
||||
_thread = boost::thread(&StoreSession::export_proc, this, snapshot);
|
||||
return !_has_error;
|
||||
}
|
||||
}
|
||||
|
||||
_error.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
void StoreSession::export_proc(shared_ptr<data::Snapshot> snapshot)
|
||||
{
|
||||
assert(snapshot);
|
||||
|
||||
shared_ptr<data::LogicSnapshot> logic_snapshot;
|
||||
shared_ptr<data::AnalogSnapshot> analog_snapshot;
|
||||
shared_ptr<data::DsoSnapshot> dso_snapshot;
|
||||
int channel_type;
|
||||
|
||||
if (logic_snapshot = boost::dynamic_pointer_cast<data::LogicSnapshot>(snapshot)) {
|
||||
channel_type = SR_CHANNEL_LOGIC;
|
||||
} else if (dso_snapshot = boost::dynamic_pointer_cast<data::DsoSnapshot>(snapshot)) {
|
||||
channel_type = SR_CHANNEL_DSO;
|
||||
} else {
|
||||
_has_error = true;
|
||||
_error = tr("data type don't support.");
|
||||
return;
|
||||
}
|
||||
|
||||
GHashTable *params = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
GVariant* filenameGVariant = g_variant_new_bytestring(_file_name.toLocal8Bit().data());
|
||||
g_hash_table_insert(params, (char*)"filename", filenameGVariant);
|
||||
GVariant* typeGVariant = g_variant_new_int16(channel_type);
|
||||
g_hash_table_insert(params, (char*)"type", typeGVariant);
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _session.get_signals()) {
|
||||
boost::shared_ptr<view::DsoSignal> dsoSig;
|
||||
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(s)) {
|
||||
GVariant* timebaseGVariant = g_variant_new_uint64(dsoSig->get_hDialValue());
|
||||
g_hash_table_insert(params, (char*)"timebase", timebaseGVariant);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct sr_output output;
|
||||
output.module = (sr_output_module*) _outModule;
|
||||
output.sdi = _session.get_device()->dev_inst();
|
||||
output.param = NULL;
|
||||
if(_outModule->init)
|
||||
_outModule->init(&output, params);
|
||||
QFile file(_file_name);
|
||||
file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
QTextStream out(&file);
|
||||
out.setCodec("UTF-8");
|
||||
out.setGenerateByteOrderMark(true);
|
||||
|
||||
if (channel_type == SR_CHANNEL_LOGIC) {
|
||||
_unit_count = logic_snapshot->get_sample_count();
|
||||
int blk_num = logic_snapshot->get_block_num();
|
||||
bool sample;
|
||||
std::vector<uint8_t *> buf_vec;
|
||||
std::vector<bool> buf_sample;
|
||||
for (int blk = 0; !boost::this_thread::interruption_requested() &&
|
||||
blk < blk_num; blk++) {
|
||||
uint64_t buf_sample_num = logic_snapshot->get_block_size(blk) * 8;
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::Signal> s, _session.get_signals()) {
|
||||
int ch_type = s->get_type();
|
||||
if (ch_type == SR_CHANNEL_LOGIC) {
|
||||
int ch_index = s->get_index();
|
||||
if (!logic_snapshot->has_data(ch_index))
|
||||
continue;
|
||||
uint8_t *buf = logic_snapshot->get_block_buf(blk, ch_index, sample);
|
||||
buf_vec.push_back(buf);
|
||||
buf_sample.push_back(sample);
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t unitsize = ceil(buf_vec.size() / 8.0);
|
||||
GString *data_out;
|
||||
unsigned int usize = 8192;
|
||||
unsigned int size = usize;
|
||||
struct sr_datafeed_logic lp;
|
||||
struct sr_datafeed_packet p;
|
||||
for(uint64_t i = 0; !boost::this_thread::interruption_requested() &&
|
||||
i < buf_sample_num; i+=usize){
|
||||
if(buf_sample_num - i < usize)
|
||||
size = buf_sample_num - i;
|
||||
uint8_t *xbuf = (uint8_t *)malloc(size * unitsize);
|
||||
if (xbuf == NULL) {
|
||||
_has_error = true;
|
||||
_error = tr("xbuffer malloc failed.");
|
||||
return;
|
||||
}
|
||||
memset(xbuf, 0, size * unitsize);
|
||||
for (uint64_t j = 0; j < usize; j++) {
|
||||
for (unsigned int k = 0; k < buf_vec.size(); k++) {
|
||||
if (buf_vec[k] == NULL && buf_sample[k])
|
||||
xbuf[j*unitsize+k/8] += 1 << k%8;
|
||||
else if (buf_vec[k] && (buf_vec[k][(i+j)/8] & (1 << j%8)))
|
||||
xbuf[j*unitsize+k/8] += 1 << k%8;
|
||||
}
|
||||
}
|
||||
lp.data = xbuf;
|
||||
lp.length = size * unitsize;
|
||||
lp.unitsize = unitsize;
|
||||
p.type = SR_DF_LOGIC;
|
||||
p.status = SR_PKT_OK;
|
||||
p.payload = &lp;
|
||||
_outModule->receive(&output, &p, &data_out);
|
||||
if(data_out){
|
||||
out << QString::fromUtf8((char*) data_out->str);
|
||||
g_string_free(data_out,TRUE);
|
||||
}
|
||||
|
||||
_units_stored += size;
|
||||
if (xbuf)
|
||||
free(xbuf);
|
||||
progress_updated();
|
||||
}
|
||||
}
|
||||
} else if (channel_type = SR_CHANNEL_DSO) {
|
||||
_unit_count = snapshot->get_sample_count();
|
||||
unsigned char* datat = (unsigned char*)snapshot->get_data();
|
||||
GString *data_out;
|
||||
unsigned int usize = 8192;
|
||||
unsigned int size = usize;
|
||||
struct sr_datafeed_dso dp;
|
||||
struct sr_datafeed_packet p;
|
||||
for(uint64_t i = 0; !boost::this_thread::interruption_requested() && i < _unit_count; i+=usize){
|
||||
if(_unit_count - i < usize)
|
||||
size = _unit_count - i;
|
||||
dp.data = &datat[i*snapshot->get_channel_num()];
|
||||
dp.num_samples = size;
|
||||
p.type = SR_DF_DSO;
|
||||
p.status = SR_PKT_OK;
|
||||
p.payload = &dp;
|
||||
_outModule->receive(&output, &p, &data_out);
|
||||
if(data_out){
|
||||
out << (char*) data_out->str;
|
||||
g_string_free(data_out,TRUE);
|
||||
}
|
||||
|
||||
_units_stored += size;
|
||||
progress_updated();
|
||||
}
|
||||
}
|
||||
|
||||
// optional, as QFile destructor will already do it:
|
||||
file.close();
|
||||
_outModule->cleanup(&output);
|
||||
g_hash_table_destroy(params);
|
||||
g_variant_unref(filenameGVariant);
|
||||
|
||||
progress_updated();
|
||||
}
|
||||
|
||||
#ifdef ENABLE_DECODE
|
||||
QString StoreSession::decoders_gen()
|
||||
{
|
||||
QDir dir;
|
||||
#if QT_VERSION >= 0x050400
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
|
||||
#else
|
||||
QString path = QStandardPaths::writableLocation(QStandardPaths::DataLocation);
|
||||
#endif
|
||||
if(dir.mkpath(path)) {
|
||||
dir.cd(path);
|
||||
|
||||
QString file_name = dir.absolutePath() + "/DSView-decoders-XXXXXX";
|
||||
QFile sessionFile(file_name);
|
||||
if (!sessionFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
qDebug("Warning: Couldn't open session file to write!");
|
||||
return NULL;
|
||||
}
|
||||
QTextStream outStream(&sessionFile);
|
||||
outStream.setCodec("UTF-8");
|
||||
outStream.setGenerateByteOrderMark(true);
|
||||
|
||||
QJsonArray dec_array = json_decoders();
|
||||
QJsonDocument sessionDoc(dec_array);
|
||||
outStream << QString::fromUtf8(sessionDoc.toJson());
|
||||
sessionFile.close();
|
||||
|
||||
return file_name;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QJsonArray StoreSession::json_decoders()
|
||||
{
|
||||
QJsonArray dec_array;
|
||||
BOOST_FOREACH(boost::shared_ptr<view::DecodeTrace> t, _session.get_decode_signals()) {
|
||||
QJsonObject dec_obj;
|
||||
QJsonArray stack_array;
|
||||
QJsonObject show_obj;
|
||||
const boost::shared_ptr<data::DecoderStack>& stack = t->decoder();
|
||||
const std::list< boost::shared_ptr<data::decode::Decoder> >& decoder = stack->stack();
|
||||
BOOST_FOREACH(boost::shared_ptr<data::decode::Decoder> dec, decoder) {
|
||||
QJsonArray ch_array;
|
||||
const srd_decoder *const d = dec->decoder();;
|
||||
const bool have_probes = (d->channels || d->opt_channels) != 0;
|
||||
if (have_probes) {
|
||||
for(std::map<const srd_channel*, int>::const_iterator i = dec->channels().begin();
|
||||
i != dec->channels().end(); i++) {
|
||||
QJsonObject ch_obj;
|
||||
ch_obj[(*i).first->id] = QJsonValue::fromVariant((*i).second);
|
||||
ch_array.push_back(ch_obj);
|
||||
}
|
||||
}
|
||||
|
||||
QJsonObject options_obj;
|
||||
boost::shared_ptr<prop::binding::DecoderOptions> dec_binding(
|
||||
new prop::binding::DecoderOptions(stack, dec));
|
||||
for (GSList *l = d->options; l; l = l->next)
|
||||
{
|
||||
const srd_decoder_option *const opt =
|
||||
(srd_decoder_option*)l->data;
|
||||
|
||||
const std::map<string, GVariant*>& options = dec->options();
|
||||
std::map<string, GVariant*>::const_iterator iter = options.find(opt->id);
|
||||
if (opt->values) {
|
||||
for (GSList *vl = opt->values; vl; vl = vl->next) {
|
||||
GVariant *const var = (GVariant*)vl->data;
|
||||
assert(var);
|
||||
if (iter == options.end()) {
|
||||
options_obj[opt->id] = QJsonValue::fromVariant(dec_binding->print_gvariant(opt->def));
|
||||
break;
|
||||
} else if (g_variant_compare((*iter).second, var) == 0) {
|
||||
options_obj[opt->id] = QJsonValue::fromVariant(dec_binding->print_gvariant(var));
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("d"))) {
|
||||
GVariant *const var = dec_binding->getter(opt->id);
|
||||
options_obj[opt->id] = QJsonValue::fromVariant(g_variant_get_double(var));
|
||||
g_variant_unref(var);
|
||||
} else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("x"))) {
|
||||
GVariant *const var = dec_binding->getter(opt->id);
|
||||
options_obj[opt->id] = QJsonValue::fromVariant(get_double(var));
|
||||
g_variant_unref(var);
|
||||
} else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("s"))) {
|
||||
GVariant *const var = dec_binding->getter(opt->id);
|
||||
options_obj[opt->id] = QJsonValue::fromVariant(g_variant_get_string(var, NULL));
|
||||
g_variant_unref(var);
|
||||
}else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (have_probes) {
|
||||
dec_obj["id"] = QJsonValue::fromVariant(d->id);
|
||||
dec_obj["channel"] = ch_array;
|
||||
dec_obj["options"] = options_obj;
|
||||
} else {
|
||||
QJsonObject stack_obj;
|
||||
stack_obj["id"] = QJsonValue::fromVariant(d->id);
|
||||
stack_obj["options"] = options_obj;
|
||||
stack_array.push_back(stack_obj);
|
||||
}
|
||||
show_obj[d->id] = QJsonValue::fromVariant(dec->shown());
|
||||
}
|
||||
dec_obj["stacked decoders"] = stack_array;
|
||||
|
||||
|
||||
std::map<const pv::data::decode::Row, bool> rows = stack->get_rows_gshow();
|
||||
for (std::map<const pv::data::decode::Row, bool>::const_iterator i = rows.begin();
|
||||
i != rows.end(); i++) {
|
||||
show_obj[(*i).first.title()] = QJsonValue::fromVariant((*i).second);
|
||||
}
|
||||
dec_obj["show"] = show_obj;
|
||||
|
||||
dec_array.push_back(dec_obj);
|
||||
}
|
||||
return dec_array;
|
||||
}
|
||||
|
||||
void StoreSession::load_decoders(dock::ProtocolDock *widget, QJsonArray dec_array)
|
||||
{
|
||||
if (_session.get_device()->dev_inst()->mode != LOGIC ||
|
||||
dec_array.empty())
|
||||
return;
|
||||
|
||||
foreach (const QJsonValue &dec_value, dec_array) {
|
||||
QJsonObject dec_obj = dec_value.toObject();
|
||||
const vector< boost::shared_ptr<view::DecodeTrace> > pre_dsigs(
|
||||
_session.get_decode_signals());
|
||||
if (widget->sel_protocol(dec_obj["id"].toString()))
|
||||
widget->add_protocol(true);
|
||||
const vector< boost::shared_ptr<view::DecodeTrace> > aft_dsigs(
|
||||
_session.get_decode_signals());
|
||||
|
||||
if (aft_dsigs.size() > pre_dsigs.size()) {
|
||||
const GSList *l;
|
||||
boost::shared_ptr<view::DecodeTrace> new_dsig = aft_dsigs.back();
|
||||
const boost::shared_ptr<data::DecoderStack>& stack = new_dsig->decoder();
|
||||
|
||||
if (dec_obj.contains("stacked decoders")) {
|
||||
foreach(const QJsonValue &value, dec_obj["stacked decoders"].toArray()) {
|
||||
QJsonObject stacked_obj = value.toObject();
|
||||
|
||||
GSList *dl = g_slist_copy((GSList*)srd_decoder_list());
|
||||
for(; dl; dl = dl->next) {
|
||||
const srd_decoder *const d = (srd_decoder*)dl->data;
|
||||
assert(d);
|
||||
|
||||
if (QString::fromUtf8(d->id) == stacked_obj["id"].toString()) {
|
||||
stack->push(boost::shared_ptr<data::decode::Decoder>(
|
||||
new data::decode::Decoder(d)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_slist_free(dl);
|
||||
}
|
||||
}
|
||||
|
||||
const std::list< boost::shared_ptr<data::decode::Decoder> >& decoder = stack->stack();
|
||||
BOOST_FOREACH(boost::shared_ptr<data::decode::Decoder> dec, decoder) {
|
||||
const srd_decoder *const d = dec->decoder();
|
||||
QJsonObject options_obj;
|
||||
|
||||
if (dec == decoder.front()) {
|
||||
std::map<const srd_channel*, int> probe_map;
|
||||
// Load the mandatory channels
|
||||
for(l = d->channels; l; l = l->next) {
|
||||
const struct srd_channel *const pdch =
|
||||
(struct srd_channel *)l->data;
|
||||
foreach (const QJsonValue &value, dec_obj["channel"].toArray()) {
|
||||
QJsonObject ch_obj = value.toObject();
|
||||
if (ch_obj.contains(pdch->id)) {
|
||||
probe_map[pdch] = ch_obj[pdch->id].toInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Load the optional channels
|
||||
for(l = d->opt_channels; l; l = l->next) {
|
||||
const struct srd_channel *const pdch =
|
||||
(struct srd_channel *)l->data;
|
||||
foreach (const QJsonValue &value, dec_obj["channel"].toArray()) {
|
||||
QJsonObject ch_obj = value.toObject();
|
||||
if (ch_obj.contains(pdch->id)) {
|
||||
probe_map[pdch] = ch_obj[pdch->id].toInt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
dec->set_probes(probe_map);
|
||||
options_obj = dec_obj["options"].toObject();
|
||||
} else {
|
||||
foreach(const QJsonValue &value, dec_obj["stacked decoders"].toArray()) {
|
||||
QJsonObject stacked_obj = value.toObject();
|
||||
if (QString::fromUtf8(d->id) == stacked_obj["id"].toString()) {
|
||||
options_obj = stacked_obj["options"].toObject();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (l = d->options; l; l = l->next) {
|
||||
const srd_decoder_option *const opt =
|
||||
(srd_decoder_option*)l->data;
|
||||
if (options_obj.contains(opt->id)) {
|
||||
if (opt->values) {
|
||||
QString enum_option = options_obj[opt->id].toString();
|
||||
for (GSList *vl = opt->values; vl; vl = vl->next) {
|
||||
GVariant *const var = (GVariant*)vl->data;
|
||||
assert(var);
|
||||
if (enum_option == QString::fromUtf8(g_variant_get_string(var, NULL))) {
|
||||
dec->set_option(opt->id, var);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("d"))) {
|
||||
double d_option = options_obj[opt->id].toDouble();
|
||||
dec->set_option(opt->id, g_variant_new_double(d_option));
|
||||
} else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("x"))) {
|
||||
int64_t d_option = options_obj[opt->id].toDouble();
|
||||
GVariant *new_value = NULL;
|
||||
const GVariantType *const type = g_variant_get_type(opt->def);
|
||||
if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE))
|
||||
new_value = g_variant_new_byte(d_option);
|
||||
else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16))
|
||||
new_value = g_variant_new_int16(d_option);
|
||||
else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16))
|
||||
new_value = g_variant_new_uint16(d_option);
|
||||
else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32))
|
||||
new_value = g_variant_new_int32(d_option);
|
||||
else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32))
|
||||
new_value = g_variant_new_int32(d_option);
|
||||
else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64))
|
||||
new_value = g_variant_new_int64(d_option);
|
||||
else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64))
|
||||
new_value = g_variant_new_uint64(d_option);
|
||||
if (new_value != NULL)
|
||||
dec->set_option(opt->id, new_value);
|
||||
} else if (g_variant_is_of_type(opt->def, G_VARIANT_TYPE("s"))) {
|
||||
QString s_option = options_obj[opt->id].toString();
|
||||
dec->set_option(opt->id, g_variant_new_string(s_option.toLocal8Bit().data()));
|
||||
}
|
||||
}
|
||||
}
|
||||
dec->commit();
|
||||
|
||||
if (dec_obj.contains("show")) {
|
||||
QJsonObject show_obj = dec_obj["show"].toObject();
|
||||
if (show_obj.contains(d->id)) {
|
||||
dec->show(show_obj[d->id].toBool());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dec_obj.contains("show")) {
|
||||
QJsonObject show_obj = dec_obj["show"].toObject();
|
||||
std::map<const pv::data::decode::Row, bool> rows = stack->get_rows_gshow();
|
||||
for (std::map<const pv::data::decode::Row, bool>::const_iterator i = rows.begin();
|
||||
i != rows.end(); i++) {
|
||||
if (show_obj.contains((*i).first.title())) {
|
||||
stack->set_rows_gshow((*i).first, show_obj[(*i).first.title()].toBool());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
double StoreSession::get_double(GVariant *var)
|
||||
{
|
||||
double val;
|
||||
const GVariantType *const type = g_variant_get_type(var);
|
||||
assert(type);
|
||||
|
||||
if (g_variant_type_equal(type, G_VARIANT_TYPE_BYTE))
|
||||
val = g_variant_get_byte(var);
|
||||
else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT16))
|
||||
val = g_variant_get_int16(var);
|
||||
else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT16))
|
||||
val = g_variant_get_uint16(var);
|
||||
else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT32))
|
||||
val = g_variant_get_int32(var);
|
||||
else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT32))
|
||||
val = g_variant_get_uint32(var);
|
||||
else if (g_variant_type_equal(type, G_VARIANT_TYPE_INT64))
|
||||
val = g_variant_get_int64(var);
|
||||
else if (g_variant_type_equal(type, G_VARIANT_TYPE_UINT64))
|
||||
val = g_variant_get_uint64(var);
|
||||
else
|
||||
assert(0);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
} // pv
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
* This file is part of the PulseView project.
|
||||
*
|
||||
* Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||
* Copyright (C) 2016 DreamSourceLab <support@dreamsourcelab.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -22,19 +23,25 @@
|
||||
#define DSVIEW_PV_STORESESSION_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <libsigrok4DSL/libsigrok.h>
|
||||
#include <libsigrokdecode/libsigrokdecode.h>
|
||||
|
||||
namespace pv {
|
||||
|
||||
class SigSession;
|
||||
|
||||
namespace data {
|
||||
class LogicSnapshot;
|
||||
class Snapshot;
|
||||
}
|
||||
|
||||
namespace dock {
|
||||
class ProtocolDock;
|
||||
}
|
||||
|
||||
class StoreSession : public QObject
|
||||
@@ -42,11 +49,10 @@ class StoreSession : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
static const size_t BlockSize;
|
||||
const static int File_Version = 2;
|
||||
|
||||
public:
|
||||
StoreSession(const std::string &file_name,
|
||||
SigSession &session);
|
||||
StoreSession(SigSession &session);
|
||||
|
||||
~StoreSession();
|
||||
|
||||
@@ -54,27 +60,48 @@ public:
|
||||
|
||||
const QString& error() const;
|
||||
|
||||
bool start();
|
||||
bool save_start();
|
||||
|
||||
bool export_start();
|
||||
|
||||
void wait();
|
||||
|
||||
void cancel();
|
||||
|
||||
private:
|
||||
void store_proc(boost::shared_ptr<pv::data::LogicSnapshot> snapshot);
|
||||
void save_proc(boost::shared_ptr<pv::data::Snapshot> snapshot);
|
||||
QString meta_gen(boost::shared_ptr<data::Snapshot> snapshot);
|
||||
void export_proc(boost::shared_ptr<pv::data::Snapshot> snapshot);
|
||||
#ifdef ENABLE_DECODE
|
||||
QString decoders_gen();
|
||||
#endif
|
||||
|
||||
public:
|
||||
#ifdef ENABLE_DECODE
|
||||
QJsonArray json_decoders();
|
||||
void load_decoders(dock::ProtocolDock *widget, QJsonArray dec_array);
|
||||
#endif
|
||||
|
||||
private:
|
||||
QList<QString> getSuportedExportFormats();
|
||||
double get_double(GVariant * var);
|
||||
|
||||
signals:
|
||||
void progress_updated();
|
||||
|
||||
private:
|
||||
const std::string _file_name;
|
||||
QString _file_name;
|
||||
QString _suffix;
|
||||
SigSession &_session;
|
||||
|
||||
boost::thread _thread;
|
||||
|
||||
const struct sr_output_module* _outModule;
|
||||
|
||||
//mutable boost::mutex _mutex;
|
||||
uint64_t _units_stored;
|
||||
uint64_t _unit_count;
|
||||
bool _has_error;
|
||||
QString _error;
|
||||
};
|
||||
|
||||
|
||||
@@ -91,13 +91,13 @@ FileBar::FileBar(SigSession &session, QWidget *parent) :
|
||||
_action_save->setIcon(QIcon::fromTheme("file",
|
||||
QIcon(":/icons/save.png")));
|
||||
_action_save->setObjectName(QString::fromUtf8("actionSave"));
|
||||
connect(_action_save, SIGNAL(triggered()), this, SLOT(on_actionSave_triggered()));
|
||||
connect(_action_save, SIGNAL(triggered()), this, SIGNAL(on_save()));
|
||||
|
||||
_action_export = new QAction(this);
|
||||
_action_export->setText(QApplication::translate("File", "&Export...", 0));
|
||||
_action_export->setIcon(QIcon::fromTheme("file",QIcon(":/icons/export.png")));
|
||||
_action_export->setObjectName(QString::fromUtf8("actionExport"));
|
||||
connect(_action_export, SIGNAL(triggered()), this, SLOT(on_actionExport_triggered()));
|
||||
connect(_action_export, SIGNAL(triggered()), this, SIGNAL(on_export()));
|
||||
|
||||
|
||||
_action_capture = new QAction(this);
|
||||
@@ -119,9 +119,6 @@ FileBar::FileBar(SigSession &session, QWidget *parent) :
|
||||
_menu->addAction(_action_capture);
|
||||
_file_button.setMenu(_menu);
|
||||
addWidget(&_file_button);
|
||||
|
||||
_screenshot_timer.setSingleShot(true);
|
||||
connect(&_screenshot_timer, SIGNAL(timeout()), this, SIGNAL(on_screenShot()));
|
||||
}
|
||||
|
||||
void FileBar::on_actionOpen_triggered()
|
||||
@@ -131,7 +128,7 @@ void FileBar::on_actionOpen_triggered()
|
||||
// Show the dialog
|
||||
const QString file_name = QFileDialog::getOpenFileName(
|
||||
this, tr("Open File"), settings.value(DIR_KEY).toString(), tr(
|
||||
"DSView Data (*.dsl);;All Files (*.*)"));
|
||||
"DSView Data (*.dsl)"));
|
||||
if (!file_name.isEmpty()) {
|
||||
QDir CurrentDir;
|
||||
settings.setValue(DIR_KEY, CurrentDir.absoluteFilePath(file_name));
|
||||
@@ -158,74 +155,6 @@ void FileBar::show_session_error(
|
||||
msg.exec();
|
||||
}
|
||||
|
||||
void FileBar::on_actionExport_triggered(){
|
||||
const QString DIR_KEY("ExportPath");
|
||||
QSettings settings;
|
||||
int unit_size;
|
||||
uint64_t length;
|
||||
const void* buf = _session.get_buf(unit_size, length);
|
||||
if (!buf) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Data Export"));
|
||||
msg.mBox()->setInformativeText(tr("No Data to Save!"));
|
||||
msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
} else {
|
||||
QList<QString> supportedFormats = _session.getSuportedExportFormats();
|
||||
QString filter;
|
||||
for(int i = 0; i < supportedFormats.count();i++){
|
||||
filter.append(supportedFormats[i]);
|
||||
if(i < supportedFormats.count() - 1)
|
||||
filter.append(";;");
|
||||
}
|
||||
QString file_name = QFileDialog::getSaveFileName(
|
||||
this, tr("Export Data"), settings.value(DIR_KEY).toString(),filter,&filter);
|
||||
if (!file_name.isEmpty()) {
|
||||
QFileInfo f(file_name);
|
||||
QStringList list = filter.split('.').last().split(')');
|
||||
QString ext = list.first();
|
||||
if(f.suffix().compare(ext))
|
||||
file_name+=tr(".")+ext;
|
||||
QDir CurrentDir;
|
||||
settings.setValue(DIR_KEY, CurrentDir.absoluteFilePath(file_name));
|
||||
_session.export_file(file_name, this, ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileBar::on_actionSave_triggered()
|
||||
{
|
||||
const QString DIR_KEY("SavePath");
|
||||
QSettings settings;
|
||||
//save();
|
||||
int unit_size;
|
||||
uint64_t length;
|
||||
const void* buf = _session.get_buf(unit_size, length);
|
||||
if (!buf) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("File Save"));
|
||||
msg.mBox()->setInformativeText(tr("No Data to Save!"));
|
||||
msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
} else {
|
||||
QString file_name = QFileDialog::getSaveFileName(
|
||||
this, tr("Save File"), settings.value(DIR_KEY).toString(),
|
||||
tr("DSView Data (*.dsl)"));
|
||||
|
||||
if (!file_name.isEmpty()) {
|
||||
QFileInfo f(file_name);
|
||||
if(f.suffix().compare("dsl"))
|
||||
file_name.append(tr(".dsl"));
|
||||
QDir CurrentDir;
|
||||
settings.setValue(DIR_KEY, CurrentDir.absoluteFilePath(file_name));
|
||||
_session.save_file(file_name, this, _session.get_device()->dev_inst()->mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FileBar::on_actionLoad_triggered()
|
||||
{
|
||||
const QString DIR_KEY("SessionLoadPath");
|
||||
@@ -282,7 +211,7 @@ void FileBar::on_actionCapture_triggered()
|
||||
{
|
||||
_file_button.close();
|
||||
QCoreApplication::sendPostedEvents();
|
||||
_screenshot_timer.start(100);
|
||||
QTimer::singleShot(100, this, SIGNAL(on_screenShot()));
|
||||
}
|
||||
|
||||
void FileBar::enable_toggle(bool enable)
|
||||
|
||||
@@ -53,7 +53,8 @@ private:
|
||||
|
||||
signals:
|
||||
void load_file(QString);
|
||||
void save();
|
||||
void on_save();
|
||||
void on_export();
|
||||
void on_screenShot();
|
||||
void load_session(QString);
|
||||
void store_session(QString);
|
||||
@@ -63,9 +64,7 @@ private slots:
|
||||
void on_actionStore_triggered();
|
||||
void on_actionDefault_triggered();
|
||||
void on_actionOpen_triggered();
|
||||
void on_actionSave_triggered();
|
||||
void on_actionCapture_triggered();
|
||||
void on_actionExport_triggered();
|
||||
|
||||
private:
|
||||
bool _enable;
|
||||
@@ -84,9 +83,6 @@ private:
|
||||
QAction *_action_save;
|
||||
QAction *_action_export;
|
||||
QAction *_action_capture;
|
||||
|
||||
QTimer _screenshot_timer;
|
||||
|
||||
};
|
||||
|
||||
} // namespace toolbars
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <QDebug>
|
||||
#include <QLabel>
|
||||
#include <QAbstractItemView>
|
||||
#include <QApplication>
|
||||
|
||||
#include "samplingbar.h"
|
||||
|
||||
@@ -41,6 +42,7 @@
|
||||
#include "../dialogs/waitingdialog.h"
|
||||
#include "../dialogs/dsmessagebox.h"
|
||||
#include "../view/dsosignal.h"
|
||||
#include "../dialogs/interval.h"
|
||||
|
||||
using namespace boost;
|
||||
using boost::shared_ptr;
|
||||
@@ -74,12 +76,15 @@ const uint64_t SamplingBar::RecordLengths[19] = {
|
||||
40000000,
|
||||
};
|
||||
|
||||
const QString SamplingBar::RLEString = "(RLE)";
|
||||
|
||||
const uint64_t SamplingBar::DefaultRecordLength = 1000000;
|
||||
|
||||
SamplingBar::SamplingBar(SigSession &session, QWidget *parent) :
|
||||
QToolBar("Sampling Bar", parent),
|
||||
_session(session),
|
||||
_enable(true),
|
||||
_sampling(false),
|
||||
_device_selector(this),
|
||||
_updating_device_selector(false),
|
||||
_configure_button(this),
|
||||
@@ -94,6 +99,11 @@ SamplingBar::SamplingBar(SigSession &session, QWidget *parent) :
|
||||
_icon_instant_dis(":/icons/instant_dis.png"),
|
||||
_run_stop_button(this),
|
||||
_instant_button(this),
|
||||
_mode_button(this),
|
||||
_icon_repeat(":/icons/moder.png"),
|
||||
_icon_single(":/icons/modes.png"),
|
||||
_icon_repeat_dis(":/icons/moder_dis.png"),
|
||||
_icon_single_dis(":/icons/modes_dis.png"),
|
||||
_instant(false)
|
||||
{
|
||||
setMovable(false);
|
||||
@@ -112,6 +122,8 @@ SamplingBar::SamplingBar(SigSession &session, QWidget *parent) :
|
||||
_configure_button.setIcon(QIcon::fromTheme("configure",
|
||||
QIcon(":/icons/params.png")));
|
||||
|
||||
_mode_button.setPopupMode(QToolButton::InstantPopup);
|
||||
_mode_button.setIcon(_session.get_run_mode() == pv::SigSession::Single ? _icon_single : _icon_repeat);
|
||||
_run_stop_button.setIcon(_icon_start);
|
||||
_instant_button.setIcon(_icon_instant);
|
||||
|
||||
@@ -138,6 +150,25 @@ SamplingBar::SamplingBar(SigSession &session, QWidget *parent) :
|
||||
addWidget(&_sample_count);
|
||||
addWidget(new QLabel(tr(" @ ")));
|
||||
addWidget(&_sample_rate);
|
||||
|
||||
_action_single = new QAction(this);
|
||||
_action_single->setText(QApplication::translate("Sampling", "&Single", 0));
|
||||
_action_single->setIcon(QIcon::fromTheme("Sampling",
|
||||
QIcon(":/icons/oneloop.png")));
|
||||
connect(_action_single, SIGNAL(triggered()), this, SLOT(on_mode()));
|
||||
|
||||
_action_repeat = new QAction(this);
|
||||
_action_repeat->setText(QApplication::translate("Sampling", "&Repetitive", 0));
|
||||
_action_repeat->setIcon(QIcon::fromTheme("Sampling",
|
||||
QIcon(":/icons/repeat.png")));
|
||||
connect(_action_repeat, SIGNAL(triggered()), this, SLOT(on_mode()));
|
||||
|
||||
_mode_menu = new QMenu(this);
|
||||
_mode_menu->addAction(_action_single);
|
||||
_mode_menu->addAction(_action_repeat);
|
||||
_mode_button.setMenu(_mode_menu);
|
||||
_mode_action = addWidget(&_mode_button);
|
||||
|
||||
_run_stop_action = addWidget(&_run_stop_button);
|
||||
_instant_action = addWidget(&_instant_button);
|
||||
}
|
||||
@@ -245,10 +276,8 @@ void SamplingBar::on_configure()
|
||||
if (test) {
|
||||
update_sample_count_selector_value();
|
||||
update_sample_rate_selector_value();
|
||||
#ifndef TEST_MODE
|
||||
_sample_count.setDisabled(true);
|
||||
_sample_rate.setDisabled(true);
|
||||
#endif
|
||||
} else if (dev_inst->dev_inst()->mode != DSO) {
|
||||
_sample_count.setDisabled(false);
|
||||
_sample_rate.setDisabled(false);
|
||||
@@ -277,7 +306,7 @@ void SamplingBar::zero_adj()
|
||||
}
|
||||
|
||||
if (_session.get_capture_state() == pv::SigSession::Running)
|
||||
run_stop();
|
||||
on_run_stop();
|
||||
}
|
||||
|
||||
uint64_t SamplingBar::get_record_length() const
|
||||
@@ -322,8 +351,20 @@ void SamplingBar::update_sample_rate()
|
||||
this, SLOT(on_samplerate_sel(int)));
|
||||
}
|
||||
|
||||
bool SamplingBar::get_sampling() const
|
||||
{
|
||||
return _sampling;
|
||||
}
|
||||
|
||||
bool SamplingBar::get_instant() const
|
||||
{
|
||||
return _instant;
|
||||
}
|
||||
|
||||
void SamplingBar::set_sampling(bool sampling)
|
||||
{
|
||||
lock_guard<boost::recursive_mutex> lock(_sampling_mutex);
|
||||
_sampling = sampling;
|
||||
if (_instant) {
|
||||
_instant_button.setIcon(sampling ? _icon_stop : _icon_instant);
|
||||
_run_stop_button.setIcon(sampling ? _icon_start_dis : _icon_start);
|
||||
@@ -342,6 +383,9 @@ void SamplingBar::set_sampling(bool sampling)
|
||||
enable_run_stop(true);
|
||||
}
|
||||
|
||||
_mode_button.setEnabled(!sampling);
|
||||
_mode_button.setIcon(sampling ? (_session.get_run_mode() == pv::SigSession::Single ? _icon_single_dis : _icon_repeat_dis) :
|
||||
(_session.get_run_mode() == pv::SigSession::Single ? _icon_single : _icon_repeat));
|
||||
_configure_button.setEnabled(!sampling);
|
||||
_configure_button.setIcon(sampling ? QIcon(":/icons/params_dis.png") :
|
||||
QIcon(":/icons/params.png"));
|
||||
@@ -482,7 +526,6 @@ void SamplingBar::on_samplecount_sel(int index)
|
||||
{
|
||||
uint64_t sample_count = 0;
|
||||
|
||||
qDebug() << "index: " << index;
|
||||
if (index >= 0)
|
||||
sample_count = _sample_count.itemData(
|
||||
index).value<uint64_t>();
|
||||
@@ -509,13 +552,13 @@ void SamplingBar::on_samplerate_sel(int index)
|
||||
sample_rate = _sample_rate.itemData(
|
||||
index).value<uint64_t>();
|
||||
|
||||
boost::shared_ptr<pv::device::DevInst> _devInst = get_selected_device();
|
||||
assert(_devInst);
|
||||
boost::shared_ptr<pv::device::DevInst> dev_inst = get_selected_device();
|
||||
assert(dev_inst);
|
||||
|
||||
// Get last samplerate
|
||||
//last_sample_rate = get_selected_device()->get_sample_rate();
|
||||
|
||||
if (_devInst->name() == "DSLogic" && _devInst->dev_inst()->mode != DSO) {
|
||||
if (dev_inst->name() == "DSLogic" && dev_inst->dev_inst()->mode != DSO) {
|
||||
// Set the samplerate
|
||||
get_selected_device()->set_config(NULL, NULL,
|
||||
SR_CONF_SAMPLERATE,
|
||||
@@ -529,7 +572,8 @@ void SamplingBar::update_sample_count_selector()
|
||||
const uint64_t *elements = NULL;
|
||||
gsize num_elements;
|
||||
bool stream_mode = false;
|
||||
uint64_t max_sample_count = 0;
|
||||
uint64_t hw_depth;
|
||||
uint64_t sw_depth;
|
||||
|
||||
if (_updating_sample_count)
|
||||
return;
|
||||
@@ -557,9 +601,9 @@ void SamplingBar::update_sample_count_selector()
|
||||
stream_mode = g_variant_get_boolean(gvar);
|
||||
g_variant_unref(gvar);
|
||||
}
|
||||
gvar = dev_inst->get_config(NULL, NULL, SR_CONF_RLE_SAMPLELIMITS);
|
||||
gvar = dev_inst->get_config(NULL, NULL, SR_CONF_HW_DEPTH);
|
||||
if (gvar != NULL) {
|
||||
max_sample_count = g_variant_get_uint64(gvar);
|
||||
hw_depth = g_variant_get_uint64(gvar);
|
||||
g_variant_unref(gvar);
|
||||
}
|
||||
|
||||
@@ -570,11 +614,23 @@ void SamplingBar::update_sample_count_selector()
|
||||
gvar_list, &num_elements, sizeof(uint64_t));
|
||||
_sample_count.clear();
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
sw_depth = elements[num_elements - 1];
|
||||
#elif defined(__i386) || defined(_M_IX86)
|
||||
int ch_num = _session.get_ch_num(SR_CHANNEL_LOGIC);
|
||||
if (ch_num <= 0)
|
||||
sw_depth = SR_GB(8);
|
||||
else
|
||||
sw_depth = SR_GB(8) / ch_num;
|
||||
#endif
|
||||
|
||||
for (unsigned int i = 0; i < num_elements; i++)
|
||||
{
|
||||
if (elements[i] > sw_depth)
|
||||
break;
|
||||
char *const s = sr_samplecount_string(elements[i]);
|
||||
if (!stream_mode && (elements[i] > max_sample_count))
|
||||
_sample_count.addItem(QString(s)+"(RLE)",
|
||||
if (!stream_mode && (elements[i] > hw_depth))
|
||||
_sample_count.addItem(QString(s)+RLEString,
|
||||
qVariantFromValue(elements[i]));
|
||||
else
|
||||
_sample_count.addItem(QString(s),
|
||||
@@ -647,81 +703,118 @@ void SamplingBar::commit_sample_count()
|
||||
g_variant_new_uint64(sample_count));
|
||||
}
|
||||
|
||||
bool rle_mode = _sample_count.currentText().contains(RLEString);
|
||||
get_selected_device()->set_config(NULL, NULL,
|
||||
SR_CONF_RLE,
|
||||
g_variant_new_boolean(rle_mode));
|
||||
|
||||
_updating_sample_count = false;
|
||||
}
|
||||
|
||||
void SamplingBar::on_run_stop()
|
||||
{
|
||||
enable_run_stop(false);
|
||||
enable_instant(false);
|
||||
commit_sample_rate();
|
||||
commit_sample_count();
|
||||
_instant = false;
|
||||
const shared_ptr<device::DevInst> dev_inst = get_selected_device();
|
||||
if (!dev_inst)
|
||||
return;
|
||||
if (dev_inst->dev_inst()->mode == DSO) {
|
||||
GVariant* gvar = dev_inst->get_config(NULL, NULL, SR_CONF_ZERO);
|
||||
if (gvar != NULL) {
|
||||
bool zero = g_variant_get_boolean(gvar);
|
||||
g_variant_unref(gvar);
|
||||
if (zero) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Zero Adjustment"));
|
||||
msg.mBox()->setInformativeText(tr("Please adjust zero skew and save the result!"));
|
||||
//msg.setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole);
|
||||
msg.mBox()->addButton(tr("Skip"), QMessageBox::RejectRole);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
if (msg.exec()) {
|
||||
zero_adj();
|
||||
} else {
|
||||
dev_inst->set_config(NULL, NULL, SR_CONF_ZERO, g_variant_new_boolean(false));
|
||||
enable_run_stop(true);
|
||||
enable_instant(true);
|
||||
}
|
||||
return;
|
||||
if (get_sampling() || _session.isRepeating()) {
|
||||
_session.set_repeating(false);
|
||||
bool wait_upload = false;
|
||||
if (_session.get_run_mode() != SigSession::Repetitive) {
|
||||
GVariant *gvar = get_selected_device()->get_config(NULL, NULL, SR_CONF_WAIT_UPLOAD);
|
||||
if (gvar != NULL) {
|
||||
wait_upload = g_variant_get_boolean(gvar);
|
||||
g_variant_unref(gvar);
|
||||
}
|
||||
}
|
||||
if (!wait_upload) {
|
||||
_session.stop_capture();
|
||||
_session.capture_state_changed(SigSession::Stopped);
|
||||
}
|
||||
} else {
|
||||
enable_run_stop(false);
|
||||
enable_instant(false);
|
||||
commit_sample_rate();
|
||||
commit_sample_count();
|
||||
_instant = false;
|
||||
const shared_ptr<device::DevInst> dev_inst = get_selected_device();
|
||||
if (!dev_inst)
|
||||
return;
|
||||
if (dev_inst->dev_inst()->mode == DSO) {
|
||||
GVariant* gvar = dev_inst->get_config(NULL, NULL, SR_CONF_ZERO);
|
||||
if (gvar != NULL) {
|
||||
bool zero = g_variant_get_boolean(gvar);
|
||||
g_variant_unref(gvar);
|
||||
if (zero) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Auto Calibration"));
|
||||
msg.mBox()->setInformativeText(tr("Please adjust zero skew and save the result!"));
|
||||
//msg.setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole);
|
||||
msg.mBox()->addButton(tr("Skip"), QMessageBox::RejectRole);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
if (msg.exec()) {
|
||||
zero_adj();
|
||||
} else {
|
||||
dev_inst->set_config(NULL, NULL, SR_CONF_ZERO, g_variant_new_boolean(false));
|
||||
enable_run_stop(true);
|
||||
enable_instant(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
run_stop();
|
||||
}
|
||||
run_stop();
|
||||
}
|
||||
|
||||
void SamplingBar::on_instant_stop()
|
||||
{
|
||||
enable_run_stop(false);
|
||||
enable_instant(false);
|
||||
commit_sample_rate();
|
||||
commit_sample_count();
|
||||
_instant = true;
|
||||
const shared_ptr<device::DevInst> dev_inst = get_selected_device();
|
||||
if (!dev_inst)
|
||||
return;
|
||||
if (dev_inst->dev_inst()->mode == DSO) {
|
||||
GVariant* gvar = dev_inst->get_config(NULL, NULL, SR_CONF_ZERO);
|
||||
if (gvar != NULL) {
|
||||
bool zero = g_variant_get_boolean(gvar);
|
||||
g_variant_unref(gvar);
|
||||
if (zero) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Zero Adjustment"));
|
||||
msg.mBox()->setInformativeText(tr("Zero adjustment program will be started. Please keep all channels out of singal input. It can take a while!"));
|
||||
//msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole);
|
||||
msg.mBox()->addButton(tr("Skip"), QMessageBox::RejectRole);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
if (msg.exec()) {
|
||||
zero_adj();
|
||||
} else {
|
||||
dev_inst->set_config(NULL, NULL, SR_CONF_ZERO, g_variant_new_boolean(false));
|
||||
enable_run_stop(true);
|
||||
enable_instant(true);
|
||||
}
|
||||
return;
|
||||
if (get_sampling()) {
|
||||
_session.set_repeating(false);
|
||||
bool wait_upload = false;
|
||||
if (_session.get_run_mode() != SigSession::Repetitive) {
|
||||
GVariant *gvar = get_selected_device()->get_config(NULL, NULL, SR_CONF_WAIT_UPLOAD);
|
||||
if (gvar != NULL) {
|
||||
wait_upload = g_variant_get_boolean(gvar);
|
||||
g_variant_unref(gvar);
|
||||
}
|
||||
}
|
||||
if (!wait_upload) {
|
||||
_session.stop_capture();
|
||||
_session.capture_state_changed(SigSession::Stopped);
|
||||
}
|
||||
} else {
|
||||
enable_run_stop(false);
|
||||
enable_instant(false);
|
||||
commit_sample_rate();
|
||||
commit_sample_count();
|
||||
_instant = true;
|
||||
const shared_ptr<device::DevInst> dev_inst = get_selected_device();
|
||||
if (!dev_inst)
|
||||
return;
|
||||
if (dev_inst->dev_inst()->mode == DSO) {
|
||||
GVariant* gvar = dev_inst->get_config(NULL, NULL, SR_CONF_ZERO);
|
||||
if (gvar != NULL) {
|
||||
bool zero = g_variant_get_boolean(gvar);
|
||||
g_variant_unref(gvar);
|
||||
if (zero) {
|
||||
dialogs::DSMessageBox msg(this);
|
||||
msg.mBox()->setText(tr("Auto Calibration"));
|
||||
msg.mBox()->setInformativeText(tr("Auto Calibration program will be started. Please keep all channels out of singal input. It can take a while!"));
|
||||
//msg.mBox()->setStandardButtons(QMessageBox::Ok);
|
||||
msg.mBox()->addButton(tr("Ok"), QMessageBox::AcceptRole);
|
||||
msg.mBox()->addButton(tr("Skip"), QMessageBox::RejectRole);
|
||||
msg.mBox()->setIcon(QMessageBox::Warning);
|
||||
if (msg.exec()) {
|
||||
zero_adj();
|
||||
} else {
|
||||
dev_inst->set_config(NULL, NULL, SR_CONF_ZERO, g_variant_new_boolean(false));
|
||||
enable_run_stop(true);
|
||||
enable_instant(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
instant_stop();
|
||||
}
|
||||
instant_stop();
|
||||
}
|
||||
|
||||
void SamplingBar::on_device_selected()
|
||||
@@ -757,6 +850,9 @@ void SamplingBar::enable_toggle(bool enable)
|
||||
if (!test) {
|
||||
_sample_count.setDisabled(!enable);
|
||||
_sample_rate.setDisabled(!enable);
|
||||
} else {
|
||||
_sample_count.setDisabled(true);
|
||||
_sample_rate.setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -787,10 +883,17 @@ void SamplingBar::reload()
|
||||
_icon_instant = QIcon(":/icons/instant.png");
|
||||
_icon_instant_dis = QIcon(":/icons/instant_dis.png");
|
||||
_instant_button.setIcon(_icon_instant);
|
||||
if (_session.get_device()->name() == "virtual-session") {
|
||||
_mode_action->setVisible(false);
|
||||
} else {
|
||||
_mode_button.setIcon(_session.get_run_mode() == pv::SigSession::Single ? _icon_single : _icon_repeat);
|
||||
_mode_action->setVisible(true);
|
||||
}
|
||||
_run_stop_action->setVisible(true);
|
||||
_instant_action->setVisible(true);
|
||||
enable_toggle(true);
|
||||
} else if (_session.get_device()->dev_inst()->mode == ANALOG) {
|
||||
_mode_action->setVisible(false);
|
||||
_run_stop_action->setVisible(true);
|
||||
_instant_action->setVisible(false);
|
||||
enable_toggle(true);
|
||||
@@ -798,6 +901,7 @@ void SamplingBar::reload()
|
||||
_icon_instant = QIcon(":/icons/single.png");
|
||||
_icon_instant_dis = QIcon(":/icons/single_dis.png");
|
||||
_instant_button.setIcon(_icon_instant);
|
||||
_mode_action->setVisible(false);
|
||||
_run_stop_action->setVisible(true);
|
||||
_instant_action->setVisible(true);
|
||||
enable_toggle(false);
|
||||
@@ -805,5 +909,19 @@ void SamplingBar::reload()
|
||||
update();
|
||||
}
|
||||
|
||||
void SamplingBar::on_mode()
|
||||
{
|
||||
QAction *act = qobject_cast<QAction *>(sender());
|
||||
if (act == _action_single) {
|
||||
_mode_button.setIcon(_icon_single);
|
||||
_session.set_run_mode(pv::SigSession::Single);
|
||||
} else if (act == _action_repeat) {
|
||||
_mode_button.setIcon(_icon_repeat);
|
||||
pv::dialogs::Interval interval_dlg(_session, this);
|
||||
interval_dlg.exec();
|
||||
_session.set_run_mode(pv::SigSession::Repetitive);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace toolbars
|
||||
} // namespace pv
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include <QComboBox>
|
||||
#include <QToolBar>
|
||||
#include <QToolButton>
|
||||
#include <QAction>
|
||||
#include <QMenu>
|
||||
|
||||
#include <libsigrok4DSL/libsigrok.h>
|
||||
|
||||
@@ -64,6 +66,7 @@ private:
|
||||
static const uint64_t RecordLengths[19];
|
||||
static const uint64_t DefaultRecordLength;
|
||||
static const int ComboBoxMaxWidth = 200;
|
||||
static const QString RLEString;
|
||||
|
||||
public:
|
||||
SamplingBar(SigSession &session, QWidget *parent);
|
||||
@@ -80,6 +83,8 @@ public:
|
||||
void update_sample_rate();
|
||||
|
||||
void set_sampling(bool sampling);
|
||||
bool get_sampling() const;
|
||||
bool get_instant() const;
|
||||
|
||||
void enable_toggle(bool enable);
|
||||
|
||||
@@ -110,6 +115,7 @@ private:
|
||||
void setting_adj();
|
||||
|
||||
private slots:
|
||||
void on_mode();
|
||||
void on_run_stop();
|
||||
void on_instant_stop();
|
||||
void on_device_selected();
|
||||
@@ -127,7 +133,9 @@ public slots:
|
||||
private:
|
||||
SigSession &_session;
|
||||
|
||||
mutable boost::recursive_mutex _sampling_mutex;
|
||||
bool _enable;
|
||||
bool _sampling;
|
||||
|
||||
QComboBox _device_selector;
|
||||
std::map<const void*, boost::weak_ptr<device::DevInst> >
|
||||
@@ -151,6 +159,17 @@ private:
|
||||
QAction* _run_stop_action;
|
||||
QAction* _instant_action;
|
||||
|
||||
QAction* _mode_action;
|
||||
QToolButton _mode_button;
|
||||
QMenu *_mode_menu;
|
||||
QAction *_action_repeat;
|
||||
QAction *_action_single;
|
||||
|
||||
QIcon _icon_repeat;
|
||||
QIcon _icon_single;
|
||||
QIcon _icon_repeat_dis;
|
||||
QIcon _icon_single_dis;
|
||||
|
||||
bool _instant;
|
||||
};
|
||||
|
||||
|
||||
@@ -85,7 +85,7 @@ void AnalogSignal::paint_mid(QPainter &p, int left, int right)
|
||||
const int y = get_y() + _totalHeight * 0.5;
|
||||
const double scale = _view->scale();
|
||||
assert(scale > 0);
|
||||
const double offset = _view->offset();
|
||||
const int64_t offset = _view->offset();
|
||||
|
||||
const deque< boost::shared_ptr<pv::data::AnalogSnapshot> > &snapshots =
|
||||
_data->get_snapshots();
|
||||
@@ -98,15 +98,15 @@ void AnalogSignal::paint_mid(QPainter &p, int left, int right)
|
||||
if (snapshot->empty())
|
||||
return;
|
||||
|
||||
if (get_index() >= (int)snapshot->get_channel_num())
|
||||
const int order = snapshot->get_ch_order(get_index());
|
||||
if (order == -1)
|
||||
return;
|
||||
|
||||
const double pixels_offset = offset / scale;
|
||||
const double pixels_offset = offset;
|
||||
const double samplerate = _data->samplerate();
|
||||
const double start_time = _data->get_start_time();
|
||||
const int64_t last_sample = max((int64_t)(snapshot->get_sample_count() - 1), (int64_t)0);
|
||||
const double samples_per_pixel = samplerate * scale;
|
||||
const double start = samplerate * (offset - start_time);
|
||||
const double start = offset * samples_per_pixel;
|
||||
const double end = start + samples_per_pixel * (right - left);
|
||||
|
||||
const int64_t start_sample = min(max((int64_t)floor(start),
|
||||
@@ -117,17 +117,18 @@ void AnalogSignal::paint_mid(QPainter &p, int left, int right)
|
||||
if (samples_per_pixel < EnvelopeThreshold)
|
||||
paint_trace(p, snapshot, y, left,
|
||||
start_sample, end_sample,
|
||||
pixels_offset, samples_per_pixel);
|
||||
pixels_offset, samples_per_pixel, order);
|
||||
else
|
||||
paint_envelope(p, snapshot, y, left,
|
||||
start_sample, end_sample,
|
||||
pixels_offset, samples_per_pixel);
|
||||
pixels_offset, samples_per_pixel, order);
|
||||
}
|
||||
|
||||
void AnalogSignal::paint_trace(QPainter &p,
|
||||
const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot,
|
||||
int y, int left, const int64_t start, const int64_t end,
|
||||
const double pixels_offset, const double samples_per_pixel)
|
||||
const double pixels_offset, const double samples_per_pixel,
|
||||
int order)
|
||||
{
|
||||
const int64_t sample_count = end - start;
|
||||
const int64_t channel_num = snapshot->get_channel_num();
|
||||
@@ -145,7 +146,7 @@ void AnalogSignal::paint_trace(QPainter &p,
|
||||
const float x = (sample / samples_per_pixel -
|
||||
pixels_offset) + left;
|
||||
*point++ = QPointF(x,
|
||||
y - samples[(sample - start) * channel_num + get_index()] * _scale);
|
||||
y - samples[(sample - start) * channel_num + order] * _scale);
|
||||
}
|
||||
|
||||
p.drawPolyline(points, point - points);
|
||||
@@ -157,13 +158,14 @@ void AnalogSignal::paint_trace(QPainter &p,
|
||||
void AnalogSignal::paint_envelope(QPainter &p,
|
||||
const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot,
|
||||
int y, int left, const int64_t start, const int64_t end,
|
||||
const double pixels_offset, const double samples_per_pixel)
|
||||
const double pixels_offset, const double samples_per_pixel,
|
||||
int order)
|
||||
{
|
||||
using namespace Qt;
|
||||
using pv::data::AnalogSnapshot;
|
||||
|
||||
AnalogSnapshot::EnvelopeSection e;
|
||||
snapshot->get_envelope_section(e, start, end, samples_per_pixel, get_index());
|
||||
snapshot->get_envelope_section(e, start, end, samples_per_pixel, order);
|
||||
|
||||
if (e.length < 2)
|
||||
return;
|
||||
@@ -201,10 +203,5 @@ void AnalogSignal::paint_envelope(QPainter &p,
|
||||
//delete[] e.samples;
|
||||
}
|
||||
|
||||
const std::vector< std::pair<uint64_t, bool> > AnalogSignal::cur_edges() const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} // namespace view
|
||||
} // namespace pv
|
||||
|
||||
@@ -64,18 +64,16 @@ public:
|
||||
**/
|
||||
void paint_mid(QPainter &p, int left, int right);
|
||||
|
||||
const std::vector< std::pair<uint64_t, bool> > cur_edges() const;
|
||||
|
||||
private:
|
||||
void paint_trace(QPainter &p,
|
||||
const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot,
|
||||
int y, int left, const int64_t start, const int64_t end,
|
||||
const double pixels_offset, const double samples_per_pixel);
|
||||
void paint_trace(QPainter &p,
|
||||
const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot,
|
||||
int y, int left, const int64_t start, const int64_t end,
|
||||
const double pixels_offset, const double samples_per_pixel, int order);
|
||||
|
||||
void paint_envelope(QPainter &p,
|
||||
const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot,
|
||||
int y, int left, const int64_t start, const int64_t end,
|
||||
const double pixels_offset, const double samples_per_pixel);
|
||||
void paint_envelope(QPainter &p,
|
||||
const boost::shared_ptr<pv::data::AnalogSnapshot> &snapshot,
|
||||
int y, int left, const int64_t start, const int64_t end,
|
||||
const double pixels_offset, const double samples_per_pixel, int order);
|
||||
|
||||
private:
|
||||
boost::shared_ptr<pv::data::Analog> _data;
|
||||
|
||||
@@ -58,25 +58,31 @@ Cursor::Cursor(View &view, QColor color, uint64_t index) :
|
||||
{
|
||||
}
|
||||
|
||||
QRectF Cursor::get_label_rect(const QRect &rect) const
|
||||
QRect Cursor::get_label_rect(const QRect &rect, bool &visible) const
|
||||
{
|
||||
const double samples_per_pixel = _view.session().cur_samplerate() * _view.scale();
|
||||
const double x = _index/samples_per_pixel - (_view.offset() / _view.scale());
|
||||
const double cur_offset = _index / samples_per_pixel;
|
||||
if (cur_offset < _view.offset() ||
|
||||
cur_offset > (_view.offset() + _view.width())) {
|
||||
visible = false;
|
||||
return QRect(-1, -1, 0, 0);
|
||||
}
|
||||
const int64_t x = _index/samples_per_pixel - _view.offset();
|
||||
|
||||
const QSizeF label_size(
|
||||
const QSize label_size(
|
||||
_text_size.width() + View::LabelPadding.width() * 2,
|
||||
_text_size.height() + View::LabelPadding.height() * 2);
|
||||
const float top = rect.height() - label_size.height() -
|
||||
const int top = rect.height() - label_size.height() -
|
||||
Cursor::Offset - Cursor::ArrowSize - 0.5f;
|
||||
const float height = label_size.height();
|
||||
const int height = label_size.height();
|
||||
|
||||
return QRectF(x - label_size.width() / 2, top, label_size.width(), height);
|
||||
visible = true;
|
||||
return QRect(x - label_size.width() / 2, top, label_size.width(), height);
|
||||
}
|
||||
|
||||
QRectF Cursor::get_close_rect(const QRect &rect) const
|
||||
QRect Cursor::get_close_rect(const QRect &rect) const
|
||||
{
|
||||
const QRectF r(get_label_rect(rect));
|
||||
return QRectF(r.right() - CloseSize, r.top(), CloseSize, CloseSize);
|
||||
return QRect(rect.right() - CloseSize, rect.top(), CloseSize, CloseSize);
|
||||
}
|
||||
|
||||
void Cursor::paint_label(QPainter &p, const QRect &rect,
|
||||
@@ -85,10 +91,13 @@ void Cursor::paint_label(QPainter &p, const QRect &rect,
|
||||
assert(index > 0);
|
||||
|
||||
using pv::view::Ruler;
|
||||
bool visible;
|
||||
|
||||
compute_text_size(p, prefix);
|
||||
const QRectF r(get_label_rect(rect));
|
||||
const QRectF close(get_close_rect(rect));
|
||||
compute_text_size(p, prefix);
|
||||
const QRect r(get_label_rect(rect, visible));
|
||||
if (!visible)
|
||||
return;
|
||||
const QRect close(get_close_rect(r));
|
||||
|
||||
p.setPen(Qt::transparent);
|
||||
if (close.contains(QPoint(_view.hover_point().x(), _view.hover_point().y())))
|
||||
@@ -99,10 +108,10 @@ void Cursor::paint_label(QPainter &p, const QRect &rect,
|
||||
p.setBrush(Ruler::CursorColor[(index - 1) % 8]);
|
||||
p.drawRect(r);
|
||||
|
||||
const QPointF points[] = {
|
||||
QPointF(r.left() + r.width() / 2 - ArrowSize, r.bottom()),
|
||||
QPointF(r.left() + r.width() / 2 + ArrowSize, r.bottom()),
|
||||
QPointF(r.left() + r.width() / 2, rect.bottom()),
|
||||
const QPoint points[] = {
|
||||
QPoint(r.left() + r.width() / 2 - ArrowSize, r.bottom()),
|
||||
QPoint(r.left() + r.width() / 2 + ArrowSize, r.bottom()),
|
||||
QPoint(r.left() + r.width() / 2, rect.bottom()),
|
||||
};
|
||||
p.drawPolygon(points, countof(points));
|
||||
|
||||
@@ -118,7 +127,7 @@ void Cursor::paint_label(QPainter &p, const QRect &rect,
|
||||
p.drawText(r, Qt::AlignCenter | Qt::AlignVCenter,
|
||||
Ruler::format_real_time(_index, _view.session().cur_samplerate()));
|
||||
|
||||
const QRectF arrowRect = QRectF(r.bottomLeft().x(), r.bottomLeft().y(), r.width(), ArrowSize);
|
||||
const QRect arrowRect = QRect(r.bottomLeft().x(), r.bottomLeft().y(), r.width(), ArrowSize);
|
||||
p.drawText(arrowRect, Qt::AlignCenter | Qt::AlignVCenter, QString::number(index));
|
||||
}
|
||||
|
||||
@@ -126,18 +135,21 @@ void Cursor::paint_fix_label(QPainter &p, const QRect &rect,
|
||||
unsigned int prefix, QChar label, QColor color)
|
||||
{
|
||||
using pv::view::Ruler;
|
||||
bool visible;
|
||||
|
||||
compute_text_size(p, prefix);
|
||||
const QRectF r(get_label_rect(rect));
|
||||
const QRect r(get_label_rect(rect, visible));
|
||||
if (!visible)
|
||||
return;
|
||||
|
||||
p.setPen(Qt::transparent);
|
||||
p.setBrush(color);
|
||||
p.drawRect(r);
|
||||
|
||||
const QPointF points[] = {
|
||||
QPointF(r.left() + r.width() / 2 - ArrowSize, r.bottom()),
|
||||
QPointF(r.left() + r.width() / 2 + ArrowSize, r.bottom()),
|
||||
QPointF(r.left() + r.width() / 2, rect.bottom()),
|
||||
const QPoint points[] = {
|
||||
QPoint(r.left() + r.width() / 2 - ArrowSize, r.bottom()),
|
||||
QPoint(r.left() + r.width() / 2 + ArrowSize, r.bottom()),
|
||||
QPoint(r.left() + r.width() / 2, rect.bottom()),
|
||||
};
|
||||
p.drawPolygon(points, countof(points));
|
||||
|
||||
@@ -145,14 +157,14 @@ void Cursor::paint_fix_label(QPainter &p, const QRect &rect,
|
||||
p.drawText(r, Qt::AlignCenter | Qt::AlignVCenter,
|
||||
Ruler::format_real_time(_index, _view.session().cur_samplerate()));
|
||||
|
||||
const QRectF arrowRect = QRectF(r.bottomLeft().x(), r.bottomLeft().y(), r.width(), ArrowSize);
|
||||
const QRect arrowRect = QRect(r.bottomLeft().x(), r.bottomLeft().y(), r.width(), ArrowSize);
|
||||
p.drawText(arrowRect, Qt::AlignCenter | Qt::AlignVCenter, label);
|
||||
}
|
||||
|
||||
void Cursor::compute_text_size(QPainter &p, unsigned int prefix)
|
||||
{
|
||||
(void)prefix;
|
||||
_text_size = p.boundingRect(QRectF(), 0,
|
||||
_text_size = p.boundingRect(QRect(), 0,
|
||||
Ruler::format_real_time(_index, _view.session().cur_samplerate())).size();
|
||||
}
|
||||
|
||||
|
||||
@@ -64,9 +64,9 @@ public:
|
||||
* @param rect The rectangle of the ruler client area.
|
||||
* @return Returns the label rectangle.
|
||||
*/
|
||||
QRectF get_label_rect(const QRect &rect) const;
|
||||
QRect get_label_rect(const QRect &rect, bool &visible) const;
|
||||
|
||||
QRectF get_close_rect(const QRect &rect) const;
|
||||
QRect get_close_rect(const QRect &rect) const;
|
||||
|
||||
/**
|
||||
* Paints the cursor's label to the ruler.
|
||||
|
||||
@@ -179,8 +179,8 @@ void DecodeTrace::paint_back(QPainter &p, int left, int right)
|
||||
|
||||
// --draw decode region control
|
||||
const double samples_per_pixel = _session.cur_samplerate() * _view->scale();
|
||||
const double startX = _decode_start/samples_per_pixel - (_view->offset() / _view->scale());
|
||||
const double endX = _decode_end/samples_per_pixel - (_view->offset() / _view->scale());
|
||||
const double startX = _decode_start/samples_per_pixel - _view->offset();
|
||||
const double endX = _decode_end/samples_per_pixel - _view->offset();
|
||||
const double regionY = get_y() - _totalHeight*0.5 - ControlRectWidth;
|
||||
|
||||
p.setBrush(Signal::dsBlue);
|
||||
@@ -245,41 +245,42 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right)
|
||||
if (!err.isEmpty())
|
||||
{
|
||||
draw_error(p, err, left, right);
|
||||
return;
|
||||
//return;
|
||||
}
|
||||
|
||||
const double scale = _view->scale();
|
||||
assert(scale > 0);
|
||||
const double scale = _view->scale();
|
||||
assert(scale > 0);
|
||||
|
||||
double samplerate = _decoder_stack->samplerate();
|
||||
double samplerate = _decoder_stack->samplerate();
|
||||
|
||||
_cur_row_headings.clear();
|
||||
_cur_row_headings.clear();
|
||||
|
||||
// Show sample rate as 1Hz when it is unknown
|
||||
if (samplerate == 0.0)
|
||||
samplerate = 1.0;
|
||||
// Show sample rate as 1Hz when it is unknown
|
||||
if (samplerate == 0.0)
|
||||
samplerate = 1.0;
|
||||
|
||||
const double pixels_offset = (_view->offset() -
|
||||
_decoder_stack->get_start_time()) / scale;
|
||||
const double samples_per_pixel = samplerate * scale;
|
||||
const int64_t pixels_offset = _view->offset();
|
||||
const double samples_per_pixel = samplerate * scale;
|
||||
|
||||
const uint64_t start_sample = (uint64_t)max((left + pixels_offset) *
|
||||
samples_per_pixel, 0.0);
|
||||
uint64_t start_sample = (uint64_t)max((left + pixels_offset) *
|
||||
samples_per_pixel, 0.0);
|
||||
uint64_t end_sample = (uint64_t)max((right + pixels_offset) *
|
||||
samples_per_pixel, 0.0);
|
||||
const uint64_t samples_decoded = _decoder_stack->samples_decoded();
|
||||
if (samples_decoded < start_sample)
|
||||
samples_per_pixel, 0.0);
|
||||
BOOST_FOREACH(const boost::shared_ptr<data::decode::Decoder> &dec, _decoder_stack->stack()) {
|
||||
start_sample = max(dec->decode_start(), start_sample);
|
||||
end_sample = min(dec->decode_end(), end_sample);
|
||||
break;
|
||||
}
|
||||
if (end_sample < start_sample)
|
||||
return;
|
||||
if (samples_decoded < end_sample)
|
||||
end_sample = samples_decoded;
|
||||
|
||||
const int annotation_height = _view->get_signalHeight();
|
||||
|
||||
// Iterate through the rows
|
||||
assert(_view);
|
||||
// Iterate through the rows
|
||||
assert(_view);
|
||||
int y = get_y() - (_totalHeight - annotation_height)*0.5;
|
||||
|
||||
assert(_decoder_stack);
|
||||
assert(_decoder_stack);
|
||||
|
||||
BOOST_FOREACH(boost::shared_ptr<data::decode::Decoder> dec,
|
||||
_decoder_stack->stack()) {
|
||||
@@ -299,7 +300,8 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right)
|
||||
const uint64_t max_annotation =
|
||||
_decoder_stack->get_max_annotation(row);
|
||||
const double max_annWidth = max_annotation / samples_per_pixel;
|
||||
if (max_annWidth > 5) {
|
||||
if ((max_annWidth > 10 && min_annWidth > 1) ||
|
||||
(max_annWidth == 0 && samples_per_pixel < 10)) {
|
||||
vector<Annotation> annotations;
|
||||
_decoder_stack->get_annotation_subset(annotations, row,
|
||||
start_sample, end_sample);
|
||||
@@ -310,13 +312,11 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right)
|
||||
samples_per_pixel, pixels_offset, y,
|
||||
0, min_annWidth);
|
||||
}
|
||||
} else if (max_annWidth != 0){
|
||||
} else {
|
||||
draw_nodetail(p, annotation_height, left, right, y, 0);
|
||||
}
|
||||
if (max_annWidth != 0) {
|
||||
y += annotation_height;
|
||||
_cur_row_headings.push_back(row.title());
|
||||
}
|
||||
y += annotation_height;
|
||||
_cur_row_headings.push_back(row.title());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -495,12 +495,50 @@ void DecodeTrace::draw_annotation(const pv::data::decode::Annotation &a,
|
||||
if (start > right + DrawPadding || end < left - DrawPadding)
|
||||
return;
|
||||
|
||||
if (_decoder_stack->get_mark_index() == (a.start_sample()+ a.end_sample())/2) {
|
||||
p.setPen(Signal::dsBlue);
|
||||
int xpos = (start+end)/2;
|
||||
int ypos = get_y()+_totalHeight*0.5 + 1;
|
||||
const QPoint triangle[] = {
|
||||
QPoint(xpos, ypos),
|
||||
QPoint(xpos-1, ypos + 1),
|
||||
QPoint(xpos, ypos + 1),
|
||||
QPoint(xpos+1, ypos + 1),
|
||||
QPoint(xpos-2, ypos + 2),
|
||||
QPoint(xpos-1, ypos + 2),
|
||||
QPoint(xpos, ypos + 2),
|
||||
QPoint(xpos+1, ypos + 2),
|
||||
QPoint(xpos+2, ypos + 2),
|
||||
};
|
||||
p.drawPoints(triangle, 9);
|
||||
}
|
||||
|
||||
if (a.start_sample() == a.end_sample())
|
||||
draw_instant(a, p, fill, outline, text_color, h,
|
||||
start, y, min_annWidth);
|
||||
else
|
||||
else {
|
||||
draw_range(a, p, fill, outline, text_color, h,
|
||||
start, end, y);
|
||||
if ((a.type()/100 == 2) && (end - start > 20)) {
|
||||
BOOST_FOREACH(boost::shared_ptr<data::decode::Decoder> dec,
|
||||
_decoder_stack->stack()) {
|
||||
for (auto& iter: dec->channels()) {
|
||||
int type = dec->get_channel_type(iter.first);
|
||||
if ((type == SRD_CHANNEL_COMMON) ||
|
||||
((type%100 != a.type()%100) && (type%100 != 0)))
|
||||
continue;
|
||||
boost::shared_ptr<LogicSignal> logic_sig;
|
||||
BOOST_FOREACH(boost::shared_ptr<view::Signal> sig, _session.get_signals()) {
|
||||
if((sig->get_index() == iter.second) &&
|
||||
(logic_sig = dynamic_pointer_cast<view::LogicSignal>(sig))) {
|
||||
logic_sig->paint_mark(p, start, end, type/100);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DecodeTrace::draw_nodetail(QPainter &p,
|
||||
@@ -723,13 +761,12 @@ QComboBox* DecodeTrace::create_probe_selector(
|
||||
const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
|
||||
|
||||
assert(_decoder_stack);
|
||||
const map<const srd_channel*,
|
||||
boost::shared_ptr<LogicSignal> >::const_iterator probe_iter =
|
||||
const map<const srd_channel*, int>::const_iterator probe_iter =
|
||||
dec->channels().find(pdch);
|
||||
|
||||
QComboBox *selector = new QComboBox(parent);
|
||||
|
||||
selector->addItem("-", qVariantFromValue((void*)NULL));
|
||||
selector->addItem("-", qVariantFromValue(-1));
|
||||
|
||||
if (probe_iter == dec->channels().end())
|
||||
selector->setCurrentIndex(0);
|
||||
@@ -741,9 +778,9 @@ QComboBox* DecodeTrace::create_probe_selector(
|
||||
if (dynamic_pointer_cast<LogicSignal>(s) && s->enabled())
|
||||
{
|
||||
selector->addItem(s->get_name(),
|
||||
qVariantFromValue((void*)s.get()));
|
||||
qVariantFromValue(s->get_index()));
|
||||
if (probe_iter != dec->channels().end()) {
|
||||
if ((*probe_iter).second->get_index() == s->get_index())
|
||||
if ((*probe_iter).second == s->get_index())
|
||||
selector->setCurrentIndex(i + 1);
|
||||
}
|
||||
}
|
||||
@@ -756,7 +793,7 @@ void DecodeTrace::commit_decoder_probes(boost::shared_ptr<data::decode::Decoder>
|
||||
{
|
||||
assert(dec);
|
||||
|
||||
map<const srd_channel*, boost::shared_ptr<LogicSignal> > probe_map;
|
||||
map<const srd_channel*, int> probe_map;
|
||||
const vector< boost::shared_ptr<Signal> > sigs(_session.get_signals());
|
||||
|
||||
_index_list.clear();
|
||||
@@ -765,15 +802,13 @@ void DecodeTrace::commit_decoder_probes(boost::shared_ptr<data::decode::Decoder>
|
||||
if(s._decoder != dec)
|
||||
break;
|
||||
|
||||
const LogicSignal *const selection =
|
||||
(LogicSignal*)s._combo->itemData(
|
||||
s._combo->currentIndex()).value<void*>();
|
||||
const int selection = s._combo->itemData(
|
||||
s._combo->currentIndex()).value<int>();
|
||||
|
||||
BOOST_FOREACH(boost::shared_ptr<Signal> sig, sigs)
|
||||
if(sig.get() == selection) {
|
||||
probe_map[s._pdch] =
|
||||
dynamic_pointer_cast<LogicSignal>(sig);
|
||||
_index_list.push_back(sig->get_index());
|
||||
if(sig->get_index() == selection) {
|
||||
probe_map[s._pdch] = selection;
|
||||
_index_list.push_back(selection);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ void DevMode::on_mode_change()
|
||||
if ((*i).first == button) {
|
||||
if (dev_inst->dev_inst()->mode != (*i).second->mode) {
|
||||
_session.stop_capture();
|
||||
_session.on_mode_change();
|
||||
_session.session_save();
|
||||
dev_inst->set_config(NULL, NULL,
|
||||
SR_CONF_DEVICE_MODE,
|
||||
g_variant_new_int16((*i).second->mode));
|
||||
|
||||
@@ -171,9 +171,9 @@ void DsoSignal::set_viewport(pv::view::Viewport *viewport)
|
||||
|
||||
}
|
||||
|
||||
void DsoSignal::set_scale(float scale)
|
||||
void DsoSignal::set_scale(int height)
|
||||
{
|
||||
_scale = scale;
|
||||
_scale = height * 1.0f / (1 << _bits);
|
||||
}
|
||||
|
||||
float DsoSignal::get_scale()
|
||||
@@ -186,48 +186,38 @@ void DsoSignal::set_enable(bool enable)
|
||||
if (_dev_inst->name() == "DSLogic" &&
|
||||
get_index() == 0)
|
||||
return;
|
||||
_view->session().refresh(INT_MAX);
|
||||
/*
|
||||
* avoid race condition for en_ch_num
|
||||
* data lock need to lock usb event
|
||||
*/
|
||||
_dev_inst->set_config(_probe, NULL, SR_CONF_DATALOCK,
|
||||
g_variant_new_boolean(true));
|
||||
set_vDialActive(false);
|
||||
_dev_inst->set_config(_probe, NULL, SR_CONF_EN_CH,
|
||||
g_variant_new_boolean(enable));
|
||||
int ch_num = _view->session().get_ch_num(SR_CHANNEL_DSO);
|
||||
|
||||
GVariant* gvar;
|
||||
uint64_t max_sample_rate;
|
||||
uint64_t max_sample_limit;
|
||||
gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_MAX_DSO_SAMPLERATE);
|
||||
bool cur_enable;
|
||||
gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_EN_CH);
|
||||
if (gvar != NULL) {
|
||||
max_sample_rate = g_variant_get_uint64(gvar);
|
||||
cur_enable = g_variant_get_boolean(gvar);
|
||||
g_variant_unref(gvar);
|
||||
} else {
|
||||
qDebug() << "ERROR: config_get SR_CONF_MAX_DSO_SAMPLERATE failed.";
|
||||
return;
|
||||
}
|
||||
gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_MAX_DSO_SAMPLELIMITS);
|
||||
if (gvar != NULL) {
|
||||
max_sample_limit = g_variant_get_uint64(gvar);
|
||||
g_variant_unref(gvar);
|
||||
} else {
|
||||
qDebug() << "ERROR: config_get SR_CONF_MAX_DSO_SAMPLELIMITS failed.";
|
||||
if (cur_enable == enable)
|
||||
return;
|
||||
|
||||
bool running = false;
|
||||
if (_view->session().get_capture_state() == SigSession::Running) {
|
||||
running = true;
|
||||
_view->session().stop_capture();
|
||||
}
|
||||
while(_view->session().get_capture_state() == SigSession::Running)
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
set_vDialActive(false);
|
||||
_dev_inst->set_config(_probe, NULL, SR_CONF_EN_CH,
|
||||
g_variant_new_boolean(enable));
|
||||
int ch_num = _view->session().get_ch_num(SR_CHANNEL_DSO);
|
||||
|
||||
if (running) {
|
||||
update_capture();
|
||||
_view->session().repeat_resume();
|
||||
}
|
||||
|
||||
uint64_t sample_limit = (uint64_t)(max_sample_limit / (ch_num ? ch_num : 1));
|
||||
uint64_t sample_rate = min((uint64_t)(sample_limit * std::pow(10.0, 9.0) / (_hDial->get_value() * DS_CONF_DSO_HDIVS)),
|
||||
(uint64_t)(max_sample_rate / (ch_num ? ch_num : 1)));
|
||||
|
||||
_view->set_sample_rate(sample_rate, true);
|
||||
_view->set_sample_limit(sample_limit, true);
|
||||
|
||||
_dev_inst->set_config(_probe, NULL, SR_CONF_DATALOCK,
|
||||
g_variant_new_boolean(false));
|
||||
_view->session().refresh(RefreshLong);
|
||||
_view->set_update(_viewport, true);
|
||||
_view->update();
|
||||
}
|
||||
@@ -304,11 +294,11 @@ bool DsoSignal::go_hDialPre(bool setted)
|
||||
uint64_t sample_rate = _view->session().get_device()->get_sample_rate();
|
||||
const uint64_t min_div = std::pow(10.0, 9.0) / sample_rate;
|
||||
if (_view->session().get_capture_state() != SigSession::Running &&
|
||||
!_data->get_snapshots().empty()) {
|
||||
!_data->get_snapshots().front()->empty()) {
|
||||
if (_hDial->get_value() > min_div)
|
||||
_hDial->set_sel(_hDial->get_sel() - 1);
|
||||
} else if ((_view->session().get_capture_state() == SigSession::Running ||
|
||||
_data->get_snapshots().empty()) &&
|
||||
_data->get_snapshots().front()->empty()) &&
|
||||
!_view->session().get_instant()) {
|
||||
_view->session().refresh(RefreshShort);
|
||||
_hDial->set_sel(_hDial->get_sel() - 1);
|
||||
@@ -346,17 +336,16 @@ bool DsoSignal::go_hDialPre(bool setted)
|
||||
}
|
||||
}
|
||||
|
||||
bool DsoSignal::go_hDialCur()
|
||||
bool DsoSignal::update_capture()
|
||||
{
|
||||
int ch_num = _view->session().get_ch_num(SR_CHANNEL_DSO);
|
||||
if (ch_num == 0)
|
||||
return false;
|
||||
|
||||
_view->session().refresh(RefreshShort);
|
||||
uint64_t sample_limit = _view->session().get_device()->get_sample_limit();
|
||||
GVariant* gvar;
|
||||
uint64_t max_sample_rate;
|
||||
gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_MAX_DSO_SAMPLERATE);
|
||||
uint64_t max_sample_limit;
|
||||
GVariant *gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_MAX_DSO_SAMPLERATE);
|
||||
if (gvar != NULL) {
|
||||
max_sample_rate = g_variant_get_uint64(gvar);
|
||||
g_variant_unref(gvar);
|
||||
@@ -364,11 +353,19 @@ bool DsoSignal::go_hDialCur()
|
||||
qDebug() << "ERROR: config_get SR_CONF_MAX_DSO_SAMPLERATE failed.";
|
||||
return false;
|
||||
}
|
||||
gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_MAX_DSO_SAMPLELIMITS);
|
||||
if (gvar != NULL) {
|
||||
max_sample_limit = g_variant_get_uint64(gvar);
|
||||
g_variant_unref(gvar);
|
||||
} else {
|
||||
qDebug() << "ERROR: config_get SR_CONF_MAX_DSO_SAMPLELIMITS failed.";
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t sample_limit = (uint64_t)(max_sample_limit / (ch_num ? ch_num : 1));
|
||||
uint64_t sample_rate = min((uint64_t)(sample_limit * std::pow(10.0, 9.0) / (_hDial->get_value() * DS_CONF_DSO_HDIVS)),
|
||||
(uint64_t)(max_sample_rate / (ch_num ? ch_num : 1)));
|
||||
// _dev_inst->set_config(NULL, NULL, SR_CONF_SAMPLERATE,
|
||||
// g_variant_new_uint64(sample_rate));
|
||||
|
||||
_view->set_sample_limit(sample_limit, true);
|
||||
_view->set_sample_rate(sample_rate, true);
|
||||
_dev_inst->set_config(_probe, NULL, SR_CONF_TIMEBASE,
|
||||
@@ -381,10 +378,10 @@ bool DsoSignal::go_hDialNext(bool setted)
|
||||
int ch_num = _view->session().get_ch_num(SR_CHANNEL_DSO);
|
||||
if (ch_num != 0 && !_hDial->isMax()) {
|
||||
if (_view->session().get_capture_state() != SigSession::Running &&
|
||||
!_data->get_snapshots().empty()) {
|
||||
!_data->get_snapshots().front()->empty()) {
|
||||
_hDial->set_sel(_hDial->get_sel() + 1);
|
||||
} else if ((_view->session().get_capture_state() == SigSession::Running ||
|
||||
_data->get_snapshots().empty()) &&
|
||||
_data->get_snapshots().front()->empty()) &&
|
||||
!_view->session().get_instant()) {
|
||||
_view->session().refresh(RefreshShort);
|
||||
_hDial->set_sel(_hDial->get_sel() + 1);
|
||||
@@ -428,15 +425,17 @@ bool DsoSignal::load_settings()
|
||||
GVariant* gvar;
|
||||
|
||||
// -- enable
|
||||
//bool enable;
|
||||
//gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_EN_CH);
|
||||
//if (gvar != NULL) {
|
||||
// enable = g_variant_get_boolean(gvar);
|
||||
// g_variant_unref(gvar);
|
||||
//} else {
|
||||
// qDebug() << "ERROR: config_get SR_CONF_EN_CH failed.";
|
||||
// return false;
|
||||
//}
|
||||
bool enable;
|
||||
gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_EN_CH);
|
||||
if (gvar != NULL) {
|
||||
enable = g_variant_get_boolean(gvar);
|
||||
g_variant_unref(gvar);
|
||||
} else {
|
||||
qDebug() << "ERROR: config_get SR_CONF_EN_CH failed.";
|
||||
return false;
|
||||
}
|
||||
|
||||
// dso channel bits
|
||||
gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_DSO_BITS);
|
||||
if (gvar != NULL) {
|
||||
_bits = g_variant_get_byte(gvar);
|
||||
@@ -444,7 +443,8 @@ bool DsoSignal::load_settings()
|
||||
} else {
|
||||
_bits = DefaultBits;
|
||||
qDebug("Warning: config_get SR_CONF_DSO_BITS failed, set to %d(default).", DefaultBits);
|
||||
return false;
|
||||
if (strncmp(_dev_inst->name().toLocal8Bit(), "virtual", 7))
|
||||
return false;
|
||||
}
|
||||
|
||||
// -- hdiv
|
||||
@@ -515,10 +515,8 @@ bool DsoSignal::load_settings()
|
||||
return false;
|
||||
}
|
||||
_zero_vrate = min(max((0.5 - vpos / (_vDial->get_value() * DS_CONF_DSO_VDIVS)), 0.0), 1.0);
|
||||
if (_dev_inst->name() == "DSCope")
|
||||
_zero_value = _zero_vrate * ((1 << _bits) - 1);
|
||||
else
|
||||
_zero_value = 0x80;
|
||||
if (_dev_inst->name().contains("virtual"))
|
||||
cur_hw_offset = _zero_vrate * ((1 << _bits) - 1);
|
||||
|
||||
// -- trig_value
|
||||
gvar = _dev_inst->get_config(_probe, NULL, SR_CONF_TRIGGER_VALUE);
|
||||
@@ -528,7 +526,8 @@ bool DsoSignal::load_settings()
|
||||
g_variant_unref(gvar);
|
||||
} else {
|
||||
qDebug() << "ERROR: config_get SR_CONF_TRIGGER_VALUE failed.";
|
||||
return false;
|
||||
if (strncmp(_dev_inst->name().toLocal8Bit(), "virtual", 7))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (_view) {
|
||||
@@ -666,29 +665,33 @@ double DsoSignal::get_zero_vrate()
|
||||
return _zero_vrate;
|
||||
}
|
||||
|
||||
double DsoSignal::get_zero_value()
|
||||
double DsoSignal::get_hw_offset()
|
||||
{
|
||||
return _zero_value;
|
||||
return cur_hw_offset;
|
||||
}
|
||||
|
||||
void DsoSignal::set_zero_vpos(int pos)
|
||||
{
|
||||
if (enabled()) {
|
||||
double delta = _trig_delta* get_view_rect().height();
|
||||
_zero_vrate = min(max(pos - UpMargin, 0), get_view_rect().height()) * 1.0 / get_view_rect().height();
|
||||
set_zero_vrate(min(max(pos - UpMargin, 0), get_view_rect().height()) * 1.0 / get_view_rect().height(), false);
|
||||
set_trig_vpos(get_zero_vpos() + delta, false);
|
||||
update_offset();
|
||||
}
|
||||
}
|
||||
|
||||
void DsoSignal::set_zero_vrate(double rate)
|
||||
void DsoSignal::set_zero_vrate(double rate, bool force_update)
|
||||
{
|
||||
_zero_vrate = rate;
|
||||
if (_dev_inst->name() == "DSCope")
|
||||
_zero_value = _zero_vrate * ((1 << _bits) - 1);
|
||||
else
|
||||
_zero_value = 0x80;
|
||||
update_offset();
|
||||
|
||||
if (!_dev_inst->name().contains("virtual") &&
|
||||
(force_update ||
|
||||
_view->session().get_capture_state() == SigSession::Running)) {
|
||||
if (_dev_inst->name() == "DSLogic")
|
||||
cur_hw_offset = 0x80;
|
||||
else
|
||||
cur_hw_offset = _zero_vrate * ((1 << _bits) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
void DsoSignal::set_factor(uint64_t factor)
|
||||
@@ -818,8 +821,7 @@ void DsoSignal::paint_back(QPainter &p, int left, int right)
|
||||
const double samplerate = _dev_inst->get_sample_rate();
|
||||
const double samples_per_pixel = samplerate * _view->scale();
|
||||
const double shown_rate = min(samples_per_pixel * width * 1.0 / sample_len, 1.0);
|
||||
const double start_time = _data->get_start_time();
|
||||
const double start = samplerate * (_view->offset() - start_time);
|
||||
const double start = _view->offset() * samples_per_pixel;
|
||||
const double shown_offset = min(start / sample_len, 1.0) * width;
|
||||
const double shown_len = shown_rate * width;
|
||||
const QPointF left_edge[] = {QPoint(shown_offset + 3, UpMargin/2 - 6),
|
||||
@@ -875,7 +877,7 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right)
|
||||
const int y = get_zero_vpos() + height * 0.5;
|
||||
const double scale = _view->scale();
|
||||
assert(scale > 0);
|
||||
const double offset = _view->offset();
|
||||
const int64_t offset = _view->offset();
|
||||
|
||||
const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
|
||||
_data->get_snapshots();
|
||||
@@ -886,18 +888,16 @@ void DsoSignal::paint_mid(QPainter &p, int left, int right)
|
||||
if (snapshot->empty())
|
||||
return;
|
||||
|
||||
const uint16_t number_channels = snapshot->get_channel_num();
|
||||
if (_dev_inst->name() == "DSLogic" &&
|
||||
(unsigned int)get_index() >= number_channels)
|
||||
if (!snapshot->has_data(get_index()))
|
||||
return;
|
||||
|
||||
const double pixels_offset = offset / scale;
|
||||
const uint16_t number_channels = snapshot->get_channel_num();
|
||||
const double pixels_offset = offset;
|
||||
//const double samplerate = _data->samplerate();
|
||||
const double samplerate = _dev_inst->get_sample_rate();
|
||||
const double start_time = _data->get_start_time();
|
||||
const int64_t last_sample = max((int64_t)(snapshot->get_sample_count() - 1), (int64_t)0);
|
||||
const double samples_per_pixel = samplerate * scale;
|
||||
const double start = samplerate * (offset - start_time);
|
||||
const double start = offset * samples_per_pixel;
|
||||
const double end = start + samples_per_pixel * width;
|
||||
|
||||
const int64_t start_sample = min(max((int64_t)floor(start),
|
||||
@@ -923,6 +923,9 @@ void DsoSignal::paint_fore(QPainter &p, int left, int right)
|
||||
{
|
||||
assert(_view);
|
||||
|
||||
bool antialiasing = p.Antialiasing;
|
||||
p.setRenderHint(QPainter::Antialiasing, false);
|
||||
|
||||
QPen pen(Signal::dsGray);
|
||||
pen.setStyle(Qt::DotLine);
|
||||
p.setPen(pen);
|
||||
@@ -967,6 +970,8 @@ void DsoSignal::paint_fore(QPainter &p, int left, int right)
|
||||
// Paint measure
|
||||
paint_measure(p);
|
||||
}
|
||||
|
||||
p.setRenderHint(QPainter::Antialiasing, antialiasing);
|
||||
}
|
||||
|
||||
QRectF DsoSignal::get_trig_rect(int left, int right) const
|
||||
@@ -1001,9 +1006,6 @@ void DsoSignal::paint_trace(QPainter &p,
|
||||
float top = get_view_rect().top();
|
||||
float bottom = get_view_rect().bottom();
|
||||
float zeroP = _zero_vrate * get_view_rect().height() + top;;
|
||||
if (_dev_inst->name() == "DSCope" &&
|
||||
_view->session().get_capture_state() == SigSession::Running)
|
||||
_zero_value = _zero_vrate * ((1 << _bits) - 1);
|
||||
float x = (start / samples_per_pixel - pixels_offset) + left;
|
||||
double pixels_per_sample = 1.0/samples_per_pixel;
|
||||
uint8_t offset;
|
||||
@@ -1014,7 +1016,7 @@ void DsoSignal::paint_trace(QPainter &p,
|
||||
|
||||
//offset = samples[(sample - start)*num_channels];
|
||||
offset = samples[sample];
|
||||
const float y = min(max(top, zeroP + (offset - _zero_value) * _scale), bottom);
|
||||
const float y = min(max(top, zeroP + (offset - cur_hw_offset) * _scale), bottom);
|
||||
*point++ = QPointF(x, y);
|
||||
x += pixels_per_sample;
|
||||
//*point++ = QPointF(x, top + offset);
|
||||
@@ -1057,9 +1059,6 @@ void DsoSignal::paint_envelope(QPainter &p,
|
||||
float top = get_view_rect().top();
|
||||
float bottom = get_view_rect().bottom();
|
||||
float zeroP = _zero_vrate * get_view_rect().height() + top;
|
||||
if (_dev_inst->name() == "DSCope" &&
|
||||
_view->session().get_capture_state() == SigSession::Running)
|
||||
_zero_value = _zero_vrate * ((1 << _bits) - 1);
|
||||
for(uint64_t sample = 0; sample < e.length-1; sample++) {
|
||||
const float x = ((e.scale * sample + e.start) /
|
||||
samples_per_pixel - pixels_offset) + left;
|
||||
@@ -1068,8 +1067,8 @@ void DsoSignal::paint_envelope(QPainter &p,
|
||||
|
||||
// We overlap this sample with the next so that vertical
|
||||
// gaps do not appear during steep rising or falling edges
|
||||
const float b = min(max(top, ((max(s->max, (s+1)->min) - _zero_value) * _scale + zeroP)), bottom);
|
||||
const float t = min(max(top, ((min(s->min, (s+1)->max) - _zero_value) * _scale + zeroP)), bottom);
|
||||
const float b = min(max(top, ((max(s->max, (s+1)->min) - cur_hw_offset) * _scale + zeroP)), bottom);
|
||||
const float t = min(max(top, ((min(s->min, (s+1)->max) - cur_hw_offset) * _scale + zeroP)), bottom);
|
||||
|
||||
float h = b - t;
|
||||
if(h >= 0.0f && h <= 1.0f)
|
||||
@@ -1086,11 +1085,6 @@ void DsoSignal::paint_envelope(QPainter &p,
|
||||
//delete[] e.samples;
|
||||
}
|
||||
|
||||
const std::vector< std::pair<uint64_t, bool> > DsoSignal::cur_edges() const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DsoSignal::paint_type_options(QPainter &p, int right, const QPoint pt)
|
||||
{
|
||||
int y = get_y();
|
||||
@@ -1328,21 +1322,21 @@ void DsoSignal::paint_measure(QPainter &p)
|
||||
_min = (index == 0) ? status.ch0_min : status.ch1_min;
|
||||
const uint64_t period = (index == 0) ? status.ch0_period : status.ch1_period;
|
||||
const uint32_t count = (index == 0) ? status.ch0_pcnt : status.ch1_pcnt;
|
||||
double value_max = (_zero_value - _min) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
|
||||
double value_min = (_zero_value - _max) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
|
||||
double value_max = (cur_hw_offset - _min) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
|
||||
double value_min = (cur_hw_offset - _max) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
|
||||
double value_p2p = value_max - value_min;
|
||||
_period = (count == 0) ? period * 10.0 : period * 10.0 / count;
|
||||
const int channel_count = _view->session().get_ch_num(SR_CHANNEL_DSO);
|
||||
uint64_t sample_rate = _dev_inst->get_sample_rate();
|
||||
_period = _period * 200.0 / (channel_count * sample_rate * 1.0 / SR_MHZ(1));
|
||||
_ms_string[DSO_MS_VMAX] = "Vmax: " + (abs(value_max) > 1000 ? QString::number(value_max/1000.0, 'f', 2) + "V" : QString::number(value_max, 'f', 2) + "mV");
|
||||
_ms_string[DSO_MS_VMIN] = "Vmin: " + (abs(value_min) > 1000 ? QString::number(value_min/1000.0, 'f', 2) + "V" : QString::number(value_min, 'f', 2) + "mV");
|
||||
_ms_string[DSO_MS_PERD] = "Perd: " + (abs(_period) > 1000000000 ? QString::number(_period/1000000000, 'f', 2) + "S" :
|
||||
_ms_string[DSO_MS_VMAX] = tr("Vmax: ") + (abs(value_max) > 1000 ? QString::number(value_max/1000.0, 'f', 2) + "V" : QString::number(value_max, 'f', 2) + "mV");
|
||||
_ms_string[DSO_MS_VMIN] = tr("Vmin: ") + (abs(value_min) > 1000 ? QString::number(value_min/1000.0, 'f', 2) + "V" : QString::number(value_min, 'f', 2) + "mV");
|
||||
_ms_string[DSO_MS_PERD] = tr("Perd: ") + (abs(_period) > 1000000000 ? QString::number(_period/1000000000, 'f', 2) + "S" :
|
||||
abs(_period) > 1000000 ? QString::number(_period/1000000, 'f', 2) + "mS" :
|
||||
abs(_period) > 1000 ? QString::number(_period/1000, 'f', 2) + "uS" : QString::number(_period, 'f', 2) + "nS");
|
||||
_ms_string[DSO_MS_FREQ] = "Freq: " + (abs(_period) > 1000000 ? QString::number(1000000000/_period, 'f', 2) + "Hz" :
|
||||
_ms_string[DSO_MS_FREQ] = tr("Freq: ") + (abs(_period) > 1000000 ? QString::number(1000000000/_period, 'f', 2) + "Hz" :
|
||||
abs(_period) > 1000 ? QString::number(1000000/_period, 'f', 2) + "kHz" : QString::number(1000/_period, 'f', 2) + "MHz");
|
||||
_ms_string[DSO_MS_VP2P] = "Vp-p: " + (abs(value_p2p) > 1000 ? QString::number(value_p2p/1000.0, 'f', 2) + "V" : QString::number(value_p2p, 'f', 2) + "mV");
|
||||
_ms_string[DSO_MS_VP2P] = tr("Vp-p: ") + (abs(value_p2p) > 1000 ? QString::number(value_p2p/1000.0, 'f', 2) + "V" : QString::number(value_p2p, 'f', 2) + "mV");
|
||||
|
||||
if (_probe->ms_show && _probe->ms_en[DSO_MS_VRMS]) {
|
||||
const deque< boost::shared_ptr<pv::data::DsoSnapshot> > &snapshots =
|
||||
@@ -1350,9 +1344,9 @@ void DsoSignal::paint_measure(QPainter &p)
|
||||
if (!snapshots.empty()) {
|
||||
const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot =
|
||||
snapshots.front();
|
||||
const double vrms = snapshot->cal_vrms(_zero_value, get_index());
|
||||
const double vrms = snapshot->cal_vrms(cur_hw_offset, get_index());
|
||||
const double value_vrms = vrms * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
|
||||
_ms_string[DSO_MS_VRMS] = "Vrms: " + (abs(value_vrms) > 1000 ? QString::number(value_vrms/1000.0, 'f', 2) + "V" : QString::number(value_vrms, 'f', 2) + "mV");
|
||||
_ms_string[DSO_MS_VRMS] = tr("Vrms: ") + (abs(value_vrms) > 1000 ? QString::number(value_vrms/1000.0, 'f', 2) + "V" : QString::number(value_vrms, 'f', 2) + "mV");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1363,18 +1357,18 @@ void DsoSignal::paint_measure(QPainter &p)
|
||||
const boost::shared_ptr<pv::data::DsoSnapshot> &snapshot =
|
||||
snapshots.front();
|
||||
const double vmean = snapshot->cal_vmean(get_index());
|
||||
const double value_vmean = (_zero_value - vmean) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
|
||||
_ms_string[DSO_MS_VMEA] = "Vmean: " + (abs(value_vmean) > 1000 ? QString::number(value_vmean/1000.0, 'f', 2) + "V" : QString::number(value_vmean, 'f', 2) + "mV");
|
||||
const double value_vmean = (cur_hw_offset - vmean) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
|
||||
_ms_string[DSO_MS_VMEA] = tr("Vmean: ") + (abs(value_vmean) > 1000 ? QString::number(value_vmean/1000.0, 'f', 2) + "V" : QString::number(value_vmean, 'f', 2) + "mV");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_ms_string[DSO_MS_VMAX] = "Vmax: #####";
|
||||
_ms_string[DSO_MS_VMIN] = "Vmin: #####";
|
||||
_ms_string[DSO_MS_PERD] = "Perd: #####";
|
||||
_ms_string[DSO_MS_FREQ] = "Freq: #####";
|
||||
_ms_string[DSO_MS_VP2P] = "Vp-p: #####";
|
||||
_ms_string[DSO_MS_VRMS] = "Vrms: #####";
|
||||
_ms_string[DSO_MS_VMEA] = "Vmean: #####";
|
||||
_ms_string[DSO_MS_VMAX] = tr("Vmax: #####");
|
||||
_ms_string[DSO_MS_VMIN] = tr("Vmin: #####");
|
||||
_ms_string[DSO_MS_PERD] = tr("Perd: #####");
|
||||
_ms_string[DSO_MS_FREQ] = tr("Freq: #####");
|
||||
_ms_string[DSO_MS_VP2P] = tr("Vp-p: #####");
|
||||
_ms_string[DSO_MS_VRMS] = tr("Vrms: #####");
|
||||
_ms_string[DSO_MS_VMEA] = tr("Vmean: #####");
|
||||
}
|
||||
|
||||
QColor measure_colour = _colour;
|
||||
@@ -1506,8 +1500,7 @@ bool DsoSignal::measure(const QPointF &p)
|
||||
|
||||
const double scale = _view->scale();
|
||||
assert(scale > 0);
|
||||
const double offset = _view->offset();
|
||||
const double pixels_offset = offset / scale;
|
||||
const int64_t pixels_offset = _view->offset();
|
||||
const double samplerate = _dev_inst->get_sample_rate();
|
||||
const double samples_per_pixel = samplerate * scale;
|
||||
|
||||
@@ -1529,17 +1522,17 @@ bool DsoSignal::measure(const QPointF &p)
|
||||
const uint8_t cur_sample = *snapshot->get_samples(_hover_index, _hover_index, get_index());
|
||||
const uint8_t nxt_sample = *snapshot->get_samples(nxt_index, nxt_index, get_index());
|
||||
|
||||
_hover_value = (_zero_value - cur_sample) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
|
||||
_hover_value = (cur_hw_offset - cur_sample) * _scale * _vDial->get_value() * _vDial->get_factor() * DS_CONF_DSO_VDIVS / get_view_rect().height();
|
||||
|
||||
float top = get_view_rect().top();
|
||||
float bottom = get_view_rect().bottom();
|
||||
float zeroP = _zero_vrate * get_view_rect().height() + top;
|
||||
float pre_x = (pre_index / samples_per_pixel - pixels_offset);
|
||||
const float pre_y = min(max(top, zeroP + (pre_sample - _zero_value)* _scale), bottom);
|
||||
const float pre_y = min(max(top, zeroP + (pre_sample - cur_hw_offset)* _scale), bottom);
|
||||
float x = (_hover_index / samples_per_pixel - pixels_offset);
|
||||
const float y = min(max(top, zeroP + (cur_sample - _zero_value)* _scale), bottom);
|
||||
const float y = min(max(top, zeroP + (cur_sample - cur_hw_offset)* _scale), bottom);
|
||||
float nxt_x = (nxt_index / samples_per_pixel - pixels_offset);
|
||||
const float nxt_y = min(max(top, zeroP + (nxt_sample - _zero_value)* _scale), bottom);
|
||||
const float nxt_y = min(max(top, zeroP + (nxt_sample - cur_hw_offset)* _scale), bottom);
|
||||
const QRectF slope_rect = QRectF(QPointF(pre_x - 10, pre_y - 10), QPointF(nxt_x + 10, nxt_y + 10));
|
||||
if (abs(y-p.y()) < 20 || slope_rect.contains(p)) {
|
||||
_hover_point = QPointF(x, y);
|
||||
|
||||
@@ -100,7 +100,7 @@ public:
|
||||
boost::shared_ptr<pv::data::Dso> dso_data() const;
|
||||
void set_viewport(pv::view::Viewport *viewport);
|
||||
|
||||
void set_scale(float scale);
|
||||
void set_scale(int height);
|
||||
float get_scale();
|
||||
|
||||
/**
|
||||
@@ -115,7 +115,7 @@ public:
|
||||
bool go_vDialNext();
|
||||
bool go_hDialPre(bool setted);
|
||||
bool go_hDialNext(bool setted);
|
||||
bool go_hDialCur();
|
||||
bool update_capture();
|
||||
uint64_t get_vDialValue() const;
|
||||
uint64_t get_hDialValue() const;
|
||||
uint16_t get_vDialSel() const;
|
||||
@@ -148,12 +148,12 @@ public:
|
||||
*/
|
||||
int get_zero_vpos();
|
||||
double get_zero_vrate();
|
||||
double get_zero_value();
|
||||
double get_hw_offset();
|
||||
/**
|
||||
* Sets the mid-Y position of this signal.
|
||||
*/
|
||||
void set_zero_vpos(int pos);
|
||||
void set_zero_vrate(double rate);
|
||||
void set_zero_vrate(double rate, bool force_update);
|
||||
void update_offset();
|
||||
|
||||
/**
|
||||
@@ -180,8 +180,6 @@ public:
|
||||
**/
|
||||
void paint_fore(QPainter &p, int left, int right);
|
||||
|
||||
const std::vector< std::pair<uint64_t, bool> > cur_edges() const;
|
||||
|
||||
QRect get_view_rect() const;
|
||||
|
||||
QRectF get_trig_rect(int left, int right) const;
|
||||
@@ -234,7 +232,7 @@ private:
|
||||
int _trig_value;
|
||||
double _trig_delta;
|
||||
double _zero_vrate;
|
||||
float _zero_value;
|
||||
float cur_hw_offset;
|
||||
|
||||
uint8_t _max;
|
||||
uint8_t _min;
|
||||
|
||||
@@ -81,7 +81,7 @@ void GroupSignal::paint_mid(QPainter &p, int left, int right)
|
||||
const int y = get_y() + _totalHeight * 0.5;
|
||||
const double scale = _view->scale();
|
||||
assert(scale > 0);
|
||||
const double offset = _view->offset();
|
||||
const int64_t offset = _view->offset();
|
||||
|
||||
_scale = _totalHeight * 1.0f / std::pow(2.0, static_cast<int>(_index_list.size()));
|
||||
|
||||
@@ -93,12 +93,11 @@ void GroupSignal::paint_mid(QPainter &p, int left, int right)
|
||||
const boost::shared_ptr<pv::data::GroupSnapshot> &snapshot =
|
||||
snapshots.at(_sec_index);
|
||||
|
||||
const double pixels_offset = offset / scale;
|
||||
const double pixels_offset = offset;
|
||||
const double samplerate = _data->samplerate();
|
||||
const double start_time = _data->get_start_time();
|
||||
const int64_t last_sample = snapshot->get_sample_count() - 1;
|
||||
const double samples_per_pixel = samplerate * scale;
|
||||
const double start = samplerate * (offset - start_time);
|
||||
const double start = offset * samples_per_pixel;
|
||||
const double end = start + samples_per_pixel * (right - left);
|
||||
|
||||
const int64_t start_sample = min(max((int64_t)floor(start),
|
||||
@@ -190,11 +189,6 @@ void GroupSignal::paint_envelope(QPainter &p,
|
||||
delete[] e.samples;
|
||||
}
|
||||
|
||||
const std::vector< std::pair<uint64_t, bool> > GroupSignal::cur_edges() const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void GroupSignal::paint_type_options(QPainter &p, int right, const QPoint pt)
|
||||
{
|
||||
(void)pt;
|
||||
|
||||
@@ -76,8 +76,6 @@ public:
|
||||
**/
|
||||
void paint_mid(QPainter &p, int left, int right);
|
||||
|
||||
const std::vector< std::pair<uint64_t, bool> > cur_edges() const;
|
||||
|
||||
QRectF get_rect(GroupSetRegions type, int y, int right);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -75,9 +75,6 @@ Header::Header(View &parent) :
|
||||
|
||||
connect(nameEdit, SIGNAL(editingFinished()),
|
||||
this, SLOT(on_action_set_name_triggered()));
|
||||
|
||||
connect(&_view, SIGNAL(traces_moved()),
|
||||
this, SLOT(on_traces_moved()));
|
||||
}
|
||||
|
||||
|
||||
@@ -322,7 +319,6 @@ void Header::mouseMoveEvent(QMouseEvent *event)
|
||||
}
|
||||
}
|
||||
}
|
||||
//traces_moved();
|
||||
}
|
||||
update();
|
||||
}
|
||||
@@ -380,11 +376,6 @@ void Header::on_action_del_group_triggered()
|
||||
_view.session().del_group();
|
||||
}
|
||||
|
||||
void Header::on_traces_moved()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void Header::header_resize()
|
||||
{
|
||||
//if (nameEdit->isVisible()) {
|
||||
|
||||
@@ -77,8 +77,6 @@ private slots:
|
||||
|
||||
void on_action_del_group_triggered();
|
||||
|
||||
void on_traces_moved();
|
||||
|
||||
signals:
|
||||
void traces_moved();
|
||||
void header_updated();
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <libsigrokdecode/libsigrokdecode.h>
|
||||
|
||||
#include <extdef.h>
|
||||
|
||||
@@ -74,6 +75,7 @@ LogicSignal::LogicSignal(boost::shared_ptr<view::LogicSignal> s,
|
||||
LogicSignal::~LogicSignal()
|
||||
{
|
||||
_cur_edges.clear();
|
||||
_cur_pulses.clear();
|
||||
}
|
||||
|
||||
const sr_channel* LogicSignal::probe() const
|
||||
@@ -128,8 +130,6 @@ void LogicSignal::paint_mid(QPainter &p, int left, int right)
|
||||
{
|
||||
using pv::view::View;
|
||||
|
||||
QLineF *line;
|
||||
|
||||
assert(_data);
|
||||
assert(_view);
|
||||
assert(right >= left);
|
||||
@@ -137,10 +137,10 @@ void LogicSignal::paint_mid(QPainter &p, int left, int right)
|
||||
const int y = get_y() + _totalHeight * 0.5;
|
||||
const double scale = _view->scale();
|
||||
assert(scale > 0);
|
||||
const double offset = _view->offset();
|
||||
const int64_t offset = _view->offset();
|
||||
|
||||
const float high_offset = y - _totalHeight + 0.5f;
|
||||
const float low_offset = y + 0.5f;
|
||||
const int high_offset = y - _totalHeight + 0.5f;
|
||||
const int low_offset = y + 0.5f;
|
||||
|
||||
const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
|
||||
_data->get_snapshots();
|
||||
@@ -150,47 +150,60 @@ void LogicSignal::paint_mid(QPainter &p, int left, int right)
|
||||
|
||||
const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
|
||||
snapshots.front();
|
||||
if (snapshot->empty())
|
||||
if (snapshot->empty() || !snapshot->has_data(_probe->index))
|
||||
return;
|
||||
|
||||
const double pixels_offset = offset / scale;
|
||||
const double start_time = _data->get_start_time();
|
||||
const int64_t last_sample = snapshot->get_sample_count() - 1;
|
||||
const double samples_per_pixel = samplerate * scale;
|
||||
const double start = samplerate * (offset - start_time);
|
||||
const double end = start + samples_per_pixel * (right - left);
|
||||
|
||||
snapshot->get_subsampled_edges(_cur_edges,
|
||||
min(max((int64_t)floor(start), (int64_t)0), last_sample),
|
||||
min(max((int64_t)ceil(end), (int64_t)0), last_sample),
|
||||
samples_per_pixel / Oversampling, _probe->index);
|
||||
if (_cur_edges.size() < 2)
|
||||
uint16_t width = right - left;
|
||||
const double start = offset * samples_per_pixel;
|
||||
const double end = (offset + width + 1) * samples_per_pixel;
|
||||
const uint64_t end_index = min(max((int64_t)ceil(end), (int64_t)0), last_sample);
|
||||
const uint64_t start_index = max((uint64_t)floor(start), (uint64_t)0);
|
||||
if (start_index > end_index)
|
||||
return;
|
||||
width = min(width, (uint16_t)ceil((end_index + 1)/samples_per_pixel - offset));
|
||||
const uint16_t max_togs = width / TogMaxScale;
|
||||
|
||||
// Paint the edges
|
||||
const unsigned int edge_count = 2 * _cur_edges.size() - 3;
|
||||
QLineF *const edge_lines = new QLineF[edge_count];
|
||||
line = edge_lines;
|
||||
const bool first_sample = snapshot->get_display_edges(_cur_pulses, _cur_edges,
|
||||
start_index, end_index, width, max_togs,
|
||||
offset,
|
||||
samples_per_pixel, _probe->index);
|
||||
assert(_cur_pulses.size() >= width);
|
||||
|
||||
double preX = ((*(_cur_edges.begin())).first / samples_per_pixel - pixels_offset) + left;
|
||||
double preY = (*(_cur_edges.begin())).second ? high_offset : low_offset;
|
||||
vector<pv::data::LogicSnapshot::EdgePair>::const_iterator i;
|
||||
for ( i = _cur_edges.begin() + 1; i != _cur_edges.end() - 1; i++) {
|
||||
const double x = ((*i).first / samples_per_pixel -
|
||||
pixels_offset) + left;
|
||||
const double y = (*i).second ? high_offset : low_offset;
|
||||
*line++ = QLineF(preX, preY, x, preY);
|
||||
*line++ = QLineF(x, high_offset, x, low_offset);
|
||||
preX = x;
|
||||
preY = y;
|
||||
int preX = 0;
|
||||
int preY = first_sample ? high_offset : low_offset;
|
||||
int x = preX;
|
||||
std::vector<QLine> wave_lines;
|
||||
if (_cur_edges.size() < max_togs) {
|
||||
std::vector<std::pair<uint16_t, bool>>::const_iterator i;
|
||||
for (i = _cur_edges.begin() + 1; i != _cur_edges.end() - 1; i++) {
|
||||
x = (*i).first;
|
||||
wave_lines.push_back(QLine(preX, preY, x, preY));
|
||||
wave_lines.push_back(QLine(x, high_offset, x, low_offset));
|
||||
preX = x;
|
||||
preY = (*i).second ? high_offset : low_offset;
|
||||
}
|
||||
x = (*i).first;
|
||||
wave_lines.push_back(QLine(preX, preY, x, preY));
|
||||
} else {
|
||||
std::vector<std::pair<bool, bool>>::const_iterator i = _cur_pulses.begin();
|
||||
while (i != _cur_pulses.end() - 1) {
|
||||
if ((*i).first) {
|
||||
wave_lines.push_back(QLine(preX, preY, x, preY));
|
||||
wave_lines.push_back(QLine(x, high_offset, x, low_offset));
|
||||
preX = x;
|
||||
preY = (*i).second ? high_offset : low_offset;
|
||||
}
|
||||
x++;
|
||||
i++;
|
||||
}
|
||||
wave_lines.push_back(QLine(preX, preY, x, preY));
|
||||
}
|
||||
const double x = ((*i).first / samples_per_pixel -
|
||||
pixels_offset) + left;
|
||||
*line++ = QLineF(preX, preY, x, preY);
|
||||
|
||||
p.setPen(_colour);
|
||||
p.drawLines(edge_lines, edge_count);
|
||||
delete[] edge_lines;
|
||||
p.drawLines(wave_lines.data(), wave_lines.size());
|
||||
}
|
||||
|
||||
void LogicSignal::paint_caps(QPainter &p, QLineF *const lines,
|
||||
@@ -216,11 +229,6 @@ void LogicSignal::paint_caps(QPainter &p, QLineF *const lines,
|
||||
p.drawLines(lines, line - lines);
|
||||
}
|
||||
|
||||
const std::vector< std::pair<uint64_t, bool> > LogicSignal::cur_edges() const
|
||||
{
|
||||
return _cur_edges;
|
||||
}
|
||||
|
||||
void LogicSignal::paint_type_options(QPainter &p, int right, const QPoint pt)
|
||||
{
|
||||
int y = get_y();
|
||||
@@ -305,32 +313,43 @@ bool LogicSignal::measure(const QPointF &p, uint64_t &index0, uint64_t &index1,
|
||||
|
||||
const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
|
||||
snapshots.front();
|
||||
if (snapshot->empty())
|
||||
if (snapshot->empty() || !snapshot->has_data(_probe->index))
|
||||
return false;
|
||||
|
||||
uint64_t index = _data->samplerate() * (_view->offset() - _data->get_start_time() + p.x() * _view->scale());
|
||||
if (index == 0 || index >= (snapshot->get_sample_count() - 1))
|
||||
const uint64_t end = snapshot->get_sample_count() - 1;
|
||||
uint64_t index = _data->samplerate() * _view->scale() * (_view->offset() + p.x());
|
||||
if (index > end)
|
||||
return false;
|
||||
|
||||
const uint64_t sig_mask = 1ULL << get_index();
|
||||
bool sample = snapshot->get_sample(index) & sig_mask;
|
||||
index--;
|
||||
if (!snapshot->get_pre_edge(index, sample, 1, get_index()))
|
||||
return false;
|
||||
bool sample = snapshot->get_sample(index, get_index());
|
||||
if (index == 0)
|
||||
index0 = index;
|
||||
else {
|
||||
index--;
|
||||
if (snapshot->get_pre_edge(index, sample, 1, get_index()))
|
||||
index0 = index;
|
||||
else
|
||||
index0 = 0;
|
||||
}
|
||||
|
||||
index0 = index;
|
||||
sample = snapshot->get_sample(index) & sig_mask;
|
||||
sample = snapshot->get_sample(index, get_index());
|
||||
index++;
|
||||
if (!snapshot->get_nxt_edge(index, sample, snapshot->get_sample_count(), 1, get_index()))
|
||||
return false;
|
||||
|
||||
index1 = index;
|
||||
sample = snapshot->get_sample(index) & sig_mask;
|
||||
index++;
|
||||
if (!snapshot->get_nxt_edge(index, sample, snapshot->get_sample_count(), 1, get_index()))
|
||||
if (snapshot->get_nxt_edge(index, sample, end, 1, get_index()))
|
||||
index1 = index;
|
||||
else {
|
||||
if (index0 == 0)
|
||||
return false;
|
||||
index1 = end + 1;
|
||||
index2 = 0;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
sample = snapshot->get_sample(index, get_index());
|
||||
index++;
|
||||
if (snapshot->get_nxt_edge(index, sample, end, 1, get_index()))
|
||||
index2 = index;
|
||||
else
|
||||
index2 = end + 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -343,44 +362,51 @@ bool LogicSignal::edges(const QPointF &p, uint64_t start, uint64_t &rising, uint
|
||||
uint64_t index, end;
|
||||
const float gap = abs(p.y() - get_y());
|
||||
if (gap < get_totalHeight() * 0.5) {
|
||||
const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
|
||||
_data->get_snapshots();
|
||||
if (snapshots.empty())
|
||||
return false;
|
||||
|
||||
const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
|
||||
snapshots.front();
|
||||
if (snapshot->empty())
|
||||
return false;
|
||||
|
||||
end = _data->samplerate() * (_view->offset() - _data->get_start_time() + p.x() * _view->scale());
|
||||
index = min(start, end);
|
||||
end = max(start, end);
|
||||
start = index;
|
||||
if (end > (snapshot->get_sample_count() - 1))
|
||||
return false;
|
||||
|
||||
const uint64_t sig_mask = 1ULL << get_index();
|
||||
bool sample = snapshot->get_sample(start) & sig_mask;
|
||||
|
||||
rising = 0;
|
||||
falling = 0;
|
||||
do {
|
||||
if (snapshot->get_nxt_edge(index, sample, snapshot->get_sample_count(), 1, get_index())) {
|
||||
if (index > end)
|
||||
break;
|
||||
rising += !sample;
|
||||
falling += sample;
|
||||
sample = !sample;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while(index <= end);
|
||||
return true;
|
||||
end = _data->samplerate() * _view->scale() * (_view->offset() + p.x());
|
||||
return edges(end, start, rising, falling);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LogicSignal::edges(uint64_t end, uint64_t start, uint64_t &rising, uint64_t &falling) const
|
||||
{
|
||||
const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
|
||||
_data->get_snapshots();
|
||||
if (snapshots.empty())
|
||||
return false;
|
||||
|
||||
const boost::shared_ptr<pv::data::LogicSnapshot> &snapshot =
|
||||
snapshots.front();
|
||||
if (snapshot->empty() || !snapshot->has_data(_probe->index))
|
||||
return false;
|
||||
|
||||
uint64_t index = min(start, end);
|
||||
const uint64_t sample_count = snapshot->get_sample_count();
|
||||
end = max(start, end);
|
||||
start = index;
|
||||
if (end > (sample_count - 1))
|
||||
return false;
|
||||
|
||||
const int ch_index = get_index();
|
||||
bool sample = snapshot->get_sample(start, ch_index);
|
||||
|
||||
rising = 0;
|
||||
falling = 0;
|
||||
do {
|
||||
if (snapshot->get_nxt_edge(index, sample, sample_count, 1, ch_index)) {
|
||||
if (index > end)
|
||||
break;
|
||||
rising += !sample;
|
||||
falling += sample;
|
||||
sample = !sample;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while(index <= end);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LogicSignal::mouse_press(int right, const QPoint pt)
|
||||
{
|
||||
int y = get_y();
|
||||
@@ -439,5 +465,38 @@ QRectF LogicSignal::get_rect(LogicSetRegions type, int y, int right)
|
||||
return QRectF(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
void LogicSignal::paint_mark(QPainter &p, int xstart, int xend, int type)
|
||||
{
|
||||
const int ypos = get_y();
|
||||
const int msize = 3;
|
||||
p.setPen(p.brush().color());
|
||||
if (type == SRD_CHANNEL_SDATA) {
|
||||
p.drawEllipse(QPoint(xstart, ypos), msize, msize);
|
||||
} else if (type == SRD_CHANNEL_SCLK) {
|
||||
const QPoint triangle[] = {
|
||||
QPoint(xstart, ypos - 2),
|
||||
QPoint(xstart-1, ypos - 1),
|
||||
QPoint(xstart, ypos - 1),
|
||||
QPoint(xstart+1, ypos - 1),
|
||||
QPoint(xstart-2, ypos),
|
||||
QPoint(xstart-1, ypos),
|
||||
QPoint(xstart, ypos),
|
||||
QPoint(xstart+1, ypos),
|
||||
QPoint(xstart+2, ypos),
|
||||
QPoint(xstart-3, ypos + 1),
|
||||
QPoint(xstart-2, ypos + 1),
|
||||
QPoint(xstart-1, ypos + 1),
|
||||
QPoint(xstart, ypos + 1),
|
||||
QPoint(xstart+1, ypos + 1),
|
||||
QPoint(xstart+2, ypos + 1),
|
||||
QPoint(xstart+3, ypos + 1),
|
||||
};
|
||||
p.drawPoints(triangle, 16);
|
||||
} else if (type == SRD_CHANNEL_ADATA) {
|
||||
p.drawEllipse(QPoint((xstart+xend)/2, ypos), msize, msize);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace view
|
||||
} // namespace pv
|
||||
|
||||
@@ -53,6 +53,8 @@ private:
|
||||
static const int StateHeight;
|
||||
static const int StateRound;
|
||||
|
||||
static const int TogMaxScale = 10;
|
||||
|
||||
enum LogicSetRegions{
|
||||
NONTRIG = 0,
|
||||
POSTRIG,
|
||||
@@ -94,16 +96,18 @@ public:
|
||||
**/
|
||||
void paint_mid(QPainter &p, int left, int right);
|
||||
|
||||
const std::vector< std::pair<uint64_t, bool> > cur_edges() const;
|
||||
|
||||
bool measure(const QPointF &p, uint64_t &index0, uint64_t &index1, uint64_t &index2) const;
|
||||
|
||||
bool edges(const QPointF &p, uint64_t start, uint64_t &rising, uint64_t &falling) const;
|
||||
|
||||
bool edges(uint64_t end, uint64_t start, uint64_t &rising, uint64_t &falling) const;
|
||||
|
||||
bool mouse_press(int right, const QPoint pt);
|
||||
|
||||
QRectF get_rect(LogicSetRegions type, int y, int right);
|
||||
|
||||
void paint_mark(QPainter &p, int xstart, int xend, int type);
|
||||
|
||||
protected:
|
||||
void paint_type_options(QPainter &p, int right, const QPoint pt);
|
||||
|
||||
@@ -116,7 +120,8 @@ private:
|
||||
|
||||
private:
|
||||
boost::shared_ptr<pv::data::Logic> _data;
|
||||
std::vector< std::pair<uint64_t, bool> > _cur_edges;
|
||||
std::vector< std::pair<uint16_t, bool> > _cur_edges;
|
||||
std::vector<std::pair<bool, bool>> _cur_pulses;
|
||||
LogicSetRegions _trig;
|
||||
};
|
||||
|
||||
|
||||
@@ -205,8 +205,9 @@ void Ruler::mouseMoveEvent(QMouseEvent *e)
|
||||
(void)e;
|
||||
|
||||
if (_grabbed_marker) {
|
||||
_grabbed_marker->set_index((_view.offset() +
|
||||
_view.hover_point().x() * _view.scale()) * _view.session().cur_samplerate());
|
||||
_grabbed_marker->set_index((_view.offset() + _view.hover_point().x()) *
|
||||
_view.scale() * _view.session().cur_samplerate());
|
||||
_view.cursor_moving();
|
||||
}
|
||||
|
||||
update();
|
||||
@@ -228,6 +229,7 @@ void Ruler::mousePressEvent(QMouseEvent *e)
|
||||
void Ruler::mouseReleaseEvent(QMouseEvent *event)
|
||||
{
|
||||
bool addCursor = false;
|
||||
bool visible;
|
||||
if (event->button() & Qt::LeftButton) {
|
||||
bool hitCursor = false;
|
||||
if (!_cursor_sel_visible & !_view.get_cursorList().empty()) {
|
||||
@@ -235,10 +237,12 @@ void Ruler::mouseReleaseEvent(QMouseEvent *event)
|
||||
if (_grabbed_marker) {
|
||||
rel_grabbed_cursor();
|
||||
hitCursor = true;
|
||||
_view.cursor_moved();
|
||||
} else {
|
||||
list<Cursor*>::iterator i = _view.get_cursorList().begin();
|
||||
while (i != _view.get_cursorList().end()) {
|
||||
if ((*i)->get_close_rect(rect()).contains(event->pos())) {
|
||||
const QRect cursor_rect((*i)->get_label_rect(rect(), visible));
|
||||
if ((*i)->get_close_rect(cursor_rect).contains(event->pos())) {
|
||||
_view.del_cursor(*i);
|
||||
if (_view.get_cursorList().empty()) {
|
||||
_cursor_sel_visible = false;
|
||||
@@ -247,7 +251,7 @@ void Ruler::mouseReleaseEvent(QMouseEvent *event)
|
||||
hitCursor = true;
|
||||
break;
|
||||
}
|
||||
if ((*i)->get_label_rect(rect()).contains(event->pos())) {
|
||||
if (cursor_rect.contains(event->pos())) {
|
||||
set_grabbed_cursor(*i);
|
||||
_cursor_sel_visible = false;
|
||||
_cursor_go_visible = false;
|
||||
@@ -265,7 +269,7 @@ void Ruler::mouseReleaseEvent(QMouseEvent *event)
|
||||
_cursor_sel_visible = true;
|
||||
} else {
|
||||
int overCursor;
|
||||
uint64_t index = (_view.offset() + (_cursor_sel_x + 0.5) * _view.scale()) * _view.session().cur_samplerate();
|
||||
uint64_t index = (_view.offset() + _cursor_sel_x + 0.5) * _view.scale() * _view.session().cur_samplerate();
|
||||
overCursor = in_cursor_sel_rect(event->pos());
|
||||
if (overCursor == 0) {
|
||||
_view.add_cursor(CursorColor[_view.get_cursorList().size() % 8], index);
|
||||
@@ -354,7 +358,7 @@ void Ruler::draw_tick_mark(QPainter &p)
|
||||
|
||||
|
||||
typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX,
|
||||
AlignLeft | AlignTop, format_time(_view.offset(),
|
||||
AlignLeft | AlignTop, format_time(_view.offset() * _view.scale(),
|
||||
prefix)).width() + MinValueSpacing;
|
||||
|
||||
min_width += SpacingIncrement;
|
||||
@@ -369,9 +373,9 @@ void Ruler::draw_tick_mark(QPainter &p)
|
||||
|
||||
const double minor_tick_period = tick_period / MinorTickSubdivision;
|
||||
const double first_major_division =
|
||||
floor(_view.offset() / tick_period);
|
||||
floor(_view.offset() * _view.scale() / tick_period);
|
||||
const double first_minor_division =
|
||||
ceil(_view.offset() / minor_tick_period);
|
||||
ceil(_view.offset() * _view.scale() / minor_tick_period);
|
||||
const double t0 = first_major_division * tick_period;
|
||||
|
||||
int division = (int)round(first_minor_division -
|
||||
@@ -385,7 +389,7 @@ void Ruler::draw_tick_mark(QPainter &p)
|
||||
|
||||
do {
|
||||
const double t = t0 + division * minor_tick_period;
|
||||
x = (t - _view.offset()) / _view.scale();
|
||||
x = t / _view.scale() - _view.offset();
|
||||
|
||||
if (division % MinorTickSubdivision == 0)
|
||||
{
|
||||
@@ -432,7 +436,7 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
|
||||
double typical_width;
|
||||
double tick_period = 0;
|
||||
double scale = _view.scale();
|
||||
double offset = _view.offset();
|
||||
int64_t offset = _view.offset();
|
||||
|
||||
const uint64_t cur_period_scale = ceil((scale * min_width) / abs_min_period);
|
||||
|
||||
@@ -449,7 +453,7 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
|
||||
_cur_prefix = prefix;
|
||||
assert(prefix < countof(SIPrefixes));
|
||||
typical_width = p.boundingRect(0, 0, INT_MAX, INT_MAX,
|
||||
AlignLeft | AlignTop, format_time(offset,
|
||||
AlignLeft | AlignTop, format_time(offset * scale,
|
||||
prefix)).width() + MinValueSpacing;
|
||||
do
|
||||
{
|
||||
@@ -470,9 +474,9 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
|
||||
assert(minor_prefix < countof(SIPrefixes));
|
||||
|
||||
const double first_major_division =
|
||||
floor(offset / tick_period);
|
||||
floor(offset * scale / tick_period);
|
||||
const double first_minor_division =
|
||||
floor(offset / minor_tick_period + 1);
|
||||
floor(offset * scale / minor_tick_period + 1);
|
||||
const double t0 = first_major_division * tick_period;
|
||||
|
||||
int division = (int)round(first_minor_division -
|
||||
@@ -482,7 +486,7 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
|
||||
const int tick_y2 = height();
|
||||
const int minor_tick_y1 = (major_tick_y1 + tick_y2) / 2;
|
||||
|
||||
double x;
|
||||
int x;
|
||||
|
||||
const double inc_text_width = p.boundingRect(0, 0, INT_MAX, INT_MAX,
|
||||
AlignLeft | AlignTop,
|
||||
@@ -492,7 +496,7 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
|
||||
const double t = t0 + division * minor_tick_period;
|
||||
const double major_t = t0 + floor(division / MinPeriodScale) * tick_period;
|
||||
|
||||
x = (t - offset) / scale;
|
||||
x = t / scale - offset;
|
||||
|
||||
if (division % MinPeriodScale == 0)
|
||||
{
|
||||
@@ -500,8 +504,8 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
|
||||
p.drawText(x, 2 * ValueMargin, 0, text_height,
|
||||
AlignCenter | AlignTop | TextDontClip,
|
||||
format_time(t, prefix));
|
||||
p.drawLine(QPointF(x, major_tick_y1),
|
||||
QPointF(x, tick_y2));
|
||||
p.drawLine(QPoint(x, major_tick_y1),
|
||||
QPoint(x, tick_y2));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -516,8 +520,8 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
|
||||
p.drawText(x, 2 * ValueMargin, 0, minor_tick_y1 + ValueMargin,
|
||||
AlignCenter | AlignTop | TextDontClip,
|
||||
format_time(t - major_t, minor_prefix));
|
||||
p.drawLine(QPointF(x, minor_tick_y1),
|
||||
QPointF(x, tick_y2));
|
||||
p.drawLine(QPoint(x, minor_tick_y1),
|
||||
QPoint(x, tick_y2));
|
||||
}
|
||||
|
||||
division++;
|
||||
@@ -533,13 +537,12 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
|
||||
index++;
|
||||
i++;
|
||||
}
|
||||
_view.on_cursor_moved();
|
||||
}
|
||||
if (_view.trig_cursor_shown()) {
|
||||
_view.get_trig_cursor()->paint_fix_label(p, rect(), prefix, 'T', Trace::dsLightRed);
|
||||
_view.get_trig_cursor()->paint_fix_label(p, rect(), prefix, 'T', _view.get_trig_cursor()->colour());
|
||||
}
|
||||
if (_view.search_cursor_shown()) {
|
||||
_view.get_search_cursor()->paint_fix_label(p, rect(), prefix, 'S', Trace::dsLightBlue);
|
||||
_view.get_search_cursor()->paint_fix_label(p, rect(), prefix, 'S', _view.get_search_cursor()->colour());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,8 +67,6 @@ protected:
|
||||
public:
|
||||
virtual boost::shared_ptr<pv::data::SignalData> data() const = 0;
|
||||
|
||||
virtual const std::vector< std::pair<uint64_t, bool> > cur_edges() const = 0;
|
||||
|
||||
/**
|
||||
* Returns true if the trace is visible and enabled.
|
||||
*/
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "timemarker.h"
|
||||
|
||||
#include "view.h"
|
||||
#include "ruler.h"
|
||||
#include "../device/device.h"
|
||||
|
||||
#include <QPainter>
|
||||
@@ -48,6 +49,16 @@ TimeMarker::TimeMarker(const TimeMarker &s) :
|
||||
{
|
||||
}
|
||||
|
||||
QColor TimeMarker::colour() const
|
||||
{
|
||||
return _colour;
|
||||
}
|
||||
|
||||
void TimeMarker::set_colour(QColor color)
|
||||
{
|
||||
_colour = color;
|
||||
}
|
||||
|
||||
bool TimeMarker::grabbed() const
|
||||
{
|
||||
return _grabbed;
|
||||
@@ -68,14 +79,15 @@ void TimeMarker::set_index(uint64_t index)
|
||||
time_changed();
|
||||
}
|
||||
|
||||
void TimeMarker::paint(QPainter &p, const QRect &rect, const bool highlight)
|
||||
void TimeMarker::paint(QPainter &p, const QRect &rect, const bool highlight, int order)
|
||||
{
|
||||
const uint64_t sample_rate = _view.session().cur_samplerate();
|
||||
const double scale = _view.scale();
|
||||
const double samples_per_pixel = sample_rate * scale;
|
||||
const double x = _index/samples_per_pixel - (_view.offset() / scale);
|
||||
p.setPen((_grabbed | highlight) ? QPen(_colour.lighter(), 2, Qt::DashLine) : QPen(_colour, 1, Qt::DashLine));
|
||||
p.drawLine(QPointF(x, rect.top()), QPointF(x, rect.bottom()));
|
||||
const int64_t x = _index/samples_per_pixel - _view.offset();
|
||||
QColor color = (order == -1) ? _colour : Ruler::CursorColor[order%8];
|
||||
p.setPen((_grabbed | highlight) ? QPen(color.lighter(), 2, Qt::DashLine) : QPen(color, 1, Qt::DashLine));
|
||||
p.drawLine(QPoint(x, rect.top()), QPoint(x, rect.bottom()));
|
||||
}
|
||||
|
||||
} // namespace view
|
||||
|
||||
@@ -68,6 +68,12 @@ public:
|
||||
*/
|
||||
void set_index(uint64_t index);
|
||||
|
||||
/**
|
||||
* Gets/Sets colour of the marker
|
||||
*/
|
||||
QColor colour() const;
|
||||
void set_colour(QColor color);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
@@ -79,14 +85,15 @@ public:
|
||||
* @param p The painter to draw with.
|
||||
* @param rect The rectangle of the viewport client area.
|
||||
*/
|
||||
virtual void paint(QPainter &p, const QRect &rect, const bool highlight);
|
||||
virtual void paint(QPainter &p, const QRect &rect, const bool highlight, int order);
|
||||
|
||||
/**
|
||||
* Gets the marker label rectangle.
|
||||
* @param rect The rectangle of the ruler client area.
|
||||
* @param visible is this marker in visible area
|
||||
* @return Returns the label rectangle.
|
||||
*/
|
||||
virtual QRectF get_label_rect(const QRect &rect) const = 0;
|
||||
virtual QRect get_label_rect(const QRect &rect, bool &visible) const = 0;
|
||||
|
||||
/**
|
||||
* Paints the marker's label to the ruler.
|
||||
|
||||
@@ -73,7 +73,7 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget
|
||||
QScrollArea(parent),
|
||||
_session(session),
|
||||
_sampling_bar(sampling_bar),
|
||||
_scale(1e-5),
|
||||
_scale(10),
|
||||
_preScale(1e-6),
|
||||
_maxscale(1e9),
|
||||
_minscale(1e-15),
|
||||
@@ -82,6 +82,7 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget
|
||||
_updating_scroll(false),
|
||||
_show_cursors(false),
|
||||
_hover_point(-1, -1),
|
||||
_search_hit(false),
|
||||
_dso_auto(true)
|
||||
{
|
||||
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
@@ -113,6 +114,7 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget
|
||||
_time_viewport->setMinimumHeight(100);
|
||||
connect(_time_viewport, SIGNAL(measure_updated()),
|
||||
this, SLOT(on_measure_updated()));
|
||||
connect(_time_viewport, SIGNAL(prgRate(int)), this, SIGNAL(prgRate(int)));
|
||||
_fft_viewport = new Viewport(*this, FFT_VIEW);
|
||||
_fft_viewport->setVisible(false);
|
||||
_fft_viewport->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
||||
@@ -140,7 +142,7 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget
|
||||
layout->setContentsMargins(0,0,0,0);
|
||||
_viewcenter->setLayout(layout);
|
||||
layout->addWidget(_vsplitter, 0, 0);
|
||||
_viewbottom = new widgets::ViewStatus(this);
|
||||
_viewbottom = new widgets::ViewStatus(_session, this);
|
||||
_viewbottom->setFixedHeight(StatusHeight);
|
||||
layout->addWidget(_viewbottom, 1, 0);
|
||||
setViewport(_viewcenter);
|
||||
@@ -153,21 +155,21 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget
|
||||
this, SLOT(signals_changed()), Qt::DirectConnection);
|
||||
connect(&_session, SIGNAL(data_updated()),
|
||||
this, SLOT(data_updated()));
|
||||
connect(&_session, SIGNAL(receive_header()),
|
||||
this, SLOT(receive_header()));
|
||||
connect(&_session, SIGNAL(receive_trigger(quint64)),
|
||||
this, SLOT(receive_trigger(quint64)));
|
||||
connect(&_session, SIGNAL(frame_ended()),
|
||||
this, SLOT(receive_end()));
|
||||
connect(&_session, SIGNAL(frame_began()),
|
||||
this, SLOT(frame_began()));
|
||||
connect(&_session, SIGNAL(show_region(uint64_t,uint64_t)),
|
||||
this, SLOT(show_region(uint64_t, uint64_t)));
|
||||
connect(&_session, SIGNAL(show_region(uint64_t, uint64_t, bool)),
|
||||
this, SLOT(show_region(uint64_t, uint64_t, bool)));
|
||||
connect(&_session, SIGNAL(show_wait_trigger()),
|
||||
_time_viewport, SLOT(show_wait_trigger()));
|
||||
connect(&_session, SIGNAL(repeat_hold(int)),
|
||||
this, SLOT(repeat_show()));
|
||||
|
||||
connect(_devmode, SIGNAL(mode_changed()),
|
||||
parent, SLOT(mode_changed()), Qt::DirectConnection);
|
||||
this, SLOT(mode_changed()), Qt::DirectConnection);
|
||||
|
||||
connect(_header, SIGNAL(traces_moved()),
|
||||
this, SLOT(on_traces_moved()));
|
||||
@@ -188,7 +190,7 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget
|
||||
_trig_cursor = new Cursor(*this, Trace::dsLightRed, 0);
|
||||
_show_search_cursor = false;
|
||||
_search_pos = 0;
|
||||
_search_cursor = new Cursor(*this, Trace::dsLightBlue, _search_pos);
|
||||
_search_cursor = new Cursor(*this, Trace::dsGray, _search_pos);
|
||||
|
||||
_cali = new pv::dialogs::Calibration(this);
|
||||
_cali->hide();
|
||||
@@ -204,7 +206,7 @@ double View::scale() const
|
||||
return _scale;
|
||||
}
|
||||
|
||||
double View::offset() const
|
||||
int64_t View::offset() const
|
||||
{
|
||||
return _offset;
|
||||
}
|
||||
@@ -219,6 +221,17 @@ double View::get_maxscale() const
|
||||
return _maxscale;
|
||||
}
|
||||
|
||||
void View::capture_init(bool instant)
|
||||
{
|
||||
if (_session.get_device()->dev_inst()->mode == DSO)
|
||||
show_trig_cursor(true);
|
||||
else if (!_session.isRepeating())
|
||||
show_trig_cursor(false);
|
||||
|
||||
update_sample(instant);
|
||||
status_clear();
|
||||
}
|
||||
|
||||
void View::zoom(double steps)
|
||||
{
|
||||
zoom(steps, get_view_width() / 2);
|
||||
@@ -241,7 +254,7 @@ void View::update_sample(bool instant)
|
||||
BOOST_FOREACH(const boost::shared_ptr<pv::view::Signal> s, _session.get_signals()) {
|
||||
boost::shared_ptr<pv::view::DsoSignal> dsoSig;
|
||||
if (dsoSig = dynamic_pointer_cast<pv::view::DsoSignal>(s)) {
|
||||
dsoSig->go_hDialCur();
|
||||
dsoSig->update_capture();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -271,7 +284,6 @@ void View::zoom(double steps, int offset)
|
||||
_preScale = _scale;
|
||||
_preOffset = _offset;
|
||||
|
||||
const double cursor_offset = _offset + _scale * offset;
|
||||
if (_session.get_device()->dev_inst()->mode != DSO) {
|
||||
_scale *= std::pow(3.0/2.0, -steps);
|
||||
_scale = max(min(_scale, _maxscale), _minscale);
|
||||
@@ -292,7 +304,7 @@ void View::zoom(double steps, int offset)
|
||||
}
|
||||
}
|
||||
|
||||
_offset = cursor_offset - _scale * offset;
|
||||
_offset = floor((_offset + offset) * (_preScale / _scale) - offset);
|
||||
_offset = max(min(_offset, get_max_offset()), get_min_offset());
|
||||
|
||||
if (_scale != _preScale || _offset != _preOffset) {
|
||||
@@ -305,14 +317,14 @@ void View::zoom(double steps, int offset)
|
||||
}
|
||||
|
||||
|
||||
void View::set_scale_offset(double scale, double offset)
|
||||
void View::set_scale_offset(double scale, int64_t offset)
|
||||
{
|
||||
//if (_session.get_capture_state() == SigSession::Stopped) {
|
||||
_preScale = _scale;
|
||||
_preOffset = _offset;
|
||||
|
||||
_scale = max(min(scale, _maxscale), _minscale);
|
||||
_offset = max(min(offset, get_max_offset()), get_min_offset());
|
||||
_offset = floor(max(min(offset, get_max_offset()), get_min_offset()));
|
||||
|
||||
if (_scale != _preScale || _offset != _preOffset) {
|
||||
update_scroll();
|
||||
@@ -419,15 +431,18 @@ void View::status_clear()
|
||||
_viewbottom->clear();
|
||||
}
|
||||
|
||||
void View::receive_header()
|
||||
void View::repeat_unshow()
|
||||
{
|
||||
status_clear();
|
||||
_viewbottom->repeat_unshow();
|
||||
}
|
||||
|
||||
void View::frame_began()
|
||||
{
|
||||
if (_session.get_device()->dev_inst()->mode == LOGIC)
|
||||
_viewbottom->set_trig_time(_session.get_trigger_time());
|
||||
_search_hit = false;
|
||||
_search_pos = 0;
|
||||
set_search_pos(_search_pos, _search_hit);
|
||||
}
|
||||
|
||||
void View::receive_end()
|
||||
@@ -460,7 +475,7 @@ void View::receive_trigger(quint64 trig_pos)
|
||||
_session.get_device()->name() == "virtual-session" ||
|
||||
_session.get_device()->dev_inst()->mode == DSO) {
|
||||
_show_trig_cursor = true;
|
||||
set_scale_offset(_scale, time - _scale * get_view_width() / 2);
|
||||
set_scale_offset(_scale, (time / _scale) - (get_view_width() / 2));
|
||||
}
|
||||
|
||||
_ruler->update();
|
||||
@@ -473,16 +488,21 @@ void View::set_trig_pos(int percent)
|
||||
receive_trigger(index);
|
||||
}
|
||||
|
||||
void View::set_search_pos(uint64_t search_pos)
|
||||
void View::set_search_pos(uint64_t search_pos, bool hit)
|
||||
{
|
||||
//assert(search_pos >= 0);
|
||||
|
||||
const double time = search_pos * 1.0 / _session.cur_samplerate();
|
||||
_search_pos = search_pos;
|
||||
_search_hit = hit;
|
||||
_search_cursor->set_index(search_pos);
|
||||
set_scale_offset(_scale, time - _scale * get_view_width() / 2);
|
||||
_ruler->update();
|
||||
viewport_update();
|
||||
_search_cursor->set_colour(hit ? Trace::dsLightBlue : Trace::dsGray);
|
||||
|
||||
if (hit) {
|
||||
set_scale_offset(_scale, (time / _scale) - (get_view_width() / 2));
|
||||
_ruler->update();
|
||||
viewport_update();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t View::get_search_pos()
|
||||
@@ -490,6 +510,11 @@ uint64_t View::get_search_pos()
|
||||
return _search_pos;
|
||||
}
|
||||
|
||||
bool View::get_search_hit()
|
||||
{
|
||||
return _search_hit;
|
||||
}
|
||||
|
||||
const QPoint& View::hover_point() const
|
||||
{
|
||||
return _hover_point;
|
||||
@@ -522,14 +547,14 @@ int View::get_signalHeight()
|
||||
return _signalHeight;
|
||||
}
|
||||
|
||||
void View::get_scroll_layout(double &length, double &offset) const
|
||||
void View::get_scroll_layout(int64_t &length, int64_t &offset) const
|
||||
{
|
||||
const set< boost::shared_ptr<data::SignalData> > data_set = _session.get_data();
|
||||
if (data_set.empty())
|
||||
return;
|
||||
|
||||
length = _session.get_device()->get_sample_time() / _scale;
|
||||
offset = _offset / _scale;
|
||||
length = ceil(_session.cur_sampletime() / _scale);
|
||||
offset = _offset;
|
||||
}
|
||||
|
||||
void View::update_scroll()
|
||||
@@ -539,9 +564,10 @@ void View::update_scroll()
|
||||
const QSize areaSize = _viewcenter->size();
|
||||
|
||||
// Set the horizontal scroll bar
|
||||
double length = 0, offset = 0;
|
||||
int64_t length = 0;
|
||||
int64_t offset = 0;
|
||||
get_scroll_layout(length, offset);
|
||||
length = max(length - areaSize.width(), 0.0);
|
||||
length = max(length - areaSize.width(), (int64_t)0);
|
||||
|
||||
horizontalScrollBar()->setPageStep(areaSize.width() / 2);
|
||||
|
||||
@@ -553,7 +579,7 @@ void View::update_scroll()
|
||||
} else {
|
||||
horizontalScrollBar()->setRange(0, MaxScrollValue);
|
||||
horizontalScrollBar()->setSliderPosition(
|
||||
_offset * MaxScrollValue / (_scale * length));
|
||||
_offset * MaxScrollValue / length);
|
||||
}
|
||||
|
||||
_updating_scroll = false;
|
||||
@@ -569,7 +595,6 @@ void View::update_scale_offset()
|
||||
assert(sample_rate > 0);
|
||||
|
||||
if (_session.get_device()->dev_inst()->mode != DSO) {
|
||||
//_scale = (1.0 / sample_rate) / WellPixelsPerSample;
|
||||
_maxscale = _session.cur_sampletime() / (get_view_width() * MaxViewRate);
|
||||
_minscale = (1.0 / sample_rate) / MaxPixelsPerSample;
|
||||
} else {
|
||||
@@ -578,7 +603,6 @@ void View::update_scale_offset()
|
||||
_minscale = 1e-15;
|
||||
}
|
||||
|
||||
|
||||
_scale = max(min(_scale, _maxscale), _minscale);
|
||||
_offset = max(min(_offset, get_max_offset()), get_min_offset());
|
||||
|
||||
@@ -591,6 +615,18 @@ void View::update_scale_offset()
|
||||
viewport_update();
|
||||
}
|
||||
|
||||
void View::mode_changed()
|
||||
{
|
||||
const uint64_t sample_rate = _session.cur_samplerate();
|
||||
assert(sample_rate > 0);
|
||||
|
||||
if (_session.get_device()->name().contains("virtual"))
|
||||
_scale = WellSamplesPerPixel * 1.0 / sample_rate;
|
||||
_scale = max(min(_scale, _maxscale), _minscale);
|
||||
|
||||
update_device_list();
|
||||
}
|
||||
|
||||
void View::signals_changed()
|
||||
{
|
||||
int total_rows = 0;
|
||||
@@ -624,7 +660,7 @@ void View::signals_changed()
|
||||
_fft_viewport->setVisible(false);
|
||||
_vsplitter->refresh();
|
||||
|
||||
// Find the decoder in the stack
|
||||
// Find the _fft_viewport in the stack
|
||||
std::list< Viewport *>::iterator iter = _viewport_list.begin();
|
||||
for(unsigned int i = 0; i < _viewport_list.size(); i++, iter++)
|
||||
if ((*iter) == _fft_viewport)
|
||||
@@ -671,12 +707,7 @@ void View::signals_changed()
|
||||
|
||||
boost::shared_ptr<view::DsoSignal> dsoSig;
|
||||
if (dsoSig = dynamic_pointer_cast<view::DsoSignal>(t)) {
|
||||
GVariant *gvar = _session.get_device()->get_config(NULL, NULL, SR_CONF_DSO_BITS);
|
||||
if (gvar != NULL) {
|
||||
bits = g_variant_get_byte(gvar);
|
||||
g_variant_unref(gvar);
|
||||
}
|
||||
dsoSig->set_scale(dsoSig->get_view_rect().height() * 1.0f / (1 << bits));
|
||||
dsoSig->set_scale(dsoSig->get_view_rect().height());
|
||||
}
|
||||
}
|
||||
_time_viewport->clear_measure();
|
||||
@@ -695,10 +726,11 @@ bool View::eventFilter(QObject *object, QEvent *event)
|
||||
const QMouseEvent *const mouse_event = (QMouseEvent*)event;
|
||||
if (object == _ruler || object == _time_viewport || object == _fft_viewport) {
|
||||
//_hover_point = QPoint(mouse_event->x(), 0);
|
||||
double cur_periods = (mouse_event->pos().x() * _scale + _offset) / _ruler->get_min_period();
|
||||
int integer_x = (round(cur_periods) * _ruler->get_min_period() - _offset ) / _scale;
|
||||
double cur_periods = (mouse_event->pos().x() + _offset) * _scale / _ruler->get_min_period();
|
||||
int integer_x = round(cur_periods) * _ruler->get_min_period() / _scale - _offset;
|
||||
double cur_deviate_x = qAbs(mouse_event->pos().x() - integer_x);
|
||||
if (cur_deviate_x < 10)
|
||||
if (_session.get_device()->dev_inst()->mode == LOGIC &&
|
||||
cur_deviate_x < 10)
|
||||
_hover_point = QPoint(integer_x, mouse_event->pos().y());
|
||||
else
|
||||
_hover_point = mouse_event->pos();
|
||||
@@ -789,11 +821,12 @@ void View::h_scroll_value_changed(int value)
|
||||
|
||||
const int range = horizontalScrollBar()->maximum();
|
||||
if (range < MaxScrollValue)
|
||||
_offset = _scale * value;
|
||||
_offset = value;
|
||||
else {
|
||||
double length = 0, offset;
|
||||
int64_t length = 0;
|
||||
int64_t offset = 0;
|
||||
get_scroll_layout(length, offset);
|
||||
_offset = _scale * length * value / MaxScrollValue;
|
||||
_offset = floor(length * value / MaxScrollValue);
|
||||
}
|
||||
|
||||
_offset = max(min(_offset, get_max_offset()), get_min_offset());
|
||||
@@ -859,7 +892,6 @@ void View::on_traces_moved()
|
||||
update_scroll();
|
||||
set_update(_time_viewport, true);
|
||||
viewport_update();
|
||||
//traces_moved();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -908,7 +940,7 @@ void View::set_cursor_middle(int index)
|
||||
list<Cursor*>::iterator i = _cursorList.begin();
|
||||
while (index-- != 0)
|
||||
i++;
|
||||
set_scale_offset(_scale, (*i)->index() * 1.0 / _session.cur_samplerate() - _scale * get_view_width() / 2);
|
||||
set_scale_offset(_scale, (*i)->index() / (_session.cur_samplerate() * _scale) - (get_view_width() / 2));
|
||||
}
|
||||
|
||||
void View::on_measure_updated()
|
||||
@@ -955,11 +987,6 @@ uint64_t View::get_cursor_samples(int index)
|
||||
}
|
||||
}
|
||||
|
||||
void View::on_cursor_moved()
|
||||
{
|
||||
cursor_moved();
|
||||
}
|
||||
|
||||
void View::set_measure_en(int enable)
|
||||
{
|
||||
BOOST_FOREACH(Viewport *viewport, _viewport_list)
|
||||
@@ -1017,15 +1044,18 @@ int View::get_view_height()
|
||||
return view_height;
|
||||
}
|
||||
|
||||
double View::get_min_offset()
|
||||
int64_t View::get_min_offset()
|
||||
{
|
||||
return -(_scale * (get_view_width() * (1 - MaxViewRate)));
|
||||
if (MaxViewRate > 1)
|
||||
return floor(get_view_width() * (1 - MaxViewRate));
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
double View::get_max_offset()
|
||||
int64_t View::get_max_offset()
|
||||
{
|
||||
return _session.get_device()->get_sample_time()
|
||||
- _scale * (get_view_width() * MaxViewRate);
|
||||
return ceil((_session.cur_sampletime() / _scale) -
|
||||
(get_view_width() * MaxViewRate));
|
||||
}
|
||||
|
||||
// -- calibration dialog
|
||||
@@ -1047,13 +1077,22 @@ void View::update_calibration()
|
||||
}
|
||||
}
|
||||
|
||||
void View::show_region(uint64_t start, uint64_t end)
|
||||
void View::show_region(uint64_t start, uint64_t end, bool keep)
|
||||
{
|
||||
assert(start <= end);
|
||||
const double ideal_scale = (end-start) * 2.0 / _session.cur_samplerate() / get_view_width();
|
||||
const double new_scale = max(min(ideal_scale, _maxscale), _minscale);
|
||||
const double new_off = (start + end) * 0.5 / _session.cur_samplerate() - new_scale * get_view_width() / 2;
|
||||
set_scale_offset(new_scale, new_off);
|
||||
if (keep) {
|
||||
set_all_update(true);
|
||||
update();
|
||||
} else if (_session.get_map_zoom() == 0) {
|
||||
const double ideal_scale = (end-start) * 2.0 / _session.cur_samplerate() / get_view_width();
|
||||
const double new_scale = max(min(ideal_scale, _maxscale), _minscale);
|
||||
const double new_off = (start + end) * 0.5 / (_session.cur_samplerate() * new_scale) - (get_view_width() / 2);
|
||||
set_scale_offset(new_scale, new_off);
|
||||
} else {
|
||||
const double new_scale = scale();
|
||||
const double new_off = (start + end) * 0.5 / (_session.cur_samplerate() * new_scale) - (get_view_width() / 2);
|
||||
set_scale_offset(new_scale, new_off);
|
||||
}
|
||||
}
|
||||
|
||||
void View::viewport_update()
|
||||
@@ -1082,8 +1121,48 @@ void View::reload()
|
||||
_viewbottom->setFixedHeight(StatusHeight);
|
||||
else
|
||||
_viewbottom->setFixedHeight(10);
|
||||
}
|
||||
|
||||
void View::repeat_show()
|
||||
{
|
||||
_viewbottom->update();
|
||||
}
|
||||
|
||||
bool View::get_capture_status(bool &triggered, int &progress)
|
||||
{
|
||||
uint64_t sample_limits = _session.cur_samplelimits();
|
||||
sr_status status;
|
||||
if (sr_status_get(_session.get_device()->dev_inst(), &status, SR_STATUS_TRIG_BEGIN, SR_STATUS_TRIG_END) == SR_OK){
|
||||
triggered = status.trig_hit & 0x01;
|
||||
const bool captured_cnt_dec = status.trig_hit & 0x02;
|
||||
uint64_t captured_cnt = status.trig_hit >> 2;
|
||||
captured_cnt = ((uint64_t)status.captured_cnt0 +
|
||||
((uint64_t)status.captured_cnt1 << 8) +
|
||||
((uint64_t)status.captured_cnt2 << 16) +
|
||||
((uint64_t)status.captured_cnt3 << 24) +
|
||||
(captured_cnt << 32));
|
||||
if (_session.get_device()->dev_inst()->mode == DSO)
|
||||
captured_cnt = captured_cnt * _session.get_signals().size() / _session.get_ch_num(SR_CHANNEL_DSO);
|
||||
if (captured_cnt_dec)
|
||||
progress = (sample_limits - captured_cnt) * 100.0 / sample_limits;
|
||||
else
|
||||
progress = captured_cnt * 100.0 / sample_limits;
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void View::set_capture_status()
|
||||
{
|
||||
bool triggered;
|
||||
int progress;
|
||||
if (_session.get_capture_status(triggered, progress)) {
|
||||
_viewbottom->set_capture_status(triggered, progress);
|
||||
_viewbottom->update();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace view
|
||||
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
|
||||
static const QSizeF LabelPadding;
|
||||
|
||||
static const int WellPixelsPerSample = 10;
|
||||
static const int WellSamplesPerPixel = 2048;
|
||||
static constexpr double MaxViewRate = 1.0;
|
||||
static const int MaxPixelsPerSample = 100;
|
||||
|
||||
@@ -97,14 +97,15 @@ public:
|
||||
double scale() const;
|
||||
|
||||
/**
|
||||
* Returns the time offset of the left edge of the view in
|
||||
* seconds.
|
||||
* Returns the pixels offset of the left edge of the view
|
||||
*/
|
||||
double offset() const;
|
||||
int64_t offset() const;
|
||||
int v_offset() const;
|
||||
|
||||
double get_min_offset();
|
||||
double get_max_offset();
|
||||
int64_t get_min_offset();
|
||||
int64_t get_max_offset();
|
||||
|
||||
void capture_init(bool instant);
|
||||
|
||||
void zoom(double steps);
|
||||
void zoom(double steps, int offset);
|
||||
@@ -114,7 +115,7 @@ public:
|
||||
* @param scale The new view scale in seconds per pixel.
|
||||
* @param offset The view time offset in seconds.
|
||||
*/
|
||||
void set_scale_offset(double scale, double offset);
|
||||
void set_scale_offset(double scale, int64_t offset);
|
||||
void set_preScale_preOffset();
|
||||
|
||||
std::vector< boost::shared_ptr<Trace> > get_traces(int type);
|
||||
@@ -157,8 +158,9 @@ public:
|
||||
|
||||
Cursor* get_trig_cursor();
|
||||
Cursor* get_search_cursor();
|
||||
bool get_search_hit();
|
||||
|
||||
void set_search_pos(uint64_t search_pos);
|
||||
void set_search_pos(uint64_t search_pos, bool hit);
|
||||
|
||||
uint64_t get_search_pos();
|
||||
|
||||
@@ -175,8 +177,6 @@ public:
|
||||
QString get_cm_time(int index);
|
||||
QString get_cm_delta(int index1, int index2);
|
||||
|
||||
void on_cursor_moved();
|
||||
|
||||
void on_state_changed(bool stop);
|
||||
|
||||
QRect get_view_rect();
|
||||
@@ -193,19 +193,25 @@ public:
|
||||
|
||||
void viewport_update();
|
||||
|
||||
bool get_capture_status(bool &triggered, int &progress);
|
||||
void set_capture_status();
|
||||
|
||||
signals:
|
||||
void hover_point_changed();
|
||||
|
||||
void traces_moved();
|
||||
|
||||
void cursor_update();
|
||||
|
||||
void cursor_moving();
|
||||
void cursor_moved();
|
||||
|
||||
void measure_updated();
|
||||
|
||||
void prgRate(int progress);
|
||||
|
||||
void update_device_list();
|
||||
|
||||
private:
|
||||
void get_scroll_layout(double &length, double &offset) const;
|
||||
void get_scroll_layout(int64_t &length, int64_t &offset) const;
|
||||
|
||||
void update_scroll();
|
||||
|
||||
@@ -228,11 +234,14 @@ public slots:
|
||||
void signals_changed();
|
||||
void data_updated();
|
||||
void update_scale_offset();
|
||||
void show_region(uint64_t start, uint64_t end);
|
||||
void show_region(uint64_t start, uint64_t end, bool keep);
|
||||
// -- calibration
|
||||
void update_calibration();
|
||||
void hide_calibration();
|
||||
void status_clear();
|
||||
void repeat_unshow();
|
||||
// -- repeat
|
||||
void repeat_show();
|
||||
|
||||
private slots:
|
||||
|
||||
@@ -245,8 +254,6 @@ private slots:
|
||||
|
||||
void header_updated();
|
||||
|
||||
void receive_header();
|
||||
|
||||
void receive_trigger(quint64 trig_pos);
|
||||
void set_trig_pos(int percent);
|
||||
|
||||
@@ -260,6 +267,8 @@ private slots:
|
||||
|
||||
void splitterMoved(int pos, int index);
|
||||
|
||||
void mode_changed();
|
||||
|
||||
private:
|
||||
|
||||
SigSession &_session;
|
||||
@@ -279,32 +288,29 @@ private:
|
||||
|
||||
/// The view time scale in seconds per pixel.
|
||||
double _scale;
|
||||
double _preScale;
|
||||
double _maxscale;
|
||||
double _minscale;
|
||||
double _preScale;
|
||||
double _maxscale;
|
||||
double _minscale;
|
||||
|
||||
/// The view time offset in seconds.
|
||||
double _offset;
|
||||
double _preOffset;
|
||||
|
||||
int _spanY;
|
||||
int _signalHeight;
|
||||
|
||||
bool _updating_scroll;
|
||||
/// The pixels offset of the left edge of the view
|
||||
int64_t _offset;
|
||||
int64_t _preOffset;
|
||||
int _spanY;
|
||||
int _signalHeight;
|
||||
bool _updating_scroll;
|
||||
|
||||
bool _show_cursors;
|
||||
std::list<Cursor*> _cursorList;
|
||||
Cursor *_trig_cursor;
|
||||
bool _show_trig_cursor;
|
||||
Cursor *_search_cursor;
|
||||
bool _show_search_cursor;
|
||||
uint64_t _search_pos;
|
||||
bool _search_hit;
|
||||
|
||||
std::list<Cursor*> _cursorList;
|
||||
|
||||
Cursor *_trig_cursor;
|
||||
bool _show_trig_cursor;
|
||||
Cursor *_search_cursor;
|
||||
bool _show_search_cursor;
|
||||
uint64_t _search_pos;
|
||||
|
||||
QPoint _hover_point;
|
||||
dialogs::Calibration *_cali;
|
||||
bool _dso_auto;
|
||||
QPoint _hover_point;
|
||||
dialogs::Calibration *_cali;
|
||||
bool _dso_auto;
|
||||
};
|
||||
|
||||
} // namespace view
|
||||
|
||||
@@ -57,7 +57,7 @@ Viewport::Viewport(View &parent, View_type type) :
|
||||
_view(parent),
|
||||
_type(type),
|
||||
_need_update(false),
|
||||
_total_receive_len(0),
|
||||
_sample_received(0),
|
||||
_action_type(NO_ACTION),
|
||||
_measure_type(NO_MEASURE),
|
||||
_cur_sample(0),
|
||||
@@ -81,15 +81,13 @@ Viewport::Viewport(View &parent, View_type type) :
|
||||
_mm_freq = "#####";
|
||||
_mm_duty = "#####";
|
||||
_measure_en = true;
|
||||
triggered = false;
|
||||
transfer_started = false;
|
||||
timer_cnt = 0;
|
||||
|
||||
// drag inertial
|
||||
_drag_strength = 0;
|
||||
_drag_timer.setSingleShot(true);
|
||||
|
||||
connect(&_view, SIGNAL(traces_moved()),
|
||||
this, SLOT(on_traces_moved()));
|
||||
connect(&trigger_timer, SIGNAL(timeout()),
|
||||
this, SLOT(on_trigger_timer()));
|
||||
connect(&_drag_timer, SIGNAL(timeout()),
|
||||
@@ -135,7 +133,7 @@ void Viewport::paintEvent(QPaintEvent *event)
|
||||
{
|
||||
assert(t);
|
||||
t->paint_back(p, 0, _view.get_view_width());
|
||||
if (t->enabled() && _view.session().get_device()->dev_inst()->mode == DSO)
|
||||
if (_view.session().get_device()->dev_inst()->mode == DSO)
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -151,7 +149,12 @@ void Viewport::paintEvent(QPaintEvent *event)
|
||||
break;
|
||||
|
||||
case SigSession::Running:
|
||||
if (_type == TIME_VIEW) {
|
||||
if (_view.session().isRepeating() &&
|
||||
!transfer_started) {
|
||||
_view.set_capture_status();
|
||||
paintSignals(p);
|
||||
} else if (_type == TIME_VIEW) {
|
||||
_view.repeat_unshow();
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
paintProgress(p);
|
||||
p.setRenderHint(QPainter::Antialiasing, false);
|
||||
@@ -205,27 +208,33 @@ void Viewport::paintSignals(QPainter &p)
|
||||
p.drawPixmap(0, 0, pixmap);
|
||||
|
||||
// plot cursors
|
||||
const double samples_per_pixel = _view.session().cur_samplerate() * _view.scale();
|
||||
if (_view.cursors_shown() && _type == TIME_VIEW) {
|
||||
list<Cursor*>::iterator i = _view.get_cursorList().begin();
|
||||
double cursorX;
|
||||
const double samples_per_pixel = _view.session().cur_samplerate() * _view.scale();
|
||||
int index = 0;
|
||||
while (i != _view.get_cursorList().end()) {
|
||||
cursorX = (*i)->index()/samples_per_pixel - (_view.offset() / _view.scale());
|
||||
const int64_t cursorX = (*i)->index()/samples_per_pixel - _view.offset();
|
||||
if (rect().contains(_view.hover_point().x(), _view.hover_point().y()) &&
|
||||
qAbs(cursorX - _view.hover_point().x()) <= HitCursorMargin)
|
||||
(*i)->paint(p, rect(), 1);
|
||||
(*i)->paint(p, rect(), 1, index);
|
||||
else
|
||||
(*i)->paint(p, rect(), 0);
|
||||
(*i)->paint(p, rect(), 0, index);
|
||||
i++;
|
||||
index++;
|
||||
}
|
||||
}
|
||||
|
||||
if (_type == TIME_VIEW) {
|
||||
if (_view.trig_cursor_shown()) {
|
||||
_view.get_trig_cursor()->paint(p, rect(), 0);
|
||||
_view.get_trig_cursor()->paint(p, rect(), 0, -1);
|
||||
}
|
||||
if (_view.search_cursor_shown()) {
|
||||
_view.get_search_cursor()->paint(p, rect(), 0);
|
||||
const int64_t searchX = _view.get_search_cursor()->index()/samples_per_pixel - _view.offset();
|
||||
if (rect().contains(_view.hover_point().x(), _view.hover_point().y()) &&
|
||||
qAbs(searchX - _view.hover_point().x()) <= HitCursorMargin)
|
||||
_view.get_search_cursor()->paint(p, rect(), 1, -1);
|
||||
else
|
||||
_view.get_search_cursor()->paint(p, rect(), 0, -1);
|
||||
}
|
||||
|
||||
// plot zoom rect
|
||||
@@ -276,9 +285,9 @@ void Viewport::paintProgress(QPainter &p)
|
||||
{
|
||||
using pv::view::Signal;
|
||||
|
||||
const uint64_t _total_sample_len = _view.session().cur_samplelimits();
|
||||
const uint64_t sample_limits = _view.session().cur_samplelimits();
|
||||
|
||||
double progress = -(_total_receive_len * 1.0 / _total_sample_len * 360 * 16);
|
||||
double progress = -(_sample_received * 1.0 / sample_limits * 360 * 16);
|
||||
int captured_progress = 0;
|
||||
|
||||
p.setPen(Qt::gray);
|
||||
@@ -344,7 +353,7 @@ void Viewport::paintProgress(QPainter &p)
|
||||
p.drawEllipse(logoPoints[19].x() - 0.5 * logoRadius, logoPoints[19].y() - logoRadius,
|
||||
logoRadius, logoRadius);
|
||||
|
||||
if (!triggered) {
|
||||
if (!transfer_started) {
|
||||
const int width = _view.get_view_width();
|
||||
const QPoint cenLeftPos = QPoint(width / 2 - 0.05 * width, height() / 2);
|
||||
const QPoint cenRightPos = QPoint(width / 2 + 0.05 * width, height() / 2);
|
||||
@@ -359,37 +368,38 @@ void Viewport::paintProgress(QPainter &p)
|
||||
p.drawEllipse(cenRightPos, trigger_radius, trigger_radius);
|
||||
|
||||
sr_status status;
|
||||
if (sr_status_get(_view.session().get_device()->dev_inst(), &status, SR_STATUS_TRIG_BEGIN, SR_STATUS_TRIG_END) == SR_OK){
|
||||
const bool triggred = status.trig_hit & 0x01;
|
||||
uint32_t captured_cnt = (status.captured_cnt0 +
|
||||
(status.captured_cnt1 << 8) +
|
||||
(status.captured_cnt2 << 16) +
|
||||
(status.captured_cnt3 << 24));
|
||||
if (_view.session().get_device()->dev_inst()->mode == DSO)
|
||||
captured_cnt = captured_cnt * _view.session().get_signals().size() / _view.session().get_ch_num(SR_CHANNEL_DSO);
|
||||
if (triggred)
|
||||
captured_progress = (_total_sample_len - captured_cnt) * 100.0 / _total_sample_len;
|
||||
else
|
||||
captured_progress = captured_cnt * 100.0 / _total_sample_len;
|
||||
|
||||
|
||||
bool triggered;
|
||||
if (_view.session().get_capture_status(triggered, captured_progress)){
|
||||
p.setPen(Trace::dsLightBlue);
|
||||
QFont font=p.font();
|
||||
font.setPointSize(10);
|
||||
font.setBold(true);
|
||||
p.setFont(font);
|
||||
QRect status_rect = QRect(cenPos.x() - radius, cenPos.y() + radius * 0.4, radius * 2, radius * 0.5);
|
||||
if (triggred)
|
||||
if (triggered)
|
||||
p.drawText(status_rect,
|
||||
Qt::AlignCenter | Qt::AlignVCenter,
|
||||
"Triggered! " + QString::number(captured_progress)+"% Captured");
|
||||
tr("Triggered! ") + QString::number(captured_progress) + tr("% Captured"));
|
||||
else
|
||||
p.drawText(status_rect,
|
||||
Qt::AlignCenter | Qt::AlignVCenter,
|
||||
"Waiting for Trigger! " + QString::number(captured_progress)+"% Captured");
|
||||
tr("Waiting for Trigger! ") + QString::number(captured_progress) + tr("% Captured"));
|
||||
prgRate(captured_progress);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (_view.session().get_error() == SigSession::No_err) {
|
||||
GVariant *gvar = _view.session().get_device()->get_config(NULL, NULL, SR_CONF_HW_STATUS);
|
||||
if (gvar != NULL) {
|
||||
uint8_t hw_info = g_variant_get_byte(gvar);
|
||||
g_variant_unref(gvar);
|
||||
if (hw_info & 0x10) {
|
||||
_view.session().set_error(SigSession::Data_overflow);
|
||||
_view.session().session_error();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const int progress100 = ceil(progress / -3.6 / 16);
|
||||
p.setPen(Trace::dsGreen);
|
||||
QFont font=p.font();
|
||||
@@ -397,6 +407,7 @@ void Viewport::paintProgress(QPainter &p)
|
||||
font.setBold(true);
|
||||
p.setFont(font);
|
||||
p.drawText(rect(), Qt::AlignCenter | Qt::AlignVCenter, QString::number(progress100)+"%");
|
||||
prgRate(progress100);
|
||||
}
|
||||
|
||||
p.setPen(QPen(Trace::dsLightBlue, 4, Qt::SolidLine));
|
||||
@@ -444,7 +455,7 @@ void Viewport::mousePressEvent(QMouseEvent *event)
|
||||
_action_type = LOGIC_ZOOM;
|
||||
} else if (_view.session().get_device()->dev_inst()->mode == DSO) {
|
||||
if (_hover_hit) {
|
||||
uint64_t index = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().cur_samplerate();
|
||||
const int64_t index = (_view.offset() + event->pos().x()) * _view.scale() * _view.session().cur_samplerate();
|
||||
_view.add_cursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], index);
|
||||
_view.show_cursors(true);
|
||||
}
|
||||
@@ -460,9 +471,7 @@ void Viewport::mouseMoveEvent(QMouseEvent *event)
|
||||
if (event->buttons() & Qt::LeftButton) {
|
||||
if (_type == TIME_VIEW) {
|
||||
_view.set_scale_offset(_view.scale(),
|
||||
_mouse_down_offset +
|
||||
(_mouse_down_point - event->pos()).x() *
|
||||
_view.scale());
|
||||
_mouse_down_offset + (_mouse_down_point - event->pos()).x());
|
||||
_drag_strength = (_mouse_down_point - event->pos()).x();
|
||||
} else if (_type == FFT_VIEW) {
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::MathTrace> t, _view.session().get_math_signals()) {
|
||||
@@ -489,7 +498,7 @@ void Viewport::mouseMoveEvent(QMouseEvent *event)
|
||||
if (_action_type == CURS_MOVE) {
|
||||
uint64_t sample_rate = _view.session().cur_samplerate();
|
||||
TimeMarker* grabbed_marker = _view.get_ruler()->get_grabbed_cursor();
|
||||
if (_view.cursors_shown() && grabbed_marker) {
|
||||
if (grabbed_marker) {
|
||||
int curX = _view.hover_point().x();
|
||||
uint64_t index0 = 0, index1 = 0, index2 = 0;
|
||||
bool logic = false;
|
||||
@@ -512,13 +521,12 @@ void Viewport::mouseMoveEvent(QMouseEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
const double cur_time = _view.offset() + curX * _view.scale();
|
||||
const double cur_time = (_view.offset() + curX) * _view.scale();
|
||||
const double pos = cur_time * sample_rate;
|
||||
const double pos_delta = pos - (uint64_t)pos;
|
||||
const double samples_per_pixel = sample_rate * _view.scale();
|
||||
const double index_offset = _view.offset() / _view.scale();
|
||||
const double curP = index0 / samples_per_pixel - index_offset;
|
||||
const double curN = index1 / samples_per_pixel - index_offset;
|
||||
const double curP = index0 / samples_per_pixel - _view.offset();
|
||||
const double curN = index1 / samples_per_pixel - _view.offset();
|
||||
if (logic && (curX - curP < SnapMinSpace || curN - curX < SnapMinSpace)) {
|
||||
if (curX - curP < curN - curX)
|
||||
grabbed_marker->set_index(index0);
|
||||
@@ -529,6 +537,12 @@ void Viewport::mouseMoveEvent(QMouseEvent *event)
|
||||
} else {
|
||||
grabbed_marker->set_index((uint64_t)ceil(pos));
|
||||
}
|
||||
|
||||
if (grabbed_marker == _view.get_search_cursor()) {
|
||||
_view.set_search_pos(grabbed_marker->index(), false);
|
||||
}
|
||||
|
||||
_view.cursor_moving();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -563,15 +577,23 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event)
|
||||
assert(event);
|
||||
|
||||
if (_type == TIME_VIEW) {
|
||||
const double samples_per_pixel = _view.session().cur_samplerate() * _view.scale();
|
||||
if ((_action_type == NO_ACTION) &&
|
||||
(event->button() == Qt::LeftButton)) {
|
||||
// priority 0
|
||||
if (_action_type == NO_ACTION && _view.search_cursor_shown()) {
|
||||
const int64_t searchX = _view.get_search_cursor()->index()/samples_per_pixel - _view.offset();
|
||||
if (_view.get_search_cursor()->grabbed()) {
|
||||
_view.get_ruler()->rel_grabbed_cursor();
|
||||
} else if (qAbs(searchX - event->pos().x()) <= HitCursorMargin) {
|
||||
_view.get_ruler()->set_grabbed_cursor(_view.get_search_cursor());
|
||||
_action_type = CURS_MOVE;
|
||||
}
|
||||
}
|
||||
if (_action_type == NO_ACTION && _view.cursors_shown()) {
|
||||
list<Cursor*>::iterator i = _view.get_cursorList().begin();
|
||||
double cursorX;
|
||||
const double samples_per_pixel = _view.session().cur_samplerate() * _view.scale();
|
||||
while (i != _view.get_cursorList().end()) {
|
||||
cursorX = (*i)->index()/samples_per_pixel - (_view.offset() / _view.scale());
|
||||
const int64_t cursorX = (*i)->index()/samples_per_pixel - _view.offset();
|
||||
if ((*i)->grabbed()) {
|
||||
_view.get_ruler()->rel_grabbed_cursor();
|
||||
} else if (qAbs(cursorX - event->pos().x()) <= HitCursorMargin) {
|
||||
@@ -609,7 +631,7 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event)
|
||||
assert(s);
|
||||
if (abs(event->pos().y() - s->get_y()) < _view.get_signalHeight()) {
|
||||
_action_type = LOGIC_EDGE;
|
||||
_edge_start = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().cur_samplerate();
|
||||
_edge_start = (_view.offset() + event->pos().x()) * _view.scale() * _view.session().cur_samplerate();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -664,11 +686,7 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event)
|
||||
}
|
||||
} else if (_action_type == DSO_XM_STEP1) {
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
const uint64_t sample_rate = _view.session().cur_samplerate();
|
||||
const double scale = _view.scale();
|
||||
const double samples_per_pixel = sample_rate * scale;
|
||||
|
||||
_dso_xm_index[1] = event->pos().x() * samples_per_pixel + _view.offset() * sample_rate;
|
||||
_dso_xm_index[1] = (event->pos().x() + _view.offset()) * samples_per_pixel;
|
||||
const uint64_t max_index = max(_dso_xm_index[0], _dso_xm_index[1]);
|
||||
_dso_xm_index[0] = min(_dso_xm_index[0], _dso_xm_index[1]);
|
||||
_dso_xm_index[1] = max_index;
|
||||
@@ -685,10 +703,7 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event)
|
||||
}
|
||||
} else if (_action_type == DSO_XM_STEP2) {
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
const uint64_t sample_rate = _view.session().cur_samplerate();
|
||||
const double scale = _view.scale();
|
||||
const double samples_per_pixel = sample_rate * scale;
|
||||
_dso_xm_index[2] = event->pos().x() * samples_per_pixel + _view.offset() * sample_rate;
|
||||
_dso_xm_index[2] = (event->pos().x() + _view.offset()) * samples_per_pixel;
|
||||
uint64_t max_index = max(_dso_xm_index[1], _dso_xm_index[2]);
|
||||
_dso_xm_index[1] = min(_dso_xm_index[1], _dso_xm_index[2]);
|
||||
_dso_xm_index[2] = max_index;
|
||||
@@ -709,15 +724,18 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event)
|
||||
}
|
||||
} else if (_action_type == CURS_MOVE) {
|
||||
_action_type = NO_ACTION;
|
||||
if (_view.cursors_shown()) {
|
||||
list<Cursor*>::iterator i = _view.get_cursorList().begin();
|
||||
while (i != _view.get_cursorList().end()) {
|
||||
if ((*i)->grabbed()) {
|
||||
_view.get_ruler()->rel_grabbed_cursor();
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
_view.get_ruler()->rel_grabbed_cursor();
|
||||
|
||||
// if (_view.cursors_shown()) {
|
||||
// list<Cursor*>::iterator i = _view.get_cursorList().begin();
|
||||
// while (i != _view.get_cursorList().end()) {
|
||||
// if ((*i)->grabbed()) {
|
||||
// _view.get_ruler()->rel_grabbed_cursor();
|
||||
// }
|
||||
// i++;
|
||||
// }
|
||||
// }
|
||||
_view.cursor_moved();
|
||||
} else if (_action_type == LOGIC_EDGE) {
|
||||
_action_type = NO_ACTION;
|
||||
_edge_rising = 0;
|
||||
@@ -741,9 +759,10 @@ void Viewport::mouseReleaseEvent(QMouseEvent *event)
|
||||
}
|
||||
} else if (_action_type == LOGIC_ZOOM) {
|
||||
if (event->pos().x() != _mouse_down_point.x()) {
|
||||
const double newOffset = _view.offset() + (min(event->pos().x(), _mouse_down_point.x()) + 0.5) * _view.scale();
|
||||
int64_t newOffset = _view.offset() + (min(event->pos().x(), _mouse_down_point.x()));
|
||||
const double newScale = max(min(_view.scale() * abs(event->pos().x() - _mouse_down_point.x()) / _view.get_view_width(),
|
||||
_view.get_maxscale()), _view.get_minscale());
|
||||
newOffset = floor(newOffset * (_view.scale() / newScale));
|
||||
if (newScale != _view.scale())
|
||||
_view.set_scale_offset(newScale, newOffset);
|
||||
}
|
||||
@@ -764,9 +783,37 @@ void Viewport::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
if (_view.scale() == _view.get_maxscale())
|
||||
_view.set_preScale_preOffset();
|
||||
else
|
||||
_view.set_scale_offset(_view.get_maxscale(), 0);
|
||||
_view.set_scale_offset(_view.get_maxscale(), _view.get_min_offset());
|
||||
} else if (event->button() == Qt::LeftButton) {
|
||||
uint64_t index = (_view.offset() + (event->pos().x() + 0.5) * _view.scale()) * _view.session().cur_samplerate();
|
||||
bool logic = false;
|
||||
uint64_t index;
|
||||
uint64_t index0 = 0, index1 = 0, index2 = 0;
|
||||
if (_view.session().get_device()->dev_inst()->mode == LOGIC) {
|
||||
const vector< boost::shared_ptr<Signal> > sigs(_view.session().get_signals());
|
||||
BOOST_FOREACH(const boost::shared_ptr<Signal> s, sigs) {
|
||||
assert(s);
|
||||
boost::shared_ptr<view::LogicSignal> logicSig;
|
||||
if ((logicSig = dynamic_pointer_cast<view::LogicSignal>(s))) {
|
||||
if (logicSig->measure(event->pos(), index0, index1, index2)) {
|
||||
logic = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const uint64_t sample_rate = _view.session().cur_samplerate();
|
||||
const double curX = event->pos().x();
|
||||
const double samples_per_pixel = sample_rate * _view.scale();
|
||||
const double curP = index0 / samples_per_pixel - _view.offset();
|
||||
const double curN = index1 / samples_per_pixel - _view.offset();
|
||||
if (logic && (curX - curP < SnapMinSpace || curN - curX < SnapMinSpace)) {
|
||||
if (curX - curP < curN - curX)
|
||||
index = index0;
|
||||
else
|
||||
index = index1;
|
||||
} else {
|
||||
index = (_view.offset() + curX) * _view.scale() * sample_rate;;
|
||||
}
|
||||
_view.add_cursor(view::Ruler::CursorColor[_view.get_cursorList().size() % 8], index);
|
||||
_view.show_cursors(true);
|
||||
}
|
||||
@@ -789,8 +836,7 @@ void Viewport::mouseDoubleClickEvent(QMouseEvent *event)
|
||||
uint64_t sample_rate = _view.session().cur_samplerate();
|
||||
double scale = _view.scale();
|
||||
const double samples_per_pixel = sample_rate * scale;
|
||||
_dso_xm_index[0] = event->pos().x() * samples_per_pixel +
|
||||
_view.offset() * sample_rate;
|
||||
_dso_xm_index[0] = (event->pos().x() + _view.offset()) * samples_per_pixel;
|
||||
_dso_xm_y = event->pos().y();
|
||||
_action_type = DSO_XM_STEP0;
|
||||
}
|
||||
@@ -815,13 +861,12 @@ void Viewport::wheelEvent(QWheelEvent *event)
|
||||
} else if (_type == TIME_VIEW){
|
||||
if (event->orientation() == Qt::Vertical) {
|
||||
// Vertical scrolling is interpreted as zooming in/out
|
||||
const double offset = event->x();
|
||||
const int offset = event->x();
|
||||
_view.zoom(event->delta() / 80, offset);
|
||||
} else if (event->orientation() == Qt::Horizontal) {
|
||||
// Horizontal scrolling is interpreted as moving left/right
|
||||
_view.set_scale_offset(_view.scale(),
|
||||
event->delta() * _view.scale()
|
||||
+ _view.offset());
|
||||
event->delta() + _view.offset());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -857,22 +902,17 @@ void Viewport::leaveEvent(QEvent *)
|
||||
update();
|
||||
}
|
||||
|
||||
void Viewport::on_traces_moved()
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
void Viewport::set_receive_len(quint64 length)
|
||||
{
|
||||
if (length == 0) {
|
||||
_total_receive_len = 0;
|
||||
_sample_received = 0;
|
||||
start_trigger_timer(333);
|
||||
} else {
|
||||
stop_trigger_timer();
|
||||
if (_total_receive_len + length > _view.session().cur_samplelimits())
|
||||
_total_receive_len = _view.session().cur_samplelimits();
|
||||
if (_sample_received + length > _view.session().cur_samplelimits())
|
||||
_sample_received = _view.session().cur_samplelimits();
|
||||
else
|
||||
_total_receive_len += length;
|
||||
_sample_received += length;
|
||||
}
|
||||
update();
|
||||
}
|
||||
@@ -904,11 +944,10 @@ void Viewport::measure()
|
||||
_mm_period = _thd_sample != 0 ? _view.get_ruler()->format_real_time(_thd_sample - _cur_sample, sample_rate) : "#####";
|
||||
_mm_freq = _thd_sample != 0 ? _view.get_ruler()->format_real_freq(_thd_sample - _cur_sample, sample_rate) : "#####";
|
||||
|
||||
const double pixels_offset = _view.offset() / _view.scale();
|
||||
const double samples_per_pixel = sample_rate * _view.scale();
|
||||
_cur_preX = _cur_sample / samples_per_pixel - pixels_offset;
|
||||
_cur_aftX = _nxt_sample / samples_per_pixel - pixels_offset;
|
||||
_cur_thdX = _thd_sample / samples_per_pixel - pixels_offset;
|
||||
_cur_preX = _cur_sample / samples_per_pixel - _view.offset();
|
||||
_cur_aftX = _nxt_sample / samples_per_pixel - _view.offset();
|
||||
_cur_thdX = _thd_sample / samples_per_pixel - _view.offset();
|
||||
_cur_midY = logicSig->get_y();
|
||||
|
||||
_mm_duty = _thd_sample != 0 ? QString::number((_nxt_sample - _cur_sample) * 100.0 / (_thd_sample - _cur_sample), 'f', 2)+"%" :
|
||||
@@ -923,9 +962,8 @@ void Viewport::measure()
|
||||
}
|
||||
} else if (_action_type == LOGIC_EDGE) {
|
||||
if (logicSig->edges(_view.hover_point(), _edge_start, _edge_rising, _edge_falling)) {
|
||||
const double pixels_offset = _view.offset() / _view.scale();
|
||||
const double samples_per_pixel = sample_rate * _view.scale();
|
||||
_cur_preX = _edge_start / samples_per_pixel - pixels_offset;
|
||||
_cur_preX = _edge_start / samples_per_pixel - _view.offset();
|
||||
_cur_aftX = _view.hover_point().x();
|
||||
_cur_midY = logicSig->get_y() - logicSig->get_totalHeight()/2 - 5;
|
||||
|
||||
@@ -1086,8 +1124,8 @@ void Viewport::paintMeasure(QPainter &p)
|
||||
const int text_height = p.boundingRect(0, 0, INT_MAX, INT_MAX,
|
||||
Qt::AlignLeft | Qt::AlignTop, "W").height();
|
||||
const uint64_t sample_rate = _view.session().cur_samplerate();
|
||||
const double x = (_dso_ym_index / (sample_rate * _view.scale())) -
|
||||
_view.offset() /_view.scale();
|
||||
const int64_t x = (_dso_ym_index / (sample_rate * _view.scale())) -
|
||||
_view.offset();
|
||||
p.drawLine(x-10, _dso_ym_start,
|
||||
x+10, _dso_ym_start);
|
||||
p.drawLine(x, _dso_ym_start,
|
||||
@@ -1135,7 +1173,7 @@ void Viewport::paintMeasure(QPainter &p)
|
||||
QLineF *line;
|
||||
QLineF *const measure_lines = new QLineF[measure_line_count];
|
||||
line = measure_lines;
|
||||
double x[DsoMeasureStages];
|
||||
int64_t x[DsoMeasureStages];
|
||||
int dso_xm_stage = 0;
|
||||
if (_action_type == DSO_XM_STEP1)
|
||||
dso_xm_stage = 1;
|
||||
@@ -1146,18 +1184,18 @@ void Viewport::paintMeasure(QPainter &p)
|
||||
|
||||
for (int i = 0; i < dso_xm_stage; i++) {
|
||||
x[i] = (_dso_xm_index[i] / (sample_rate * _view.scale())) -
|
||||
_view.offset() /_view.scale();
|
||||
_view.offset();
|
||||
}
|
||||
measure_line_count = 0;
|
||||
if (dso_xm_stage > 0) {
|
||||
*line++ = QLineF(x[0], _dso_xm_y - 10,
|
||||
*line++ = QLine(x[0], _dso_xm_y - 10,
|
||||
x[0], _dso_xm_y + 10);
|
||||
measure_line_count += 1;
|
||||
}
|
||||
if (dso_xm_stage > 1) {
|
||||
*line++ = QLineF(x[1], _dso_xm_y - 10,
|
||||
*line++ = QLine(x[1], _dso_xm_y - 10,
|
||||
x[1], _dso_xm_y + 10);
|
||||
*line++ = QLineF(x[0], _dso_xm_y,
|
||||
*line++ = QLine(x[0], _dso_xm_y,
|
||||
x[1], _dso_xm_y);
|
||||
_mm_width = _view.get_ruler()->format_real_time(_dso_xm_index[1] - _dso_xm_index[0], sample_rate);
|
||||
|
||||
@@ -1274,14 +1312,14 @@ void Viewport::set_measure_en(int enable)
|
||||
void Viewport::start_trigger_timer(int msec)
|
||||
{
|
||||
assert(msec > 0);
|
||||
triggered = false;
|
||||
transfer_started = false;
|
||||
timer_cnt = 0;
|
||||
trigger_timer.start(msec);
|
||||
}
|
||||
|
||||
void Viewport::stop_trigger_timer()
|
||||
{
|
||||
triggered = true;
|
||||
transfer_started = true;
|
||||
timer_cnt = 0;
|
||||
trigger_timer.stop();
|
||||
}
|
||||
@@ -1294,13 +1332,13 @@ void Viewport::on_trigger_timer()
|
||||
|
||||
void Viewport::on_drag_timer()
|
||||
{
|
||||
const double offset = _view.offset();
|
||||
const int64_t offset = _view.offset();
|
||||
const double scale = _view.scale();
|
||||
if (_view.session().get_capture_state() == SigSession::Stopped &&
|
||||
_drag_strength != 0 &&
|
||||
offset < _view.get_max_offset() &&
|
||||
offset > _view.get_min_offset()) {
|
||||
_view.set_scale_offset(scale, offset + _drag_strength * scale);
|
||||
_view.set_scale_offset(scale, offset + _drag_strength);
|
||||
_drag_strength /= DragDamping;
|
||||
if (_drag_strength != 0)
|
||||
_drag_timer.start(DragTimerInterval);
|
||||
|
||||
@@ -119,7 +119,6 @@ private:
|
||||
void measure();
|
||||
|
||||
private slots:
|
||||
void on_traces_moved();
|
||||
void on_trigger_timer();
|
||||
void on_drag_timer();
|
||||
void set_receive_len(quint64 length);
|
||||
@@ -130,18 +129,19 @@ public slots:
|
||||
|
||||
signals:
|
||||
void measure_updated();
|
||||
void prgRate(int progress);
|
||||
|
||||
private:
|
||||
View &_view;
|
||||
View_type _type;
|
||||
bool _need_update;
|
||||
|
||||
uint64_t _total_receive_len;
|
||||
uint64_t _sample_received;
|
||||
QPoint _mouse_point;
|
||||
QPoint _mouse_down_point;
|
||||
double _mouse_down_offset;
|
||||
int64_t _mouse_down_offset;
|
||||
double _curScale;
|
||||
double _curOffset;
|
||||
int64_t _curOffset;
|
||||
int _curSignalHeight;
|
||||
|
||||
QPixmap pixmap;
|
||||
@@ -152,10 +152,10 @@ private:
|
||||
uint64_t _cur_sample;
|
||||
uint64_t _nxt_sample;
|
||||
uint64_t _thd_sample;
|
||||
double _cur_preX;
|
||||
double _cur_aftX;
|
||||
double _cur_thdX;
|
||||
double _cur_midY;
|
||||
int64_t _cur_preX;
|
||||
int64_t _cur_aftX;
|
||||
int64_t _cur_thdX;
|
||||
int _cur_midY;
|
||||
QString _mm_width;
|
||||
QString _mm_period;
|
||||
QString _mm_freq;
|
||||
@@ -169,7 +169,7 @@ private:
|
||||
QString _em_edges;
|
||||
|
||||
QTimer trigger_timer;
|
||||
bool triggered;
|
||||
bool transfer_started;
|
||||
int timer_cnt;
|
||||
|
||||
boost::shared_ptr<Signal> _drag_sig;
|
||||
|
||||
@@ -103,5 +103,10 @@ void Border::paintEvent(QPaintEvent *)
|
||||
}
|
||||
}
|
||||
|
||||
void Border::leaveEvent(QEvent*)
|
||||
{
|
||||
//setCursor(Qt::ArrowCursor);
|
||||
}
|
||||
|
||||
} // namespace widgets
|
||||
} // namespace pv
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *);
|
||||
void leaveEvent(QEvent *);
|
||||
|
||||
private:
|
||||
int _type;
|
||||
|
||||
@@ -26,11 +26,14 @@
|
||||
#include <QStyleOption>
|
||||
|
||||
#include "../view/trace.h"
|
||||
#include "../sigsession.h"
|
||||
|
||||
namespace pv {
|
||||
namespace widgets {
|
||||
|
||||
ViewStatus::ViewStatus(QWidget *parent) : QWidget(parent)
|
||||
ViewStatus::ViewStatus(SigSession &session, QWidget *parent) :
|
||||
_session(session),
|
||||
QWidget(parent)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -44,12 +47,28 @@ void ViewStatus::paintEvent(QPaintEvent *)
|
||||
p.setPen(pv::view::Trace::DARK_FORE);
|
||||
p.drawText(this->rect(), Qt::AlignLeft | Qt::AlignVCenter, _rle_depth);
|
||||
p.drawText(this->rect(), Qt::AlignRight | Qt::AlignVCenter, _trig_time);
|
||||
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(pv::view::Trace::dsLightBlue);
|
||||
p.drawRect(this->rect().left(), this->rect().bottom() - 3,
|
||||
_session.get_repeat_hold() * this->rect().width() / 100, 3);
|
||||
|
||||
p.setPen(pv::view::Trace::dsLightBlue);
|
||||
p.drawText(this->rect(), Qt::AlignCenter | Qt::AlignVCenter, _capture_status);
|
||||
}
|
||||
|
||||
void ViewStatus::clear()
|
||||
{
|
||||
_trig_time.clear();
|
||||
_rle_depth.clear();
|
||||
_capture_status.clear();
|
||||
update();
|
||||
}
|
||||
|
||||
void ViewStatus::repeat_unshow()
|
||||
{
|
||||
_capture_status.clear();
|
||||
update();
|
||||
}
|
||||
|
||||
void ViewStatus::set_trig_time(QDateTime time)
|
||||
@@ -59,7 +78,15 @@ void ViewStatus::set_trig_time(QDateTime time)
|
||||
|
||||
void ViewStatus::set_rle_depth(uint64_t depth)
|
||||
{
|
||||
_rle_depth = tr("RLE FULL: ") + QString::number(depth) + tr(" Samples Captured!");
|
||||
_rle_depth = QString::number(depth) + tr(" Samples Captured!");
|
||||
}
|
||||
|
||||
void ViewStatus::set_capture_status(bool triggered, int progess)
|
||||
{
|
||||
if (triggered)
|
||||
_capture_status = tr("Triggered! ") + QString::number(progess) + tr("% Captured");
|
||||
else
|
||||
_capture_status = tr("Waiting for Trigger! ") + QString::number(progess) + tr("% Captured");
|
||||
}
|
||||
|
||||
} // namespace widgets
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <QWidget>
|
||||
#include <QLabel>
|
||||
#include "QDateTime"
|
||||
#include <QDateTime>
|
||||
|
||||
namespace pv {
|
||||
|
||||
@@ -36,7 +36,7 @@ class ViewStatus : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ViewStatus(QWidget *parent = 0);
|
||||
explicit ViewStatus(SigSession &session, QWidget *parent = 0);
|
||||
|
||||
void paintEvent(QPaintEvent *);
|
||||
|
||||
@@ -44,12 +44,17 @@ signals:
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
void repeat_unshow();
|
||||
void set_trig_time(QDateTime time);
|
||||
void set_rle_depth(uint64_t depth);
|
||||
void set_capture_status(bool triggered, int progess);
|
||||
|
||||
private:
|
||||
SigSession &_session;
|
||||
|
||||
QString _trig_time;
|
||||
QString _rle_depth;
|
||||
QString _capture_status;
|
||||
};
|
||||
|
||||
} // namespace widgets
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user