forked from Ivasoft/DSView
Add protocol list viewer and export support
This commit is contained in:
@@ -56,5 +56,6 @@
|
|||||||
<file>icons/start_dis.png</file>
|
<file>icons/start_dis.png</file>
|
||||||
<file>icons/start_dis_cn.png</file>
|
<file>icons/start_dis_cn.png</file>
|
||||||
<file>icons/settings.png</file>
|
<file>icons/settings.png</file>
|
||||||
|
<file>darkstyle/style.qss</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
|||||||
1218
DSView/darkstyle/style.qss
Executable file
1218
DSView/darkstyle/style.qss
Executable file
File diff suppressed because it is too large
Load Diff
@@ -147,7 +147,8 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// Initialise the main window
|
// Initialise the main window
|
||||||
pv::MainWindow w(device_manager, open_file);
|
pv::MainWindow w(device_manager, open_file);
|
||||||
QFile qss(":/stylesheet.qss");
|
//QFile qss(":/stylesheet.qss");
|
||||||
|
QFile qss(":qdarkstyle/style.qss");
|
||||||
qss.open(QFile::ReadOnly);
|
qss.open(QFile::ReadOnly);
|
||||||
a.setStyleSheet(qss.readAll());
|
a.setStyleSheet(qss.readAll());
|
||||||
qss.close();
|
qss.close();
|
||||||
|
|||||||
@@ -49,6 +49,12 @@ Annotation::Annotation(const srd_proto_data *const pdata) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Annotation::Annotation()
|
||||||
|
{
|
||||||
|
_start_sample = 0;
|
||||||
|
_end_sample = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Annotation::~Annotation()
|
Annotation::~Annotation()
|
||||||
{
|
{
|
||||||
_annotations.clear();
|
_annotations.clear();
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ class Annotation
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Annotation(const srd_proto_data *const pdata);
|
Annotation(const srd_proto_data *const pdata);
|
||||||
|
Annotation();
|
||||||
~Annotation();
|
~Annotation();
|
||||||
|
|
||||||
uint64_t start_sample() const;
|
uint64_t start_sample() const;
|
||||||
|
|||||||
@@ -68,8 +68,8 @@ const QString Row::title() const
|
|||||||
|
|
||||||
bool Row::operator<(const Row &other) const
|
bool Row::operator<(const Row &other) const
|
||||||
{
|
{
|
||||||
return (_decoder < other._decoder) ||
|
return (_decoder->name < other._decoder->name) ||
|
||||||
(_decoder == other._decoder && _row < other._row);
|
(_decoder->name == other._decoder->name && _row->desc < other._row->desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // decode
|
} // decode
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ public:
|
|||||||
|
|
||||||
const QString title() const;
|
const QString title() const;
|
||||||
|
|
||||||
bool operator<(const Row &other) const;
|
bool operator<(const Row &other) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const srd_decoder *_decoder;
|
const srd_decoder *_decoder;
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include "rowdata.h"
|
#include "rowdata.h"
|
||||||
|
|
||||||
using std::max;
|
using std::max;
|
||||||
|
using std::min;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
namespace pv {
|
namespace pv {
|
||||||
@@ -30,7 +31,8 @@ namespace data {
|
|||||||
namespace decode {
|
namespace decode {
|
||||||
|
|
||||||
RowData::RowData() :
|
RowData::RowData() :
|
||||||
_max_annotation(0)
|
_max_annotation(0),
|
||||||
|
_min_annotation(UINT64_MAX)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,6 +53,11 @@ uint64_t RowData::get_max_annotation() const
|
|||||||
return _max_annotation;
|
return _max_annotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t RowData::get_min_annotation() const
|
||||||
|
{
|
||||||
|
return _min_annotation;
|
||||||
|
}
|
||||||
|
|
||||||
void RowData::get_annotation_subset(
|
void RowData::get_annotation_subset(
|
||||||
vector<pv::data::decode::Annotation> &dest,
|
vector<pv::data::decode::Annotation> &dest,
|
||||||
uint64_t start_sample, uint64_t end_sample) const
|
uint64_t start_sample, uint64_t end_sample) const
|
||||||
@@ -62,10 +69,33 @@ void RowData::get_annotation_subset(
|
|||||||
dest.push_back(*i);
|
dest.push_back(*i);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RowData::push_annotation(const Annotation &a)
|
bool RowData::push_annotation(const Annotation &a)
|
||||||
{
|
{
|
||||||
_annotations.push_back(a);
|
try {
|
||||||
_max_annotation = max(_max_annotation, a.end_sample() - a.start_sample());
|
_annotations.push_back(a);
|
||||||
|
_max_annotation = max(_max_annotation, a.end_sample() - a.start_sample());
|
||||||
|
if (a.end_sample() != a.start_sample())
|
||||||
|
_min_annotation = min(_min_annotation, a.end_sample() - a.start_sample());
|
||||||
|
return true;
|
||||||
|
} catch (const std::bad_alloc&) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t RowData::get_annotation_size() const
|
||||||
|
{
|
||||||
|
return _annotations.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RowData::get_annotation(Annotation &ann,
|
||||||
|
uint64_t index) const
|
||||||
|
{
|
||||||
|
if (index < _annotations.size()) {
|
||||||
|
ann = _annotations[index];
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // decode
|
} // decode
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public:
|
|||||||
uint64_t get_max_sample() const;
|
uint64_t get_max_sample() const;
|
||||||
|
|
||||||
uint64_t get_max_annotation() const;
|
uint64_t get_max_annotation() const;
|
||||||
|
uint64_t get_min_annotation() const;
|
||||||
/**
|
/**
|
||||||
* Extracts sorted annotations between two period into a vector.
|
* Extracts sorted annotations between two period into a vector.
|
||||||
*/
|
*/
|
||||||
@@ -46,10 +47,16 @@ public:
|
|||||||
std::vector<pv::data::decode::Annotation> &dest,
|
std::vector<pv::data::decode::Annotation> &dest,
|
||||||
uint64_t start_sample, uint64_t end_sample) const;
|
uint64_t start_sample, uint64_t end_sample) const;
|
||||||
|
|
||||||
void push_annotation(const Annotation &a);
|
bool push_annotation(const Annotation &a);
|
||||||
|
|
||||||
|
uint64_t get_annotation_size() const;
|
||||||
|
|
||||||
|
bool get_annotation(pv::data::decode::Annotation &ann,
|
||||||
|
uint64_t index) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint64_t _max_annotation;
|
uint64_t _max_annotation;
|
||||||
|
uint64_t _min_annotation;
|
||||||
std::vector<Annotation> _annotations;
|
std::vector<Annotation> _annotations;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
108
DSView/pv/data/decodermodel.cpp
Normal file
108
DSView/pv/data/decodermodel.cpp
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the DSView project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Andy Deng <andy@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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <libsigrokdecode/libsigrokdecode.h>
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
#include <boost/thread/thread.hpp>
|
||||||
|
|
||||||
|
#include <pv/data/decode/annotation.h>
|
||||||
|
#include <pv/data/decode/rowdata.h>
|
||||||
|
|
||||||
|
#include "decoderstack.h"
|
||||||
|
#include "decodermodel.h"
|
||||||
|
|
||||||
|
using namespace boost;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace pv {
|
||||||
|
namespace data {
|
||||||
|
|
||||||
|
DecoderModel::DecoderModel(QObject *parent)
|
||||||
|
: QAbstractTableModel(parent),
|
||||||
|
_decoder_stack(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DecoderModel::setDecoderStack(boost::shared_ptr<pv::data::DecoderStack> decoder_stack)
|
||||||
|
{
|
||||||
|
beginResetModel();
|
||||||
|
_decoder_stack = decoder_stack;
|
||||||
|
endResetModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
const boost::shared_ptr<pv::data::DecoderStack>& DecoderModel::getDecoderStack() const
|
||||||
|
{
|
||||||
|
return _decoder_stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DecoderModel::rowCount(const QModelIndex & /* parent */) const
|
||||||
|
{
|
||||||
|
if (_decoder_stack)
|
||||||
|
return _decoder_stack->list_annotation_size();
|
||||||
|
else
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
int DecoderModel::columnCount(const QModelIndex & /* parent */) const
|
||||||
|
{
|
||||||
|
if (_decoder_stack)
|
||||||
|
return _decoder_stack->list_rows_size();
|
||||||
|
else
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DecoderModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
if (role == Qt::TextAlignmentRole) {
|
||||||
|
return int(Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
|
} else if (role == Qt::DisplayRole) {
|
||||||
|
if (_decoder_stack) {
|
||||||
|
pv::data::decode::Annotation ann;
|
||||||
|
if (_decoder_stack->list_annotation(ann, index.column(), index.row())) {
|
||||||
|
return ann.annotations().at(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DecoderModel::headerData(int section,
|
||||||
|
Qt::Orientation orientation,
|
||||||
|
int role) const
|
||||||
|
{
|
||||||
|
if (role != Qt::DisplayRole)
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
if (orientation == Qt::Vertical)
|
||||||
|
return section;
|
||||||
|
|
||||||
|
if (_decoder_stack) {
|
||||||
|
QString title;
|
||||||
|
if (_decoder_stack->list_row_title(section, title))
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace data
|
||||||
|
} // namespace pv
|
||||||
62
DSView/pv/data/decodermodel.h
Normal file
62
DSView/pv/data/decodermodel.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the DSView project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Andy Deng <andy@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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef DSVIEW_PV_DATA_DECODERMODEL_H
|
||||||
|
#define DSVIEW_PV_DATA_DECODERMODEL_H
|
||||||
|
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
#include <pv/data/decode/rowdata.h>
|
||||||
|
|
||||||
|
namespace pv {
|
||||||
|
namespace data {
|
||||||
|
|
||||||
|
class DecoderStack;
|
||||||
|
|
||||||
|
namespace decode {
|
||||||
|
class Annotation;
|
||||||
|
class Decoder;
|
||||||
|
class Row;
|
||||||
|
}
|
||||||
|
|
||||||
|
class DecoderModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
DecoderModel(QObject *parent = 0);
|
||||||
|
|
||||||
|
int rowCount(const QModelIndex &parent) const;
|
||||||
|
int columnCount(const QModelIndex &parent) const;
|
||||||
|
QVariant data(const QModelIndex &index, int role) const;
|
||||||
|
QVariant headerData(int section, Qt::Orientation orientation,
|
||||||
|
int role) const;
|
||||||
|
|
||||||
|
void setDecoderStack(boost::shared_ptr<pv::data::DecoderStack> decoder_stack);
|
||||||
|
const boost::shared_ptr<pv::data::DecoderStack>& getDecoderStack() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
boost::shared_ptr<pv::data::DecoderStack> _decoder_stack;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace data
|
||||||
|
} // namespace pv
|
||||||
|
|
||||||
|
#endif // DSVIEW_PV_DATA_DECODERMODEL_H
|
||||||
@@ -68,7 +68,8 @@ DecoderStack::DecoderStack(pv::SigSession &session,
|
|||||||
_frame_complete(false),
|
_frame_complete(false),
|
||||||
_samples_decoded(0),
|
_samples_decoded(0),
|
||||||
_decode_state(Stopped),
|
_decode_state(Stopped),
|
||||||
_options_changed(false)
|
_options_changed(false),
|
||||||
|
_no_memory(false)
|
||||||
{
|
{
|
||||||
connect(&_session, SIGNAL(frame_began()),
|
connect(&_session, SIGNAL(frame_began()),
|
||||||
this, SLOT(on_new_frame()));
|
this, SLOT(on_new_frame()));
|
||||||
@@ -79,6 +80,8 @@ DecoderStack::DecoderStack(pv::SigSession &session,
|
|||||||
|
|
||||||
_stack.push_back(shared_ptr<decode::Decoder>(
|
_stack.push_back(shared_ptr<decode::Decoder>(
|
||||||
new decode::Decoder(dec)));
|
new decode::Decoder(dec)));
|
||||||
|
|
||||||
|
build_row();
|
||||||
}
|
}
|
||||||
|
|
||||||
DecoderStack::~DecoderStack()
|
DecoderStack::~DecoderStack()
|
||||||
@@ -89,7 +92,10 @@ DecoderStack::~DecoderStack()
|
|||||||
// }
|
// }
|
||||||
stop_decode();
|
stop_decode();
|
||||||
_stack.clear();
|
_stack.clear();
|
||||||
clear();
|
_rows.clear();
|
||||||
|
_rows_gshow.clear();
|
||||||
|
_rows_lshow.clear();
|
||||||
|
_class_rows.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::list< boost::shared_ptr<decode::Decoder> >&
|
const std::list< boost::shared_ptr<decode::Decoder> >&
|
||||||
@@ -102,20 +108,83 @@ void DecoderStack::push(boost::shared_ptr<decode::Decoder> decoder)
|
|||||||
{
|
{
|
||||||
assert(decoder);
|
assert(decoder);
|
||||||
_stack.push_back(decoder);
|
_stack.push_back(decoder);
|
||||||
|
build_row();
|
||||||
|
_options_changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecoderStack::remove(int index)
|
void DecoderStack::remove(boost::shared_ptr<Decoder> &decoder)
|
||||||
{
|
{
|
||||||
assert(index >= 0);
|
|
||||||
assert(index < (int)_stack.size());
|
|
||||||
|
|
||||||
// Find the decoder in the stack
|
// Find the decoder in the stack
|
||||||
list< shared_ptr<Decoder> >::iterator iter = _stack.begin();
|
list< shared_ptr<Decoder> >::iterator iter = _stack.begin();
|
||||||
for(int i = 0; i < index; i++, iter++)
|
for(int i = 0; i < _stack.size(); i++, iter++)
|
||||||
assert(iter != _stack.end());
|
if ((*iter) == decoder)
|
||||||
|
break;
|
||||||
|
|
||||||
// Delete the element
|
// Delete the element
|
||||||
_stack.erase(iter);
|
if (iter != _stack.end())
|
||||||
|
_stack.erase(iter);
|
||||||
|
|
||||||
|
build_row();
|
||||||
|
_options_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DecoderStack::build_row()
|
||||||
|
{
|
||||||
|
_rows.clear();
|
||||||
|
// Add classes
|
||||||
|
BOOST_FOREACH (const shared_ptr<decode::Decoder> &dec, _stack)
|
||||||
|
{
|
||||||
|
assert(dec);
|
||||||
|
const srd_decoder *const decc = dec->decoder();
|
||||||
|
assert(dec->decoder());
|
||||||
|
|
||||||
|
// Add a row for the decoder if it doesn't have a row list
|
||||||
|
if (!decc->annotation_rows) {
|
||||||
|
const Row row(decc);
|
||||||
|
_rows[row] = decode::RowData();
|
||||||
|
std::map<const decode::Row, bool>::const_iterator iter = _rows_gshow.find(row);
|
||||||
|
if (iter == _rows_gshow.end()) {
|
||||||
|
if (row.title().contains("bit", Qt::CaseInsensitive) ||
|
||||||
|
row.title().contains("warning", Qt::CaseInsensitive)) {
|
||||||
|
_rows_gshow[row] = false;
|
||||||
|
_rows_lshow[row] = false;
|
||||||
|
} else {
|
||||||
|
_rows_gshow[row] = true;
|
||||||
|
_rows_lshow[row] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the decoder rows
|
||||||
|
for (const GSList *l = decc->annotation_rows; l; l = l->next)
|
||||||
|
{
|
||||||
|
const srd_decoder_annotation_row *const ann_row =
|
||||||
|
(srd_decoder_annotation_row *)l->data;
|
||||||
|
assert(ann_row);
|
||||||
|
|
||||||
|
const Row row(decc, ann_row);
|
||||||
|
|
||||||
|
// Add a new empty row data object
|
||||||
|
_rows[row] = decode::RowData();
|
||||||
|
std::map<const decode::Row, bool>::const_iterator iter = _rows_gshow.find(row);
|
||||||
|
if (iter == _rows_gshow.end()) {
|
||||||
|
if (row.title().contains("bit", Qt::CaseInsensitive) ||
|
||||||
|
row.title().contains("warning", Qt::CaseInsensitive)) {
|
||||||
|
_rows_gshow[row] = false;
|
||||||
|
_rows_lshow[row] = false;
|
||||||
|
} else {
|
||||||
|
_rows_gshow[row] = true;
|
||||||
|
_rows_lshow[row] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map out all the classes
|
||||||
|
for (const GSList *ll = ann_row->ann_classes;
|
||||||
|
ll; ll = ll->next)
|
||||||
|
_class_rows[make_pair(decc,
|
||||||
|
GPOINTER_TO_INT(ll->data))] = row;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t DecoderStack::samples_decoded() const
|
int64_t DecoderStack::samples_decoded() const
|
||||||
@@ -124,36 +193,6 @@ int64_t DecoderStack::samples_decoded() const
|
|||||||
return _samples_decoded;
|
return _samples_decoded;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector< std::pair<decode::Row, bool> > DecoderStack::get_visible_rows() const
|
|
||||||
{
|
|
||||||
lock_guard<mutex> lock(_output_mutex);
|
|
||||||
|
|
||||||
std::vector< std::pair<decode::Row, bool> > rows;
|
|
||||||
|
|
||||||
BOOST_FOREACH (const shared_ptr<decode::Decoder> &dec, _stack)
|
|
||||||
{
|
|
||||||
assert(dec);
|
|
||||||
|
|
||||||
const srd_decoder *const decc = dec->decoder();
|
|
||||||
assert(dec->decoder());
|
|
||||||
|
|
||||||
// Add a row for the decoder if it doesn't have a row list
|
|
||||||
if (!decc->annotation_rows)
|
|
||||||
rows.push_back(make_pair(Row(decc), dec->shown()));
|
|
||||||
|
|
||||||
// Add the decoder rows
|
|
||||||
for (const GSList *l = decc->annotation_rows; l; l = l->next)
|
|
||||||
{
|
|
||||||
const srd_decoder_annotation_row *const ann_row =
|
|
||||||
(srd_decoder_annotation_row *)l->data;
|
|
||||||
assert(ann_row);
|
|
||||||
rows.push_back(make_pair(Row(decc, ann_row), dec->shown()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return rows;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DecoderStack::get_annotation_subset(
|
void DecoderStack::get_annotation_subset(
|
||||||
std::vector<pv::data::decode::Annotation> &dest,
|
std::vector<pv::data::decode::Annotation> &dest,
|
||||||
const Row &row, uint64_t start_sample,
|
const Row &row, uint64_t start_sample,
|
||||||
@@ -161,9 +200,9 @@ void DecoderStack::get_annotation_subset(
|
|||||||
{
|
{
|
||||||
lock_guard<mutex> lock(_output_mutex);
|
lock_guard<mutex> lock(_output_mutex);
|
||||||
|
|
||||||
std::map<const Row, decode::RowData>::const_iterator iter =
|
std::map<const Row, decode::RowData>::const_iterator iter =
|
||||||
_rows.find(row);
|
_rows.find(row);
|
||||||
if (iter != _rows.end())
|
if (iter != _rows.end())
|
||||||
(*iter).second.get_annotation_subset(dest,
|
(*iter).second.get_annotation_subset(dest,
|
||||||
start_sample, end_sample);
|
start_sample, end_sample);
|
||||||
}
|
}
|
||||||
@@ -180,6 +219,44 @@ uint64_t DecoderStack::get_max_annotation(const Row &row)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t DecoderStack::get_min_annotation(const Row &row)
|
||||||
|
{
|
||||||
|
lock_guard<mutex> lock(_output_mutex);
|
||||||
|
|
||||||
|
std::map<const Row, decode::RowData>::const_iterator iter =
|
||||||
|
_rows.find(row);
|
||||||
|
if (iter != _rows.end())
|
||||||
|
return (*iter).second.get_min_annotation();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<const decode::Row, bool>& DecoderStack::get_rows_gshow()
|
||||||
|
{
|
||||||
|
return _rows_gshow;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<const decode::Row, bool>& DecoderStack::get_rows_lshow()
|
||||||
|
{
|
||||||
|
return _rows_lshow;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DecoderStack::set_rows_gshow(const decode::Row row, bool show)
|
||||||
|
{
|
||||||
|
std::map<const decode::Row, bool>::const_iterator iter = _rows_gshow.find(row);
|
||||||
|
if (iter != _rows_gshow.end()) {
|
||||||
|
_rows_gshow[row] = show;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DecoderStack::set_rows_lshow(const decode::Row row, bool show)
|
||||||
|
{
|
||||||
|
std::map<const decode::Row, bool>::const_iterator iter = _rows_lshow.find(row);
|
||||||
|
if (iter != _rows_lshow.end()) {
|
||||||
|
_rows_lshow[row] = show;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool DecoderStack::has_annotations(const Row &row) const
|
bool DecoderStack::has_annotations(const Row &row) const
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(_output_mutex);
|
lock_guard<mutex> lock(_output_mutex);
|
||||||
@@ -195,6 +272,55 @@ bool DecoderStack::has_annotations(const Row &row) const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t DecoderStack::list_annotation_size() const
|
||||||
|
{
|
||||||
|
uint64_t max_annotation_size = 0;
|
||||||
|
int row = 0;
|
||||||
|
for (map<const Row, RowData>::const_iterator i = _rows.begin();
|
||||||
|
i != _rows.end(); i++) {
|
||||||
|
map<const Row, bool>::const_iterator iter = _rows_lshow.find((*i).first);
|
||||||
|
if (iter != _rows_lshow.end() && (*iter).second)
|
||||||
|
max_annotation_size = max(max_annotation_size,
|
||||||
|
(*i).second.get_annotation_size());
|
||||||
|
}
|
||||||
|
|
||||||
|
return max_annotation_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DecoderStack::list_annotation(pv::data::decode::Annotation &ann,
|
||||||
|
uint16_t row_index, uint64_t col_index) const
|
||||||
|
{
|
||||||
|
int row = 0;
|
||||||
|
for (map<const Row, RowData>::const_iterator i = _rows.begin();
|
||||||
|
i != _rows.end(); i++) {
|
||||||
|
map<const Row, bool>::const_iterator iter = _rows_lshow.find((*i).first);
|
||||||
|
if (iter != _rows_lshow.end() && (*iter).second) {
|
||||||
|
if (row_index-- == 0) {
|
||||||
|
return (*i).second.get_annotation(ann, col_index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DecoderStack::list_row_title(int row, QString &title) const
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
for (map<const Row, RowData>::const_iterator i = _rows.begin();
|
||||||
|
i != _rows.end(); i++) {
|
||||||
|
map<const Row, bool>::const_iterator iter = _rows_lshow.find((*i).first);
|
||||||
|
if (iter != _rows_lshow.end() && (*iter).second) {
|
||||||
|
if (row-- == 0) {
|
||||||
|
title = (*i).first.title();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
QString DecoderStack::error_message()
|
QString DecoderStack::error_message()
|
||||||
{
|
{
|
||||||
lock_guard<mutex> lock(_output_mutex);
|
lock_guard<mutex> lock(_output_mutex);
|
||||||
@@ -207,16 +333,20 @@ void DecoderStack::clear()
|
|||||||
_frame_complete = false;
|
_frame_complete = false;
|
||||||
_samples_decoded = 0;
|
_samples_decoded = 0;
|
||||||
_error_message = QString();
|
_error_message = QString();
|
||||||
_rows.clear();
|
for (map<const Row, RowData>::const_iterator i = _rows.begin();
|
||||||
_class_rows.clear();
|
i != _rows.end(); i++)
|
||||||
|
_rows[(*i).first] = decode::RowData();
|
||||||
|
_no_memory = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecoderStack::stop_decode()
|
void DecoderStack::stop_decode()
|
||||||
{
|
{
|
||||||
_snapshot.reset();
|
_snapshot.reset();
|
||||||
|
|
||||||
if(_decode_state == Stopped)
|
if(_decode_state == Stopped) {
|
||||||
|
clear();
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (_decode_thread.get()) {
|
if (_decode_thread.get()) {
|
||||||
_decode_thread->interrupt();
|
_decode_thread->interrupt();
|
||||||
@@ -224,6 +354,7 @@ void DecoderStack::stop_decode()
|
|||||||
_decode_state = Stopped;
|
_decode_state = Stopped;
|
||||||
}
|
}
|
||||||
_decode_thread.reset();
|
_decode_thread.reset();
|
||||||
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecoderStack::begin_decode()
|
void DecoderStack::begin_decode()
|
||||||
@@ -239,8 +370,6 @@ void DecoderStack::begin_decode()
|
|||||||
// }
|
// }
|
||||||
stop_decode();
|
stop_decode();
|
||||||
|
|
||||||
clear();
|
|
||||||
|
|
||||||
// Check that all decoders have the required channels
|
// Check that all decoders have the required channels
|
||||||
BOOST_FOREACH(const shared_ptr<decode::Decoder> &dec, _stack)
|
BOOST_FOREACH(const shared_ptr<decode::Decoder> &dec, _stack)
|
||||||
if (!dec->have_required_probes()) {
|
if (!dec->have_required_probes()) {
|
||||||
@@ -249,37 +378,6 @@ void DecoderStack::begin_decode()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add classes
|
|
||||||
BOOST_FOREACH (const shared_ptr<decode::Decoder> &dec, _stack)
|
|
||||||
{
|
|
||||||
assert(dec);
|
|
||||||
const srd_decoder *const decc = dec->decoder();
|
|
||||||
assert(dec->decoder());
|
|
||||||
|
|
||||||
// Add a row for the decoder if it doesn't have a row list
|
|
||||||
if (!decc->annotation_rows)
|
|
||||||
_rows[Row(decc)] = decode::RowData();
|
|
||||||
|
|
||||||
// Add the decoder rows
|
|
||||||
for (const GSList *l = decc->annotation_rows; l; l = l->next)
|
|
||||||
{
|
|
||||||
const srd_decoder_annotation_row *const ann_row =
|
|
||||||
(srd_decoder_annotation_row *)l->data;
|
|
||||||
assert(ann_row);
|
|
||||||
|
|
||||||
const Row row(decc, ann_row);
|
|
||||||
|
|
||||||
// Add a new empty row data object
|
|
||||||
_rows[row] = decode::RowData();
|
|
||||||
|
|
||||||
// Map out all the classes
|
|
||||||
for (const GSList *ll = ann_row->ann_classes;
|
|
||||||
ll; ll = ll->next)
|
|
||||||
_class_rows[make_pair(decc,
|
|
||||||
GPOINTER_TO_INT(ll->data))] = row;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// We get the logic data of the first channel in the list.
|
// We get the logic data of the first channel in the list.
|
||||||
// This works because we are currently assuming all
|
// This works because we are currently assuming all
|
||||||
// LogicSignals have the same data/snapshot
|
// LogicSignals have the same data/snapshot
|
||||||
@@ -313,8 +411,8 @@ uint64_t DecoderStack::get_max_sample_count() const
|
|||||||
{
|
{
|
||||||
uint64_t max_sample_count = 0;
|
uint64_t max_sample_count = 0;
|
||||||
|
|
||||||
for (map<const Row, RowData>::const_iterator i = _rows.begin();
|
for (map<const Row, RowData>::const_iterator i = _rows.begin();
|
||||||
i != _rows.end(); i++)
|
i != _rows.end(); i++)
|
||||||
max_sample_count = max(max_sample_count,
|
max_sample_count = max(max_sample_count,
|
||||||
(*i).second.get_max_sample());
|
(*i).second.get_max_sample());
|
||||||
|
|
||||||
@@ -333,48 +431,6 @@ boost::optional<uint64_t> DecoderStack::wait_for_data() const
|
|||||||
_sample_count);
|
_sample_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
//void DecoderStack::decode_data(
|
|
||||||
// const uint64_t sample_count, const unsigned int unit_size,
|
|
||||||
// srd_session *const session)
|
|
||||||
//{
|
|
||||||
// //uint8_t chunk[DecodeChunkLength];
|
|
||||||
// uint8_t *chunk = NULL;
|
|
||||||
// //chunk = (uint8_t *)realloc(chunk, DecodeChunkLength);
|
|
||||||
|
|
||||||
// const uint64_t chunk_sample_count =
|
|
||||||
// DecodeChunkLength / _snapshot->unit_size();
|
|
||||||
|
|
||||||
// for (uint64_t i = 0;
|
|
||||||
// !boost::this_thread::interruption_requested() &&
|
|
||||||
// i < sample_count;
|
|
||||||
// i += chunk_sample_count)
|
|
||||||
// {
|
|
||||||
// //lock_guard<mutex> decode_lock(_global_decode_mutex);
|
|
||||||
|
|
||||||
// const uint64_t chunk_end = min(
|
|
||||||
// i + chunk_sample_count, sample_count);
|
|
||||||
// chunk = _snapshot->get_samples(i, chunk_end);
|
|
||||||
|
|
||||||
// if (srd_session_send(session, i, i + sample_count, chunk,
|
|
||||||
// (chunk_end - i) * unit_size, unit_size) != SRD_OK) {
|
|
||||||
// _error_message = tr("Decoder reported an error");
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// {
|
|
||||||
// lock_guard<mutex> lock(_output_mutex);
|
|
||||||
// _samples_decoded = chunk_end;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (i % DecodeNotifyPeriod == 0)
|
|
||||||
// new_decode_data();
|
|
||||||
|
|
||||||
// }
|
|
||||||
// _options_changed = false;
|
|
||||||
// decode_done();
|
|
||||||
// //new_decode_data();
|
|
||||||
//}
|
|
||||||
|
|
||||||
void DecoderStack::decode_data(
|
void DecoderStack::decode_data(
|
||||||
const uint64_t decode_start, const uint64_t decode_end,
|
const uint64_t decode_start, const uint64_t decode_end,
|
||||||
const unsigned int unit_size, srd_session *const session)
|
const unsigned int unit_size, srd_session *const session)
|
||||||
@@ -386,7 +442,7 @@ void DecoderStack::decode_data(
|
|||||||
|
|
||||||
for (uint64_t i = decode_start;
|
for (uint64_t i = decode_start;
|
||||||
!boost::this_thread::interruption_requested() &&
|
!boost::this_thread::interruption_requested() &&
|
||||||
i < decode_end;
|
i < decode_end && !_no_memory;
|
||||||
i += chunk_sample_count)
|
i += chunk_sample_count)
|
||||||
{
|
{
|
||||||
//lock_guard<mutex> decode_lock(_global_decode_mutex);
|
//lock_guard<mutex> decode_lock(_global_decode_mutex);
|
||||||
@@ -490,6 +546,11 @@ uint64_t DecoderStack::sample_count() const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64_t DecoderStack::sample_rate() const
|
||||||
|
{
|
||||||
|
return _samplerate;
|
||||||
|
}
|
||||||
|
|
||||||
void DecoderStack::annotation_callback(srd_proto_data *pdata, void *decoder)
|
void DecoderStack::annotation_callback(srd_proto_data *pdata, void *decoder)
|
||||||
{
|
{
|
||||||
assert(pdata);
|
assert(pdata);
|
||||||
@@ -500,6 +561,9 @@ void DecoderStack::annotation_callback(srd_proto_data *pdata, void *decoder)
|
|||||||
|
|
||||||
lock_guard<mutex> lock(d->_output_mutex);
|
lock_guard<mutex> lock(d->_output_mutex);
|
||||||
|
|
||||||
|
if (d->_no_memory)
|
||||||
|
return;
|
||||||
|
|
||||||
const Annotation a(pdata);
|
const Annotation a(pdata);
|
||||||
|
|
||||||
// Find the row
|
// Find the row
|
||||||
@@ -508,21 +572,21 @@ void DecoderStack::annotation_callback(srd_proto_data *pdata, void *decoder)
|
|||||||
const srd_decoder *const decc = pdata->pdo->di->decoder;
|
const srd_decoder *const decc = pdata->pdo->di->decoder;
|
||||||
assert(decc);
|
assert(decc);
|
||||||
|
|
||||||
map<const Row, decode::RowData>::iterator row_iter = d->_rows.end();
|
map<const Row, decode::RowData>::iterator row_iter = d->_rows.end();
|
||||||
|
|
||||||
// Try looking up the sub-row of this class
|
// Try looking up the sub-row of this class
|
||||||
const map<pair<const srd_decoder*, int>, Row>::const_iterator r =
|
const map<pair<const srd_decoder*, int>, Row>::const_iterator r =
|
||||||
d->_class_rows.find(make_pair(decc, a.format()));
|
d->_class_rows.find(make_pair(decc, a.format()));
|
||||||
if (r != d->_class_rows.end())
|
if (r != d->_class_rows.end())
|
||||||
row_iter = d->_rows.find((*r).second);
|
row_iter = d->_rows.find((*r).second);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Failing that, use the decoder as a key
|
// Failing that, use the decoder as a key
|
||||||
row_iter = d->_rows.find(Row(decc));
|
row_iter = d->_rows.find(Row(decc));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(row_iter != d->_rows.end());
|
assert(row_iter != d->_rows.end());
|
||||||
if (row_iter == d->_rows.end()) {
|
if (row_iter == d->_rows.end()) {
|
||||||
qDebug() << "Unexpected annotation: decoder = " << decc <<
|
qDebug() << "Unexpected annotation: decoder = " << decc <<
|
||||||
", format = " << a.format();
|
", format = " << a.format();
|
||||||
assert(0);
|
assert(0);
|
||||||
@@ -530,7 +594,8 @@ void DecoderStack::annotation_callback(srd_proto_data *pdata, void *decoder)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add the annotation
|
// Add the annotation
|
||||||
(*row_iter).second.push_annotation(a);
|
if (!(*row_iter).second.push_annotation(a))
|
||||||
|
d->_no_memory = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecoderStack::on_new_frame()
|
void DecoderStack::on_new_frame()
|
||||||
@@ -560,21 +625,25 @@ void DecoderStack::on_frame_ended()
|
|||||||
begin_decode();
|
begin_decode();
|
||||||
}
|
}
|
||||||
|
|
||||||
int DecoderStack::cur_rows_size()
|
int DecoderStack::list_rows_size()
|
||||||
{
|
{
|
||||||
int rows_size = 0;
|
int rows_size = 0;
|
||||||
|
int row = 0;
|
||||||
for (map<const Row, RowData>::const_iterator i = _rows.begin();
|
for (map<const Row, RowData>::const_iterator i = _rows.begin();
|
||||||
i != _rows.end(); i++)
|
i != _rows.end(); i++) {
|
||||||
if ((*i).second.get_max_sample() != 0)
|
map<const Row, bool>::const_iterator iter = _rows_lshow.find((*i).first);
|
||||||
|
if (iter != _rows_lshow.end() && (*iter).second)
|
||||||
rows_size++;
|
rows_size++;
|
||||||
|
}
|
||||||
if (rows_size == 0)
|
return rows_size;
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return rows_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecoderStack::options_changed(bool changed)
|
bool DecoderStack::options_changed() const
|
||||||
|
{
|
||||||
|
return _options_changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DecoderStack::set_options_changed(bool changed)
|
||||||
{
|
{
|
||||||
_options_changed = changed;
|
_options_changed = changed;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,14 +86,13 @@ public:
|
|||||||
|
|
||||||
virtual ~DecoderStack();
|
virtual ~DecoderStack();
|
||||||
|
|
||||||
const std::list< boost::shared_ptr<decode::Decoder> >& stack() const;
|
const std::list< boost::shared_ptr<decode::Decoder> >& stack() const;
|
||||||
void push(boost::shared_ptr<decode::Decoder> decoder);
|
void push(boost::shared_ptr<decode::Decoder> decoder);
|
||||||
void remove(int index);
|
void remove(boost::shared_ptr<decode::Decoder>& decoder);
|
||||||
|
void build_row();
|
||||||
|
|
||||||
int64_t samples_decoded() const;
|
int64_t samples_decoded() const;
|
||||||
|
|
||||||
std::vector< std::pair<decode::Row, bool> > get_visible_rows() const;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts sorted annotations between two period into a vector.
|
* Extracts sorted annotations between two period into a vector.
|
||||||
*/
|
*/
|
||||||
@@ -103,9 +102,23 @@ public:
|
|||||||
uint64_t end_sample) const;
|
uint64_t end_sample) const;
|
||||||
|
|
||||||
uint64_t get_max_annotation(const decode::Row &row);
|
uint64_t get_max_annotation(const decode::Row &row);
|
||||||
|
uint64_t get_min_annotation(const decode::Row &row); // except instant(end=start) annotation
|
||||||
|
|
||||||
|
std::map<const decode::Row, bool> &get_rows_gshow();
|
||||||
|
std::map<const decode::Row, bool> &get_rows_lshow();
|
||||||
|
void set_rows_gshow(const decode::Row row, bool show);
|
||||||
|
void set_rows_lshow(const decode::Row row, bool show);
|
||||||
|
|
||||||
bool has_annotations(const decode::Row &row) const;
|
bool has_annotations(const decode::Row &row) const;
|
||||||
|
|
||||||
|
uint64_t list_annotation_size() const;
|
||||||
|
|
||||||
|
bool list_annotation(decode::Annotation &ann,
|
||||||
|
uint16_t row_index, uint64_t col_index) const;
|
||||||
|
|
||||||
|
|
||||||
|
bool list_row_title(int row, QString &title) const;
|
||||||
|
|
||||||
QString error_message();
|
QString error_message();
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
@@ -116,11 +129,13 @@ public:
|
|||||||
|
|
||||||
void stop_decode();
|
void stop_decode();
|
||||||
|
|
||||||
int cur_rows_size();
|
int list_rows_size();
|
||||||
|
|
||||||
void options_changed(bool changed);
|
bool options_changed() const;
|
||||||
|
void set_options_changed(bool changed);
|
||||||
|
|
||||||
uint64_t sample_count() const;
|
uint64_t sample_count() const;
|
||||||
|
uint64_t sample_rate() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::optional<uint64_t> wait_for_data() const;
|
boost::optional<uint64_t> wait_for_data() const;
|
||||||
@@ -170,9 +185,10 @@ private:
|
|||||||
mutable boost::mutex _output_mutex;
|
mutable boost::mutex _output_mutex;
|
||||||
int64_t _samples_decoded;
|
int64_t _samples_decoded;
|
||||||
|
|
||||||
std::map<const decode::Row, decode::RowData> _rows;
|
std::map<const decode::Row, decode::RowData> _rows;
|
||||||
|
std::map<const decode::Row, bool> _rows_gshow;
|
||||||
std::map<std::pair<const srd_decoder*, int>, decode::Row> _class_rows;
|
std::map<const decode::Row, bool> _rows_lshow;
|
||||||
|
std::map<std::pair<const srd_decoder*, int>, decode::Row> _class_rows;
|
||||||
|
|
||||||
QString _error_message;
|
QString _error_message;
|
||||||
|
|
||||||
@@ -180,6 +196,7 @@ private:
|
|||||||
decode_state _decode_state;
|
decode_state _decode_state;
|
||||||
|
|
||||||
bool _options_changed;
|
bool _options_changed;
|
||||||
|
bool _no_memory;
|
||||||
|
|
||||||
friend class DecoderStackTest::TwoDecoderStack;
|
friend class DecoderStackTest::TwoDecoderStack;
|
||||||
};
|
};
|
||||||
|
|||||||
215
DSView/pv/dialogs/protocolexp.cpp
Normal file
215
DSView/pv/dialogs/protocolexp.cpp
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the DSView project.
|
||||||
|
* DSView is based on PulseView.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||||
|
* Copyright (C) 2013 DreamSourceLab <dreamsourcelab@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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "protocolexp.h"
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QMessageBox>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QFileDialog>
|
||||||
|
#include <QTextStream>
|
||||||
|
#include <QProgressDialog>
|
||||||
|
#include <QFuture>
|
||||||
|
#include <QtConcurrent/QtConcurrent>
|
||||||
|
|
||||||
|
#include "../sigsession.h"
|
||||||
|
#include "../data/decoderstack.h"
|
||||||
|
#include "../data/decode/row.h"
|
||||||
|
#include "../data/decode/annotation.h"
|
||||||
|
#include "../view/decodetrace.h"
|
||||||
|
#include "../data/decodermodel.h"
|
||||||
|
|
||||||
|
using namespace boost;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace pv {
|
||||||
|
namespace dialogs {
|
||||||
|
|
||||||
|
ProtocolExp::ProtocolExp(QWidget *parent, SigSession &session) :
|
||||||
|
QDialog(parent),
|
||||||
|
_session(session),
|
||||||
|
_button_box(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
|
||||||
|
Qt::Horizontal, this),
|
||||||
|
_export_cancel(false)
|
||||||
|
{
|
||||||
|
_format_combobox = new QComboBox(this);
|
||||||
|
_format_combobox->addItem(tr("Comma-Separated Values (*.csv)"));
|
||||||
|
_format_combobox->addItem(tr("Text files (*.txt)"));
|
||||||
|
|
||||||
|
_flayout = new QFormLayout();
|
||||||
|
_flayout->addRow(new QLabel(tr("Export Format: "), this), _format_combobox);
|
||||||
|
|
||||||
|
pv::data::DecoderModel* decoder_model = _session.get_decoder_model();
|
||||||
|
const boost::shared_ptr<pv::data::DecoderStack>& decoder_stack = decoder_model->getDecoderStack();
|
||||||
|
if (decoder_stack) {
|
||||||
|
int row_index = 0;
|
||||||
|
const std::map<const pv::data::decode::Row, bool>& rows(decoder_stack->get_rows_lshow());
|
||||||
|
for (std::map<const pv::data::decode::Row, bool>::const_iterator i = rows.begin();
|
||||||
|
i != rows.end(); i++) {
|
||||||
|
if ((*i).second) {
|
||||||
|
QLabel *row_label = new QLabel((*i).first.title(), this);
|
||||||
|
QRadioButton *row_sel = new QRadioButton(this);
|
||||||
|
if (row_index == 0) {
|
||||||
|
row_sel->setChecked(true);
|
||||||
|
}
|
||||||
|
_row_label_list.push_back(row_label);
|
||||||
|
_row_sel_list.push_back(row_sel);
|
||||||
|
_flayout->addRow(row_label, row_sel);
|
||||||
|
row_sel->setProperty("index", row_index);
|
||||||
|
row_sel->setProperty("title", (*i).first.title());
|
||||||
|
row_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_layout = new QVBoxLayout(this);
|
||||||
|
_layout->addLayout(_flayout);
|
||||||
|
_layout->addWidget(&_button_box);
|
||||||
|
setLayout(_layout);
|
||||||
|
|
||||||
|
connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept()));
|
||||||
|
connect(&_button_box, SIGNAL(rejected()), this, SLOT(reject()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolExp::accept()
|
||||||
|
{
|
||||||
|
using namespace Qt;
|
||||||
|
using namespace pv::data::decode;
|
||||||
|
|
||||||
|
QDialog::accept();
|
||||||
|
|
||||||
|
if (!_row_sel_list.empty()) {
|
||||||
|
QList<QString> supportedFormats;
|
||||||
|
for (int i = _format_combobox->count() - 1; i >= 0; i--) {
|
||||||
|
supportedFormats.push_back(_format_combobox->itemText(i));
|
||||||
|
}
|
||||||
|
QString filter;
|
||||||
|
for(int i = 0; i < supportedFormats.count();i++){
|
||||||
|
filter.append(supportedFormats[i]);
|
||||||
|
if(i < supportedFormats.count() - 1)
|
||||||
|
filter.append(";;");
|
||||||
|
}
|
||||||
|
QString default_filter = _format_combobox->currentText();
|
||||||
|
QString file_name = QFileDialog::getSaveFileName(
|
||||||
|
this, tr("Export Data"), "",filter,&default_filter);
|
||||||
|
if (!file_name.isEmpty()) {
|
||||||
|
QFileInfo f(file_name);
|
||||||
|
QStringList list = default_filter.split('.').last().split(')');
|
||||||
|
QString ext = list.first();
|
||||||
|
if(f.suffix().compare(ext))
|
||||||
|
file_name+=tr(".")+ext;
|
||||||
|
|
||||||
|
QFile file(file_name);
|
||||||
|
file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||||
|
QTextStream out(&file);
|
||||||
|
out.setCodec("UTF-8");
|
||||||
|
out.setGenerateByteOrderMark(true);
|
||||||
|
|
||||||
|
QFuture<void> future;
|
||||||
|
future = QtConcurrent::run([&]{
|
||||||
|
_export_cancel = false;
|
||||||
|
QString title;
|
||||||
|
int index;
|
||||||
|
for (std::list<QRadioButton *>::const_iterator i = _row_sel_list.begin();
|
||||||
|
i != _row_sel_list.end(); i++) {
|
||||||
|
if ((*i)->isChecked()) {
|
||||||
|
title = (*i)->property("title").toString();
|
||||||
|
index = (*i)->property("index").toULongLong();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out << QString("%1;%2;%3\n")
|
||||||
|
.arg("ID")
|
||||||
|
.arg("Time[s]")
|
||||||
|
.arg(title);
|
||||||
|
|
||||||
|
pv::data::DecoderModel* decoder_model = _session.get_decoder_model();
|
||||||
|
const boost::shared_ptr<pv::data::DecoderStack>& decoder_stack = decoder_model->getDecoderStack();
|
||||||
|
int row_index = 0;
|
||||||
|
Row row;
|
||||||
|
const std::map<const Row, bool>& rows_lshow(decoder_stack->get_rows_lshow());
|
||||||
|
for (std::map<const Row, bool>::const_iterator i = rows_lshow.begin();
|
||||||
|
i != rows_lshow.end(); i++) {
|
||||||
|
if ((*i).second) {
|
||||||
|
if (index == row_index) {
|
||||||
|
row = (*i).first;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
row_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t exported = 0;
|
||||||
|
double time_pre_samples = 1.0 / decoder_stack->samplerate();
|
||||||
|
vector<Annotation> annotations;
|
||||||
|
decoder_stack->get_annotation_subset(annotations, row,
|
||||||
|
0, decoder_stack->sample_count()-1);
|
||||||
|
if (!annotations.empty()) {
|
||||||
|
BOOST_FOREACH(const Annotation &a, annotations) {
|
||||||
|
out << QString("%1;%2;%3\n")
|
||||||
|
.arg(QString::number(exported))
|
||||||
|
.arg(QString::number(a.start_sample()*time_pre_samples))
|
||||||
|
.arg(a.annotations().at(0));
|
||||||
|
exported++;
|
||||||
|
emit export_progress(exported*100/annotations.size());
|
||||||
|
if (_export_cancel)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Qt::WindowFlags flags = Qt::CustomizeWindowHint;
|
||||||
|
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);
|
||||||
|
|
||||||
|
QFutureWatcher<void> watcher;
|
||||||
|
connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel()));
|
||||||
|
connect(this,SIGNAL(export_progress(int)),&dlg,SLOT(setValue(int)));
|
||||||
|
connect(&dlg,SIGNAL(canceled()),this,SLOT(cancel_export()));
|
||||||
|
watcher.setFuture(future);
|
||||||
|
dlg.exec();
|
||||||
|
|
||||||
|
future.waitForFinished();
|
||||||
|
file.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolExp::reject()
|
||||||
|
{
|
||||||
|
using namespace Qt;
|
||||||
|
|
||||||
|
QDialog::reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolExp::cancel_export()
|
||||||
|
{
|
||||||
|
_export_cancel = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dialogs
|
||||||
|
} // namespace pv
|
||||||
85
DSView/pv/dialogs/protocolexp.h
Normal file
85
DSView/pv/dialogs/protocolexp.h
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the DSView project.
|
||||||
|
* DSView is based on PulseView.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||||
|
* Copyright (C) 2013 DreamSourceLab <dreamsourcelab@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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef DSVIEW_PV_PROTOCOLEXP_H
|
||||||
|
#define DSVIEW_PV_PROTOCOLEXP_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QRadioButton>
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
#include "../device/devinst.h"
|
||||||
|
#include "../prop/binding/deviceoptions.h"
|
||||||
|
|
||||||
|
namespace pv {
|
||||||
|
|
||||||
|
class SigSession;
|
||||||
|
|
||||||
|
namespace data {
|
||||||
|
namespace decode {
|
||||||
|
class Row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace dialogs {
|
||||||
|
|
||||||
|
class ProtocolExp : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProtocolExp(QWidget *parent, SigSession &session);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void accept();
|
||||||
|
void reject();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void export_progress(int percent);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void cancel_export();
|
||||||
|
|
||||||
|
private:
|
||||||
|
SigSession &_session;
|
||||||
|
|
||||||
|
QComboBox *_format_combobox;
|
||||||
|
std::list<QRadioButton *> _row_sel_list;
|
||||||
|
std::list<QLabel *> _row_label_list;
|
||||||
|
QFormLayout *_flayout;
|
||||||
|
QVBoxLayout *_layout;
|
||||||
|
QDialogButtonBox _button_box;
|
||||||
|
|
||||||
|
bool _export_cancel;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dialogs
|
||||||
|
} // namespace pv
|
||||||
|
|
||||||
|
#endif // DSVIEW_PV_PROTOCOLEXP_H
|
||||||
183
DSView/pv/dialogs/protocollist.cpp
Normal file
183
DSView/pv/dialogs/protocollist.cpp
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the DSView project.
|
||||||
|
* DSView is based on PulseView.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||||
|
* Copyright (C) 2013 DreamSourceLab <dreamsourcelab@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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "protocollist.h"
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QListWidget>
|
||||||
|
#include <QMessageBox>
|
||||||
|
|
||||||
|
#include "../sigsession.h"
|
||||||
|
#include "../data/decoderstack.h"
|
||||||
|
#include "../data/decode/row.h"
|
||||||
|
#include "../view/decodetrace.h"
|
||||||
|
#include "../data/decodermodel.h"
|
||||||
|
|
||||||
|
using namespace boost;
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace pv {
|
||||||
|
namespace dialogs {
|
||||||
|
|
||||||
|
ProtocolList::ProtocolList(QWidget *parent, SigSession &session) :
|
||||||
|
QDialog(parent),
|
||||||
|
_session(session),
|
||||||
|
_button_box(QDialogButtonBox::Ok,
|
||||||
|
Qt::Horizontal, this)
|
||||||
|
{
|
||||||
|
pv::data::DecoderModel* decoder_model = _session.get_decoder_model();
|
||||||
|
|
||||||
|
|
||||||
|
_protocol_combobox = new QComboBox(this);
|
||||||
|
const std::vector< boost::shared_ptr<pv::view::DecodeTrace> > decode_sigs(
|
||||||
|
_session.get_decode_signals());
|
||||||
|
int index = 0;
|
||||||
|
BOOST_FOREACH(boost::shared_ptr<pv::view::DecodeTrace> d, decode_sigs) {
|
||||||
|
_protocol_combobox->addItem(d->get_name());
|
||||||
|
if (decoder_model->getDecoderStack() == d->decoder())
|
||||||
|
_protocol_combobox->setCurrentIndex(index);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
_protocol_combobox->addItem("", qVariantFromValue(NULL));
|
||||||
|
if (decoder_model->getDecoderStack() == NULL)
|
||||||
|
_protocol_combobox->setCurrentIndex(index);
|
||||||
|
|
||||||
|
_flayout = new QFormLayout();
|
||||||
|
_flayout->addRow(new QLabel(tr("Decoded Protocols: "), this), _protocol_combobox);
|
||||||
|
|
||||||
|
_layout = new QVBoxLayout(this);
|
||||||
|
_layout->addLayout(_flayout);
|
||||||
|
_layout->addWidget(&_button_box);
|
||||||
|
setLayout(_layout);
|
||||||
|
|
||||||
|
connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept()));
|
||||||
|
connect(_protocol_combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(set_protocol(int)));
|
||||||
|
set_protocol(_protocol_combobox->currentIndex());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolList::accept()
|
||||||
|
{
|
||||||
|
using namespace Qt;
|
||||||
|
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolList::reject()
|
||||||
|
{
|
||||||
|
using namespace Qt;
|
||||||
|
|
||||||
|
QDialog::accept();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolList::set_protocol(int index)
|
||||||
|
{
|
||||||
|
(void)index;
|
||||||
|
|
||||||
|
for(std::list<QCheckBox *>::const_iterator i = _show_checkbox_list.begin();
|
||||||
|
i != _show_checkbox_list.end(); i++) {
|
||||||
|
(*i)->setParent(NULL);
|
||||||
|
_flayout->removeWidget((*i));
|
||||||
|
delete (*i);
|
||||||
|
}
|
||||||
|
_show_checkbox_list.clear();
|
||||||
|
for(std::list<QLabel *>::const_iterator i = _show_label_list.begin();
|
||||||
|
i != _show_label_list.end(); i++) {
|
||||||
|
(*i)->setParent(NULL);
|
||||||
|
_flayout->removeWidget((*i));
|
||||||
|
delete (*i);
|
||||||
|
}
|
||||||
|
_show_label_list.clear();
|
||||||
|
|
||||||
|
boost::shared_ptr<pv::data::DecoderStack> decoder_stack;
|
||||||
|
const std::vector< boost::shared_ptr<pv::view::DecodeTrace> > decode_sigs(
|
||||||
|
_session.get_decode_signals());
|
||||||
|
int cur_index = 0;
|
||||||
|
BOOST_FOREACH(boost::shared_ptr<pv::view::DecodeTrace> d, decode_sigs) {
|
||||||
|
if (index == cur_index) {
|
||||||
|
decoder_stack = d->decoder();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cur_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!decoder_stack){
|
||||||
|
_session.get_decoder_model()->setDecoderStack(NULL);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_session.get_decoder_model()->setDecoderStack(decoder_stack);
|
||||||
|
int row_index = 0;
|
||||||
|
const std::map<const pv::data::decode::Row, bool>& rows(decoder_stack->get_rows_lshow());
|
||||||
|
for (std::map<const pv::data::decode::Row, bool>::const_iterator i = rows.begin();
|
||||||
|
i != rows.end(); i++) {
|
||||||
|
QLabel *row_label = new QLabel((*i).first.title(), this);
|
||||||
|
QCheckBox *row_checkbox = new QCheckBox(this);
|
||||||
|
//row_checkbox->setChecked(false);
|
||||||
|
_show_label_list.push_back(row_label);
|
||||||
|
_show_checkbox_list.push_back(row_checkbox);
|
||||||
|
_flayout->addRow(row_label, row_checkbox);
|
||||||
|
|
||||||
|
row_checkbox->setChecked((*i).second);
|
||||||
|
connect(row_checkbox, SIGNAL(clicked(bool)), this, SLOT(on_row_check(bool)));
|
||||||
|
row_checkbox->setProperty("index", row_index);
|
||||||
|
row_index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolList::on_row_check(bool show)
|
||||||
|
{
|
||||||
|
QCheckBox *sc = dynamic_cast<QCheckBox*>(sender());
|
||||||
|
QVariant id = sc->property("index");
|
||||||
|
int index = id.toInt();
|
||||||
|
|
||||||
|
boost::shared_ptr<pv::data::DecoderStack> decoder_stack;
|
||||||
|
const std::vector< boost::shared_ptr<pv::view::DecodeTrace> > decode_sigs(
|
||||||
|
_session.get_decode_signals());
|
||||||
|
int cur_index = 0;
|
||||||
|
BOOST_FOREACH(boost::shared_ptr<pv::view::DecodeTrace> d, decode_sigs) {
|
||||||
|
if (cur_index == _protocol_combobox->currentIndex()) {
|
||||||
|
decoder_stack = d->decoder();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cur_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!decoder_stack)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::map<const pv::data::decode::Row, bool>& rows(decoder_stack->get_rows_lshow());
|
||||||
|
for (std::map<const pv::data::decode::Row, bool>::const_iterator i = rows.begin();
|
||||||
|
i != rows.end(); i++) {
|
||||||
|
if (index-- == 0) {
|
||||||
|
decoder_stack->set_rows_lshow((*i).first, show);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_session.get_decoder_model()->setDecoderStack(decoder_stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dialogs
|
||||||
|
} // namespace pv
|
||||||
76
DSView/pv/dialogs/protocollist.h
Normal file
76
DSView/pv/dialogs/protocollist.h
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the DSView project.
|
||||||
|
* DSView is based on PulseView.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
|
||||||
|
* Copyright (C) 2013 DreamSourceLab <dreamsourcelab@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
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef DSVIEW_PV_PROTOCOLLIST_H
|
||||||
|
#define DSVIEW_PV_PROTOCOLLIST_H
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QFormLayout>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QCheckBox>
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
|
#include "../device/devinst.h"
|
||||||
|
#include "../prop/binding/deviceoptions.h"
|
||||||
|
|
||||||
|
namespace pv {
|
||||||
|
|
||||||
|
class SigSession;
|
||||||
|
|
||||||
|
namespace dialogs {
|
||||||
|
|
||||||
|
class ProtocolList : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ProtocolList(QWidget *parent, SigSession &session);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void accept();
|
||||||
|
void reject();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void set_protocol(int index);
|
||||||
|
void on_row_check(bool show);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SigSession &_session;
|
||||||
|
|
||||||
|
QComboBox *_protocol_combobox;
|
||||||
|
std::list<QCheckBox *> _show_checkbox_list;
|
||||||
|
std::list<QLabel *> _show_label_list;
|
||||||
|
QFormLayout *_flayout;
|
||||||
|
QVBoxLayout *_layout;
|
||||||
|
QDialogButtonBox _button_box;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dialogs
|
||||||
|
} // namespace pv
|
||||||
|
|
||||||
|
#endif // DSVIEW_PV_PROTOCOLLIST_H
|
||||||
@@ -25,13 +25,21 @@
|
|||||||
#include "../sigsession.h"
|
#include "../sigsession.h"
|
||||||
#include "../view/decodetrace.h"
|
#include "../view/decodetrace.h"
|
||||||
#include "../device/devinst.h"
|
#include "../device/devinst.h"
|
||||||
|
#include "../data/decodermodel.h"
|
||||||
|
#include "../data/decoderstack.h"
|
||||||
|
#include "../dialogs/protocollist.h"
|
||||||
|
#include "../dialogs/protocolexp.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QFormLayout>
|
#include <QFormLayout>
|
||||||
|
#include <QStandardItemModel>
|
||||||
|
#include <QTableView>
|
||||||
|
#include <QHeaderView>
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
namespace pv {
|
namespace pv {
|
||||||
@@ -41,20 +49,20 @@ ProtocolDock::ProtocolDock(QWidget *parent, SigSession &session) :
|
|||||||
QScrollArea(parent),
|
QScrollArea(parent),
|
||||||
_session(session)
|
_session(session)
|
||||||
{
|
{
|
||||||
_widget = new QWidget(this);
|
_up_widget = new QWidget(this);
|
||||||
|
|
||||||
QHBoxLayout *hori_layout = new QHBoxLayout();
|
QHBoxLayout *hori_layout = new QHBoxLayout();
|
||||||
|
|
||||||
_add_button = new QPushButton(_widget);
|
_add_button = new QPushButton(_up_widget);
|
||||||
_add_button->setFlat(true);
|
_add_button->setFlat(true);
|
||||||
_add_button->setIcon(QIcon::fromTheme("protocol",
|
_add_button->setIcon(QIcon::fromTheme("protocol",
|
||||||
QIcon(":/icons/add.png")));
|
QIcon(":/icons/add.png")));
|
||||||
_del_all_button = new QPushButton(_widget);
|
_del_all_button = new QPushButton(_up_widget);
|
||||||
_del_all_button->setFlat(true);
|
_del_all_button->setFlat(true);
|
||||||
_del_all_button->setIcon(QIcon::fromTheme("protocol",
|
_del_all_button->setIcon(QIcon::fromTheme("protocol",
|
||||||
QIcon(":/icons/del.png")));
|
QIcon(":/icons/del.png")));
|
||||||
_del_all_button->setCheckable(true);
|
_del_all_button->setCheckable(true);
|
||||||
_protocol_combobox = new QComboBox(_widget);
|
_protocol_combobox = new QComboBox(_up_widget);
|
||||||
|
|
||||||
GSList *l = g_slist_sort(g_slist_copy(
|
GSList *l = g_slist_sort(g_slist_copy(
|
||||||
(GSList*)srd_decoder_list()), decoder_name_cmp);
|
(GSList*)srd_decoder_list()), decoder_name_cmp);
|
||||||
@@ -80,15 +88,72 @@ ProtocolDock::ProtocolDock(QWidget *parent, SigSession &session) :
|
|||||||
connect(_del_all_button, SIGNAL(clicked()),
|
connect(_del_all_button, SIGNAL(clicked()),
|
||||||
this, SLOT(del_protocol()));
|
this, SLOT(del_protocol()));
|
||||||
|
|
||||||
_layout = new QVBoxLayout();
|
_up_layout = new QVBoxLayout();
|
||||||
_layout->addLayout(hori_layout);
|
_up_layout->addLayout(hori_layout);
|
||||||
_layout->addStretch(1);
|
_up_layout->addStretch(1);
|
||||||
|
|
||||||
_widget->setLayout(_layout);
|
_up_widget->setLayout(_up_layout);
|
||||||
|
_up_widget->setMinimumHeight(120);
|
||||||
|
|
||||||
this->setWidget(_widget);
|
// this->setWidget(_widget);
|
||||||
_widget->setGeometry(0, 0, sizeHint().width(), 500);
|
// _widget->setGeometry(0, 0, sizeHint().width(), 500);
|
||||||
_widget->setObjectName("protocolWidget");
|
// _widget->setObjectName("protocolWidget");
|
||||||
|
|
||||||
|
_dn_widget = new QWidget(this);
|
||||||
|
|
||||||
|
_dn_set_button = new QPushButton(_dn_widget);
|
||||||
|
_dn_set_button->setFlat(true);
|
||||||
|
_dn_set_button->setIcon(QIcon::fromTheme("protocol",
|
||||||
|
QIcon(":/icons/gear.png")));
|
||||||
|
connect(_dn_set_button, SIGNAL(clicked()),
|
||||||
|
this, SLOT(set_model()));
|
||||||
|
|
||||||
|
_dn_save_button = new QPushButton(_dn_widget);
|
||||||
|
_dn_save_button->setFlat(true);
|
||||||
|
_dn_save_button->setIcon(QIcon::fromTheme("protocol",
|
||||||
|
QIcon(":/icons/save.png")));
|
||||||
|
connect(_dn_save_button, SIGNAL(clicked()),
|
||||||
|
this, SLOT(export_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);
|
||||||
|
|
||||||
|
_table_view = new QTableView(_dn_widget);
|
||||||
|
_table_view->setModel(_session.get_decoder_model());
|
||||||
|
_table_view->setAlternatingRowColors(true);
|
||||||
|
_table_view->setShowGrid(false);
|
||||||
|
_table_view->horizontalHeader()->setStretchLastSection(true);
|
||||||
|
_table_view->setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||||
|
_table_view->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||||
|
|
||||||
|
QVBoxLayout *dn_layout = new QVBoxLayout();
|
||||||
|
dn_layout->addLayout(dn_title_layout);
|
||||||
|
dn_layout->addWidget(_table_view);
|
||||||
|
|
||||||
|
_dn_widget->setLayout(dn_layout);
|
||||||
|
_dn_widget->setMinimumHeight(400);
|
||||||
|
|
||||||
|
_split_widget = new QSplitter(this);
|
||||||
|
_split_widget->insertWidget(0, _up_widget);
|
||||||
|
_split_widget->insertWidget(1, _dn_widget);
|
||||||
|
_split_widget->setOrientation(Qt::Vertical);
|
||||||
|
_split_widget->setCollapsible(0, false);
|
||||||
|
_split_widget->setCollapsible(1, false);
|
||||||
|
//_split_widget->setStretchFactor(1, 1);
|
||||||
|
//_split_widget
|
||||||
|
|
||||||
|
this->setWidgetResizable(true);
|
||||||
|
this->setWidget(_split_widget);
|
||||||
|
//_split_widget->setGeometry(0, 0, sizeHint().width(), 500);
|
||||||
|
_split_widget->setObjectName("protocolWidget");
|
||||||
|
|
||||||
|
connect(&_session, SIGNAL(decode_done()), this, SLOT(update_model()));
|
||||||
|
connect(this, SIGNAL(protocol_updated()), this, SLOT(update_model()));
|
||||||
|
connect(_table_view, SIGNAL(clicked(QModelIndex)), this, SLOT(item_clicked(QModelIndex)));
|
||||||
|
connect(_table_view->horizontalHeader(), SIGNAL(sectionResized(int,int,int)), this, SLOT(column_resize(int, int, int)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtocolDock::~ProtocolDock()
|
ProtocolDock::~ProtocolDock()
|
||||||
@@ -126,15 +191,15 @@ void ProtocolDock::add_protocol()
|
|||||||
//QMap <QString, QVariant>& _options = dlg.get_options();
|
//QMap <QString, QVariant>& _options = dlg.get_options();
|
||||||
//QMap <QString, int> _options_index = dlg.get_options_index();
|
//QMap <QString, int> _options_index = dlg.get_options_index();
|
||||||
|
|
||||||
QPushButton *_del_button = new QPushButton(_widget);
|
QPushButton *_del_button = new QPushButton(_up_widget);
|
||||||
QPushButton *_set_button = new QPushButton(_widget);
|
QPushButton *_set_button = new QPushButton(_up_widget);
|
||||||
_del_button->setFlat(true);
|
_del_button->setFlat(true);
|
||||||
_del_button->setIcon(QIcon::fromTheme("protocol",
|
_del_button->setIcon(QIcon::fromTheme("protocol",
|
||||||
QIcon(":/icons/del.png")));
|
QIcon(":/icons/del.png")));
|
||||||
_set_button->setFlat(true);
|
_set_button->setFlat(true);
|
||||||
_set_button->setIcon(QIcon::fromTheme("protocol",
|
_set_button->setIcon(QIcon::fromTheme("protocol",
|
||||||
QIcon(":/icons/gear.png")));
|
QIcon(":/icons/gear.png")));
|
||||||
QLabel *_protocol_label = new QLabel(_widget);
|
QLabel *_protocol_label = new QLabel(_up_widget);
|
||||||
|
|
||||||
_del_button->setCheckable(true);
|
_del_button->setCheckable(true);
|
||||||
_protocol_label->setText(_protocol_combobox->currentText());
|
_protocol_label->setText(_protocol_combobox->currentText());
|
||||||
@@ -155,9 +220,10 @@ void ProtocolDock::add_protocol()
|
|||||||
hori_layout->addWidget(_protocol_label);
|
hori_layout->addWidget(_protocol_label);
|
||||||
hori_layout->addStretch(1);
|
hori_layout->addStretch(1);
|
||||||
_hori_layout_list.push_back(hori_layout);
|
_hori_layout_list.push_back(hori_layout);
|
||||||
_layout->insertLayout(_del_button_list.size(), hori_layout);
|
_up_layout->insertLayout(_del_button_list.size(), hori_layout);
|
||||||
|
|
||||||
//_session.add_protocol_analyzer(_protocol_combobox->currentIndex(), _sel_probes, _options, _options_index);
|
//_session.add_protocol_analyzer(_protocol_combobox->currentIndex(), _sel_probes, _options, _options_index);
|
||||||
|
protocol_updated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,6 +249,7 @@ void ProtocolDock::rst_protocol()
|
|||||||
}
|
}
|
||||||
rst_index++;
|
rst_index++;
|
||||||
}
|
}
|
||||||
|
protocol_updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolDock::del_protocol()
|
void ProtocolDock::del_protocol()
|
||||||
@@ -193,7 +260,7 @@ void ProtocolDock::del_protocol()
|
|||||||
int del_index = 0;
|
int del_index = 0;
|
||||||
for (QVector <QHBoxLayout *>::const_iterator i = _hori_layout_list.begin();
|
for (QVector <QHBoxLayout *>::const_iterator i = _hori_layout_list.begin();
|
||||||
i != _hori_layout_list.end(); i++) {
|
i != _hori_layout_list.end(); i++) {
|
||||||
_layout->removeItem((*i));
|
_up_layout->removeItem((*i));
|
||||||
delete (*i);
|
delete (*i);
|
||||||
delete _del_button_list.at(del_index);
|
delete _del_button_list.at(del_index);
|
||||||
delete _set_button_list.at(del_index);
|
delete _set_button_list.at(del_index);
|
||||||
@@ -220,7 +287,7 @@ void ProtocolDock::del_protocol()
|
|||||||
for (QVector <QPushButton *>::const_iterator i = _del_button_list.begin();
|
for (QVector <QPushButton *>::const_iterator i = _del_button_list.begin();
|
||||||
i != _del_button_list.end(); i++) {
|
i != _del_button_list.end(); i++) {
|
||||||
if ((*i)->isChecked()) {
|
if ((*i)->isChecked()) {
|
||||||
_layout->removeItem(_hori_layout_list.at(del_index));
|
_up_layout->removeItem(_hori_layout_list.at(del_index));
|
||||||
|
|
||||||
delete _hori_layout_list.at(del_index);
|
delete _hori_layout_list.at(del_index);
|
||||||
delete _del_button_list.at(del_index);
|
delete _del_button_list.at(del_index);
|
||||||
@@ -234,12 +301,12 @@ void ProtocolDock::del_protocol()
|
|||||||
_protocol_index_list.remove(del_index);
|
_protocol_index_list.remove(del_index);
|
||||||
|
|
||||||
_session.remove_decode_signal(del_index);
|
_session.remove_decode_signal(del_index);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
del_index++;
|
del_index++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
protocol_updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtocolDock::del_all_protocol()
|
void ProtocolDock::del_all_protocol()
|
||||||
@@ -248,7 +315,7 @@ void ProtocolDock::del_all_protocol()
|
|||||||
int del_index = 0;
|
int del_index = 0;
|
||||||
for (QVector <QHBoxLayout *>::const_iterator i = _hori_layout_list.begin();
|
for (QVector <QHBoxLayout *>::const_iterator i = _hori_layout_list.begin();
|
||||||
i != _hori_layout_list.end(); i++) {
|
i != _hori_layout_list.end(); i++) {
|
||||||
_layout->removeItem((*i));
|
_up_layout->removeItem((*i));
|
||||||
delete (*i);
|
delete (*i);
|
||||||
delete _del_button_list.at(del_index);
|
delete _del_button_list.at(del_index);
|
||||||
delete _set_button_list.at(del_index);
|
delete _set_button_list.at(del_index);
|
||||||
@@ -262,8 +329,90 @@ void ProtocolDock::del_all_protocol()
|
|||||||
_set_button_list.clear();
|
_set_button_list.clear();
|
||||||
_protocol_label_list.clear();
|
_protocol_label_list.clear();
|
||||||
_protocol_index_list.clear();
|
_protocol_index_list.clear();
|
||||||
|
|
||||||
|
protocol_updated();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProtocolDock::set_model()
|
||||||
|
{
|
||||||
|
pv::dialogs::ProtocolList *protocollist_dlg = new pv::dialogs::ProtocolList(this, _session);
|
||||||
|
protocollist_dlg->exec();
|
||||||
|
resize_table_view(_session.get_decoder_model());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolDock::update_model()
|
||||||
|
{
|
||||||
|
pv::data::DecoderModel *decoder_model = _session.get_decoder_model();
|
||||||
|
const std::vector< boost::shared_ptr<pv::view::DecodeTrace> > decode_sigs(
|
||||||
|
_session.get_decode_signals());
|
||||||
|
if (decode_sigs.size() == 0)
|
||||||
|
decoder_model->setDecoderStack(NULL);
|
||||||
|
else if (!decoder_model->getDecoderStack())
|
||||||
|
decoder_model->setDecoderStack(decode_sigs.at(0)->decoder());
|
||||||
|
else {
|
||||||
|
int index = 0;
|
||||||
|
BOOST_FOREACH(const boost::shared_ptr<pv::view::DecodeTrace> d, decode_sigs) {
|
||||||
|
if (d->decoder() == decoder_model->getDecoderStack()) {
|
||||||
|
decoder_model->setDecoderStack(d->decoder());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
if (index >= decode_sigs.size())
|
||||||
|
decoder_model->setDecoderStack(decode_sigs.at(0)->decoder());
|
||||||
|
}
|
||||||
|
|
||||||
|
resize_table_view(decoder_model);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolDock::resize_table_view(data::DecoderModel* decoder_model)
|
||||||
|
{
|
||||||
|
if (decoder_model->getDecoderStack()) {
|
||||||
|
for (int i = 0; i < decoder_model->columnCount(QModelIndex()) - 1; i++) {
|
||||||
|
_table_view->resizeColumnToContents(i);
|
||||||
|
if (_table_view->columnWidth(i) > 200)
|
||||||
|
_table_view->setColumnWidth(i, 200);
|
||||||
|
}
|
||||||
|
int top_row = _table_view->rowAt(0);
|
||||||
|
int bom_row = _table_view->rowAt(_table_view->height());
|
||||||
|
if (bom_row >= top_row && top_row >= 0) {
|
||||||
|
for (int i = top_row; i <= bom_row; i++)
|
||||||
|
_table_view->resizeRowToContents(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolDock::item_clicked(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
pv::data::DecoderModel *decoder_model = _session.get_decoder_model();
|
||||||
|
boost::shared_ptr<pv::data::DecoderStack> decoder_stack = decoder_model->getDecoderStack();
|
||||||
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolDock::column_resize(int index, int old_size, int new_size)
|
||||||
|
{
|
||||||
|
pv::data::DecoderModel *decoder_model = _session.get_decoder_model();
|
||||||
|
if (decoder_model->getDecoderStack()) {
|
||||||
|
int top_row = _table_view->rowAt(0);
|
||||||
|
int bom_row = _table_view->rowAt(_table_view->height());
|
||||||
|
if (bom_row >= top_row && top_row >= 0) {
|
||||||
|
for (int i = top_row; i <= bom_row; i++)
|
||||||
|
_table_view->resizeRowToContents(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProtocolDock::export_table_view()
|
||||||
|
{
|
||||||
|
pv::dialogs::ProtocolExp *protocolexp_dlg = new pv::dialogs::ProtocolExp(this, _session);
|
||||||
|
protocolexp_dlg->exec();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace dock
|
} // namespace dock
|
||||||
} // namespace pv
|
} // namespace pv
|
||||||
|
|||||||
@@ -34,15 +34,23 @@
|
|||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QScrollArea>
|
#include <QScrollArea>
|
||||||
|
#include <QSplitter>
|
||||||
|
#include <QTableView>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <libsigrok4DSL/libsigrok.h>
|
#include <libsigrok4DSL/libsigrok.h>
|
||||||
|
|
||||||
|
#include "../data/decodermodel.h"
|
||||||
|
|
||||||
namespace pv {
|
namespace pv {
|
||||||
|
|
||||||
class SigSession;
|
class SigSession;
|
||||||
|
|
||||||
|
namespace data {
|
||||||
|
class DecoderModel;
|
||||||
|
}
|
||||||
|
|
||||||
namespace dock {
|
namespace dock {
|
||||||
|
|
||||||
class ProtocolDock : public QScrollArea
|
class ProtocolDock : public QScrollArea
|
||||||
@@ -58,19 +66,29 @@ public:
|
|||||||
void del_all_protocol();
|
void del_all_protocol();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
void protocol_updated();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void add_protocol();
|
void add_protocol();
|
||||||
void rst_protocol();
|
void rst_protocol();
|
||||||
void del_protocol();
|
void del_protocol();
|
||||||
|
void set_model();
|
||||||
|
void update_model();
|
||||||
|
void export_table_view();
|
||||||
|
void item_clicked(const QModelIndex &index);
|
||||||
|
void column_resize(int index, int old_size, int new_size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static int decoder_name_cmp(const void *a, const void *b);
|
static int decoder_name_cmp(const void *a, const void *b);
|
||||||
|
void resize_table_view(data::DecoderModel *decoder_model);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SigSession &_session;
|
SigSession &_session;
|
||||||
|
|
||||||
QWidget *_widget;
|
QSplitter *_split_widget;
|
||||||
|
QWidget *_up_widget;
|
||||||
|
QWidget *_dn_widget;
|
||||||
|
QTableView *_table_view;
|
||||||
|
|
||||||
QPushButton *_add_button;
|
QPushButton *_add_button;
|
||||||
QPushButton *_del_all_button;
|
QPushButton *_del_all_button;
|
||||||
@@ -80,7 +98,10 @@ private:
|
|||||||
QVector <QLabel *> _protocol_label_list;
|
QVector <QLabel *> _protocol_label_list;
|
||||||
QVector <int > _protocol_index_list;
|
QVector <int > _protocol_index_list;
|
||||||
QVector <QHBoxLayout *> _hori_layout_list;
|
QVector <QHBoxLayout *> _hori_layout_list;
|
||||||
QVBoxLayout *_layout;
|
QVBoxLayout *_up_layout;
|
||||||
|
|
||||||
|
QPushButton *_dn_set_button;
|
||||||
|
QPushButton *_dn_save_button;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dock
|
} // namespace dock
|
||||||
|
|||||||
@@ -197,7 +197,9 @@ void MainWindow::setup_ui()
|
|||||||
SLOT(device_change()));
|
SLOT(device_change()));
|
||||||
connect(_dso_trigger_widget, SIGNAL(set_trig_pos(quint64)), _view,
|
connect(_dso_trigger_widget, SIGNAL(set_trig_pos(quint64)), _view,
|
||||||
SLOT(set_trig_pos(quint64)));
|
SLOT(set_trig_pos(quint64)));
|
||||||
|
connect(_protocol_widget, SIGNAL(protocol_updated()), _view, SLOT(signals_changed()));
|
||||||
|
|
||||||
|
setIconSize(QSize(40,40));
|
||||||
addToolBar(_sampling_bar);
|
addToolBar(_sampling_bar);
|
||||||
addToolBar(_trig_bar);
|
addToolBar(_trig_bar);
|
||||||
addToolBar(_file_bar);
|
addToolBar(_file_bar);
|
||||||
|
|||||||
@@ -41,6 +41,7 @@
|
|||||||
#include "data/groupsnapshot.h"
|
#include "data/groupsnapshot.h"
|
||||||
#include "data/decoderstack.h"
|
#include "data/decoderstack.h"
|
||||||
#include "data/decode/decoder.h"
|
#include "data/decode/decoder.h"
|
||||||
|
#include "data/decodermodel.h"
|
||||||
|
|
||||||
#include "view/analogsignal.h"
|
#include "view/analogsignal.h"
|
||||||
#include "view/dsosignal.h"
|
#include "view/dsosignal.h"
|
||||||
@@ -99,6 +100,7 @@ SigSession::SigSession(DeviceManager &device_manager) :
|
|||||||
_refresh_timer.stop();
|
_refresh_timer.stop();
|
||||||
_refresh_timer.setSingleShot(true);
|
_refresh_timer.setSingleShot(true);
|
||||||
_data_lock = false;
|
_data_lock = false;
|
||||||
|
_decoder_model = new pv::data::DecoderModel(this);
|
||||||
connect(this, SIGNAL(start_timer(int)), &_view_timer, SLOT(start(int)));
|
connect(this, SIGNAL(start_timer(int)), &_view_timer, SLOT(start(int)));
|
||||||
//connect(&_view_timer, SIGNAL(timeout()), this, SLOT(refresh()));
|
//connect(&_view_timer, SIGNAL(timeout()), this, SLOT(refresh()));
|
||||||
connect(&_refresh_timer, SIGNAL(timeout()), this, SLOT(data_unlock()));
|
connect(&_refresh_timer, SIGNAL(timeout()), this, SLOT(data_unlock()));
|
||||||
@@ -455,7 +457,6 @@ void SigSession::start_capture(bool instant,
|
|||||||
_view_timer.blockSignals(false);
|
_view_timer.blockSignals(false);
|
||||||
|
|
||||||
// Begin the session
|
// Begin the session
|
||||||
|
|
||||||
_sampling_thread.reset(new boost::thread(
|
_sampling_thread.reset(new boost::thread(
|
||||||
&SigSession::sample_thread_proc, this, _dev_inst,
|
&SigSession::sample_thread_proc, this, _dev_inst,
|
||||||
error_handler));
|
error_handler));
|
||||||
@@ -1104,9 +1105,10 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
|
|||||||
_cur_logic_snapshot.reset();
|
_cur_logic_snapshot.reset();
|
||||||
_cur_dso_snapshot.reset();
|
_cur_dso_snapshot.reset();
|
||||||
_cur_analog_snapshot.reset();
|
_cur_analog_snapshot.reset();
|
||||||
|
#ifdef ENABLE_DECODE
|
||||||
BOOST_FOREACH(const boost::shared_ptr<view::DecodeTrace> d, _decode_traces)
|
BOOST_FOREACH(const boost::shared_ptr<view::DecodeTrace> d, _decode_traces)
|
||||||
d->frame_ended();
|
d->frame_ended();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_ended();
|
frame_ended();
|
||||||
@@ -1394,6 +1396,12 @@ void SigSession::rst_decoder(view::DecodeTrace *signal)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pv::data::DecoderModel* SigSession::get_decoder_model() const
|
||||||
|
{
|
||||||
|
return _decoder_model;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
} // namespace pv
|
} // namespace pv
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ class Logic;
|
|||||||
class LogicSnapshot;
|
class LogicSnapshot;
|
||||||
class Group;
|
class Group;
|
||||||
class GroupSnapshot;
|
class GroupSnapshot;
|
||||||
|
class DecoderModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace device {
|
namespace device {
|
||||||
@@ -154,6 +155,8 @@ public:
|
|||||||
|
|
||||||
void rst_decoder(view::DecodeTrace *signal);
|
void rst_decoder(view::DecodeTrace *signal);
|
||||||
|
|
||||||
|
pv::data::DecoderModel* get_decoder_model() const;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void init_signals();
|
void init_signals();
|
||||||
@@ -234,6 +237,7 @@ private:
|
|||||||
std::vector< boost::shared_ptr<view::GroupSignal> > _group_traces;
|
std::vector< boost::shared_ptr<view::GroupSignal> > _group_traces;
|
||||||
#ifdef ENABLE_DECODE
|
#ifdef ENABLE_DECODE
|
||||||
std::vector< boost::shared_ptr<view::DecodeTrace> > _decode_traces;
|
std::vector< boost::shared_ptr<view::DecodeTrace> > _decode_traces;
|
||||||
|
pv::data::DecoderModel *_decoder_model;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mutable boost::mutex _data_mutex;
|
mutable boost::mutex _data_mutex;
|
||||||
@@ -291,6 +295,10 @@ signals:
|
|||||||
void zero_adj();
|
void zero_adj();
|
||||||
void progressSaveFileValueChanged(int percent);
|
void progressSaveFileValueChanged(int percent);
|
||||||
|
|
||||||
|
void decode_done();
|
||||||
|
|
||||||
|
void show_region(uint64_t start, uint64_t end);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void reload();
|
void reload();
|
||||||
void refresh(int holdtime);
|
void refresh(int holdtime);
|
||||||
|
|||||||
@@ -454,7 +454,8 @@ void SamplingBar::update_sample_rate_selector_value()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
update_scale();
|
if (samplerate != _sample_rate.itemData(_sample_rate.currentIndex()).value<uint64_t>())
|
||||||
|
update_scale();
|
||||||
_updating_sample_rate = false;
|
_updating_sample_rate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -511,7 +512,7 @@ void SamplingBar::on_samplecount_sel(int index)
|
|||||||
g_variant_new_uint64(sample_count));
|
g_variant_new_uint64(sample_count));
|
||||||
|
|
||||||
sample_count_changed();
|
sample_count_changed();
|
||||||
update_scale();
|
//update_scale();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -535,7 +536,7 @@ void SamplingBar::on_samplerate_sel(int index)
|
|||||||
SR_CONF_SAMPLERATE,
|
SR_CONF_SAMPLERATE,
|
||||||
g_variant_new_uint64(sample_rate));
|
g_variant_new_uint64(sample_rate));
|
||||||
|
|
||||||
update_scale();
|
//update_scale();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -625,9 +626,11 @@ void SamplingBar::update_sample_count_selector_value()
|
|||||||
i).value<uint64_t>())
|
i).value<uint64_t>())
|
||||||
_sample_count.setCurrentIndex(i);
|
_sample_count.setCurrentIndex(i);
|
||||||
|
|
||||||
|
if (samplecount != _sample_count.itemData(_sample_count.currentIndex()).value<uint64_t>()) {
|
||||||
|
sample_count_changed();
|
||||||
|
update_scale();
|
||||||
|
}
|
||||||
_updating_sample_count = false;
|
_updating_sample_count = false;
|
||||||
sample_count_changed();
|
|
||||||
update_scale();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SamplingBar::commit_sample_count()
|
void SamplingBar::commit_sample_count()
|
||||||
|
|||||||
@@ -125,7 +125,6 @@ DecodeTrace::DecodeTrace(pv::SigSession &session,
|
|||||||
_end_index(0),
|
_end_index(0),
|
||||||
_start_count(0),
|
_start_count(0),
|
||||||
_end_count(0),
|
_end_count(0),
|
||||||
_show_hide_mapper(this),
|
|
||||||
_popup_form(NULL),
|
_popup_form(NULL),
|
||||||
_popup()
|
_popup()
|
||||||
{
|
{
|
||||||
@@ -137,8 +136,6 @@ DecodeTrace::DecodeTrace(pv::SigSession &session,
|
|||||||
this, SLOT(on_new_decode_data()));
|
this, SLOT(on_new_decode_data()));
|
||||||
connect(_decoder_stack.get(), SIGNAL(decode_done()),
|
connect(_decoder_stack.get(), SIGNAL(decode_done()),
|
||||||
this, SLOT(on_decode_done()));
|
this, SLOT(on_decode_done()));
|
||||||
connect(&_show_hide_mapper, SIGNAL(mapped(int)),
|
|
||||||
this, SLOT(on_show_hide_decoder(int)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DecodeTrace::~DecodeTrace()
|
DecodeTrace::~DecodeTrace()
|
||||||
@@ -203,7 +200,7 @@ void DecodeTrace::paint_back(QPainter &p, int left, int right)
|
|||||||
|
|
||||||
void DecodeTrace::paint_mid(QPainter &p, int left, int right)
|
void DecodeTrace::paint_mid(QPainter &p, int left, int right)
|
||||||
{
|
{
|
||||||
using namespace pv::data::decode;
|
using namespace pv::data::decode;
|
||||||
|
|
||||||
const double scale = _view->scale();
|
const double scale = _view->scale();
|
||||||
assert(scale > 0);
|
assert(scale > 0);
|
||||||
@@ -249,47 +246,57 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right)
|
|||||||
|
|
||||||
const double decode_startX = _decode_start/samples_per_pixel - (_view->offset() / _view->scale());
|
const double decode_startX = _decode_start/samples_per_pixel - (_view->offset() / _view->scale());
|
||||||
const double decode_endX = _decode_end/samples_per_pixel - (_view->offset() / _view->scale());
|
const double decode_endX = _decode_end/samples_per_pixel - (_view->offset() / _view->scale());
|
||||||
const std::vector< std::pair<Row, bool> > rows(_decoder_stack->get_visible_rows());
|
|
||||||
for (size_t i = 0; i < rows.size(); i++)
|
|
||||||
{
|
|
||||||
const Row &row = rows[i].first;
|
|
||||||
const bool shown = rows[i].second;
|
|
||||||
|
|
||||||
if (!shown && _decoder_stack->has_annotations(row)) {
|
BOOST_FOREACH(boost::shared_ptr<data::decode::Decoder> dec,
|
||||||
draw_unshown_row(p, y, annotation_height, decode_startX, decode_endX);
|
_decoder_stack->stack()) {
|
||||||
y += annotation_height;
|
if (dec->shown()) {
|
||||||
_cur_row_headings.push_back(row.title());
|
const std::map<const pv::data::decode::Row, bool>& rows(_decoder_stack->get_rows_gshow());
|
||||||
continue;
|
for (std::map<const pv::data::decode::Row, bool>::const_iterator i = rows.begin();
|
||||||
}
|
i != rows.end(); i++) {
|
||||||
|
if ((*i).first.decoder() == dec->decoder() &&
|
||||||
|
_decoder_stack->has_annotations((*i).first)) {
|
||||||
|
if ((*i).second) {
|
||||||
|
const Row &row = (*i).first;
|
||||||
|
size_t base_colour = 0x13579BDF;
|
||||||
|
boost::hash_combine(base_colour, this);
|
||||||
|
boost::hash_combine(base_colour, row.decoder());
|
||||||
|
boost::hash_combine(base_colour, row.row());
|
||||||
|
base_colour >>= 16;
|
||||||
|
|
||||||
size_t base_colour = 0x13579BDF;
|
const uint64_t min_annotation =
|
||||||
boost::hash_combine(base_colour, this);
|
_decoder_stack->get_min_annotation(row);
|
||||||
boost::hash_combine(base_colour, row.decoder());
|
const double min_annWidth = min_annotation / samples_per_pixel;
|
||||||
boost::hash_combine(base_colour, row.row());
|
|
||||||
base_colour >>= 16;
|
|
||||||
|
|
||||||
const uint64_t max_annotation =
|
const uint64_t max_annotation =
|
||||||
_decoder_stack->get_max_annotation(row);
|
_decoder_stack->get_max_annotation(row);
|
||||||
const double max_annWidth = max_annotation / samples_per_pixel;
|
const double max_annWidth = max_annotation / samples_per_pixel;
|
||||||
if (max_annWidth > 5) {
|
if (max_annWidth > 5) {
|
||||||
vector<Annotation> annotations;
|
vector<Annotation> annotations;
|
||||||
_decoder_stack->get_annotation_subset(annotations, row,
|
_decoder_stack->get_annotation_subset(annotations, row,
|
||||||
start_sample, end_sample);
|
start_sample, end_sample);
|
||||||
if (!annotations.empty()) {
|
if (!annotations.empty()) {
|
||||||
BOOST_FOREACH(const Annotation &a, annotations)
|
BOOST_FOREACH(const Annotation &a, annotations)
|
||||||
draw_annotation(a, p, get_text_colour(),
|
draw_annotation(a, p, get_text_colour(),
|
||||||
annotation_height, left, right,
|
annotation_height, left, right,
|
||||||
samples_per_pixel, pixels_offset, y,
|
samples_per_pixel, pixels_offset, y,
|
||||||
base_colour);
|
base_colour, min_annWidth);
|
||||||
|
}
|
||||||
|
} else if (max_annWidth != 0){
|
||||||
|
draw_nodetail(p, annotation_height, left, right, y, base_colour);
|
||||||
|
}
|
||||||
|
if (max_annWidth != 0) {
|
||||||
|
y += annotation_height;
|
||||||
|
_cur_row_headings.push_back(row.title());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else if (max_annWidth != 0){
|
} else {
|
||||||
draw_nodetail(p, annotation_height, decode_startX, decode_endX, y, base_colour);
|
draw_unshown_row(p, y, annotation_height, left, right, tr("Unshown"));
|
||||||
}
|
|
||||||
if (max_annWidth != 0) {
|
|
||||||
y += annotation_height;
|
y += annotation_height;
|
||||||
_cur_row_headings.push_back(row.title());
|
_cur_row_headings.push_back(dec->decoder()->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecodeTrace::paint_fore(QPainter &p, int left, int right)
|
void DecodeTrace::paint_fore(QPainter &p, int left, int right)
|
||||||
@@ -350,8 +357,8 @@ bool DecodeTrace::create_popup()
|
|||||||
BOOST_FOREACH(boost::shared_ptr<data::decode::Decoder> dec,
|
BOOST_FOREACH(boost::shared_ptr<data::decode::Decoder> dec,
|
||||||
_decoder_stack->stack())
|
_decoder_stack->stack())
|
||||||
{
|
{
|
||||||
if (dec->commit()) {
|
if (dec->commit() || _decoder_stack->options_changed()) {
|
||||||
_decoder_stack->options_changed(true);
|
_decoder_stack->set_options_changed(true);
|
||||||
_decode_start = dec->decode_start();
|
_decode_start = dec->decode_start();
|
||||||
_decode_end = dec->decode_end();
|
_decode_end = dec->decode_end();
|
||||||
ret = true;
|
ret = true;
|
||||||
@@ -378,6 +385,9 @@ void DecodeTrace::create_popup_form()
|
|||||||
_popup_form = new QFormLayout(_popup);
|
_popup_form = new QFormLayout(_popup);
|
||||||
_popup->setLayout(_popup_form);
|
_popup->setLayout(_popup_form);
|
||||||
populate_popup_form(_popup, _popup_form);
|
populate_popup_form(_popup, _popup_form);
|
||||||
|
const int width = _popup_form->sizeHint().width();
|
||||||
|
const int height = _popup_form->sizeHint().height();
|
||||||
|
_popup->resize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form)
|
void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form)
|
||||||
@@ -395,20 +405,15 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form)
|
|||||||
|
|
||||||
const list< boost::shared_ptr<Decoder> >& stack = _decoder_stack->stack();
|
const list< boost::shared_ptr<Decoder> >& stack = _decoder_stack->stack();
|
||||||
|
|
||||||
if (stack.empty())
|
if (stack.empty()) {
|
||||||
{
|
|
||||||
QLabel *const l = new QLabel(
|
QLabel *const l = new QLabel(
|
||||||
tr("<p><i>No decoders in the stack</i></p>"));
|
tr("<p><i>No decoders in the stack</i></p>"));
|
||||||
l->setAlignment(Qt::AlignCenter);
|
l->setAlignment(Qt::AlignCenter);
|
||||||
form->addRow(l);
|
form->addRow(l);
|
||||||
}
|
} else {
|
||||||
else
|
BOOST_FOREACH(boost::shared_ptr<Decoder> dec,stack) {
|
||||||
{
|
//boost::shared_ptr<Decoder> dec(*iter);
|
||||||
list< boost::shared_ptr<Decoder> >::const_iterator iter =
|
create_decoder_form(_decoder_stack, dec, parent, form);
|
||||||
stack.begin();
|
|
||||||
for (int i = 0; i < (int)stack.size(); i++, iter++) {
|
|
||||||
boost::shared_ptr<Decoder> dec(*iter);
|
|
||||||
create_decoder_form(i, dec, parent, form);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
form->addRow(new QLabel(
|
form->addRow(new QLabel(
|
||||||
@@ -477,9 +482,9 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DecodeTrace::draw_annotation(const pv::data::decode::Annotation &a,
|
void DecodeTrace::draw_annotation(const pv::data::decode::Annotation &a,
|
||||||
QPainter &p, QColor text_color, int h, int left, int right,
|
QPainter &p, QColor text_color, int h, int left, int right,
|
||||||
double samples_per_pixel, double pixels_offset, int y,
|
double samples_per_pixel, double pixels_offset, int y,
|
||||||
size_t base_colour) const
|
size_t base_colour, double min_annWidth) const
|
||||||
{
|
{
|
||||||
const double start = max(a.start_sample() / samples_per_pixel -
|
const double start = max(a.start_sample() / samples_per_pixel -
|
||||||
pixels_offset, (double)left);
|
pixels_offset, (double)left);
|
||||||
@@ -495,7 +500,7 @@ void DecodeTrace::draw_annotation(const pv::data::decode::Annotation &a,
|
|||||||
|
|
||||||
if (a.start_sample() == a.end_sample())
|
if (a.start_sample() == a.end_sample())
|
||||||
draw_instant(a, p, fill, outline, text_color, h,
|
draw_instant(a, p, fill, outline, text_color, h,
|
||||||
start, y);
|
start, y, min_annWidth);
|
||||||
else
|
else
|
||||||
draw_range(a, p, fill, outline, text_color, h,
|
draw_range(a, p, fill, outline, text_color, h,
|
||||||
start, end, y);
|
start, end, y);
|
||||||
@@ -506,22 +511,31 @@ void DecodeTrace::draw_nodetail(QPainter &p,
|
|||||||
size_t base_colour) const
|
size_t base_colour) const
|
||||||
{
|
{
|
||||||
const QRectF nodetail_rect(left, y - h/2 + 0.5, right - left, h);
|
const QRectF nodetail_rect(left, y - h/2 + 0.5, right - left, h);
|
||||||
const size_t colour = base_colour % countof(Colours);
|
QString info = tr("Zoom in For Detial");
|
||||||
const QColor &fill = Colours[colour];
|
int info_left = nodetail_rect.center().x() - p.boundingRect(QRectF(), 0, info).width();
|
||||||
|
int info_right = nodetail_rect.center().x() + p.boundingRect(QRectF(), 0, info).width();
|
||||||
|
int height = p.boundingRect(QRectF(), 0, info).height();
|
||||||
|
|
||||||
p.setPen(Qt::white);
|
p.setPen(Trace::DARK_FORE);
|
||||||
p.setBrush(fill);
|
p.drawLine(left, y, info_left, y);
|
||||||
p.drawRect(nodetail_rect);
|
p.drawLine(info_right, y, right, y);
|
||||||
p.drawText(nodetail_rect, Qt::AlignCenter | Qt::AlignVCenter, "Zoom in for more detials");
|
p.drawLine(info_left, y, info_left+5, y - height/2 + 0.5);
|
||||||
|
p.drawLine(info_left, y, info_left+5, y + height/2 + 0.5);
|
||||||
|
p.drawLine(info_right, y, info_right-5, y - height/2 + 0.5);
|
||||||
|
p.drawLine(info_right, y, info_right-5, y + height/2 + 0.5);
|
||||||
|
|
||||||
|
p.setPen(Trace::DARK_FORE);
|
||||||
|
p.drawText(nodetail_rect, Qt::AlignCenter | Qt::AlignVCenter, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecodeTrace::draw_instant(const pv::data::decode::Annotation &a, QPainter &p,
|
void DecodeTrace::draw_instant(const pv::data::decode::Annotation &a, QPainter &p,
|
||||||
QColor fill, QColor outline, QColor text_color, int h, double x, int y) const
|
QColor fill, QColor outline, QColor text_color, int h, double x, int y, double min_annWidth) const
|
||||||
{
|
{
|
||||||
const QString text = a.annotations().empty() ?
|
const QString text = a.annotations().empty() ?
|
||||||
QString() : a.annotations().back();
|
QString() : a.annotations().back();
|
||||||
const double w = min((double)p.boundingRect(QRectF(), 0, text).width(),
|
// const double w = min((double)p.boundingRect(QRectF(), 0, text).width(),
|
||||||
0.0) + h;
|
// 0.0) + h;
|
||||||
|
const double w = min(min_annWidth, (double)h);
|
||||||
const QRectF rect(x - w / 2, y - h / 2, w, h);
|
const QRectF rect(x - w / 2, y - h / 2, w, h);
|
||||||
|
|
||||||
p.setPen(outline);
|
p.setPen(outline);
|
||||||
@@ -564,7 +578,7 @@ void DecodeTrace::draw_range(const pv::data::decode::Annotation &a, QPainter &p,
|
|||||||
QPointF(start + cap_width, bottom)
|
QPointF(start + cap_width, bottom)
|
||||||
};
|
};
|
||||||
|
|
||||||
p.setPen(Qt::white);
|
p.setPen(DARK_BACK);
|
||||||
p.drawConvexPolygon(pts, countof(pts));
|
p.drawConvexPolygon(pts, countof(pts));
|
||||||
|
|
||||||
if (annotations.empty())
|
if (annotations.empty())
|
||||||
@@ -643,20 +657,8 @@ bool DecodeTrace::draw_unresolved_period(QPainter &p, int h, int left,
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
const int y = get_y();
|
const int y = get_y();
|
||||||
// const double start = max(samples_decoded /
|
|
||||||
// samples_per_pixel - pixels_offset, left - 1.0);
|
|
||||||
// const double end = min(sample_count / samples_per_pixel -
|
|
||||||
// pixels_offset, right + 1.0);
|
|
||||||
const QRectF no_decode_rect(left, y - h/2 + 0.5, right - left, h);
|
const QRectF no_decode_rect(left, y - h/2 + 0.5, right - left, h);
|
||||||
|
|
||||||
p.setPen(QPen(Qt::NoPen));
|
|
||||||
p.setBrush(Qt::white);
|
|
||||||
p.drawRect(no_decode_rect);
|
|
||||||
|
|
||||||
p.setPen(NoDecodeColour);
|
|
||||||
p.setBrush(QBrush(NoDecodeColour, Qt::Dense7Pattern));
|
|
||||||
p.drawRect(no_decode_rect);
|
|
||||||
|
|
||||||
const int progress100 = ceil(samples_decoded * 100.0 / need_sample_count);
|
const int progress100 = ceil(samples_decoded * 100.0 / need_sample_count);
|
||||||
p.setPen(dsLightBlue);
|
p.setPen(dsLightBlue);
|
||||||
QFont font=p.font();
|
QFont font=p.font();
|
||||||
@@ -669,40 +671,40 @@ bool DecodeTrace::draw_unresolved_period(QPainter &p, int h, int left,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DecodeTrace::draw_unshown_row(QPainter &p, int y, int h, int left,
|
void DecodeTrace::draw_unshown_row(QPainter &p, int y, int h, int left,
|
||||||
int right)
|
int right, QString info)
|
||||||
{
|
{
|
||||||
const QRectF unshown_rect(left, y - h/2 + 0.5, right - left, h);
|
const QRectF unshown_rect(left, y - h/2 + 0.5, right - left, h);
|
||||||
|
int info_left = unshown_rect.center().x() - p.boundingRect(QRectF(), 0, info).width();
|
||||||
|
int info_right = unshown_rect.center().x() + p.boundingRect(QRectF(), 0, info).width();
|
||||||
|
int height = p.boundingRect(QRectF(), 0, info).height();
|
||||||
|
|
||||||
p.setPen(QPen(Qt::NoPen));
|
p.setPen(Trace::DARK_FORE);
|
||||||
p.setBrush(QBrush(NoDecodeColour, Qt::Dense7Pattern));
|
p.drawLine(left, y, info_left, y);
|
||||||
p.drawRect(unshown_rect);
|
p.drawLine(info_right, y, right, y);
|
||||||
|
p.drawLine(info_left, y, info_left+5, y - height/2 + 0.5);
|
||||||
|
p.drawLine(info_left, y, info_left+5, y + height/2 + 0.5);
|
||||||
|
p.drawLine(info_right, y, info_right-5, y - height/2 + 0.5);
|
||||||
|
p.drawLine(info_right, y, info_right-5, y + height/2 + 0.5);
|
||||||
|
|
||||||
p.setPen(dsLightBlue);
|
p.setPen(Trace::DARK_FORE);
|
||||||
QFont font=p.font();
|
p.drawText(unshown_rect, Qt::AlignCenter | Qt::AlignVCenter, info);
|
||||||
font.setPointSize(_view->get_signalHeight()*2/3);
|
|
||||||
font.setBold(true);
|
|
||||||
p.setFont(font);
|
|
||||||
p.drawText(unshown_rect, Qt::AlignCenter | Qt::AlignVCenter, "Unshown");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecodeTrace::create_decoder_form(int index,
|
void DecodeTrace::create_decoder_form(
|
||||||
|
boost::shared_ptr<pv::data::DecoderStack> &decoder_stack,
|
||||||
boost::shared_ptr<data::decode::Decoder> &dec, QWidget *parent,
|
boost::shared_ptr<data::decode::Decoder> &dec, QWidget *parent,
|
||||||
QFormLayout *form)
|
QFormLayout *form)
|
||||||
{
|
{
|
||||||
const GSList *l;
|
const GSList *l;
|
||||||
|
|
||||||
assert(dec);
|
assert(dec);
|
||||||
const srd_decoder *const decoder = dec->decoder();
|
const srd_decoder *const decoder = dec->decoder();
|
||||||
assert(decoder);
|
assert(decoder);
|
||||||
|
|
||||||
pv::widgets::DecoderGroupBox *const group =
|
pv::widgets::DecoderGroupBox *const group =
|
||||||
new pv::widgets::DecoderGroupBox(
|
new pv::widgets::DecoderGroupBox(decoder_stack, dec);
|
||||||
QString::fromUtf8(decoder->name));
|
connect(group, SIGNAL(del_stack(boost::shared_ptr<data::decode::Decoder>&)),
|
||||||
group->set_decoder_visible(dec->shown());
|
this, SLOT(on_del_stack(boost::shared_ptr<data::decode::Decoder>&)));
|
||||||
|
|
||||||
_show_hide_mapper.setMapping(group, index);
|
|
||||||
connect(group, SIGNAL(show_hide_decoder()),
|
|
||||||
&_show_hide_mapper, SLOT(map()));
|
|
||||||
|
|
||||||
QFormLayout *const decoder_form = new QFormLayout;
|
QFormLayout *const decoder_form = new QFormLayout;
|
||||||
group->add_layout(decoder_form);
|
group->add_layout(decoder_form);
|
||||||
@@ -739,7 +741,7 @@ void DecodeTrace::create_decoder_form(int index,
|
|||||||
|
|
||||||
// Add the options
|
// Add the options
|
||||||
boost::shared_ptr<prop::binding::DecoderOptions> binding(
|
boost::shared_ptr<prop::binding::DecoderOptions> binding(
|
||||||
new prop::binding::DecoderOptions(_decoder_stack, dec));
|
new prop::binding::DecoderOptions(decoder_stack, dec));
|
||||||
binding->add_properties_to_form(decoder_form, true);
|
binding->add_properties_to_form(decoder_form, true);
|
||||||
|
|
||||||
_bindings.push_back(binding);
|
_bindings.push_back(binding);
|
||||||
@@ -837,6 +839,7 @@ void DecodeTrace::on_decode_done()
|
|||||||
_view->set_need_update(true);
|
_view->set_need_update(true);
|
||||||
_view->signals_changed();
|
_view->signals_changed();
|
||||||
}
|
}
|
||||||
|
_session.decode_done();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecodeTrace::on_delete()
|
void DecodeTrace::on_delete()
|
||||||
@@ -860,33 +863,36 @@ void DecodeTrace::on_stack_decoder(srd_decoder *decoder)
|
|||||||
create_popup_form();
|
create_popup_form();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecodeTrace::on_show_hide_decoder(int index)
|
void DecodeTrace::on_del_stack(boost::shared_ptr<data::decode::Decoder> &dec)
|
||||||
{
|
{
|
||||||
using pv::data::decode::Decoder;
|
assert(dec);
|
||||||
|
assert(_decoder_stack);
|
||||||
|
_decoder_stack->remove(dec);
|
||||||
|
|
||||||
const list< boost::shared_ptr<Decoder> > stack(_decoder_stack->stack());
|
create_popup_form();
|
||||||
|
|
||||||
// Find the decoder in the stack
|
|
||||||
list< boost::shared_ptr<Decoder> >::const_iterator iter = stack.begin();
|
|
||||||
for(int i = 0; i < index; i++, iter++)
|
|
||||||
assert(iter != stack.end());
|
|
||||||
|
|
||||||
boost::shared_ptr<Decoder> dec = *iter;
|
|
||||||
assert(dec);
|
|
||||||
|
|
||||||
const bool show = !dec->shown();
|
|
||||||
dec->show(show);
|
|
||||||
|
|
||||||
assert(index < (int)_decoder_forms.size());
|
|
||||||
_decoder_forms[index]->set_decoder_visible(show);
|
|
||||||
|
|
||||||
//_view->set_need_update(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int DecodeTrace::rows_size()
|
int DecodeTrace::rows_size()
|
||||||
{
|
{
|
||||||
return _decoder_stack->cur_rows_size();
|
using pv::data::decode::Decoder;
|
||||||
|
|
||||||
|
int size = 0;
|
||||||
|
BOOST_FOREACH(boost::shared_ptr<data::decode::Decoder> dec,
|
||||||
|
_decoder_stack->stack()) {
|
||||||
|
if (dec->shown()) {
|
||||||
|
const std::map<const pv::data::decode::Row, bool>& rows(_decoder_stack->get_rows_gshow());
|
||||||
|
for (std::map<const pv::data::decode::Row, bool>::const_iterator i = rows.begin();
|
||||||
|
i != rows.end(); i++) {
|
||||||
|
if ((*i).first.decoder() == dec->decoder() &&
|
||||||
|
_decoder_stack->has_annotations((*i).first) &&
|
||||||
|
(*i).second)
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return size == 0 ? 1 : size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecodeTrace::paint_type_options(QPainter &p, int right, const QPoint pt)
|
void DecodeTrace::paint_type_options(QPainter &p, int right, const QPoint pt)
|
||||||
@@ -897,9 +903,8 @@ void DecodeTrace::paint_type_options(QPainter &p, int right, const QPoint pt)
|
|||||||
const QRectF group_index_rect = get_rect(CHNLREG, y, right);
|
const QRectF group_index_rect = get_rect(CHNLREG, y, right);
|
||||||
QString index_string;
|
QString index_string;
|
||||||
int last_index;
|
int last_index;
|
||||||
p.setPen(Qt::transparent);
|
p.setPen(QPen(DARK_FORE, 1, Qt::DashLine));
|
||||||
p.setBrush(dsBlue);
|
p.drawLine(group_index_rect.bottomLeft(), group_index_rect.bottomRight());
|
||||||
p.drawRect(group_index_rect);
|
|
||||||
std::list<int>::iterator i = _index_list.begin();
|
std::list<int>::iterator i = _index_list.begin();
|
||||||
last_index = (*i);
|
last_index = (*i);
|
||||||
index_string = QString::number(last_index);
|
index_string = QString::number(last_index);
|
||||||
@@ -912,7 +917,7 @@ void DecodeTrace::paint_type_options(QPainter &p, int right, const QPoint pt)
|
|||||||
index_string = QString::number((*i)) + "," + index_string;
|
index_string = QString::number((*i)) + "," + index_string;
|
||||||
last_index = (*i);
|
last_index = (*i);
|
||||||
}
|
}
|
||||||
p.setPen(Qt::white);
|
p.setPen(DARK_FORE);
|
||||||
p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string);
|
p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -986,5 +991,6 @@ void DecodeTrace::frame_ended()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace view
|
} // namespace view
|
||||||
} // namespace pv
|
} // namespace pv
|
||||||
|
|||||||
@@ -152,14 +152,14 @@ private:
|
|||||||
void draw_annotation(const pv::data::decode::Annotation &a, QPainter &p,
|
void draw_annotation(const pv::data::decode::Annotation &a, QPainter &p,
|
||||||
QColor text_colour, int text_height, int left, int right,
|
QColor text_colour, int text_height, int left, int right,
|
||||||
double samples_per_pixel, double pixels_offset, int y,
|
double samples_per_pixel, double pixels_offset, int y,
|
||||||
size_t base_colour) const;
|
size_t base_colour, double min_annWidth) const;
|
||||||
void draw_nodetail(QPainter &p,
|
void draw_nodetail(QPainter &p,
|
||||||
int text_height, int left, int right, int y,
|
int text_height, int left, int right, int y,
|
||||||
size_t base_colour) const;
|
size_t base_colour) const;
|
||||||
|
|
||||||
void draw_instant(const pv::data::decode::Annotation &a, QPainter &p,
|
void draw_instant(const pv::data::decode::Annotation &a, QPainter &p,
|
||||||
QColor fill, QColor outline, QColor text_color, int h, double x,
|
QColor fill, QColor outline, QColor text_color, int h, double x,
|
||||||
int y) const;
|
int y, double min_annWidth) const;
|
||||||
|
|
||||||
void draw_range(const pv::data::decode::Annotation &a, QPainter &p,
|
void draw_range(const pv::data::decode::Annotation &a, QPainter &p,
|
||||||
QColor fill, QColor outline, QColor text_color, int h, double start,
|
QColor fill, QColor outline, QColor text_color, int h, double start,
|
||||||
@@ -172,11 +172,11 @@ private:
|
|||||||
int right);
|
int right);
|
||||||
|
|
||||||
void draw_unshown_row(QPainter &p, int y, int h, int left,
|
void draw_unshown_row(QPainter &p, int y, int h, int left,
|
||||||
int right);
|
int right, QString info);
|
||||||
|
|
||||||
void create_decoder_form(int index,
|
void create_decoder_form(boost::shared_ptr<data::DecoderStack> &decoder_stack,
|
||||||
boost::shared_ptr<pv::data::decode::Decoder> &dec,
|
boost::shared_ptr<pv::data::decode::Decoder> &dec,
|
||||||
QWidget *parent, QFormLayout *form);
|
QWidget *parent, QFormLayout *form);
|
||||||
|
|
||||||
QComboBox* create_probe_selector(QWidget *parent,
|
QComboBox* create_probe_selector(QWidget *parent,
|
||||||
const boost::shared_ptr<pv::data::decode::Decoder> &dec,
|
const boost::shared_ptr<pv::data::decode::Decoder> &dec,
|
||||||
@@ -195,8 +195,7 @@ private slots:
|
|||||||
void on_probe_selected(int);
|
void on_probe_selected(int);
|
||||||
|
|
||||||
void on_stack_decoder(srd_decoder *decoder);
|
void on_stack_decoder(srd_decoder *decoder);
|
||||||
|
void on_del_stack(boost::shared_ptr<data::decode::Decoder> &dec);
|
||||||
void on_show_hide_decoder(int index);
|
|
||||||
|
|
||||||
void on_decode_done();
|
void on_decode_done();
|
||||||
|
|
||||||
@@ -219,7 +218,6 @@ private:
|
|||||||
|
|
||||||
std::vector<QString> _cur_row_headings;
|
std::vector<QString> _cur_row_headings;
|
||||||
|
|
||||||
QSignalMapper _show_hide_mapper;
|
|
||||||
QFormLayout *_popup_form;
|
QFormLayout *_popup_form;
|
||||||
QDialog *_popup;
|
QDialog *_popup;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -44,45 +44,50 @@ using namespace std;
|
|||||||
namespace pv {
|
namespace pv {
|
||||||
namespace view {
|
namespace view {
|
||||||
|
|
||||||
DevMode::DevMode(View &parent) :
|
DevMode::DevMode(QWidget *parent, SigSession &session) :
|
||||||
QWidget(&parent),
|
QWidget(parent),
|
||||||
_view(parent),
|
_session(session),
|
||||||
layout(new QGridLayout(this))
|
_layout(new QGridLayout(this))
|
||||||
|
|
||||||
{
|
{
|
||||||
setLayout(layout);
|
setLayout(_layout);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevMode::set_device()
|
void DevMode::set_device()
|
||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
const boost::shared_ptr<device::DevInst> dev_inst = _view.session().get_device();
|
const boost::shared_ptr<device::DevInst> dev_inst = _session.get_device();
|
||||||
|
|
||||||
assert(dev_inst);
|
assert(dev_inst);
|
||||||
|
|
||||||
|
for(std::map<QPushButton *, sr_dev_mode *>::const_iterator i = _mode_button_list.begin();
|
||||||
|
i != _mode_button_list.end(); i++) {
|
||||||
|
(*i).first->setParent(NULL);
|
||||||
|
_layout->removeWidget((*i).first);
|
||||||
|
delete (*i).first;
|
||||||
|
}
|
||||||
_mode_button_list.clear();
|
_mode_button_list.clear();
|
||||||
delete layout;
|
|
||||||
layout = new QGridLayout(this);
|
|
||||||
|
|
||||||
for (GSList *l = dev_inst->get_dev_mode_list();
|
for (GSList *l = dev_inst->get_dev_mode_list();
|
||||||
l; l = l->next) {
|
l; l = l->next) {
|
||||||
sr_dev_mode *mode = (sr_dev_mode *)l->data;
|
sr_dev_mode *mode = (sr_dev_mode *)l->data;
|
||||||
|
|
||||||
boost::shared_ptr<QPushButton> mode_button = boost::shared_ptr<QPushButton>(new QPushButton(NULL));
|
QPushButton *mode_button = new QPushButton(this);
|
||||||
mode_button->setFlat(true);
|
//mode_button->setFlat(true);
|
||||||
mode_button->setText(mode->name);
|
mode_button->setText(mode->name);
|
||||||
|
mode_button->setCheckable(true);
|
||||||
|
|
||||||
_mode_button_list[mode_button] = mode;
|
_mode_button_list[mode_button] = mode;
|
||||||
|
if (dev_inst->dev_inst()->mode == _mode_button_list[mode_button]->mode)
|
||||||
|
mode_button->setChecked(true);
|
||||||
|
|
||||||
connect(mode_button.get(), SIGNAL(clicked()), this, SLOT(on_mode_change()));
|
connect(mode_button, SIGNAL(clicked()), this, SLOT(on_mode_change()));
|
||||||
|
|
||||||
layout->addWidget(mode_button.get(), index / GRID_COLS, index % GRID_COLS);
|
_layout->addWidget(mode_button, index / GRID_COLS, index % GRID_COLS);
|
||||||
layout->addWidget(new QWidget(), index / GRID_COLS, GRID_COLS);
|
//layout->addWidget(new QWidget(), index / GRID_COLS, GRID_COLS);
|
||||||
layout->setColumnStretch(GRID_COLS, 1);
|
_layout->setColumnStretch(GRID_COLS, 1);
|
||||||
index++;
|
index++;
|
||||||
}
|
}
|
||||||
|
|
||||||
setLayout(layout);
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,40 +99,27 @@ void DevMode::paintEvent(QPaintEvent*)
|
|||||||
o.initFrom(this);
|
o.initFrom(this);
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
style()->drawPrimitive(QStyle::PE_Widget, &o, &painter, this);
|
style()->drawPrimitive(QStyle::PE_Widget, &o, &painter, this);
|
||||||
|
|
||||||
painter.setRenderHint(QPainter::Antialiasing);
|
|
||||||
painter.setPen(Qt::NoPen);
|
|
||||||
for(std::map<boost::shared_ptr<QPushButton>, sr_dev_mode *>::const_iterator i = _mode_button_list.begin();
|
|
||||||
i != _mode_button_list.end(); i++) {
|
|
||||||
const boost::shared_ptr<device::DevInst> dev_inst = _view.session().get_device();
|
|
||||||
assert(dev_inst);
|
|
||||||
if (dev_inst->dev_inst()->mode == (*i).second->mode)
|
|
||||||
painter.setBrush(Trace::dsBlue);
|
|
||||||
else
|
|
||||||
painter.setBrush(Trace::dsGray);
|
|
||||||
|
|
||||||
painter.drawRoundedRect((*i).first->geometry(), 4, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
painter.end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevMode::on_mode_change()
|
void DevMode::on_mode_change()
|
||||||
{
|
{
|
||||||
const boost::shared_ptr<device::DevInst> dev_inst = _view.session().get_device();
|
const boost::shared_ptr<device::DevInst> dev_inst = _session.get_device();
|
||||||
assert(dev_inst);
|
assert(dev_inst);
|
||||||
QPushButton *button = qobject_cast<QPushButton *>(sender());
|
QPushButton *button = qobject_cast<QPushButton *>(sender());
|
||||||
|
|
||||||
for(std::map<boost::shared_ptr<QPushButton>, sr_dev_mode *>::const_iterator i = _mode_button_list.begin();
|
for(std::map<QPushButton *, sr_dev_mode *>::const_iterator i = _mode_button_list.begin();
|
||||||
i != _mode_button_list.end(); i++) {
|
i != _mode_button_list.end(); i++) {
|
||||||
if ((*i).first.get() == button) {
|
if ((*i).first == button) {
|
||||||
if (dev_inst->dev_inst()->mode != (*i).second->mode) {
|
if (dev_inst->dev_inst()->mode != (*i).second->mode) {
|
||||||
_view.session().stop_capture();
|
_session.stop_capture();
|
||||||
dev_inst->set_config(NULL, NULL,
|
dev_inst->set_config(NULL, NULL,
|
||||||
SR_CONF_DEVICE_MODE,
|
SR_CONF_DEVICE_MODE,
|
||||||
g_variant_new_int16((*i).second->mode));
|
g_variant_new_int16((*i).second->mode));
|
||||||
|
button->setChecked(true);
|
||||||
mode_changed();
|
mode_changed();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
(*i).first->setChecked(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,9 +44,9 @@ namespace device{
|
|||||||
class DevInst;
|
class DevInst;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace view {
|
class SigSession;
|
||||||
|
|
||||||
class View;
|
namespace view {
|
||||||
|
|
||||||
class DevMode : public QWidget
|
class DevMode : public QWidget
|
||||||
{
|
{
|
||||||
@@ -56,7 +56,7 @@ private:
|
|||||||
static const int GRID_COLS = 3;
|
static const int GRID_COLS = 3;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DevMode(View &parent);
|
DevMode(QWidget *parent, SigSession &session);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void paintEvent(QPaintEvent *event);
|
void paintEvent(QPaintEvent *event);
|
||||||
@@ -77,10 +77,10 @@ signals:
|
|||||||
void mode_changed();
|
void mode_changed();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
View &_view;
|
SigSession &_session;
|
||||||
|
|
||||||
QGridLayout * layout;
|
QGridLayout * _layout;
|
||||||
std::map <boost::shared_ptr<QPushButton>, sr_dev_mode *> _mode_button_list;
|
std::map <QPushButton *, sr_dev_mode *> _mode_button_list;
|
||||||
QPoint _mouse_point;
|
QPoint _mouse_point;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -204,9 +204,8 @@ void GroupSignal::paint_type_options(QPainter &p, int right, const QPoint pt)
|
|||||||
const QRectF group_index_rect = get_rect(CHNLREG, y, right);
|
const QRectF group_index_rect = get_rect(CHNLREG, y, right);
|
||||||
QString index_string;
|
QString index_string;
|
||||||
int last_index;
|
int last_index;
|
||||||
p.setPen(Qt::transparent);
|
p.setPen(QPen(DARK_FORE, 1, Qt::DashLine));
|
||||||
p.setBrush(dsBlue);
|
p.drawLine(group_index_rect.bottomLeft(), group_index_rect.bottomRight());
|
||||||
p.drawRect(group_index_rect);
|
|
||||||
std::list<int>::iterator i = _index_list.begin();
|
std::list<int>::iterator i = _index_list.begin();
|
||||||
last_index = (*i);
|
last_index = (*i);
|
||||||
index_string = QString::number(last_index);
|
index_string = QString::number(last_index);
|
||||||
@@ -219,7 +218,7 @@ void GroupSignal::paint_type_options(QPainter &p, int right, const QPoint pt)
|
|||||||
index_string = QString::number((*i)) + "," + index_string;
|
index_string = QString::number((*i)) + "," + index_string;
|
||||||
last_index = (*i);
|
last_index = (*i);
|
||||||
}
|
}
|
||||||
p.setPen(Qt::white);
|
p.setPen(DARK_FORE);
|
||||||
p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string);
|
p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -115,15 +115,13 @@ void Header::paintEvent(QPaintEvent*)
|
|||||||
QStyleOption o;
|
QStyleOption o;
|
||||||
o.initFrom(this);
|
o.initFrom(this);
|
||||||
QPainter painter(this);
|
QPainter painter(this);
|
||||||
|
//painter.setRenderHint(QPainter::Antialiasing);
|
||||||
style()->drawPrimitive(QStyle::PE_Widget, &o, &painter, this);
|
style()->drawPrimitive(QStyle::PE_Widget, &o, &painter, this);
|
||||||
|
|
||||||
const int w = width();
|
const int w = width();
|
||||||
const vector< boost::shared_ptr<Trace> > traces(
|
const vector< boost::shared_ptr<Trace> > traces(
|
||||||
_view.get_traces());
|
_view.get_traces());
|
||||||
|
|
||||||
//QPainter painter(this);
|
|
||||||
//painter.setRenderHint(QPainter::Antialiasing);
|
|
||||||
|
|
||||||
const bool dragging = !_drag_traces.empty();
|
const bool dragging = !_drag_traces.empty();
|
||||||
BOOST_FOREACH(const boost::shared_ptr<Trace> t, traces)
|
BOOST_FOREACH(const boost::shared_ptr<Trace> t, traces)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -44,24 +44,7 @@ const QColor LogicSignal::EdgeColour(0x80, 0x80, 0x80);
|
|||||||
const QColor LogicSignal::HighColour(0x00, 0xC0, 0x00);
|
const QColor LogicSignal::HighColour(0x00, 0xC0, 0x00);
|
||||||
const QColor LogicSignal::LowColour(0xC0, 0x00, 0x00);
|
const QColor LogicSignal::LowColour(0xC0, 0x00, 0x00);
|
||||||
|
|
||||||
const QColor LogicSignal::SignalColours[8] = {
|
const QColor LogicSignal::DEFAULT_COLOR = QColor(150, 150, 150, 255);
|
||||||
QColor(0x16, 0x19, 0x1A), // Black
|
|
||||||
QColor(0x8F, 0x52, 0x02), // Brown
|
|
||||||
QColor(0xCC, 0x00, 0x00), // Red
|
|
||||||
QColor(0xF5, 0x79, 0x00), // Orange
|
|
||||||
QColor(0xED, 0xD4, 0x00), // Yellow
|
|
||||||
QColor(0x73, 0xD2, 0x16), // Green
|
|
||||||
QColor(0x34, 0x65, 0xA4), // Blue
|
|
||||||
QColor(0x75, 0x50, 0x7B), // Violet
|
|
||||||
// QColor(17, 133, 209),
|
|
||||||
// QColor(17, 133, 209),
|
|
||||||
// QColor(17, 133, 209),
|
|
||||||
// QColor(17, 133, 209),
|
|
||||||
// QColor(17, 133, 209),
|
|
||||||
// QColor(17, 133, 209),
|
|
||||||
// QColor(17, 133, 209),
|
|
||||||
// QColor(17, 133, 209),
|
|
||||||
};
|
|
||||||
|
|
||||||
const int LogicSignal::StateHeight = 12;
|
const int LogicSignal::StateHeight = 12;
|
||||||
const int LogicSignal::StateRound = 5;
|
const int LogicSignal::StateRound = 5;
|
||||||
@@ -73,7 +56,8 @@ LogicSignal::LogicSignal(boost::shared_ptr<pv::device::DevInst> dev_inst,
|
|||||||
_data(data),
|
_data(data),
|
||||||
_trig(NONTRIG)
|
_trig(NONTRIG)
|
||||||
{
|
{
|
||||||
_colour = SignalColours[probe->index % countof(SignalColours)];
|
//_colour = PROBE_COLORS[probe->index % countof(PROBE_COLORS)];
|
||||||
|
_colour = DEFAULT_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
LogicSignal::LogicSignal(boost::shared_ptr<view::LogicSignal> s,
|
LogicSignal::LogicSignal(boost::shared_ptr<view::LogicSignal> s,
|
||||||
@@ -249,35 +233,37 @@ void LogicSignal::paint_type_options(QPainter &p, int right, const QPoint pt)
|
|||||||
const QRectF lowTrig_rect = get_rect(LOWTRIG, y, right);
|
const QRectF lowTrig_rect = get_rect(LOWTRIG, y, right);
|
||||||
const QRectF edgeTrig_rect = get_rect(EDGTRIG, y, right);
|
const QRectF edgeTrig_rect = get_rect(EDGTRIG, y, right);
|
||||||
|
|
||||||
p.setPen(Qt::transparent);
|
p.setPen(Qt::NoPen);
|
||||||
p.setBrush(posTrig_rect.contains(pt) ? dsYellow.darker() :
|
p.setBrush(posTrig_rect.contains(pt) ? dsBlue.lighter() :
|
||||||
(_trig == POSTRIG) ? dsYellow : dsBlue);
|
(_trig == POSTRIG) ? dsBlue : DARK_BACK);
|
||||||
p.drawRect(posTrig_rect);
|
p.drawRect(posTrig_rect);
|
||||||
p.setBrush(higTrig_rect.contains(pt) ? dsYellow.darker() :
|
p.setBrush(higTrig_rect.contains(pt) ? dsBlue.lighter() :
|
||||||
(_trig == HIGTRIG) ? dsYellow : dsBlue);
|
(_trig == HIGTRIG) ? dsBlue : DARK_BACK);
|
||||||
p.drawRect(higTrig_rect);
|
p.drawRect(higTrig_rect);
|
||||||
p.setBrush(negTrig_rect.contains(pt) ? dsYellow.darker() :
|
p.setBrush(negTrig_rect.contains(pt) ? dsBlue.lighter() :
|
||||||
(_trig == NEGTRIG) ? dsYellow : dsBlue);
|
(_trig == NEGTRIG) ? dsBlue : DARK_BACK);
|
||||||
p.drawRect(negTrig_rect);
|
p.drawRect(negTrig_rect);
|
||||||
p.setBrush(lowTrig_rect.contains(pt) ? dsYellow.darker() :
|
p.setBrush(lowTrig_rect.contains(pt) ? dsBlue.lighter() :
|
||||||
(_trig == LOWTRIG) ? dsYellow : dsBlue);
|
(_trig == LOWTRIG) ? dsBlue : DARK_BACK);
|
||||||
p.drawRect(lowTrig_rect);
|
p.drawRect(lowTrig_rect);
|
||||||
p.setBrush(edgeTrig_rect.contains(pt) ? dsYellow.darker() :
|
p.setBrush(edgeTrig_rect.contains(pt) ? dsBlue.lighter() :
|
||||||
(_trig == EDGTRIG) ? dsYellow : dsBlue);
|
(_trig == EDGTRIG) ? dsBlue : DARK_BACK);
|
||||||
p.drawRect(edgeTrig_rect);
|
p.drawRect(edgeTrig_rect);
|
||||||
|
|
||||||
p.setPen(QPen(Qt::blue, 1, Qt::DotLine));
|
p.setPen(QPen(DARK_FORE, 1, Qt::DashLine));
|
||||||
p.setBrush(Qt::transparent);
|
p.setBrush(Qt::transparent);
|
||||||
p.drawLine(posTrig_rect.right(), posTrig_rect.top() + 3,
|
// p.drawLine(posTrig_rect.right(), posTrig_rect.top(),
|
||||||
posTrig_rect.right(), posTrig_rect.bottom() - 3);
|
// posTrig_rect.right(), posTrig_rect.bottom());
|
||||||
p.drawLine(higTrig_rect.right(), higTrig_rect.top() + 3,
|
// p.drawLine(higTrig_rect.right(), higTrig_rect.top(),
|
||||||
higTrig_rect.right(), higTrig_rect.bottom() - 3);
|
// higTrig_rect.right(), higTrig_rect.bottom());
|
||||||
p.drawLine(negTrig_rect.right(), negTrig_rect.top() + 3,
|
// p.drawLine(negTrig_rect.right(), negTrig_rect.top(),
|
||||||
negTrig_rect.right(), negTrig_rect.bottom() - 3);
|
// negTrig_rect.right(), negTrig_rect.bottom());
|
||||||
p.drawLine(lowTrig_rect.right(), lowTrig_rect.top() + 3,
|
// p.drawLine(lowTrig_rect.right(), lowTrig_rect.top(),
|
||||||
lowTrig_rect.right(), lowTrig_rect.bottom() - 3);
|
// lowTrig_rect.right(), lowTrig_rect.bottom());
|
||||||
|
p.drawLine(posTrig_rect.left(), posTrig_rect.bottom(),
|
||||||
|
edgeTrig_rect.right(), edgeTrig_rect.bottom());
|
||||||
|
|
||||||
p.setPen(QPen(Qt::white, 2, Qt::SolidLine));
|
p.setPen(QPen(DARK_FORE, 2, Qt::SolidLine));
|
||||||
p.setBrush(Qt::transparent);
|
p.setBrush(Qt::transparent);
|
||||||
p.drawLine(posTrig_rect.left() + 5, posTrig_rect.bottom() - 5,
|
p.drawLine(posTrig_rect.left() + 5, posTrig_rect.bottom() - 5,
|
||||||
posTrig_rect.center().x(), posTrig_rect.bottom() - 5);
|
posTrig_rect.center().x(), posTrig_rect.bottom() - 5);
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ private:
|
|||||||
static const QColor HighColour;
|
static const QColor HighColour;
|
||||||
static const QColor LowColour;
|
static const QColor LowColour;
|
||||||
|
|
||||||
static const QColor SignalColours[8];
|
static const QColor DEFAULT_COLOR;
|
||||||
|
|
||||||
static const int StateHeight;
|
static const int StateHeight;
|
||||||
static const int StateRound;
|
static const int StateRound;
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ const QColor Ruler::dsBlue = QColor(17, 133, 209, 255);
|
|||||||
const QColor Ruler::dsYellow = QColor(238, 178, 17, 255);
|
const QColor Ruler::dsYellow = QColor(238, 178, 17, 255);
|
||||||
const QColor Ruler::dsRed = QColor(213, 15, 37, 255);
|
const QColor Ruler::dsRed = QColor(213, 15, 37, 255);
|
||||||
const QColor Ruler::dsGreen = QColor(0, 153, 37, 255);
|
const QColor Ruler::dsGreen = QColor(0, 153, 37, 255);
|
||||||
|
const QColor Ruler::RULER_COLOR = QColor(255, 255, 255, 255);
|
||||||
|
|
||||||
const QColor Ruler::HitColor = dsYellow;
|
const QColor Ruler::HitColor = dsYellow;
|
||||||
const QColor Ruler::WarnColor = dsRed;
|
const QColor Ruler::WarnColor = dsRed;
|
||||||
@@ -458,7 +459,7 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
|
|||||||
AlignLeft | AlignTop, "8").height();
|
AlignLeft | AlignTop, "8").height();
|
||||||
|
|
||||||
// Draw the tick marks
|
// Draw the tick marks
|
||||||
p.setPen(dsBlue);
|
p.setPen(Trace::DARK_FORE);
|
||||||
|
|
||||||
const double minor_tick_period = tick_period / MinPeriodScale;
|
const double minor_tick_period = tick_period / MinPeriodScale;
|
||||||
const int minor_order = (int)floorf(log10f(minor_tick_period));
|
const int minor_order = (int)floorf(log10f(minor_tick_period));
|
||||||
@@ -548,7 +549,7 @@ void Ruler::draw_hover_mark(QPainter &p)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
p.setPen(QPen(Qt::NoPen));
|
p.setPen(QPen(Qt::NoPen));
|
||||||
p.setBrush(dsBlue);
|
p.setBrush(RULER_COLOR);
|
||||||
|
|
||||||
const int b = height() - 1;
|
const int b = height() - 1;
|
||||||
const QPointF points[] = {
|
const QPointF points[] = {
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ private:
|
|||||||
static const QColor dsYellow;
|
static const QColor dsYellow;
|
||||||
static const QColor dsRed;
|
static const QColor dsRed;
|
||||||
static const QColor dsGreen;
|
static const QColor dsGreen;
|
||||||
|
static const QColor RULER_COLOR;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const QColor CursorColor[8];
|
static const QColor CursorColor[8];
|
||||||
|
|||||||
@@ -50,6 +50,29 @@ const QColor Trace::dsLightBlue = QColor(17, 133, 209, 150);
|
|||||||
const QColor Trace::dsLightRed = QColor(213, 15, 37, 150);
|
const QColor Trace::dsLightRed = QColor(213, 15, 37, 150);
|
||||||
const QPen Trace::SignalAxisPen = QColor(128, 128, 128, 64);
|
const QPen Trace::SignalAxisPen = QColor(128, 128, 128, 64);
|
||||||
|
|
||||||
|
const QColor Trace::DARK_BACK = QColor(48, 47, 47, 255);
|
||||||
|
const QColor Trace::DARK_FORE = QColor(150, 150, 150, 255);
|
||||||
|
const QColor Trace::DARK_HIGHLIGHT = QColor(32, 32, 32, 255);
|
||||||
|
|
||||||
|
const QColor Trace::PROBE_COLORS[8] = {
|
||||||
|
QColor(0x50, 0x50, 0x50), // Black
|
||||||
|
QColor(0x8F, 0x52, 0x02), // Brown
|
||||||
|
QColor(0xCC, 0x00, 0x00), // Red
|
||||||
|
QColor(0xF5, 0x79, 0x00), // Orange
|
||||||
|
QColor(0xED, 0xD4, 0x00), // Yellow
|
||||||
|
QColor(0x73, 0xD2, 0x16), // Green
|
||||||
|
QColor(0x34, 0x65, 0xA4), // Blue
|
||||||
|
QColor(0x75, 0x50, 0x7B), // Violet
|
||||||
|
// QColor(17, 133, 209),
|
||||||
|
// QColor(17, 133, 209),
|
||||||
|
// QColor(17, 133, 209),
|
||||||
|
// QColor(17, 133, 209),
|
||||||
|
// QColor(17, 133, 209),
|
||||||
|
// QColor(17, 133, 209),
|
||||||
|
// QColor(17, 133, 209),
|
||||||
|
// QColor(17, 133, 209),
|
||||||
|
};
|
||||||
|
|
||||||
const QPen Trace::AxisPen(QColor(128, 128, 128, 64));
|
const QPen Trace::AxisPen(QColor(128, 128, 128, 64));
|
||||||
const int Trace::LabelHitPadding = 2;
|
const int Trace::LabelHitPadding = 2;
|
||||||
|
|
||||||
@@ -220,14 +243,14 @@ void Trace::paint_label(QPainter &p, int right, const QPoint pt)
|
|||||||
const QRectF name_rect = get_rect("name", y, right);
|
const QRectF name_rect = get_rect("name", y, right);
|
||||||
const QRectF label_rect = get_rect("label", get_zeroPos(), right);
|
const QRectF label_rect = get_rect("label", get_zeroPos(), right);
|
||||||
|
|
||||||
p.setRenderHint(QPainter::Antialiasing);
|
//p.setRenderHint(QPainter::Antialiasing);
|
||||||
// Paint the ColorButton
|
// Paint the ColorButton
|
||||||
p.setPen(Qt::transparent);
|
p.setPen(Qt::transparent);
|
||||||
p.setBrush(enabled() ? _colour : dsDisable);
|
p.setBrush(enabled() ? _colour : dsDisable);
|
||||||
p.drawRect(color_rect);
|
p.drawRect(color_rect);
|
||||||
|
|
||||||
// Paint the signal name
|
// Paint the signal name
|
||||||
p.setPen(enabled() ? Qt::black : dsDisable);
|
p.setPen(enabled() ? DARK_FORE: dsDisable);
|
||||||
p.drawText(name_rect, Qt::AlignLeft | Qt::AlignVCenter, _name);
|
p.drawText(name_rect, Qt::AlignLeft | Qt::AlignVCenter, _name);
|
||||||
|
|
||||||
// Paint the trigButton
|
// Paint the trigButton
|
||||||
@@ -244,16 +267,14 @@ void Trace::paint_label(QPainter &p, int right, const QPoint pt)
|
|||||||
};
|
};
|
||||||
|
|
||||||
p.setPen(Qt::transparent);
|
p.setPen(Qt::transparent);
|
||||||
if (_type == SR_CHANNEL_DSO)
|
if (_type == SR_CHANNEL_DSO) {
|
||||||
p.setBrush((label_rect.contains(pt) || selected()) ? _colour.darker() : _colour);
|
p.setBrush((label_rect.contains(pt) || selected()) ? _colour.darker() : _colour);
|
||||||
else
|
p.drawPolygon(points, countof(points));
|
||||||
p.setBrush((label_rect.contains(pt) || selected()) ? dsYellow : dsBlue);
|
} else {
|
||||||
p.drawPolygon(points, countof(points));
|
QColor color = PROBE_COLORS[*_index_list.begin() % countof(PROBE_COLORS)];
|
||||||
|
p.setBrush((label_rect.contains(pt) || selected()) ? color.lighter() : color);
|
||||||
p.setPen(QPen(Qt::blue, 1, Qt::DotLine));
|
p.drawPolygon(points, countof(points));
|
||||||
p.setBrush(Qt::transparent);
|
}
|
||||||
p.drawLine(label_rect.right(), label_rect.top() + 3,
|
|
||||||
label_rect.right(), label_rect.bottom() - 3);
|
|
||||||
|
|
||||||
// Paint the text
|
// Paint the text
|
||||||
p.setPen(Qt::white);
|
p.setPen(Qt::white);
|
||||||
@@ -326,30 +347,6 @@ void Trace::compute_text_size(QPainter &p)
|
|||||||
p.boundingRect(QRectF(), 0, "99").height());
|
p.boundingRect(QRectF(), 0, "99").height());
|
||||||
}
|
}
|
||||||
|
|
||||||
QRectF Trace::get_rect(const char *s, int y, int right)
|
|
||||||
{
|
|
||||||
const QSizeF color_size(SquareWidth, SquareWidth);
|
|
||||||
const QSizeF name_size(right - get_leftWidth() - get_rightWidth(), SquareWidth);
|
|
||||||
//const QSizeF label_size(_text_size.width() + Margin, SquareWidth);
|
|
||||||
const QSizeF label_size(SquareWidth, SquareWidth);
|
|
||||||
|
|
||||||
if (!strcmp(s, "name"))
|
|
||||||
return QRectF(
|
|
||||||
get_leftWidth(),
|
|
||||||
y - name_size.height() / 2,
|
|
||||||
name_size.width(), name_size.height());
|
|
||||||
else if (!strcmp(s, "label"))
|
|
||||||
return QRectF(
|
|
||||||
right - 1.5f * label_size.width(),
|
|
||||||
y - SquareWidth / 2,
|
|
||||||
label_size.width(), label_size.height());
|
|
||||||
else
|
|
||||||
return QRectF(
|
|
||||||
2,
|
|
||||||
y - SquareWidth / 2,
|
|
||||||
SquareWidth, SquareWidth);
|
|
||||||
}
|
|
||||||
|
|
||||||
QRectF Trace::get_view_rect() const
|
QRectF Trace::get_view_rect() const
|
||||||
{
|
{
|
||||||
assert(_view);
|
assert(_view);
|
||||||
@@ -385,7 +382,7 @@ int Trace::rows_size()
|
|||||||
|
|
||||||
int Trace::get_leftWidth() const
|
int Trace::get_leftWidth() const
|
||||||
{
|
{
|
||||||
return SquareWidth + Margin;
|
return SquareWidth/2 + Margin;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Trace::get_rightWidth() const
|
int Trace::get_rightWidth() const
|
||||||
@@ -398,5 +395,34 @@ int Trace::get_headerHeight() const
|
|||||||
return SquareWidth;
|
return SquareWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRectF Trace::get_rect(const char *s, int y, int right) const
|
||||||
|
{
|
||||||
|
const QSizeF color_size(get_leftWidth() - Margin, SquareWidth);
|
||||||
|
const QSizeF name_size(right - get_leftWidth() - get_rightWidth(), SquareWidth);
|
||||||
|
//const QSizeF label_size(_text_size.width() + Margin, SquareWidth);
|
||||||
|
const QSizeF label_size(SquareWidth, SquareWidth);
|
||||||
|
|
||||||
|
if (!strcmp(s, "name"))
|
||||||
|
return QRectF(
|
||||||
|
get_leftWidth(),
|
||||||
|
y - name_size.height() / 2,
|
||||||
|
name_size.width(), name_size.height());
|
||||||
|
else if (!strcmp(s, "label"))
|
||||||
|
return QRectF(
|
||||||
|
right - 1.5f * label_size.width(),
|
||||||
|
y - label_size.height() / 2,
|
||||||
|
label_size.width(), label_size.height());
|
||||||
|
else if (!strcmp(s, "color"))
|
||||||
|
return QRectF(
|
||||||
|
2,
|
||||||
|
y - color_size.height() / 2,
|
||||||
|
color_size.width(), color_size.height());
|
||||||
|
else
|
||||||
|
return QRectF(
|
||||||
|
2,
|
||||||
|
y - SquareWidth / 2,
|
||||||
|
SquareWidth, SquareWidth);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace view
|
} // namespace view
|
||||||
} // namespace pv
|
} // namespace pv
|
||||||
|
|||||||
@@ -70,6 +70,12 @@ public:
|
|||||||
static const QColor dsLightRed;
|
static const QColor dsLightRed;
|
||||||
static const QPen SignalAxisPen;
|
static const QPen SignalAxisPen;
|
||||||
|
|
||||||
|
static const QColor DARK_BACK;
|
||||||
|
static const QColor DARK_FORE;
|
||||||
|
static const QColor DARK_HIGHLIGHT;
|
||||||
|
|
||||||
|
static const QColor PROBE_COLORS[8];
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Trace(QString name, uint16_t index, int type);
|
Trace(QString name, uint16_t index, int type);
|
||||||
Trace(QString name, std::list<int> index_list, int type, int sec_index);
|
Trace(QString name, std::list<int> index_list, int type, int sec_index);
|
||||||
@@ -225,7 +231,7 @@ public:
|
|||||||
* area.
|
* area.
|
||||||
* @return Returns the rectangle of the signal label.
|
* @return Returns the rectangle of the signal label.
|
||||||
*/
|
*/
|
||||||
QRectF get_rect(const char *s, int y, int right);
|
QRectF get_rect(const char *s, int y, int right) const;
|
||||||
|
|
||||||
virtual int rows_size();
|
virtual int rows_size();
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget
|
|||||||
_viewport(new Viewport(*this)),
|
_viewport(new Viewport(*this)),
|
||||||
_ruler(new Ruler(*this)),
|
_ruler(new Ruler(*this)),
|
||||||
_header(new Header(*this)),
|
_header(new Header(*this)),
|
||||||
_devmode(new DevMode(*this)),
|
_devmode(new DevMode(this, session)),
|
||||||
_scale(1e-8),
|
_scale(1e-8),
|
||||||
_preScale(1e-6),
|
_preScale(1e-6),
|
||||||
_maxscale(1e9),
|
_maxscale(1e9),
|
||||||
@@ -98,15 +98,17 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget
|
|||||||
setViewportMargins(headerWidth(), RulerHeight, 0, 0);
|
setViewportMargins(headerWidth(), RulerHeight, 0, 0);
|
||||||
setViewport(_viewport);
|
setViewport(_viewport);
|
||||||
|
|
||||||
|
connect(&_session, SIGNAL(device_setted()),
|
||||||
|
_devmode, SLOT(set_device()));
|
||||||
connect(&_session, SIGNAL(signals_changed()),
|
connect(&_session, SIGNAL(signals_changed()),
|
||||||
this, SLOT(signals_changed()));
|
this, SLOT(signals_changed()));
|
||||||
connect(&_session, SIGNAL(data_updated()),
|
connect(&_session, SIGNAL(data_updated()),
|
||||||
this, SLOT(data_updated()));
|
this, SLOT(data_updated()));
|
||||||
connect(&_session, SIGNAL(receive_trigger(quint64)),
|
connect(&_session, SIGNAL(receive_trigger(quint64)),
|
||||||
this, SLOT(set_trig_pos(quint64)));
|
this, SLOT(set_trig_pos(quint64)));
|
||||||
|
connect(&_session, SIGNAL(show_region(uint64_t,uint64_t)),
|
||||||
|
this, SLOT(show_region(uint64_t, uint64_t)));
|
||||||
|
|
||||||
connect(&_session, SIGNAL(device_setted()),
|
|
||||||
_devmode, SLOT(set_device()));
|
|
||||||
connect(_devmode, SIGNAL(mode_changed()),
|
connect(_devmode, SIGNAL(mode_changed()),
|
||||||
this, SIGNAL(mode_changed()));
|
this, SIGNAL(mode_changed()));
|
||||||
|
|
||||||
@@ -464,9 +466,9 @@ void View::update_scale()
|
|||||||
}
|
}
|
||||||
|
|
||||||
_minscale = (1.0 / sample_rate) / MaxPixelsPerSample;
|
_minscale = (1.0 / sample_rate) / MaxPixelsPerSample;
|
||||||
_offset = 0;
|
//_offset = 0;
|
||||||
_preScale = _scale;
|
_preScale = _scale;
|
||||||
_preOffset = _offset;
|
//_preOffset = _offset;
|
||||||
|
|
||||||
_trig_cursor->set_index(_trig_pos);
|
_trig_cursor->set_index(_trig_pos);
|
||||||
|
|
||||||
@@ -514,6 +516,7 @@ void View::signals_changed()
|
|||||||
_viewport->clear_measure();
|
_viewport->clear_measure();
|
||||||
header_updated();
|
header_updated();
|
||||||
normalize_layout();
|
normalize_layout();
|
||||||
|
data_updated();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool View::eventFilter(QObject *object, QEvent *event)
|
bool View::eventFilter(QObject *object, QEvent *event)
|
||||||
@@ -834,5 +837,14 @@ QString View::trigger_time()
|
|||||||
return _trigger_time.toString("yyyy-MM-dd hh:mm:ss ddd");
|
return _trigger_time.toString("yyyy-MM-dd hh:mm:ss ddd");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void View::show_region(uint64_t start, uint64_t end)
|
||||||
|
{
|
||||||
|
assert(start <= end);
|
||||||
|
const double ideal_scale = (end-start) * 2.0 / _session.get_device()->get_sample_rate() / get_view_width();
|
||||||
|
const double new_scale = max(min(ideal_scale, _maxscale), _minscale);
|
||||||
|
const double new_off = (start + end) * 0.5 / _session.get_device()->get_sample_rate() - new_scale * get_view_width() / 2;
|
||||||
|
set_scale_offset(new_scale, new_off);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace view
|
} // namespace view
|
||||||
} // namespace pv
|
} // namespace pv
|
||||||
|
|||||||
@@ -221,6 +221,7 @@ public slots:
|
|||||||
void signals_changed();
|
void signals_changed();
|
||||||
void data_updated();
|
void data_updated();
|
||||||
void update_scale();
|
void update_scale();
|
||||||
|
void show_region(uint64_t start, uint64_t end);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
||||||
|
|||||||
@@ -445,11 +445,11 @@ void Viewport::mouseMoveEvent(QMouseEvent *event)
|
|||||||
|
|
||||||
if (_action_type == DSO_YM)
|
if (_action_type == DSO_YM)
|
||||||
_dso_ym_end = event->pos().y();
|
_dso_ym_end = event->pos().y();
|
||||||
|
|
||||||
measure();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_mouse_point = event->pos();
|
_mouse_point = event->pos();
|
||||||
|
|
||||||
|
measure();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -719,7 +719,6 @@ void Viewport::leaveEvent(QEvent *)
|
|||||||
_mm_period = "#####";
|
_mm_period = "#####";
|
||||||
_mm_freq = "#####";
|
_mm_freq = "#####";
|
||||||
_mm_duty = "#####";
|
_mm_duty = "#####";
|
||||||
measure_updated();
|
|
||||||
} else if (_action_type == DSO_YM) {
|
} else if (_action_type == DSO_YM) {
|
||||||
_dso_ym_valid = false;
|
_dso_ym_valid = false;
|
||||||
}
|
}
|
||||||
@@ -727,6 +726,7 @@ void Viewport::leaveEvent(QEvent *)
|
|||||||
if (_action_type != NO_ACTION)
|
if (_action_type != NO_ACTION)
|
||||||
_action_type = NO_ACTION;
|
_action_type = NO_ACTION;
|
||||||
|
|
||||||
|
measure();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -767,7 +767,7 @@ void Viewport::measure()
|
|||||||
boost::shared_ptr<view::DsoSignal> dsoSig;
|
boost::shared_ptr<view::DsoSignal> dsoSig;
|
||||||
if (logicSig = dynamic_pointer_cast<view::LogicSignal>(s)) {
|
if (logicSig = dynamic_pointer_cast<view::LogicSignal>(s)) {
|
||||||
if (_action_type == NO_ACTION) {
|
if (_action_type == NO_ACTION) {
|
||||||
if (logicSig->measure(_view.hover_point(), _cur_sample, _nxt_sample, _thd_sample)) {
|
if (logicSig->measure(_mouse_point, _cur_sample, _nxt_sample, _thd_sample)) {
|
||||||
_measure_type = LOGIC_FREQ;
|
_measure_type = LOGIC_FREQ;
|
||||||
|
|
||||||
_mm_width = _view.get_ruler()->format_real_time(_nxt_sample - _cur_sample, sample_rate);
|
_mm_width = _view.get_ruler()->format_real_time(_nxt_sample - _cur_sample, sample_rate);
|
||||||
@@ -1173,7 +1173,7 @@ void Viewport::on_drag_timer()
|
|||||||
void Viewport::paintTrigTime(QPainter &p)
|
void Viewport::paintTrigTime(QPainter &p)
|
||||||
{
|
{
|
||||||
if (_view.session().get_device()->dev_inst()->mode == LOGIC) {
|
if (_view.session().get_device()->dev_inst()->mode == LOGIC) {
|
||||||
p.setPen(Trace::dsBack);
|
p.setPen(Trace::DARK_FORE);
|
||||||
p.drawText(this->rect(), Qt::AlignRight | Qt::AlignBottom,
|
p.drawText(this->rect(), Qt::AlignRight | Qt::AlignBottom,
|
||||||
"Last Trigger Time: "+_view.trigger_time());
|
"Last Trigger Time: "+_view.trigger_time());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,52 +17,134 @@
|
|||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*/
|
*/
|
||||||
|
extern "C" {
|
||||||
|
#include <libsigrokdecode/libsigrokdecode.h>
|
||||||
|
}
|
||||||
|
|
||||||
#include "decodergroupbox.h"
|
#include "decodergroupbox.h"
|
||||||
|
#include "../data/decoderstack.h"
|
||||||
|
#include "../data/decode/decoder.h"
|
||||||
|
#include "../data/decode/row.h"
|
||||||
|
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
#include <QVariant>
|
||||||
|
|
||||||
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
namespace pv {
|
namespace pv {
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
DecoderGroupBox::DecoderGroupBox(QString title, QWidget *parent) :
|
DecoderGroupBox::DecoderGroupBox(boost::shared_ptr<data::DecoderStack> &decoder_stack,
|
||||||
QWidget(parent),
|
boost::shared_ptr<data::decode::Decoder> &dec,
|
||||||
_layout(new QGridLayout),
|
QWidget *parent) :
|
||||||
_show_hide_button(QIcon(":/icons/shown.png"), QString(), this)
|
QWidget(parent),
|
||||||
|
_decoder_stack(decoder_stack),
|
||||||
|
_dec(dec),
|
||||||
|
_layout(new QGridLayout)
|
||||||
{
|
{
|
||||||
_layout->setContentsMargins(0, 0, 0, 0);
|
_layout->setContentsMargins(0, 0, 0, 0);
|
||||||
setLayout(_layout);
|
setLayout(_layout);
|
||||||
|
|
||||||
_layout->addWidget(new QLabel(QString("<h3>%1</h3>").arg(title)),
|
_layout->addWidget(new QLabel(QString("<h3>%1</h3>").arg(_dec->decoder()->name)),
|
||||||
0, 0);
|
0, 0);
|
||||||
_layout->setColumnStretch(0, 1);
|
_layout->setColumnStretch(0, 1);
|
||||||
|
|
||||||
QHBoxLayout *const toolbar = new QHBoxLayout;
|
const srd_decoder *const d = _dec->decoder();
|
||||||
_layout->addLayout(toolbar, 0, 1);
|
assert(d);
|
||||||
|
const bool have_probes = (d->channels || d->opt_channels) != 0;
|
||||||
|
if (!have_probes) {
|
||||||
|
_del_button = new QPushButton(QIcon(":/icons/del.png"), QString(), this);
|
||||||
|
_layout->addWidget(_del_button, 0, 1);
|
||||||
|
connect(_del_button, SIGNAL(clicked()), this, SLOT(on_del_stack()));
|
||||||
|
}
|
||||||
|
|
||||||
_show_hide_button.setFlat(true);
|
_index = 0;
|
||||||
//_show_hide_button.setIconSize(QSize(16, 16));
|
BOOST_FOREACH(boost::shared_ptr<data::decode::Decoder> dec,
|
||||||
connect(&_show_hide_button, SIGNAL(clicked()),
|
_decoder_stack->stack()) {
|
||||||
this, SIGNAL(show_hide_decoder()));
|
if (dec == _dec)
|
||||||
toolbar->addWidget(&_show_hide_button);
|
break;
|
||||||
|
_index++;
|
||||||
|
}
|
||||||
|
_show_button = new QPushButton(QIcon(_dec->shown() ?
|
||||||
|
":/icons/shown.png" :
|
||||||
|
":/icons/hidden.png"), QString(), this);
|
||||||
|
_show_button->setProperty("index", -1);
|
||||||
|
connect(_show_button, SIGNAL(clicked()),
|
||||||
|
this, SLOT(tog_icon()));
|
||||||
|
_layout->addWidget(_show_button, 0, 2);
|
||||||
|
|
||||||
|
|
||||||
|
// add row show/hide
|
||||||
|
int index = 0;
|
||||||
|
const std::map<const pv::data::decode::Row, bool>& rows(_decoder_stack->get_rows_gshow());
|
||||||
|
for (std::map<const pv::data::decode::Row, bool>::const_iterator i = rows.begin();
|
||||||
|
i != rows.end(); i++) {
|
||||||
|
if ((*i).first.decoder() == _dec->decoder()) {
|
||||||
|
QPushButton *show_button = new QPushButton(QIcon((*i).second ?
|
||||||
|
":/icons/shown.png" :
|
||||||
|
":/icons/hidden.png"), QString(), this);
|
||||||
|
show_button->setProperty("index", index);
|
||||||
|
connect(show_button, SIGNAL(clicked()), this, SLOT(tog_icon()));
|
||||||
|
_row_show_button.push_back(show_button);
|
||||||
|
_layout->addWidget(new QLabel((*i).first.title(), this), _row_show_button.size(), 0);
|
||||||
|
_layout->addWidget(show_button, _row_show_button.size(), 2);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecoderGroupBox::add_layout(QLayout *layout)
|
void DecoderGroupBox::add_layout(QLayout *layout)
|
||||||
{
|
{
|
||||||
assert(layout);
|
assert(layout);
|
||||||
_layout->addLayout(layout, 1, 0, 1, 2);
|
_layout->addLayout(layout, _row_show_button.size()+1, 0, 1, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DecoderGroupBox::set_decoder_visible(bool visible)
|
void DecoderGroupBox::tog_icon()
|
||||||
{
|
{
|
||||||
_show_hide_button.setIcon(QIcon(visible ?
|
QPushButton *sc = dynamic_cast<QPushButton*>(sender());
|
||||||
":/icons/shown.png" :
|
QVariant id = sc->property("index");
|
||||||
":/icons/hidden.png"));
|
int index = id.toInt();
|
||||||
|
if (index == -1) {
|
||||||
|
int i = _index;
|
||||||
|
BOOST_FOREACH(boost::shared_ptr<data::decode::Decoder> dec,
|
||||||
|
_decoder_stack->stack()) {
|
||||||
|
if (i-- == 0) {
|
||||||
|
dec->show(!dec->shown());
|
||||||
|
sc->setIcon(QIcon(dec->shown() ? ":/icons/shown.png" :
|
||||||
|
":/icons/hidden.png"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
std::map<const pv::data::decode::Row, bool>& rows(_decoder_stack->get_rows_gshow());
|
||||||
|
for (std::map<const pv::data::decode::Row, bool>::const_iterator i = rows.begin();
|
||||||
|
i != rows.end(); i++) {
|
||||||
|
if (index-- == 0) {
|
||||||
|
_decoder_stack->set_rows_gshow((*i).first, !(*i).second);
|
||||||
|
//rows[(*i).first] = !(*i).second;
|
||||||
|
sc->setIcon(QIcon(rows[(*i).first] ? ":/icons/shown.png" :
|
||||||
|
":/icons/hidden.png"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DecoderGroupBox::on_del_stack()
|
||||||
|
{
|
||||||
|
int i = _index;
|
||||||
|
BOOST_FOREACH(boost::shared_ptr<data::decode::Decoder> dec,
|
||||||
|
_decoder_stack->stack()) {
|
||||||
|
if (i-- == 0) {
|
||||||
|
del_stack(dec);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // widgets
|
} // widgets
|
||||||
|
|||||||
@@ -22,11 +22,19 @@
|
|||||||
#define DSVIEW_PV_WIDGETS_DECODERGROUPBOX_H
|
#define DSVIEW_PV_WIDGETS_DECODERGROUPBOX_H
|
||||||
|
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
|
#include <QGridLayout>
|
||||||
class QGridLayout;
|
#include <QToolBar>
|
||||||
class QToolBar;
|
#include <boost/shared_ptr.hpp>
|
||||||
|
|
||||||
namespace pv {
|
namespace pv {
|
||||||
|
|
||||||
|
namespace data{
|
||||||
|
class DecoderStack;
|
||||||
|
namespace decode{
|
||||||
|
class Decoder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace widgets {
|
namespace widgets {
|
||||||
|
|
||||||
class DecoderGroupBox : public QWidget
|
class DecoderGroupBox : public QWidget
|
||||||
@@ -34,18 +42,30 @@ class DecoderGroupBox : public QWidget
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DecoderGroupBox(QString title, QWidget *parent = NULL);
|
DecoderGroupBox(boost::shared_ptr<pv::data::DecoderStack> &decoder_stack,
|
||||||
|
boost::shared_ptr<data::decode::Decoder> &dec,
|
||||||
|
QWidget *parent = NULL);
|
||||||
|
|
||||||
void add_layout(QLayout *layout);
|
void add_layout(QLayout *layout);
|
||||||
|
|
||||||
void set_decoder_visible(bool visible);
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void show_hide_decoder();
|
void show_hide_decoder();
|
||||||
|
void show_hide_row();
|
||||||
|
void del_stack(boost::shared_ptr<data::decode::Decoder> &_dec);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void tog_icon();
|
||||||
|
void on_del_stack();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QGridLayout *const _layout;
|
boost::shared_ptr<pv::data::DecoderStack> &_decoder_stack;
|
||||||
QPushButton _show_hide_button;
|
boost::shared_ptr<data::decode::Decoder> &_dec;
|
||||||
|
int _index;
|
||||||
|
|
||||||
|
QGridLayout *const _layout;
|
||||||
|
QPushButton *_del_button;
|
||||||
|
QPushButton *_show_button;
|
||||||
|
std::list <QPushButton *> _row_show_button;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // widgets
|
} // widgets
|
||||||
|
|||||||
@@ -261,4 +261,24 @@ QSlider::add-page:horizontal{
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* <<< QTableView */
|
||||||
|
QHeaderView::section {
|
||||||
|
background-color: #646464;
|
||||||
|
padding: 4px;
|
||||||
|
font-size: 14pt;
|
||||||
|
border-style: none;
|
||||||
|
border-bottom: 1px solid #fffff8;
|
||||||
|
border-right: 1px solid #fffff8;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHeaderView::section:horizontal
|
||||||
|
{
|
||||||
|
border-top: 1px solid #fffff8;
|
||||||
|
}
|
||||||
|
|
||||||
|
QHeaderView::section:vertical
|
||||||
|
{
|
||||||
|
border-left: 1px solid #fffff8;
|
||||||
|
}
|
||||||
|
|
||||||
/* <<< QDockWidget */
|
/* <<< QDockWidget */
|
||||||
|
|||||||
Reference in New Issue
Block a user