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_cn.png</file>
|
||||
<file>icons/settings.png</file>
|
||||
<file>darkstyle/style.qss</file>
|
||||
</qresource>
|
||||
</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
|
||||
pv::MainWindow w(device_manager, open_file);
|
||||
QFile qss(":/stylesheet.qss");
|
||||
//QFile qss(":/stylesheet.qss");
|
||||
QFile qss(":qdarkstyle/style.qss");
|
||||
qss.open(QFile::ReadOnly);
|
||||
a.setStyleSheet(qss.readAll());
|
||||
qss.close();
|
||||
|
||||
@@ -49,6 +49,12 @@ Annotation::Annotation(const srd_proto_data *const pdata) :
|
||||
}
|
||||
}
|
||||
|
||||
Annotation::Annotation()
|
||||
{
|
||||
_start_sample = 0;
|
||||
_end_sample = 0;
|
||||
}
|
||||
|
||||
Annotation::~Annotation()
|
||||
{
|
||||
_annotations.clear();
|
||||
|
||||
@@ -35,6 +35,7 @@ class Annotation
|
||||
{
|
||||
public:
|
||||
Annotation(const srd_proto_data *const pdata);
|
||||
Annotation();
|
||||
~Annotation();
|
||||
|
||||
uint64_t start_sample() const;
|
||||
|
||||
@@ -68,8 +68,8 @@ const QString Row::title() const
|
||||
|
||||
bool Row::operator<(const Row &other) const
|
||||
{
|
||||
return (_decoder < other._decoder) ||
|
||||
(_decoder == other._decoder && _row < other._row);
|
||||
return (_decoder->name < other._decoder->name) ||
|
||||
(_decoder->name == other._decoder->name && _row->desc < other._row->desc);
|
||||
}
|
||||
|
||||
} // decode
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
|
||||
const QString title() const;
|
||||
|
||||
bool operator<(const Row &other) const;
|
||||
bool operator<(const Row &other) const;
|
||||
|
||||
private:
|
||||
const srd_decoder *_decoder;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "rowdata.h"
|
||||
|
||||
using std::max;
|
||||
using std::min;
|
||||
using std::vector;
|
||||
|
||||
namespace pv {
|
||||
@@ -30,7 +31,8 @@ namespace data {
|
||||
namespace decode {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
uint64_t RowData::get_min_annotation() const
|
||||
{
|
||||
return _min_annotation;
|
||||
}
|
||||
|
||||
void RowData::get_annotation_subset(
|
||||
vector<pv::data::decode::Annotation> &dest,
|
||||
uint64_t start_sample, uint64_t end_sample) const
|
||||
@@ -62,10 +69,33 @@ void RowData::get_annotation_subset(
|
||||
dest.push_back(*i);
|
||||
}
|
||||
|
||||
void RowData::push_annotation(const Annotation &a)
|
||||
bool RowData::push_annotation(const Annotation &a)
|
||||
{
|
||||
_annotations.push_back(a);
|
||||
_max_annotation = max(_max_annotation, a.end_sample() - a.start_sample());
|
||||
try {
|
||||
_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
|
||||
|
||||
@@ -39,6 +39,7 @@ public:
|
||||
uint64_t get_max_sample() const;
|
||||
|
||||
uint64_t get_max_annotation() const;
|
||||
uint64_t get_min_annotation() const;
|
||||
/**
|
||||
* Extracts sorted annotations between two period into a vector.
|
||||
*/
|
||||
@@ -46,10 +47,16 @@ public:
|
||||
std::vector<pv::data::decode::Annotation> &dest,
|
||||
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:
|
||||
uint64_t _max_annotation;
|
||||
uint64_t _min_annotation;
|
||||
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),
|
||||
_samples_decoded(0),
|
||||
_decode_state(Stopped),
|
||||
_options_changed(false)
|
||||
_options_changed(false),
|
||||
_no_memory(false)
|
||||
{
|
||||
connect(&_session, SIGNAL(frame_began()),
|
||||
this, SLOT(on_new_frame()));
|
||||
@@ -79,6 +80,8 @@ DecoderStack::DecoderStack(pv::SigSession &session,
|
||||
|
||||
_stack.push_back(shared_ptr<decode::Decoder>(
|
||||
new decode::Decoder(dec)));
|
||||
|
||||
build_row();
|
||||
}
|
||||
|
||||
DecoderStack::~DecoderStack()
|
||||
@@ -89,7 +92,10 @@ DecoderStack::~DecoderStack()
|
||||
// }
|
||||
stop_decode();
|
||||
_stack.clear();
|
||||
clear();
|
||||
_rows.clear();
|
||||
_rows_gshow.clear();
|
||||
_rows_lshow.clear();
|
||||
_class_rows.clear();
|
||||
}
|
||||
|
||||
const std::list< boost::shared_ptr<decode::Decoder> >&
|
||||
@@ -102,20 +108,83 @@ void DecoderStack::push(boost::shared_ptr<decode::Decoder> decoder)
|
||||
{
|
||||
assert(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
|
||||
list< shared_ptr<Decoder> >::iterator iter = _stack.begin();
|
||||
for(int i = 0; i < index; i++, iter++)
|
||||
assert(iter != _stack.end());
|
||||
for(int i = 0; i < _stack.size(); i++, iter++)
|
||||
if ((*iter) == decoder)
|
||||
break;
|
||||
|
||||
// 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
|
||||
@@ -124,36 +193,6 @@ int64_t DecoderStack::samples_decoded() const
|
||||
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(
|
||||
std::vector<pv::data::decode::Annotation> &dest,
|
||||
const Row &row, uint64_t start_sample,
|
||||
@@ -161,9 +200,9 @@ void DecoderStack::get_annotation_subset(
|
||||
{
|
||||
lock_guard<mutex> lock(_output_mutex);
|
||||
|
||||
std::map<const Row, decode::RowData>::const_iterator iter =
|
||||
_rows.find(row);
|
||||
if (iter != _rows.end())
|
||||
std::map<const Row, decode::RowData>::const_iterator iter =
|
||||
_rows.find(row);
|
||||
if (iter != _rows.end())
|
||||
(*iter).second.get_annotation_subset(dest,
|
||||
start_sample, end_sample);
|
||||
}
|
||||
@@ -180,6 +219,44 @@ uint64_t DecoderStack::get_max_annotation(const Row &row)
|
||||
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
|
||||
{
|
||||
lock_guard<mutex> lock(_output_mutex);
|
||||
@@ -195,6 +272,55 @@ bool DecoderStack::has_annotations(const Row &row) const
|
||||
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()
|
||||
{
|
||||
lock_guard<mutex> lock(_output_mutex);
|
||||
@@ -207,16 +333,20 @@ void DecoderStack::clear()
|
||||
_frame_complete = false;
|
||||
_samples_decoded = 0;
|
||||
_error_message = QString();
|
||||
_rows.clear();
|
||||
_class_rows.clear();
|
||||
for (map<const Row, RowData>::const_iterator i = _rows.begin();
|
||||
i != _rows.end(); i++)
|
||||
_rows[(*i).first] = decode::RowData();
|
||||
_no_memory = false;
|
||||
}
|
||||
|
||||
void DecoderStack::stop_decode()
|
||||
{
|
||||
_snapshot.reset();
|
||||
|
||||
if(_decode_state == Stopped)
|
||||
if(_decode_state == Stopped) {
|
||||
clear();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_decode_thread.get()) {
|
||||
_decode_thread->interrupt();
|
||||
@@ -224,6 +354,7 @@ void DecoderStack::stop_decode()
|
||||
_decode_state = Stopped;
|
||||
}
|
||||
_decode_thread.reset();
|
||||
clear();
|
||||
}
|
||||
|
||||
void DecoderStack::begin_decode()
|
||||
@@ -239,8 +370,6 @@ void DecoderStack::begin_decode()
|
||||
// }
|
||||
stop_decode();
|
||||
|
||||
clear();
|
||||
|
||||
// Check that all decoders have the required channels
|
||||
BOOST_FOREACH(const shared_ptr<decode::Decoder> &dec, _stack)
|
||||
if (!dec->have_required_probes()) {
|
||||
@@ -249,37 +378,6 @@ void DecoderStack::begin_decode()
|
||||
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.
|
||||
// This works because we are currently assuming all
|
||||
// LogicSignals have the same data/snapshot
|
||||
@@ -313,8 +411,8 @@ uint64_t DecoderStack::get_max_sample_count() const
|
||||
{
|
||||
uint64_t max_sample_count = 0;
|
||||
|
||||
for (map<const Row, RowData>::const_iterator i = _rows.begin();
|
||||
i != _rows.end(); i++)
|
||||
for (map<const Row, RowData>::const_iterator i = _rows.begin();
|
||||
i != _rows.end(); i++)
|
||||
max_sample_count = max(max_sample_count,
|
||||
(*i).second.get_max_sample());
|
||||
|
||||
@@ -333,48 +431,6 @@ boost::optional<uint64_t> DecoderStack::wait_for_data() const
|
||||
_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(
|
||||
const uint64_t decode_start, const uint64_t decode_end,
|
||||
const unsigned int unit_size, srd_session *const session)
|
||||
@@ -386,7 +442,7 @@ void DecoderStack::decode_data(
|
||||
|
||||
for (uint64_t i = decode_start;
|
||||
!boost::this_thread::interruption_requested() &&
|
||||
i < decode_end;
|
||||
i < decode_end && !_no_memory;
|
||||
i += chunk_sample_count)
|
||||
{
|
||||
//lock_guard<mutex> decode_lock(_global_decode_mutex);
|
||||
@@ -490,6 +546,11 @@ uint64_t DecoderStack::sample_count() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64_t DecoderStack::sample_rate() const
|
||||
{
|
||||
return _samplerate;
|
||||
}
|
||||
|
||||
void DecoderStack::annotation_callback(srd_proto_data *pdata, void *decoder)
|
||||
{
|
||||
assert(pdata);
|
||||
@@ -500,6 +561,9 @@ void DecoderStack::annotation_callback(srd_proto_data *pdata, void *decoder)
|
||||
|
||||
lock_guard<mutex> lock(d->_output_mutex);
|
||||
|
||||
if (d->_no_memory)
|
||||
return;
|
||||
|
||||
const Annotation a(pdata);
|
||||
|
||||
// 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;
|
||||
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
|
||||
const map<pair<const srd_decoder*, int>, Row>::const_iterator r =
|
||||
d->_class_rows.find(make_pair(decc, a.format()));
|
||||
if (r != d->_class_rows.end())
|
||||
row_iter = d->_rows.find((*r).second);
|
||||
row_iter = d->_rows.find((*r).second);
|
||||
else
|
||||
{
|
||||
// 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());
|
||||
if (row_iter == d->_rows.end()) {
|
||||
assert(row_iter != d->_rows.end());
|
||||
if (row_iter == d->_rows.end()) {
|
||||
qDebug() << "Unexpected annotation: decoder = " << decc <<
|
||||
", format = " << a.format();
|
||||
assert(0);
|
||||
@@ -530,7 +594,8 @@ void DecoderStack::annotation_callback(srd_proto_data *pdata, void *decoder)
|
||||
}
|
||||
|
||||
// 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()
|
||||
@@ -560,21 +625,25 @@ void DecoderStack::on_frame_ended()
|
||||
begin_decode();
|
||||
}
|
||||
|
||||
int DecoderStack::cur_rows_size()
|
||||
int DecoderStack::list_rows_size()
|
||||
{
|
||||
int rows_size = 0;
|
||||
int row = 0;
|
||||
for (map<const Row, RowData>::const_iterator i = _rows.begin();
|
||||
i != _rows.end(); i++)
|
||||
if ((*i).second.get_max_sample() != 0)
|
||||
i != _rows.end(); i++) {
|
||||
map<const Row, bool>::const_iterator iter = _rows_lshow.find((*i).first);
|
||||
if (iter != _rows_lshow.end() && (*iter).second)
|
||||
rows_size++;
|
||||
|
||||
if (rows_size == 0)
|
||||
return 1;
|
||||
else
|
||||
return rows_size;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -86,14 +86,13 @@ public:
|
||||
|
||||
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 remove(int index);
|
||||
void remove(boost::shared_ptr<decode::Decoder>& decoder);
|
||||
void build_row();
|
||||
|
||||
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.
|
||||
*/
|
||||
@@ -103,9 +102,23 @@ public:
|
||||
uint64_t end_sample) const;
|
||||
|
||||
uint64_t get_max_annotation(const decode::Row &row);
|
||||
uint64_t get_min_annotation(const decode::Row &row); // except instant(end=start) annotation
|
||||
|
||||
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;
|
||||
|
||||
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();
|
||||
|
||||
void clear();
|
||||
@@ -116,11 +129,13 @@ public:
|
||||
|
||||
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_rate() const;
|
||||
|
||||
private:
|
||||
boost::optional<uint64_t> wait_for_data() const;
|
||||
@@ -170,9 +185,10 @@ private:
|
||||
mutable boost::mutex _output_mutex;
|
||||
int64_t _samples_decoded;
|
||||
|
||||
std::map<const decode::Row, decode::RowData> _rows;
|
||||
|
||||
std::map<std::pair<const srd_decoder*, int>, decode::Row> _class_rows;
|
||||
std::map<const decode::Row, decode::RowData> _rows;
|
||||
std::map<const decode::Row, bool> _rows_gshow;
|
||||
std::map<const decode::Row, bool> _rows_lshow;
|
||||
std::map<std::pair<const srd_decoder*, int>, decode::Row> _class_rows;
|
||||
|
||||
QString _error_message;
|
||||
|
||||
@@ -180,6 +196,7 @@ private:
|
||||
decode_state _decode_state;
|
||||
|
||||
bool _options_changed;
|
||||
bool _no_memory;
|
||||
|
||||
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 "../view/decodetrace.h"
|
||||
#include "../device/devinst.h"
|
||||
#include "../data/decodermodel.h"
|
||||
#include "../data/decoderstack.h"
|
||||
#include "../dialogs/protocollist.h"
|
||||
#include "../dialogs/protocolexp.h"
|
||||
|
||||
#include <QObject>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPainter>
|
||||
#include <QMessageBox>
|
||||
#include <QFormLayout>
|
||||
#include <QStandardItemModel>
|
||||
#include <QTableView>
|
||||
#include <QHeaderView>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace pv {
|
||||
@@ -41,20 +49,20 @@ ProtocolDock::ProtocolDock(QWidget *parent, SigSession &session) :
|
||||
QScrollArea(parent),
|
||||
_session(session)
|
||||
{
|
||||
_widget = new QWidget(this);
|
||||
_up_widget = new QWidget(this);
|
||||
|
||||
QHBoxLayout *hori_layout = new QHBoxLayout();
|
||||
|
||||
_add_button = new QPushButton(_widget);
|
||||
_add_button = new QPushButton(_up_widget);
|
||||
_add_button->setFlat(true);
|
||||
_add_button->setIcon(QIcon::fromTheme("protocol",
|
||||
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->setIcon(QIcon::fromTheme("protocol",
|
||||
QIcon(":/icons/del.png")));
|
||||
_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*)srd_decoder_list()), decoder_name_cmp);
|
||||
@@ -80,15 +88,72 @@ ProtocolDock::ProtocolDock(QWidget *parent, SigSession &session) :
|
||||
connect(_del_all_button, SIGNAL(clicked()),
|
||||
this, SLOT(del_protocol()));
|
||||
|
||||
_layout = new QVBoxLayout();
|
||||
_layout->addLayout(hori_layout);
|
||||
_layout->addStretch(1);
|
||||
_up_layout = new QVBoxLayout();
|
||||
_up_layout->addLayout(hori_layout);
|
||||
_up_layout->addStretch(1);
|
||||
|
||||
_widget->setLayout(_layout);
|
||||
_up_widget->setLayout(_up_layout);
|
||||
_up_widget->setMinimumHeight(120);
|
||||
|
||||
this->setWidget(_widget);
|
||||
_widget->setGeometry(0, 0, sizeHint().width(), 500);
|
||||
_widget->setObjectName("protocolWidget");
|
||||
// this->setWidget(_widget);
|
||||
// _widget->setGeometry(0, 0, sizeHint().width(), 500);
|
||||
// _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()
|
||||
@@ -126,15 +191,15 @@ void ProtocolDock::add_protocol()
|
||||
//QMap <QString, QVariant>& _options = dlg.get_options();
|
||||
//QMap <QString, int> _options_index = dlg.get_options_index();
|
||||
|
||||
QPushButton *_del_button = new QPushButton(_widget);
|
||||
QPushButton *_set_button = new QPushButton(_widget);
|
||||
QPushButton *_del_button = new QPushButton(_up_widget);
|
||||
QPushButton *_set_button = new QPushButton(_up_widget);
|
||||
_del_button->setFlat(true);
|
||||
_del_button->setIcon(QIcon::fromTheme("protocol",
|
||||
QIcon(":/icons/del.png")));
|
||||
_set_button->setFlat(true);
|
||||
_set_button->setIcon(QIcon::fromTheme("protocol",
|
||||
QIcon(":/icons/gear.png")));
|
||||
QLabel *_protocol_label = new QLabel(_widget);
|
||||
QLabel *_protocol_label = new QLabel(_up_widget);
|
||||
|
||||
_del_button->setCheckable(true);
|
||||
_protocol_label->setText(_protocol_combobox->currentText());
|
||||
@@ -155,9 +220,10 @@ void ProtocolDock::add_protocol()
|
||||
hori_layout->addWidget(_protocol_label);
|
||||
hori_layout->addStretch(1);
|
||||
_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);
|
||||
protocol_updated();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -183,6 +249,7 @@ void ProtocolDock::rst_protocol()
|
||||
}
|
||||
rst_index++;
|
||||
}
|
||||
protocol_updated();
|
||||
}
|
||||
|
||||
void ProtocolDock::del_protocol()
|
||||
@@ -193,7 +260,7 @@ void ProtocolDock::del_protocol()
|
||||
int del_index = 0;
|
||||
for (QVector <QHBoxLayout *>::const_iterator i = _hori_layout_list.begin();
|
||||
i != _hori_layout_list.end(); i++) {
|
||||
_layout->removeItem((*i));
|
||||
_up_layout->removeItem((*i));
|
||||
delete (*i);
|
||||
delete _del_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();
|
||||
i != _del_button_list.end(); i++) {
|
||||
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 _del_button_list.at(del_index);
|
||||
@@ -234,12 +301,12 @@ void ProtocolDock::del_protocol()
|
||||
_protocol_index_list.remove(del_index);
|
||||
|
||||
_session.remove_decode_signal(del_index);
|
||||
|
||||
break;
|
||||
}
|
||||
del_index++;
|
||||
}
|
||||
}
|
||||
protocol_updated();
|
||||
}
|
||||
|
||||
void ProtocolDock::del_all_protocol()
|
||||
@@ -248,7 +315,7 @@ void ProtocolDock::del_all_protocol()
|
||||
int del_index = 0;
|
||||
for (QVector <QHBoxLayout *>::const_iterator i = _hori_layout_list.begin();
|
||||
i != _hori_layout_list.end(); i++) {
|
||||
_layout->removeItem((*i));
|
||||
_up_layout->removeItem((*i));
|
||||
delete (*i);
|
||||
delete _del_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();
|
||||
_protocol_label_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 pv
|
||||
|
||||
@@ -34,15 +34,23 @@
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QScrollArea>
|
||||
#include <QSplitter>
|
||||
#include <QTableView>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <libsigrok4DSL/libsigrok.h>
|
||||
|
||||
#include "../data/decodermodel.h"
|
||||
|
||||
namespace pv {
|
||||
|
||||
class SigSession;
|
||||
|
||||
namespace data {
|
||||
class DecoderModel;
|
||||
}
|
||||
|
||||
namespace dock {
|
||||
|
||||
class ProtocolDock : public QScrollArea
|
||||
@@ -58,19 +66,29 @@ public:
|
||||
void del_all_protocol();
|
||||
|
||||
signals:
|
||||
void protocol_updated();
|
||||
|
||||
private slots:
|
||||
void add_protocol();
|
||||
void rst_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:
|
||||
static int decoder_name_cmp(const void *a, const void *b);
|
||||
void resize_table_view(data::DecoderModel *decoder_model);
|
||||
|
||||
private:
|
||||
SigSession &_session;
|
||||
|
||||
QWidget *_widget;
|
||||
QSplitter *_split_widget;
|
||||
QWidget *_up_widget;
|
||||
QWidget *_dn_widget;
|
||||
QTableView *_table_view;
|
||||
|
||||
QPushButton *_add_button;
|
||||
QPushButton *_del_all_button;
|
||||
@@ -80,7 +98,10 @@ private:
|
||||
QVector <QLabel *> _protocol_label_list;
|
||||
QVector <int > _protocol_index_list;
|
||||
QVector <QHBoxLayout *> _hori_layout_list;
|
||||
QVBoxLayout *_layout;
|
||||
QVBoxLayout *_up_layout;
|
||||
|
||||
QPushButton *_dn_set_button;
|
||||
QPushButton *_dn_save_button;
|
||||
};
|
||||
|
||||
} // namespace dock
|
||||
|
||||
@@ -197,7 +197,9 @@ void MainWindow::setup_ui()
|
||||
SLOT(device_change()));
|
||||
connect(_dso_trigger_widget, SIGNAL(set_trig_pos(quint64)), _view,
|
||||
SLOT(set_trig_pos(quint64)));
|
||||
connect(_protocol_widget, SIGNAL(protocol_updated()), _view, SLOT(signals_changed()));
|
||||
|
||||
setIconSize(QSize(40,40));
|
||||
addToolBar(_sampling_bar);
|
||||
addToolBar(_trig_bar);
|
||||
addToolBar(_file_bar);
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "data/groupsnapshot.h"
|
||||
#include "data/decoderstack.h"
|
||||
#include "data/decode/decoder.h"
|
||||
#include "data/decodermodel.h"
|
||||
|
||||
#include "view/analogsignal.h"
|
||||
#include "view/dsosignal.h"
|
||||
@@ -99,6 +100,7 @@ SigSession::SigSession(DeviceManager &device_manager) :
|
||||
_refresh_timer.stop();
|
||||
_refresh_timer.setSingleShot(true);
|
||||
_data_lock = false;
|
||||
_decoder_model = new pv::data::DecoderModel(this);
|
||||
connect(this, SIGNAL(start_timer(int)), &_view_timer, SLOT(start(int)));
|
||||
//connect(&_view_timer, SIGNAL(timeout()), this, SLOT(refresh()));
|
||||
connect(&_refresh_timer, SIGNAL(timeout()), this, SLOT(data_unlock()));
|
||||
@@ -455,7 +457,6 @@ void SigSession::start_capture(bool instant,
|
||||
_view_timer.blockSignals(false);
|
||||
|
||||
// Begin the session
|
||||
|
||||
_sampling_thread.reset(new boost::thread(
|
||||
&SigSession::sample_thread_proc, this, _dev_inst,
|
||||
error_handler));
|
||||
@@ -1104,9 +1105,10 @@ void SigSession::data_feed_in(const struct sr_dev_inst *sdi,
|
||||
_cur_logic_snapshot.reset();
|
||||
_cur_dso_snapshot.reset();
|
||||
_cur_analog_snapshot.reset();
|
||||
|
||||
#ifdef ENABLE_DECODE
|
||||
BOOST_FOREACH(const boost::shared_ptr<view::DecodeTrace> d, _decode_traces)
|
||||
d->frame_ended();
|
||||
#endif
|
||||
}
|
||||
|
||||
frame_ended();
|
||||
@@ -1394,6 +1396,12 @@ void SigSession::rst_decoder(view::DecodeTrace *signal)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pv::data::DecoderModel* SigSession::get_decoder_model() const
|
||||
{
|
||||
return _decoder_model;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace pv
|
||||
|
||||
@@ -67,6 +67,7 @@ class Logic;
|
||||
class LogicSnapshot;
|
||||
class Group;
|
||||
class GroupSnapshot;
|
||||
class DecoderModel;
|
||||
}
|
||||
|
||||
namespace device {
|
||||
@@ -154,6 +155,8 @@ public:
|
||||
|
||||
void rst_decoder(view::DecodeTrace *signal);
|
||||
|
||||
pv::data::DecoderModel* get_decoder_model() const;
|
||||
|
||||
#endif
|
||||
|
||||
void init_signals();
|
||||
@@ -234,6 +237,7 @@ private:
|
||||
std::vector< boost::shared_ptr<view::GroupSignal> > _group_traces;
|
||||
#ifdef ENABLE_DECODE
|
||||
std::vector< boost::shared_ptr<view::DecodeTrace> > _decode_traces;
|
||||
pv::data::DecoderModel *_decoder_model;
|
||||
#endif
|
||||
|
||||
mutable boost::mutex _data_mutex;
|
||||
@@ -291,6 +295,10 @@ signals:
|
||||
void zero_adj();
|
||||
void progressSaveFileValueChanged(int percent);
|
||||
|
||||
void decode_done();
|
||||
|
||||
void show_region(uint64_t start, uint64_t end);
|
||||
|
||||
public slots:
|
||||
void reload();
|
||||
void refresh(int holdtime);
|
||||
|
||||
@@ -454,7 +454,8 @@ void SamplingBar::update_sample_rate_selector_value()
|
||||
break;
|
||||
}
|
||||
}
|
||||
update_scale();
|
||||
if (samplerate != _sample_rate.itemData(_sample_rate.currentIndex()).value<uint64_t>())
|
||||
update_scale();
|
||||
_updating_sample_rate = false;
|
||||
}
|
||||
|
||||
@@ -511,7 +512,7 @@ void SamplingBar::on_samplecount_sel(int index)
|
||||
g_variant_new_uint64(sample_count));
|
||||
|
||||
sample_count_changed();
|
||||
update_scale();
|
||||
//update_scale();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -535,7 +536,7 @@ void SamplingBar::on_samplerate_sel(int index)
|
||||
SR_CONF_SAMPLERATE,
|
||||
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>())
|
||||
_sample_count.setCurrentIndex(i);
|
||||
|
||||
if (samplecount != _sample_count.itemData(_sample_count.currentIndex()).value<uint64_t>()) {
|
||||
sample_count_changed();
|
||||
update_scale();
|
||||
}
|
||||
_updating_sample_count = false;
|
||||
sample_count_changed();
|
||||
update_scale();
|
||||
}
|
||||
|
||||
void SamplingBar::commit_sample_count()
|
||||
|
||||
@@ -125,7 +125,6 @@ DecodeTrace::DecodeTrace(pv::SigSession &session,
|
||||
_end_index(0),
|
||||
_start_count(0),
|
||||
_end_count(0),
|
||||
_show_hide_mapper(this),
|
||||
_popup_form(NULL),
|
||||
_popup()
|
||||
{
|
||||
@@ -137,8 +136,6 @@ DecodeTrace::DecodeTrace(pv::SigSession &session,
|
||||
this, SLOT(on_new_decode_data()));
|
||||
connect(_decoder_stack.get(), SIGNAL(decode_done()),
|
||||
this, SLOT(on_decode_done()));
|
||||
connect(&_show_hide_mapper, SIGNAL(mapped(int)),
|
||||
this, SLOT(on_show_hide_decoder(int)));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
using namespace pv::data::decode;
|
||||
using namespace pv::data::decode;
|
||||
|
||||
const double scale = _view->scale();
|
||||
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_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)) {
|
||||
draw_unshown_row(p, y, annotation_height, decode_startX, decode_endX);
|
||||
y += annotation_height;
|
||||
_cur_row_headings.push_back(row.title());
|
||||
continue;
|
||||
}
|
||||
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)) {
|
||||
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;
|
||||
boost::hash_combine(base_colour, this);
|
||||
boost::hash_combine(base_colour, row.decoder());
|
||||
boost::hash_combine(base_colour, row.row());
|
||||
base_colour >>= 16;
|
||||
const uint64_t min_annotation =
|
||||
_decoder_stack->get_min_annotation(row);
|
||||
const double min_annWidth = min_annotation / samples_per_pixel;
|
||||
|
||||
const uint64_t max_annotation =
|
||||
_decoder_stack->get_max_annotation(row);
|
||||
const double max_annWidth = max_annotation / samples_per_pixel;
|
||||
if (max_annWidth > 5) {
|
||||
vector<Annotation> annotations;
|
||||
_decoder_stack->get_annotation_subset(annotations, row,
|
||||
start_sample, end_sample);
|
||||
if (!annotations.empty()) {
|
||||
BOOST_FOREACH(const Annotation &a, annotations)
|
||||
draw_annotation(a, p, get_text_colour(),
|
||||
annotation_height, left, right,
|
||||
samples_per_pixel, pixels_offset, y,
|
||||
base_colour);
|
||||
const uint64_t max_annotation =
|
||||
_decoder_stack->get_max_annotation(row);
|
||||
const double max_annWidth = max_annotation / samples_per_pixel;
|
||||
if (max_annWidth > 5) {
|
||||
vector<Annotation> annotations;
|
||||
_decoder_stack->get_annotation_subset(annotations, row,
|
||||
start_sample, end_sample);
|
||||
if (!annotations.empty()) {
|
||||
BOOST_FOREACH(const Annotation &a, annotations)
|
||||
draw_annotation(a, p, get_text_colour(),
|
||||
annotation_height, left, right,
|
||||
samples_per_pixel, pixels_offset, y,
|
||||
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){
|
||||
draw_nodetail(p, annotation_height, decode_startX, decode_endX, y, base_colour);
|
||||
}
|
||||
if (max_annWidth != 0) {
|
||||
} else {
|
||||
draw_unshown_row(p, y, annotation_height, left, right, tr("Unshown"));
|
||||
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)
|
||||
@@ -350,8 +357,8 @@ bool DecodeTrace::create_popup()
|
||||
BOOST_FOREACH(boost::shared_ptr<data::decode::Decoder> dec,
|
||||
_decoder_stack->stack())
|
||||
{
|
||||
if (dec->commit()) {
|
||||
_decoder_stack->options_changed(true);
|
||||
if (dec->commit() || _decoder_stack->options_changed()) {
|
||||
_decoder_stack->set_options_changed(true);
|
||||
_decode_start = dec->decode_start();
|
||||
_decode_end = dec->decode_end();
|
||||
ret = true;
|
||||
@@ -378,6 +385,9 @@ void DecodeTrace::create_popup_form()
|
||||
_popup_form = new QFormLayout(_popup);
|
||||
_popup->setLayout(_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)
|
||||
@@ -395,20 +405,15 @@ void DecodeTrace::populate_popup_form(QWidget *parent, QFormLayout *form)
|
||||
|
||||
const list< boost::shared_ptr<Decoder> >& stack = _decoder_stack->stack();
|
||||
|
||||
if (stack.empty())
|
||||
{
|
||||
if (stack.empty()) {
|
||||
QLabel *const l = new QLabel(
|
||||
tr("<p><i>No decoders in the stack</i></p>"));
|
||||
l->setAlignment(Qt::AlignCenter);
|
||||
form->addRow(l);
|
||||
}
|
||||
else
|
||||
{
|
||||
list< boost::shared_ptr<Decoder> >::const_iterator iter =
|
||||
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);
|
||||
} else {
|
||||
BOOST_FOREACH(boost::shared_ptr<Decoder> dec,stack) {
|
||||
//boost::shared_ptr<Decoder> dec(*iter);
|
||||
create_decoder_form(_decoder_stack, dec, parent, form);
|
||||
}
|
||||
|
||||
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,
|
||||
QPainter &p, QColor text_color, int h, int left, int right,
|
||||
double samples_per_pixel, double pixels_offset, int y,
|
||||
size_t base_colour) const
|
||||
QPainter &p, QColor text_color, int h, int left, int right,
|
||||
double samples_per_pixel, double pixels_offset, int y,
|
||||
size_t base_colour, double min_annWidth) const
|
||||
{
|
||||
const double start = max(a.start_sample() / samples_per_pixel -
|
||||
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())
|
||||
draw_instant(a, p, fill, outline, text_color, h,
|
||||
start, y);
|
||||
start, y, min_annWidth);
|
||||
else
|
||||
draw_range(a, p, fill, outline, text_color, h,
|
||||
start, end, y);
|
||||
@@ -506,22 +511,31 @@ void DecodeTrace::draw_nodetail(QPainter &p,
|
||||
size_t base_colour) const
|
||||
{
|
||||
const QRectF nodetail_rect(left, y - h/2 + 0.5, right - left, h);
|
||||
const size_t colour = base_colour % countof(Colours);
|
||||
const QColor &fill = Colours[colour];
|
||||
QString info = tr("Zoom in For Detial");
|
||||
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.setBrush(fill);
|
||||
p.drawRect(nodetail_rect);
|
||||
p.drawText(nodetail_rect, Qt::AlignCenter | Qt::AlignVCenter, "Zoom in for more detials");
|
||||
p.setPen(Trace::DARK_FORE);
|
||||
p.drawLine(left, y, info_left, y);
|
||||
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(Trace::DARK_FORE);
|
||||
p.drawText(nodetail_rect, Qt::AlignCenter | Qt::AlignVCenter, info);
|
||||
}
|
||||
|
||||
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() ?
|
||||
QString() : a.annotations().back();
|
||||
const double w = min((double)p.boundingRect(QRectF(), 0, text).width(),
|
||||
0.0) + h;
|
||||
// const double w = min((double)p.boundingRect(QRectF(), 0, text).width(),
|
||||
// 0.0) + h;
|
||||
const double w = min(min_annWidth, (double)h);
|
||||
const QRectF rect(x - w / 2, y - h / 2, w, h);
|
||||
|
||||
p.setPen(outline);
|
||||
@@ -564,7 +578,7 @@ void DecodeTrace::draw_range(const pv::data::decode::Annotation &a, QPainter &p,
|
||||
QPointF(start + cap_width, bottom)
|
||||
};
|
||||
|
||||
p.setPen(Qt::white);
|
||||
p.setPen(DARK_BACK);
|
||||
p.drawConvexPolygon(pts, countof(pts));
|
||||
|
||||
if (annotations.empty())
|
||||
@@ -643,20 +657,8 @@ bool DecodeTrace::draw_unresolved_period(QPainter &p, int h, int left,
|
||||
return false;
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
p.setPen(dsLightBlue);
|
||||
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,
|
||||
int right)
|
||||
int right, QString info)
|
||||
{
|
||||
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.setBrush(QBrush(NoDecodeColour, Qt::Dense7Pattern));
|
||||
p.drawRect(unshown_rect);
|
||||
p.setPen(Trace::DARK_FORE);
|
||||
p.drawLine(left, y, info_left, y);
|
||||
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);
|
||||
QFont font=p.font();
|
||||
font.setPointSize(_view->get_signalHeight()*2/3);
|
||||
font.setBold(true);
|
||||
p.setFont(font);
|
||||
p.drawText(unshown_rect, Qt::AlignCenter | Qt::AlignVCenter, "Unshown");
|
||||
p.setPen(Trace::DARK_FORE);
|
||||
p.drawText(unshown_rect, Qt::AlignCenter | Qt::AlignVCenter, info);
|
||||
}
|
||||
|
||||
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,
|
||||
QFormLayout *form)
|
||||
QFormLayout *form)
|
||||
{
|
||||
const GSList *l;
|
||||
|
||||
assert(dec);
|
||||
assert(dec);
|
||||
const srd_decoder *const decoder = dec->decoder();
|
||||
assert(decoder);
|
||||
|
||||
pv::widgets::DecoderGroupBox *const group =
|
||||
new pv::widgets::DecoderGroupBox(
|
||||
QString::fromUtf8(decoder->name));
|
||||
group->set_decoder_visible(dec->shown());
|
||||
|
||||
_show_hide_mapper.setMapping(group, index);
|
||||
connect(group, SIGNAL(show_hide_decoder()),
|
||||
&_show_hide_mapper, SLOT(map()));
|
||||
pv::widgets::DecoderGroupBox *const group =
|
||||
new pv::widgets::DecoderGroupBox(decoder_stack, dec);
|
||||
connect(group, SIGNAL(del_stack(boost::shared_ptr<data::decode::Decoder>&)),
|
||||
this, SLOT(on_del_stack(boost::shared_ptr<data::decode::Decoder>&)));
|
||||
|
||||
QFormLayout *const decoder_form = new QFormLayout;
|
||||
group->add_layout(decoder_form);
|
||||
@@ -739,7 +741,7 @@ void DecodeTrace::create_decoder_form(int index,
|
||||
|
||||
// Add the options
|
||||
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);
|
||||
|
||||
_bindings.push_back(binding);
|
||||
@@ -837,6 +839,7 @@ void DecodeTrace::on_decode_done()
|
||||
_view->set_need_update(true);
|
||||
_view->signals_changed();
|
||||
}
|
||||
_session.decode_done();
|
||||
}
|
||||
|
||||
void DecodeTrace::on_delete()
|
||||
@@ -860,33 +863,36 @@ void DecodeTrace::on_stack_decoder(srd_decoder *decoder)
|
||||
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());
|
||||
|
||||
// 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);
|
||||
create_popup_form();
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
@@ -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);
|
||||
QString index_string;
|
||||
int last_index;
|
||||
p.setPen(Qt::transparent);
|
||||
p.setBrush(dsBlue);
|
||||
p.drawRect(group_index_rect);
|
||||
p.setPen(QPen(DARK_FORE, 1, Qt::DashLine));
|
||||
p.drawLine(group_index_rect.bottomLeft(), group_index_rect.bottomRight());
|
||||
std::list<int>::iterator i = _index_list.begin();
|
||||
last_index = (*i);
|
||||
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;
|
||||
last_index = (*i);
|
||||
}
|
||||
p.setPen(Qt::white);
|
||||
p.setPen(DARK_FORE);
|
||||
p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string);
|
||||
}
|
||||
|
||||
@@ -986,5 +991,6 @@ void DecodeTrace::frame_ended()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // namespace view
|
||||
} // namespace pv
|
||||
|
||||
@@ -152,14 +152,14 @@ private:
|
||||
void draw_annotation(const pv::data::decode::Annotation &a, QPainter &p,
|
||||
QColor text_colour, int text_height, int left, int right,
|
||||
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,
|
||||
int text_height, int left, int right, int y,
|
||||
size_t base_colour) const;
|
||||
|
||||
void draw_instant(const pv::data::decode::Annotation &a, QPainter &p,
|
||||
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,
|
||||
QColor fill, QColor outline, QColor text_color, int h, double start,
|
||||
@@ -172,11 +172,11 @@ private:
|
||||
int right);
|
||||
|
||||
void draw_unshown_row(QPainter &p, int y, int h, int left,
|
||||
int right);
|
||||
int right, QString info);
|
||||
|
||||
void create_decoder_form(int index,
|
||||
boost::shared_ptr<pv::data::decode::Decoder> &dec,
|
||||
QWidget *parent, QFormLayout *form);
|
||||
void create_decoder_form(boost::shared_ptr<data::DecoderStack> &decoder_stack,
|
||||
boost::shared_ptr<pv::data::decode::Decoder> &dec,
|
||||
QWidget *parent, QFormLayout *form);
|
||||
|
||||
QComboBox* create_probe_selector(QWidget *parent,
|
||||
const boost::shared_ptr<pv::data::decode::Decoder> &dec,
|
||||
@@ -195,8 +195,7 @@ private slots:
|
||||
void on_probe_selected(int);
|
||||
|
||||
void on_stack_decoder(srd_decoder *decoder);
|
||||
|
||||
void on_show_hide_decoder(int index);
|
||||
void on_del_stack(boost::shared_ptr<data::decode::Decoder> &dec);
|
||||
|
||||
void on_decode_done();
|
||||
|
||||
@@ -219,7 +218,6 @@ private:
|
||||
|
||||
std::vector<QString> _cur_row_headings;
|
||||
|
||||
QSignalMapper _show_hide_mapper;
|
||||
QFormLayout *_popup_form;
|
||||
QDialog *_popup;
|
||||
};
|
||||
|
||||
@@ -44,45 +44,50 @@ using namespace std;
|
||||
namespace pv {
|
||||
namespace view {
|
||||
|
||||
DevMode::DevMode(View &parent) :
|
||||
QWidget(&parent),
|
||||
_view(parent),
|
||||
layout(new QGridLayout(this))
|
||||
DevMode::DevMode(QWidget *parent, SigSession &session) :
|
||||
QWidget(parent),
|
||||
_session(session),
|
||||
_layout(new QGridLayout(this))
|
||||
|
||||
{
|
||||
setLayout(layout);
|
||||
setLayout(_layout);
|
||||
}
|
||||
|
||||
void DevMode::set_device()
|
||||
{
|
||||
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);
|
||||
|
||||
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();
|
||||
delete layout;
|
||||
layout = new QGridLayout(this);
|
||||
|
||||
for (GSList *l = dev_inst->get_dev_mode_list();
|
||||
l; l = l->next) {
|
||||
sr_dev_mode *mode = (sr_dev_mode *)l->data;
|
||||
|
||||
boost::shared_ptr<QPushButton> mode_button = boost::shared_ptr<QPushButton>(new QPushButton(NULL));
|
||||
mode_button->setFlat(true);
|
||||
QPushButton *mode_button = new QPushButton(this);
|
||||
//mode_button->setFlat(true);
|
||||
mode_button->setText(mode->name);
|
||||
mode_button->setCheckable(true);
|
||||
|
||||
_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(new QWidget(), index / GRID_COLS, GRID_COLS);
|
||||
layout->setColumnStretch(GRID_COLS, 1);
|
||||
_layout->addWidget(mode_button, index / GRID_COLS, index % GRID_COLS);
|
||||
//layout->addWidget(new QWidget(), index / GRID_COLS, GRID_COLS);
|
||||
_layout->setColumnStretch(GRID_COLS, 1);
|
||||
index++;
|
||||
}
|
||||
|
||||
setLayout(layout);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -94,40 +99,27 @@ void DevMode::paintEvent(QPaintEvent*)
|
||||
o.initFrom(this);
|
||||
QPainter 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()
|
||||
{
|
||||
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);
|
||||
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++) {
|
||||
if ((*i).first.get() == button) {
|
||||
if ((*i).first == button) {
|
||||
if (dev_inst->dev_inst()->mode != (*i).second->mode) {
|
||||
_view.session().stop_capture();
|
||||
_session.stop_capture();
|
||||
dev_inst->set_config(NULL, NULL,
|
||||
SR_CONF_DEVICE_MODE,
|
||||
g_variant_new_int16((*i).second->mode));
|
||||
button->setChecked(true);
|
||||
mode_changed();
|
||||
}
|
||||
} else {
|
||||
(*i).first->setChecked(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,9 +44,9 @@ namespace device{
|
||||
class DevInst;
|
||||
}
|
||||
|
||||
namespace view {
|
||||
class SigSession;
|
||||
|
||||
class View;
|
||||
namespace view {
|
||||
|
||||
class DevMode : public QWidget
|
||||
{
|
||||
@@ -56,7 +56,7 @@ private:
|
||||
static const int GRID_COLS = 3;
|
||||
|
||||
public:
|
||||
DevMode(View &parent);
|
||||
DevMode(QWidget *parent, SigSession &session);
|
||||
|
||||
private:
|
||||
void paintEvent(QPaintEvent *event);
|
||||
@@ -77,10 +77,10 @@ signals:
|
||||
void mode_changed();
|
||||
|
||||
private:
|
||||
View &_view;
|
||||
SigSession &_session;
|
||||
|
||||
QGridLayout * layout;
|
||||
std::map <boost::shared_ptr<QPushButton>, sr_dev_mode *> _mode_button_list;
|
||||
QGridLayout * _layout;
|
||||
std::map <QPushButton *, sr_dev_mode *> _mode_button_list;
|
||||
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);
|
||||
QString index_string;
|
||||
int last_index;
|
||||
p.setPen(Qt::transparent);
|
||||
p.setBrush(dsBlue);
|
||||
p.drawRect(group_index_rect);
|
||||
p.setPen(QPen(DARK_FORE, 1, Qt::DashLine));
|
||||
p.drawLine(group_index_rect.bottomLeft(), group_index_rect.bottomRight());
|
||||
std::list<int>::iterator i = _index_list.begin();
|
||||
last_index = (*i);
|
||||
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;
|
||||
last_index = (*i);
|
||||
}
|
||||
p.setPen(Qt::white);
|
||||
p.setPen(DARK_FORE);
|
||||
p.drawText(group_index_rect, Qt::AlignRight | Qt::AlignVCenter, index_string);
|
||||
}
|
||||
|
||||
|
||||
@@ -115,15 +115,13 @@ void Header::paintEvent(QPaintEvent*)
|
||||
QStyleOption o;
|
||||
o.initFrom(this);
|
||||
QPainter painter(this);
|
||||
//painter.setRenderHint(QPainter::Antialiasing);
|
||||
style()->drawPrimitive(QStyle::PE_Widget, &o, &painter, this);
|
||||
|
||||
const int w = width();
|
||||
const vector< boost::shared_ptr<Trace> > traces(
|
||||
_view.get_traces());
|
||||
|
||||
//QPainter painter(this);
|
||||
//painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
const bool dragging = !_drag_traces.empty();
|
||||
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::LowColour(0xC0, 0x00, 0x00);
|
||||
|
||||
const QColor LogicSignal::SignalColours[8] = {
|
||||
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 QColor LogicSignal::DEFAULT_COLOR = QColor(150, 150, 150, 255);
|
||||
|
||||
const int LogicSignal::StateHeight = 12;
|
||||
const int LogicSignal::StateRound = 5;
|
||||
@@ -73,7 +56,8 @@ LogicSignal::LogicSignal(boost::shared_ptr<pv::device::DevInst> dev_inst,
|
||||
_data(data),
|
||||
_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,
|
||||
@@ -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 edgeTrig_rect = get_rect(EDGTRIG, y, right);
|
||||
|
||||
p.setPen(Qt::transparent);
|
||||
p.setBrush(posTrig_rect.contains(pt) ? dsYellow.darker() :
|
||||
(_trig == POSTRIG) ? dsYellow : dsBlue);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(posTrig_rect.contains(pt) ? dsBlue.lighter() :
|
||||
(_trig == POSTRIG) ? dsBlue : DARK_BACK);
|
||||
p.drawRect(posTrig_rect);
|
||||
p.setBrush(higTrig_rect.contains(pt) ? dsYellow.darker() :
|
||||
(_trig == HIGTRIG) ? dsYellow : dsBlue);
|
||||
p.setBrush(higTrig_rect.contains(pt) ? dsBlue.lighter() :
|
||||
(_trig == HIGTRIG) ? dsBlue : DARK_BACK);
|
||||
p.drawRect(higTrig_rect);
|
||||
p.setBrush(negTrig_rect.contains(pt) ? dsYellow.darker() :
|
||||
(_trig == NEGTRIG) ? dsYellow : dsBlue);
|
||||
p.setBrush(negTrig_rect.contains(pt) ? dsBlue.lighter() :
|
||||
(_trig == NEGTRIG) ? dsBlue : DARK_BACK);
|
||||
p.drawRect(negTrig_rect);
|
||||
p.setBrush(lowTrig_rect.contains(pt) ? dsYellow.darker() :
|
||||
(_trig == LOWTRIG) ? dsYellow : dsBlue);
|
||||
p.setBrush(lowTrig_rect.contains(pt) ? dsBlue.lighter() :
|
||||
(_trig == LOWTRIG) ? dsBlue : DARK_BACK);
|
||||
p.drawRect(lowTrig_rect);
|
||||
p.setBrush(edgeTrig_rect.contains(pt) ? dsYellow.darker() :
|
||||
(_trig == EDGTRIG) ? dsYellow : dsBlue);
|
||||
p.setBrush(edgeTrig_rect.contains(pt) ? dsBlue.lighter() :
|
||||
(_trig == EDGTRIG) ? dsBlue : DARK_BACK);
|
||||
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.drawLine(posTrig_rect.right(), posTrig_rect.top() + 3,
|
||||
posTrig_rect.right(), posTrig_rect.bottom() - 3);
|
||||
p.drawLine(higTrig_rect.right(), higTrig_rect.top() + 3,
|
||||
higTrig_rect.right(), higTrig_rect.bottom() - 3);
|
||||
p.drawLine(negTrig_rect.right(), negTrig_rect.top() + 3,
|
||||
negTrig_rect.right(), negTrig_rect.bottom() - 3);
|
||||
p.drawLine(lowTrig_rect.right(), lowTrig_rect.top() + 3,
|
||||
lowTrig_rect.right(), lowTrig_rect.bottom() - 3);
|
||||
// p.drawLine(posTrig_rect.right(), posTrig_rect.top(),
|
||||
// posTrig_rect.right(), posTrig_rect.bottom());
|
||||
// p.drawLine(higTrig_rect.right(), higTrig_rect.top(),
|
||||
// higTrig_rect.right(), higTrig_rect.bottom());
|
||||
// p.drawLine(negTrig_rect.right(), negTrig_rect.top(),
|
||||
// negTrig_rect.right(), negTrig_rect.bottom());
|
||||
// p.drawLine(lowTrig_rect.right(), lowTrig_rect.top(),
|
||||
// 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.drawLine(posTrig_rect.left() + 5, posTrig_rect.bottom() - 5,
|
||||
posTrig_rect.center().x(), posTrig_rect.bottom() - 5);
|
||||
|
||||
@@ -48,7 +48,7 @@ private:
|
||||
static const QColor HighColour;
|
||||
static const QColor LowColour;
|
||||
|
||||
static const QColor SignalColours[8];
|
||||
static const QColor DEFAULT_COLOR;
|
||||
|
||||
static const int StateHeight;
|
||||
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::dsRed = QColor(213, 15, 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::WarnColor = dsRed;
|
||||
@@ -458,7 +459,7 @@ void Ruler::draw_logic_tick_mark(QPainter &p)
|
||||
AlignLeft | AlignTop, "8").height();
|
||||
|
||||
// Draw the tick marks
|
||||
p.setPen(dsBlue);
|
||||
p.setPen(Trace::DARK_FORE);
|
||||
|
||||
const double minor_tick_period = tick_period / MinPeriodScale;
|
||||
const int minor_order = (int)floorf(log10f(minor_tick_period));
|
||||
@@ -548,7 +549,7 @@ void Ruler::draw_hover_mark(QPainter &p)
|
||||
return;
|
||||
|
||||
p.setPen(QPen(Qt::NoPen));
|
||||
p.setBrush(dsBlue);
|
||||
p.setBrush(RULER_COLOR);
|
||||
|
||||
const int b = height() - 1;
|
||||
const QPointF points[] = {
|
||||
|
||||
@@ -54,6 +54,7 @@ private:
|
||||
static const QColor dsYellow;
|
||||
static const QColor dsRed;
|
||||
static const QColor dsGreen;
|
||||
static const QColor RULER_COLOR;
|
||||
|
||||
public:
|
||||
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 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 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 label_rect = get_rect("label", get_zeroPos(), right);
|
||||
|
||||
p.setRenderHint(QPainter::Antialiasing);
|
||||
//p.setRenderHint(QPainter::Antialiasing);
|
||||
// Paint the ColorButton
|
||||
p.setPen(Qt::transparent);
|
||||
p.setBrush(enabled() ? _colour : dsDisable);
|
||||
p.drawRect(color_rect);
|
||||
|
||||
// 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);
|
||||
|
||||
// Paint the trigButton
|
||||
@@ -244,16 +267,14 @@ void Trace::paint_label(QPainter &p, int right, const QPoint pt)
|
||||
};
|
||||
|
||||
p.setPen(Qt::transparent);
|
||||
if (_type == SR_CHANNEL_DSO)
|
||||
if (_type == SR_CHANNEL_DSO) {
|
||||
p.setBrush((label_rect.contains(pt) || selected()) ? _colour.darker() : _colour);
|
||||
else
|
||||
p.setBrush((label_rect.contains(pt) || selected()) ? dsYellow : dsBlue);
|
||||
p.drawPolygon(points, countof(points));
|
||||
|
||||
p.setPen(QPen(Qt::blue, 1, Qt::DotLine));
|
||||
p.setBrush(Qt::transparent);
|
||||
p.drawLine(label_rect.right(), label_rect.top() + 3,
|
||||
label_rect.right(), label_rect.bottom() - 3);
|
||||
p.drawPolygon(points, countof(points));
|
||||
} else {
|
||||
QColor color = PROBE_COLORS[*_index_list.begin() % countof(PROBE_COLORS)];
|
||||
p.setBrush((label_rect.contains(pt) || selected()) ? color.lighter() : color);
|
||||
p.drawPolygon(points, countof(points));
|
||||
}
|
||||
|
||||
// Paint the text
|
||||
p.setPen(Qt::white);
|
||||
@@ -326,30 +347,6 @@ void Trace::compute_text_size(QPainter &p)
|
||||
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
|
||||
{
|
||||
assert(_view);
|
||||
@@ -385,7 +382,7 @@ int Trace::rows_size()
|
||||
|
||||
int Trace::get_leftWidth() const
|
||||
{
|
||||
return SquareWidth + Margin;
|
||||
return SquareWidth/2 + Margin;
|
||||
}
|
||||
|
||||
int Trace::get_rightWidth() const
|
||||
@@ -398,5 +395,34 @@ int Trace::get_headerHeight() const
|
||||
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 pv
|
||||
|
||||
@@ -70,6 +70,12 @@ public:
|
||||
static const QColor dsLightRed;
|
||||
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:
|
||||
Trace(QString name, uint16_t index, int type);
|
||||
Trace(QString name, std::list<int> index_list, int type, int sec_index);
|
||||
@@ -225,7 +231,7 @@ public:
|
||||
* area.
|
||||
* @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();
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget
|
||||
_viewport(new Viewport(*this)),
|
||||
_ruler(new Ruler(*this)),
|
||||
_header(new Header(*this)),
|
||||
_devmode(new DevMode(*this)),
|
||||
_devmode(new DevMode(this, session)),
|
||||
_scale(1e-8),
|
||||
_preScale(1e-6),
|
||||
_maxscale(1e9),
|
||||
@@ -98,15 +98,17 @@ View::View(SigSession &session, pv::toolbars::SamplingBar *sampling_bar, QWidget
|
||||
setViewportMargins(headerWidth(), RulerHeight, 0, 0);
|
||||
setViewport(_viewport);
|
||||
|
||||
connect(&_session, SIGNAL(device_setted()),
|
||||
_devmode, SLOT(set_device()));
|
||||
connect(&_session, SIGNAL(signals_changed()),
|
||||
this, SLOT(signals_changed()));
|
||||
connect(&_session, SIGNAL(data_updated()),
|
||||
this, SLOT(data_updated()));
|
||||
connect(&_session, SIGNAL(receive_trigger(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()),
|
||||
this, SIGNAL(mode_changed()));
|
||||
|
||||
@@ -464,9 +466,9 @@ void View::update_scale()
|
||||
}
|
||||
|
||||
_minscale = (1.0 / sample_rate) / MaxPixelsPerSample;
|
||||
_offset = 0;
|
||||
//_offset = 0;
|
||||
_preScale = _scale;
|
||||
_preOffset = _offset;
|
||||
//_preOffset = _offset;
|
||||
|
||||
_trig_cursor->set_index(_trig_pos);
|
||||
|
||||
@@ -514,6 +516,7 @@ void View::signals_changed()
|
||||
_viewport->clear_measure();
|
||||
header_updated();
|
||||
normalize_layout();
|
||||
data_updated();
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
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 pv
|
||||
|
||||
@@ -221,6 +221,7 @@ public slots:
|
||||
void signals_changed();
|
||||
void data_updated();
|
||||
void update_scale();
|
||||
void show_region(uint64_t start, uint64_t end);
|
||||
|
||||
private slots:
|
||||
|
||||
|
||||
@@ -445,11 +445,11 @@ void Viewport::mouseMoveEvent(QMouseEvent *event)
|
||||
|
||||
if (_action_type == DSO_YM)
|
||||
_dso_ym_end = event->pos().y();
|
||||
|
||||
measure();
|
||||
}
|
||||
|
||||
_mouse_point = event->pos();
|
||||
|
||||
measure();
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -719,7 +719,6 @@ void Viewport::leaveEvent(QEvent *)
|
||||
_mm_period = "#####";
|
||||
_mm_freq = "#####";
|
||||
_mm_duty = "#####";
|
||||
measure_updated();
|
||||
} else if (_action_type == DSO_YM) {
|
||||
_dso_ym_valid = false;
|
||||
}
|
||||
@@ -727,6 +726,7 @@ void Viewport::leaveEvent(QEvent *)
|
||||
if (_action_type != NO_ACTION)
|
||||
_action_type = NO_ACTION;
|
||||
|
||||
measure();
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -767,7 +767,7 @@ void Viewport::measure()
|
||||
boost::shared_ptr<view::DsoSignal> dsoSig;
|
||||
if (logicSig = dynamic_pointer_cast<view::LogicSignal>(s)) {
|
||||
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;
|
||||
|
||||
_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)
|
||||
{
|
||||
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,
|
||||
"Last Trigger Time: "+_view.trigger_time());
|
||||
}
|
||||
|
||||
@@ -17,52 +17,134 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
extern "C" {
|
||||
#include <libsigrokdecode/libsigrokdecode.h>
|
||||
}
|
||||
|
||||
#include "decodergroupbox.h"
|
||||
#include "../data/decoderstack.h"
|
||||
#include "../data/decode/decoder.h"
|
||||
#include "../data/decode/row.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QVariant>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
namespace pv {
|
||||
namespace widgets {
|
||||
|
||||
DecoderGroupBox::DecoderGroupBox(QString title, QWidget *parent) :
|
||||
QWidget(parent),
|
||||
_layout(new QGridLayout),
|
||||
_show_hide_button(QIcon(":/icons/shown.png"), QString(), this)
|
||||
DecoderGroupBox::DecoderGroupBox(boost::shared_ptr<data::DecoderStack> &decoder_stack,
|
||||
boost::shared_ptr<data::decode::Decoder> &dec,
|
||||
QWidget *parent) :
|
||||
QWidget(parent),
|
||||
_decoder_stack(decoder_stack),
|
||||
_dec(dec),
|
||||
_layout(new QGridLayout)
|
||||
{
|
||||
_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);
|
||||
_layout->setColumnStretch(0, 1);
|
||||
|
||||
QHBoxLayout *const toolbar = new QHBoxLayout;
|
||||
_layout->addLayout(toolbar, 0, 1);
|
||||
const srd_decoder *const d = _dec->decoder();
|
||||
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);
|
||||
//_show_hide_button.setIconSize(QSize(16, 16));
|
||||
connect(&_show_hide_button, SIGNAL(clicked()),
|
||||
this, SIGNAL(show_hide_decoder()));
|
||||
toolbar->addWidget(&_show_hide_button);
|
||||
_index = 0;
|
||||
BOOST_FOREACH(boost::shared_ptr<data::decode::Decoder> dec,
|
||||
_decoder_stack->stack()) {
|
||||
if (dec == _dec)
|
||||
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)
|
||||
{
|
||||
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 ?
|
||||
":/icons/shown.png" :
|
||||
":/icons/hidden.png"));
|
||||
QPushButton *sc = dynamic_cast<QPushButton*>(sender());
|
||||
QVariant id = sc->property("index");
|
||||
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
|
||||
|
||||
@@ -22,11 +22,19 @@
|
||||
#define DSVIEW_PV_WIDGETS_DECODERGROUPBOX_H
|
||||
|
||||
#include <QPushButton>
|
||||
|
||||
class QGridLayout;
|
||||
class QToolBar;
|
||||
#include <QGridLayout>
|
||||
#include <QToolBar>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
namespace pv {
|
||||
|
||||
namespace data{
|
||||
class DecoderStack;
|
||||
namespace decode{
|
||||
class Decoder;
|
||||
}
|
||||
}
|
||||
|
||||
namespace widgets {
|
||||
|
||||
class DecoderGroupBox : public QWidget
|
||||
@@ -34,18 +42,30 @@ class DecoderGroupBox : public QWidget
|
||||
Q_OBJECT
|
||||
|
||||
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 set_decoder_visible(bool visible);
|
||||
|
||||
signals:
|
||||
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:
|
||||
QGridLayout *const _layout;
|
||||
QPushButton _show_hide_button;
|
||||
boost::shared_ptr<pv::data::DecoderStack> &_decoder_stack;
|
||||
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
|
||||
|
||||
@@ -261,4 +261,24 @@ QSlider::add-page:horizontal{
|
||||
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 */
|
||||
|
||||
Reference in New Issue
Block a user