Introduce pv::data::SignalBase

This commit is contained in:
Soeren Apel 2016-08-16 21:09:58 +02:00 committed by Uwe Hermann
parent 14f9d4a1f4
commit bf0edd2b0c
22 changed files with 423 additions and 171 deletions

View File

@ -216,6 +216,7 @@ set(pulseview_SOURCES
pv/data/analogsegment.cpp
pv/data/logic.cpp
pv/data/logicsegment.cpp
pv/data/signalbase.cpp
pv/data/signaldata.cpp
pv/data/segment.cpp
pv/devices/device.cpp
@ -280,6 +281,7 @@ set(pulseview_HEADERS
pv/session.hpp
pv/storesession.hpp
pv/binding/device.hpp
pv/data/signalbase.hpp
pv/dialogs/about.hpp
pv/dialogs/connect.hpp
pv/dialogs/inputoutputoptions.hpp

103
pv/data/signalbase.cpp Normal file
View File

@ -0,0 +1,103 @@
/*
* This file is part of the PulseView project.
*
* Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
* Copyright (C) 2016 Soeren Apel <soeren@apelpie.net>
*
* 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 "signalbase.hpp"
using std::shared_ptr;
using sigrok::Channel;
using sigrok::ChannelType;
namespace pv {
namespace data {
const int SignalBase::ColourBGAlpha = 8*256/100;
SignalBase::SignalBase(shared_ptr<sigrok::Channel> channel) :
channel_(channel)
{
}
shared_ptr<sigrok::Channel> SignalBase::channel() const
{
return channel_;
}
QString SignalBase::name() const
{
return (channel_) ? QString::fromStdString(channel_->name()) : name_;
}
void SignalBase::set_name(QString name)
{
if (channel_)
channel_->set_name(name.toUtf8().constData());
name_ = name;
name_changed(name);
}
bool SignalBase::enabled() const
{
return (channel_) ? channel_->enabled() : true;
}
void SignalBase::set_enabled(bool value)
{
if (channel_) {
channel_->set_enabled(value);
enabled_changed(value);
}
}
const ChannelType *SignalBase::type() const
{
return (channel_) ? channel_->type() : nullptr;
}
unsigned int SignalBase::index() const
{
return (channel_) ? channel_->index() : (unsigned int)-1;
}
QColor SignalBase::colour() const
{
return colour_;
}
void SignalBase::set_colour(QColor colour)
{
colour_ = colour;
bgcolour_ = colour;
bgcolour_.setAlpha(ColourBGAlpha);
colour_changed(colour);
}
QColor SignalBase::bgcolour() const
{
return bgcolour_;
}
} // namespace data
} // namespace pv

119
pv/data/signalbase.hpp Normal file
View File

@ -0,0 +1,119 @@
/*
* This file is part of the PulseView project.
*
* Copyright (C) 2012 Joel Holdsworth <joel@airwebreathe.org.uk>
* Copyright (C) 2016 Soeren Apel <soeren@apelpie.net>
*
* 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 PULSEVIEW_PV_DATA_SIGNALBASE_HPP
#define PULSEVIEW_PV_DATA_SIGNALBASE_HPP
#include <QColor>
#include <QObject>
#include <QString>
#include <libsigrokcxx/libsigrokcxx.hpp>
namespace sigrok {
class Channel;
class ChannelType;
}
namespace pv {
namespace data {
class SignalBase : public QObject
{
Q_OBJECT
private:
static const int ColourBGAlpha;
public:
SignalBase(std::shared_ptr<sigrok::Channel> channel);
virtual ~SignalBase() {}
public:
/**
* Returns the underlying SR channel.
*/
std::shared_ptr<sigrok::Channel> channel() const;
/**
* Returns enabled status of this channel.
*/
bool enabled() const;
/**
* Sets the enabled status of this channel.
* @param value Boolean value to set.
*/
void set_enabled(bool value);
/**
* Gets the type of this channel.
*/
const sigrok::ChannelType *type() const;
/**
* Gets the index number of this channel.
*/
unsigned int index() const;
/**
* Gets the name of this signal.
*/
QString name() const;
/**
* Sets the name of the signal.
*/
virtual void set_name(QString name);
/**
* Get the colour of the signal.
*/
QColor colour() const;
/**
* Set the colour of the signal.
*/
void set_colour(QColor colour);
/**
* Get the background colour of the signal.
*/
QColor bgcolour() const;
Q_SIGNALS:
void enabled_changed(const bool &value);
void name_changed(const QString &name);
void colour_changed(const QColor &colour);
private:
std::shared_ptr<sigrok::Channel> channel_;
QString name_;
QColor colour_, bgcolour_;
};
} // namespace data
} // namespace pv
#endif // PULSEVIEW_PV_DATA_SIGNALBASE_HPP

View File

@ -36,6 +36,7 @@
#include "channels.hpp"
#include <pv/binding/device.hpp>
#include <pv/data/signalbase.hpp>
#include <pv/devices/device.hpp>
#include <pv/session.hpp>
#include <pv/view/signal.hpp>
@ -54,12 +55,12 @@ using std::shared_ptr;
using std::unordered_set;
using std::vector;
using pv::data::SignalBase;
using sigrok::Channel;
using sigrok::ChannelGroup;
using sigrok::Device;
using pv::view::Signal;
namespace pv {
namespace popups {
@ -78,11 +79,13 @@ Channels::Channels(Session &session, QWidget *parent) :
assert(device);
// Collect a set of signals
map<shared_ptr<Channel>, shared_ptr<Signal> > signal_map;
map<shared_ptr<Channel>, shared_ptr<SignalBase> > signal_map;
const unordered_set< shared_ptr<Signal> > sigs(session_.signals());
unordered_set< shared_ptr<SignalBase> > sigs;
for (const shared_ptr<view::Signal> s : session_.signals())
sigs.insert(s->channel());
for (const shared_ptr<Signal> &sig : sigs)
for (const shared_ptr<SignalBase> &sig : sigs)
signal_map[sig->channel()] = sig;
// Populate channel groups
@ -90,7 +93,7 @@ Channels::Channels(Session &session, QWidget *parent) :
shared_ptr<ChannelGroup> group = entry.second;
// Make a set of signals, and removed this signals from the
// signal map.
vector< shared_ptr<Signal> > group_sigs;
vector< shared_ptr<SignalBase> > group_sigs;
for (auto channel : group->channels()) {
const auto iter = signal_map.find(channel);
@ -105,9 +108,9 @@ Channels::Channels(Session &session, QWidget *parent) :
}
// Make a vector of the remaining channels
vector< shared_ptr<Signal> > global_sigs;
vector< shared_ptr<SignalBase> > global_sigs;
for (auto channel : device->channels()) {
const map<shared_ptr<Channel>, shared_ptr<Signal> >::
const map<shared_ptr<Channel>, shared_ptr<SignalBase> >::
const_iterator iter = signal_map.find(channel);
if (iter != signal_map.end())
global_sigs.push_back((*iter).second);
@ -140,13 +143,13 @@ void Channels::set_all_channels(bool set)
{
updating_channels_ = true;
for (map<QCheckBox*, shared_ptr<Signal> >::const_iterator i =
for (map<QCheckBox*, shared_ptr<SignalBase> >::const_iterator i =
check_box_signal_map_.begin();
i != check_box_signal_map_.end(); i++) {
const shared_ptr<Signal> sig = (*i).second;
const shared_ptr<SignalBase> sig = (*i).second;
assert(sig);
sig->enable(set);
sig->set_enabled(set);
(*i).first->setChecked(set);
}
@ -154,7 +157,7 @@ void Channels::set_all_channels(bool set)
}
void Channels::populate_group(shared_ptr<ChannelGroup> group,
const vector< shared_ptr<pv::view::Signal> > sigs)
const vector< shared_ptr<SignalBase> > sigs)
{
using pv::binding::Device;
@ -185,12 +188,12 @@ void Channels::populate_group(shared_ptr<ChannelGroup> group,
}
QGridLayout* Channels::create_channel_group_grid(
const vector< shared_ptr<pv::view::Signal> > sigs)
const vector< shared_ptr<SignalBase> > sigs)
{
int row = 0, col = 0;
QGridLayout *const grid = new QGridLayout();
for (const shared_ptr<pv::view::Signal>& sig : sigs) {
for (const shared_ptr<SignalBase>& sig : sigs) {
assert(sig);
QCheckBox *const checkbox = new QCheckBox(sig->name());
@ -215,10 +218,10 @@ void Channels::showEvent(QShowEvent *event)
updating_channels_ = true;
for (map<QCheckBox*, shared_ptr<Signal> >::const_iterator i =
for (map<QCheckBox*, shared_ptr<SignalBase> >::const_iterator i =
check_box_signal_map_.begin();
i != check_box_signal_map_.end(); i++) {
const shared_ptr<Signal> sig = (*i).second;
const shared_ptr<SignalBase> sig = (*i).second;
assert(sig);
(*i).first->setChecked(sig->enabled());
@ -236,14 +239,14 @@ void Channels::on_channel_checked(QWidget *widget)
assert(check_box);
// Look up the signal of this check-box
map< QCheckBox*, shared_ptr<Signal> >::const_iterator iter =
map< QCheckBox*, shared_ptr<SignalBase> >::const_iterator iter =
check_box_signal_map_.find((QCheckBox*)check_box);
assert(iter != check_box_signal_map_.end());
const shared_ptr<pv::view::Signal> s = (*iter).second;
const shared_ptr<SignalBase> s = (*iter).second;
assert(s);
s->enable(check_box->isChecked());
s->set_enabled(check_box->isChecked());
}
void Channels::enable_all_channels()

View File

@ -47,6 +47,10 @@ namespace binding {
class Device;
}
namespace data {
class SignalBase;
}
namespace view {
class Signal;
}
@ -64,10 +68,10 @@ private:
void set_all_channels(bool set);
void populate_group(std::shared_ptr<sigrok::ChannelGroup> group,
const std::vector< std::shared_ptr<pv::view::Signal> > sigs);
const std::vector< std::shared_ptr<pv::data::SignalBase> > sigs);
QGridLayout* create_channel_group_grid(
const std::vector< std::shared_ptr<pv::view::Signal> > sigs);
const std::vector< std::shared_ptr<pv::data::SignalBase> > sigs);
private:
void showEvent(QShowEvent *event);
@ -87,7 +91,7 @@ private:
std::vector< std::shared_ptr<pv::binding::Device> >
group_bindings_;
std::map< QCheckBox*, std::shared_ptr<pv::view::Signal> >
std::map< QCheckBox*, std::shared_ptr<pv::data::SignalBase> >
check_box_signal_map_;
QHBoxLayout buttons_bar_;

View File

@ -39,6 +39,7 @@
#include "data/decoderstack.hpp"
#include "data/logic.hpp"
#include "data/logicsegment.hpp"
#include "data/signalbase.hpp"
#include "data/decode/decoder.hpp"
#include "devices/hardwaredevice.hpp"
@ -298,7 +299,7 @@ bool Session::add_decoder(srd_decoder *const dec)
dynamic_pointer_cast<view::LogicSignal>(s);
if (l && QString::fromUtf8(pdch->name).
toLower().contains(
l->name().toLower()))
s->channel()->name().toLower()))
channels[pdch] = l;
}
@ -308,8 +309,11 @@ bool Session::add_decoder(srd_decoder *const dec)
decoder_stack->stack().front()->set_channels(channels);
// Create the decode signal
shared_ptr<data::SignalBase> signalbase =
shared_ptr<data::SignalBase>(new data::SignalBase(nullptr));
shared_ptr<view::DecodeTrace> d(
new view::DecodeTrace(*this, decoder_stack,
new view::DecodeTrace(*this, signalbase, decoder_stack,
decode_traces_.size()));
decode_traces_.push_back(d);
} catch (std::runtime_error e) {
@ -401,13 +405,14 @@ void Session::update_signals()
signals_.clear();
for (auto channel : sr_dev->channels()) {
shared_ptr<data::SignalBase> signalbase;
shared_ptr<view::Signal> signal;
// Find the channel in the old signals
const auto iter = std::find_if(
prev_sigs.cbegin(), prev_sigs.cend(),
[&](const shared_ptr<view::Signal> &s) {
return s->channel() == channel;
return s->channel()->channel() == channel;
});
if (iter != prev_sigs.end()) {
// Copy the signal from the old set to the new
@ -419,13 +424,16 @@ void Session::update_signals()
logic_data_);
} else {
// Create a new signal
signalbase = shared_ptr<data::SignalBase>(
new data::SignalBase(channel));
switch(channel->type()->id()) {
case SR_CHANNEL_LOGIC:
signal = shared_ptr<view::Signal>(
new view::LogicSignal(*this,
device_, channel,
logic_data_));
device_, signalbase, logic_data_));
all_signal_data_.insert(logic_data_);
signalbases_.insert(signalbase);
break;
case SR_CHANNEL_ANALOG:
@ -434,8 +442,9 @@ void Session::update_signals()
new data::Analog());
signal = shared_ptr<view::Signal>(
new view::AnalogSignal(
*this, channel, data));
*this, signalbase, data));
all_signal_data_.insert(data);
signalbases_.insert(signalbase);
break;
}
@ -453,16 +462,15 @@ void Session::update_signals()
signals_changed();
}
shared_ptr<view::Signal> Session::signal_from_channel(
shared_ptr<Channel> channel) const
shared_ptr<data::SignalBase> Session::signal_from_channel(
shared_ptr<sigrok::Channel> channel) const
{
lock_guard<boost::shared_mutex> lock(signals_mutex_);
for (shared_ptr<view::Signal> sig : signals_) {
for (shared_ptr<data::SignalBase> sig : signalbases_) {
assert(sig);
if (sig->channel() == channel)
return sig;
}
return shared_ptr<view::Signal>();
return shared_ptr<data::SignalBase>();
}
void Session::sample_thread_proc(function<void (const QString)> error_handler)

View File

@ -64,6 +64,7 @@ class Analog;
class AnalogSegment;
class Logic;
class LogicSegment;
class SignalBase;
class SignalData;
}
@ -133,7 +134,7 @@ private:
void update_signals();
std::shared_ptr<view::Signal> signal_from_channel(
std::shared_ptr<data::SignalBase> signal_from_channel(
std::shared_ptr<sigrok::Channel> channel) const;
private:
@ -165,6 +166,8 @@ private:
mutable boost::shared_mutex signals_mutex_;
std::unordered_set< std::shared_ptr<view::Signal> > signals_;
std::set< std::shared_ptr<data::SignalBase> > signalbases_;
std::set< std::shared_ptr<data::SignalData> > all_signal_data_;
mutable std::recursive_mutex data_mutex_;

View File

@ -36,6 +36,7 @@
#include <pv/data/analogsegment.hpp>
#include <pv/data/logic.hpp>
#include <pv/data/logicsegment.hpp>
#include <pv/data/signalbase.hpp>
#include <pv/devices/device.hpp>
#include <pv/view/signal.hpp>
@ -109,7 +110,7 @@ bool StoreSession::start()
shared_ptr<data::Segment> any_segment;
shared_ptr<data::LogicSegment> lsegment;
vector< shared_ptr<sigrok::Channel> > achannel_list;
vector< shared_ptr<data::SignalBase> > achannel_list;
vector< shared_ptr<data::AnalogSegment> > asegment_list;
for (shared_ptr<view::Signal> signal : sigs) {
@ -214,7 +215,7 @@ void StoreSession::cancel()
interrupt_ = true;
}
void StoreSession::store_proc(vector< shared_ptr<sigrok::Channel> > achannel_list,
void StoreSession::store_proc(vector< shared_ptr<data::SignalBase> > achannel_list,
vector< shared_ptr<data::AnalogSegment> > asegment_list,
shared_ptr<data::LogicSegment> lsegment)
{
@ -259,7 +260,7 @@ void StoreSession::store_proc(vector< shared_ptr<sigrok::Channel> > achannel_lis
const auto context = session_.device_manager().context();
for (unsigned int i = 0; i < achannel_list.size(); i++) {
shared_ptr<sigrok::Channel> achannel = achannel_list.at(i);
shared_ptr<sigrok::Channel> achannel = (achannel_list.at(i))->channel();
shared_ptr<data::AnalogSegment> asegment = asegment_list.at(i);
const float *adata =

View File

@ -36,7 +36,6 @@
#include <QObject>
namespace sigrok {
class Channel;
class Output;
class OutputFormat;
}
@ -46,6 +45,7 @@ namespace pv {
class Session;
namespace data {
class SignalBase;
class AnalogSegment;
class LogicSegment;
}
@ -77,7 +77,7 @@ public:
void cancel();
private:
void store_proc(std::vector< std::shared_ptr<sigrok::Channel> > achannel_list,
void store_proc(std::vector< std::shared_ptr<data::SignalBase> > achannel_list,
std::vector< std::shared_ptr<pv::data::AnalogSegment> > asegment_list,
std::shared_ptr<pv::data::LogicSegment> lsegment);

View File

@ -36,6 +36,7 @@
#include "analogsignal.hpp"
#include "pv/data/analog.hpp"
#include "pv/data/analogsegment.hpp"
#include "pv/data/signalbase.hpp"
#include "pv/view/view.hpp"
#include <libsigrokcxx/libsigrokcxx.hpp>
@ -46,8 +47,6 @@ using std::min;
using std::shared_ptr;
using std::deque;
using sigrok::Channel;
namespace pv {
namespace view {
@ -72,7 +71,7 @@ const int AnalogSignal::InfoTextMarginBottom = 5;
AnalogSignal::AnalogSignal(
pv::Session &session,
shared_ptr<Channel> channel,
shared_ptr<data::SignalBase> channel,
shared_ptr<data::Analog> data) :
Signal(session, channel),
data_(data),
@ -82,7 +81,7 @@ AnalogSignal::AnalogSignal(
vdivs_(1),
resolution_(0)
{
set_colour(SignalColours[channel_->index() % countof(SignalColours)]);
channel_->set_colour(SignalColours[channel_->index() % countof(SignalColours)]);
update_scale();
}
@ -187,7 +186,7 @@ void AnalogSignal::paint_fore(QPainter &p, const ViewItemPaintParams &pp)
// Show the info section on the right side of the trace
const QString infotext = QString("%1 V/div").arg(resolution_);
p.setPen(colour_);
p.setPen(channel_->colour());
p.setFont(QApplication::font());
const QRectF bounding_rect = QRectF(pp.left(),
@ -236,7 +235,7 @@ void AnalogSignal::paint_trace(QPainter &p,
const float *const samples = segment->get_samples(start, end);
assert(samples);
p.setPen(colour_);
p.setPen(channel_->colour());
QPointF *points = new QPointF[sample_count];
QPointF *point = points;
@ -268,7 +267,7 @@ void AnalogSignal::paint_envelope(QPainter &p,
return;
p.setPen(QPen(Qt::NoPen));
p.setBrush(colour_);
p.setBrush(channel_->colour());
QRectF *const rects = new QRectF[e.length];
QRectF *rect = rects;

View File

@ -32,6 +32,7 @@ namespace pv {
namespace data {
class Analog;
class AnalogSegment;
class SignalBase;
}
namespace view {
@ -52,7 +53,7 @@ private:
public:
AnalogSignal(pv::Session &session,
std::shared_ptr<sigrok::Channel> channel,
std::shared_ptr<data::SignalBase> channel,
std::shared_ptr<pv::data::Analog> data);
virtual ~AnalogSignal() = default;

View File

@ -129,10 +129,11 @@ const QColor DecodeTrace::OutlineColours[16] = {
};
DecodeTrace::DecodeTrace(pv::Session &session,
shared_ptr<data::SignalBase> signalbase,
std::shared_ptr<pv::data::DecoderStack> decoder_stack, int index) :
Trace(QString::fromUtf8(
decoder_stack->stack().front()->decoder()->name)),
Trace(signalbase),
session_(session),
signalbase_(signalbase),
decoder_stack_(decoder_stack),
row_height_(0),
max_visible_rows_(0),
@ -145,7 +146,8 @@ DecodeTrace::DecodeTrace(pv::Session &session,
QFontMetrics m(QApplication::font());
min_useful_label_width_ = m.width("XX"); // e.g. two hex characters
set_colour(DecodeColours[index % countof(DecodeColours)]);
signalbase_->set_name(QString::fromUtf8(decoder_stack->stack().front()->decoder()->name));
signalbase_->set_colour(DecodeColours[index % countof(DecodeColours)]);
connect(decoder_stack_.get(), SIGNAL(new_decode_data()),
this, SLOT(on_new_decode_data()));
@ -849,8 +851,8 @@ QComboBox* DecodeTrace::create_channel_selector(
vector< shared_ptr<Signal> > sig_list(sigs.begin(), sigs.end());
std::sort(sig_list.begin(), sig_list.end(),
[](const shared_ptr<Signal> &a, const shared_ptr<Signal> b) {
return strnatcasecmp(a->name().toStdString(),
b->name().toStdString()) < 0; });
return strnatcasecmp(a->channel()->name().toStdString(),
b->channel()->name().toStdString()) < 0; });
assert(decoder_stack_);
const auto channel_iter = dec->channels().find(pdch);
@ -865,7 +867,7 @@ QComboBox* DecodeTrace::create_channel_selector(
for (const shared_ptr<view::Signal> &s : sig_list) {
assert(s);
if (dynamic_pointer_cast<LogicSignal>(s) && s->enabled()) {
selector->addItem(s->name(),
selector->addItem(s->channel()->name(),
qVariantFromValue((void*)s.get()));
if (channel_iter != dec->channels().end() &&

View File

@ -31,6 +31,7 @@
#include <QSignalMapper>
#include <pv/binding/decoder.hpp>
#include <pv/data/signalbase.hpp>
#include <pv/data/decode/row.hpp>
struct srd_channel;
@ -84,7 +85,7 @@ private:
static const QColor OutlineColours[16];
public:
DecodeTrace(pv::Session &session,
DecodeTrace(pv::Session &session, std::shared_ptr<data::SignalBase> signalbase,
std::shared_ptr<pv::data::DecoderStack> decoder_stack,
int index);
@ -196,6 +197,7 @@ private Q_SLOTS:
private:
pv::Session &session_;
std::shared_ptr<data::SignalBase> signalbase_;
std::shared_ptr<pv::data::DecoderStack> decoder_stack_;
uint64_t decode_start_, decode_end_;

View File

@ -37,6 +37,7 @@
#include <pv/devices/device.hpp>
#include <pv/data/logic.hpp>
#include <pv/data/logicsegment.hpp>
#include <pv/data/signalbase.hpp>
#include <pv/view/view.hpp>
#include <libsigrokcxx/libsigrokcxx.hpp>
@ -49,7 +50,6 @@ using std::pair;
using std::shared_ptr;
using std::vector;
using sigrok::Channel;
using sigrok::ConfigKey;
using sigrok::Capability;
using sigrok::Error;
@ -99,7 +99,7 @@ QCache<QString, const QPixmap> LogicSignal::pixmap_cache_;
LogicSignal::LogicSignal(
pv::Session &session,
shared_ptr<devices::Device> device,
shared_ptr<Channel> channel,
shared_ptr<data::SignalBase> channel,
shared_ptr<data::Logic> data) :
Signal(session, channel),
signal_height_(QFontMetrics(QApplication::font()).height() * 2),
@ -114,7 +114,7 @@ LogicSignal::LogicSignal(
{
shared_ptr<Trigger> trigger;
set_colour(SignalColours[channel->index() % countof(SignalColours)]);
channel_->set_colour(SignalColours[channel->index() % countof(SignalColours)]);
/* Populate this channel's trigger setting with whatever we
* find in the current session trigger, if anything. */
@ -122,7 +122,7 @@ LogicSignal::LogicSignal(
if ((trigger = session_.session()->trigger()))
for (auto stage : trigger->stages())
for (auto match : stage->matches())
if (match->channel() == channel_)
if (match->channel() == channel_->channel())
trigger_match_ = match->type();
}
@ -430,12 +430,12 @@ void LogicSignal::modify_trigger()
const auto &matches = stage->matches();
if (std::none_of(matches.begin(), matches.end(),
[&](shared_ptr<TriggerMatch> match) {
return match->channel() != channel_; }))
return match->channel() != channel_->channel(); }))
continue;
auto new_stage = new_trigger->add_stage();
for (auto match : stage->matches()) {
if (match->channel() == channel_)
if (match->channel() == channel_->channel())
continue;
new_stage->add_match(match->channel(), match->type());
}
@ -449,7 +449,8 @@ void LogicSignal::modify_trigger()
if (new_trigger->stages().empty())
new_trigger->add_stage();
new_trigger->stages().back()->add_match(channel_, trigger_match_);
new_trigger->stages().back()->add_match(channel_->channel(),
trigger_match_);
}
session_.session()->set_trigger(

View File

@ -66,7 +66,7 @@ private:
public:
LogicSignal(pv::Session &session,
std::shared_ptr<devices::Device> device,
std::shared_ptr<sigrok::Channel> channel,
std::shared_ptr<data::SignalBase> channel,
std::shared_ptr<pv::data::Logic> data);
virtual ~LogicSignal() = default;

View File

@ -31,14 +31,14 @@
#include <libsigrokcxx/libsigrokcxx.hpp>
#include "pv/data/signalbase.hpp"
#include "signal.hpp"
#include "view.hpp"
using std::shared_ptr;
using std::make_shared;
using sigrok::Channel;
namespace pv {
namespace view {
@ -60,10 +60,9 @@ const char *const ChannelNames[] = {
};
Signal::Signal(pv::Session &session,
std::shared_ptr<sigrok::Channel> channel) :
Trace(QString::fromUtf8(channel->name().c_str())),
std::shared_ptr<data::SignalBase> channel) :
Trace(channel),
session_(session),
channel_(channel),
scale_handle_(make_shared<SignalScaleHandle>(*this)),
items_({scale_handle_}),
name_widget_(nullptr)
@ -77,10 +76,6 @@ void Signal::set_name(QString name)
if (name != name_widget_->currentText())
name_widget_->setEditText(name);
// Store the channel name in sigrok::Channel so that it
// will end up in the .sr file upon save.
channel_->set_name(name.toUtf8().constData());
}
bool Signal::enabled() const
@ -96,7 +91,7 @@ void Signal::enable(bool enable)
owner_->extents_changed(true, true);
}
shared_ptr<Channel> Signal::channel() const
shared_ptr<data::SignalBase> Signal::channel() const
{
return channel_;
}
@ -121,17 +116,17 @@ void Signal::populate_popup_form(QWidget *parent, QFormLayout *form)
for (unsigned int i = 0; i < countof(ChannelNames); i++)
name_widget_->insertItem(i, ChannelNames[i]);
const int index = name_widget_->findText(name_, Qt::MatchExactly);
const int index = name_widget_->findText(channel_->name(), Qt::MatchExactly);
if (index == -1) {
name_widget_->insertItem(0, name_);
name_widget_->insertItem(0, channel_->name());
name_widget_->setCurrentIndex(0);
} else {
name_widget_->setCurrentIndex(index);
}
connect(name_widget_, SIGNAL(editTextChanged(const QString&)),
this, SLOT(on_text_changed(const QString&)));
this, SLOT(on_nameedit_changed(const QString&)));
form->addRow(tr("Name"), name_widget_);
@ -157,6 +152,14 @@ void Signal::delete_pressed()
on_disable();
}
void Signal::on_name_changed(const QString &text)
{
if (text != name_widget_->currentText())
name_widget_->setEditText(text);
Trace::on_name_changed(text);
}
void Signal::on_disable()
{
enable(false);

View File

@ -32,15 +32,12 @@
#include "trace.hpp"
#include "viewitemowner.hpp"
namespace sigrok {
class Channel;
}
namespace pv {
class Session;
namespace data {
class SignalBase;
class SignalData;
}
@ -52,13 +49,13 @@ class Signal : public Trace, public ViewItemOwner
protected:
Signal(pv::Session &session,
std::shared_ptr<sigrok::Channel> channel);
std::shared_ptr<data::SignalBase> channel);
public:
/**
* Sets the name of the signal.
*/
void set_name(QString name);
virtual void set_name(QString name);
virtual std::shared_ptr<pv::data::SignalData> data() const = 0;
@ -69,7 +66,7 @@ public:
void enable(bool enable = true);
std::shared_ptr<sigrok::Channel> channel() const;
std::shared_ptr<data::SignalBase> channel() const;
/**
* Returns a list of row items owned by this object.
@ -100,12 +97,13 @@ public:
*/
virtual void scale_handle_released() {};
private Q_SLOTS:
protected Q_SLOTS:
virtual void on_name_changed(const QString &text);
void on_disable();
protected:
pv::Session &session_;
std::shared_ptr<sigrok::Channel> channel_;
const std::shared_ptr<SignalScaleHandle> scale_handle_;
const item_list items_;

View File

@ -41,39 +41,19 @@ namespace view {
const QPen Trace::AxisPen(QColor(0, 0, 0, 30*256/100));
const int Trace::LabelHitPadding = 2;
const int Trace::ColourBGAlpha = 8*256/100;
const QColor Trace::BrightGrayBGColour = QColor(0, 0, 0, 10*255/100);
const QColor Trace::DarkGrayBGColour = QColor(0, 0, 0, 15*255/100);
Trace::Trace(QString name) :
name_(name),
Trace::Trace(std::shared_ptr<data::SignalBase> channel) :
channel_(channel),
coloured_bg_(true), // Default setting is set in MainWindow::setup_ui()
popup_(nullptr),
popup_form_(nullptr)
{
}
QString Trace::name() const
{
return name_;
}
void Trace::set_name(QString name)
{
name_ = name;
}
QColor Trace::colour() const
{
return colour_;
}
void Trace::set_colour(QColor colour)
{
colour_ = colour;
bgcolour_ = colour;
bgcolour_.setAlpha(ColourBGAlpha);
connect(channel.get(), SIGNAL(name_changed(const QString&)),
this, SLOT(on_name_changed(const QString&)));
connect(channel.get(), SIGNAL(colour_changed(const QColor&)),
this, SLOT(on_colour_changed(const QColor&)));
}
void Trace::set_coloured_bg(bool state)
@ -85,7 +65,7 @@ void Trace::paint_label(QPainter &p, const QRect &rect, bool hover)
{
const int y = get_visual_y();
p.setBrush(colour_);
p.setBrush(channel_->colour());
if (!enabled())
return;
@ -116,23 +96,23 @@ void Trace::paint_label(QPainter &p, const QRect &rect, bool hover)
}
p.setPen(Qt::transparent);
p.setBrush(hover ? colour_.lighter() : colour_);
p.setBrush(hover ? channel_->colour().lighter() : channel_->colour());
p.drawPolygon(points, countof(points));
p.setPen(colour_.lighter());
p.setPen(channel_->colour().lighter());
p.setBrush(Qt::transparent);
p.drawPolygon(highlight_points, countof(highlight_points));
p.setPen(colour_.darker());
p.setPen(channel_->colour().darker());
p.setBrush(Qt::transparent);
p.drawPolygon(points, countof(points));
// Paint the text
p.setPen(select_text_colour(colour_));
p.setPen(select_text_colour(channel_->colour()));
p.setFont(QApplication::font());
p.drawText(QRectF(r.x(), r.y(),
r.width() - label_arrow_length, r.height()),
Qt::AlignCenter | Qt::AlignVCenter, name_);
Qt::AlignCenter | Qt::AlignVCenter, channel_->name());
}
QMenu* Trace::create_context_menu(QWidget *parent)
@ -164,7 +144,7 @@ QRectF Trace::label_rect(const QRectF &rect) const
QFontMetrics m(QApplication::font());
const QSize text_size(
m.boundingRect(QRect(), 0, name_).width(), m.height());
m.boundingRect(QRect(), 0, channel_->name()).width(), m.height());
const QSizeF label_size(
text_size.width() + LabelPadding.width() * 2,
ceilf((text_size.height() + LabelPadding.height() * 2) / 2) * 2);
@ -179,7 +159,7 @@ QRectF Trace::label_rect(const QRectF &rect) const
void Trace::paint_back(QPainter &p, const ViewItemPaintParams &pp)
{
if (coloured_bg_)
p.setBrush(bgcolour_);
p.setBrush(channel_->bgcolour());
else
p.setBrush(bgcolour_state_ ? BrightGrayBGColour : DarkGrayBGColour);
@ -212,9 +192,9 @@ void Trace::add_colour_option(QWidget *parent, QFormLayout *form)
ColourButton *const colour_button = new ColourButton(
TracePalette::Rows, TracePalette::Cols, parent);
colour_button->set_palette(TracePalette::Colours);
colour_button->set_colour(colour_);
colour_button->set_colour(channel_->colour());
connect(colour_button, SIGNAL(selected(const QColor&)),
this, SLOT(on_colour_changed(const QColor&)));
this, SLOT(on_colouredit_changed(const QColor&)));
form->addRow(tr("Colour"), colour_button);
}
@ -242,34 +222,60 @@ void Trace::create_popup_form()
void Trace::populate_popup_form(QWidget *parent, QFormLayout *form)
{
QLineEdit *const name_edit = new QLineEdit(parent);
name_edit->setText(name_);
name_edit->setText(channel_->name());
connect(name_edit, SIGNAL(textChanged(const QString&)),
this, SLOT(on_text_changed(const QString&)));
this, SLOT(on_nameedit_changed(const QString&)));
form->addRow(tr("Name"), name_edit);
add_colour_option(parent, form);
}
void Trace::set_name(QString name)
{
channel_->set_name(name);
}
void Trace::set_colour(QColor colour)
{
channel_->set_colour(colour);
}
void Trace::on_name_changed(const QString &text)
{
/* This event handler is called by SignalBase when the name was changed there */
(void)text;
if (owner_) {
owner_->extents_changed(true, false);
owner_->row_item_appearance_changed(true, false);
}
}
void Trace::on_colour_changed(const QColor &colour)
{
/* This event handler is called by SignalBase when the colour was changed there */
(void)colour;
if (owner_)
owner_->row_item_appearance_changed(true, true);
}
void Trace::on_popup_closed()
{
popup_ = nullptr;
popup_form_ = nullptr;
}
void Trace::on_text_changed(const QString &text)
void Trace::on_nameedit_changed(const QString &name)
{
set_name(text);
if (owner_)
owner_->extents_changed(true, false);
/* This event handler notifies SignalBase that the name changed */
set_name(name);
}
void Trace::on_colour_changed(const QColor &colour)
void Trace::on_colouredit_changed(const QColor &colour)
{
/* This event handler notifies SignalBase that the colour changed */
set_colour(colour);
if (owner_)
owner_->row_item_appearance_changed(true, true);
}
} // namespace view

View File

@ -31,6 +31,8 @@
#include "tracetreeitem.hpp"
#include "pv/data/signalbase.hpp"
class QFormLayout;
namespace pv {
@ -49,33 +51,22 @@ private:
static const QPen AxisPen;
static const int LabelHitPadding;
static const int ColourBGAlpha;
static const QColor BrightGrayBGColour;
static const QColor DarkGrayBGColour;
protected:
Trace(QString name);
Trace(std::shared_ptr<data::SignalBase> channel);
public:
/**
* Gets the name of this signal.
*/
QString name() const;
/**
* Sets the name of the signal.
*/
virtual void set_name(QString name);
/**
* Get the colour of the signal.
*/
QColor colour() const;
/**
* Set the colour of the signal.
*/
void set_colour(QColor colour);
virtual void set_colour(QColor colour);
/**
* Enables or disables the coloured background for this trace.
@ -123,16 +114,20 @@ protected:
virtual void populate_popup_form(QWidget *parent, QFormLayout *form);
private Q_SLOTS:
void on_text_changed(const QString &text);
protected Q_SLOTS:
virtual void on_name_changed(const QString &text);
void on_colour_changed(const QColor &colour);
virtual void on_colour_changed(const QColor &colour);
void on_popup_closed();
private Q_SLOTS:
void on_nameedit_changed(const QString &name);
void on_colouredit_changed(const QColor &colour);
protected:
QString name_;
QColor colour_, bgcolour_;
std::shared_ptr<data::SignalBase> channel_;
bool coloured_bg_, coloured_bg_state_;
private:

View File

@ -739,7 +739,7 @@ void View::update_layout()
TraceTreeItemOwner* View::find_prevalent_trace_group(
const shared_ptr<sigrok::ChannelGroup> &group,
const unordered_map<shared_ptr<sigrok::Channel>, shared_ptr<Signal> >
const unordered_map<shared_ptr<data::SignalBase>, shared_ptr<Signal> >
&signal_map)
{
assert(group);
@ -749,13 +749,13 @@ TraceTreeItemOwner* View::find_prevalent_trace_group(
// Make a set and a list of all the owners
for (const auto &channel : group->channels()) {
const auto iter = signal_map.find(channel);
if (iter == signal_map.end())
continue;
TraceTreeItemOwner *const o = (*iter).second->owner();
owner_list.push_back(o);
owners.insert(o);
for (auto entry : signal_map) {
if (entry.first->channel() == channel) {
TraceTreeItemOwner *const o = (entry.second)->owner();
owner_list.push_back(o);
owners.insert(o);
}
}
}
// Iterate through the list of owners, and find the most prevalent
@ -776,24 +776,24 @@ TraceTreeItemOwner* View::find_prevalent_trace_group(
vector< shared_ptr<Trace> > View::extract_new_traces_for_channels(
const vector< shared_ptr<sigrok::Channel> > &channels,
const unordered_map<shared_ptr<sigrok::Channel>, shared_ptr<Signal> >
const unordered_map<shared_ptr<data::SignalBase>, shared_ptr<Signal> >
&signal_map,
set< shared_ptr<Trace> > &add_list)
{
vector< shared_ptr<Trace> > filtered_traces;
for (const auto &channel : channels) {
const auto map_iter = signal_map.find(channel);
if (map_iter == signal_map.end())
continue;
for (auto entry : signal_map) {
if (entry.first->channel() == channel) {
shared_ptr<Trace> trace = entry.second;
const auto list_iter = add_list.find(trace);
if (list_iter == add_list.end())
continue;
shared_ptr<Trace> trace = (*map_iter).second;
const auto list_iter = add_list.find(trace);
if (list_iter == add_list.end())
continue;
filtered_traces.push_back(trace);
add_list.erase(list_iter);
filtered_traces.push_back(trace);
add_list.erase(list_iter);
}
}
}
return filtered_traces;
@ -973,7 +973,7 @@ void View::signals_changed()
inserter(remove_traces, remove_traces.begin()));
// Make a look-up table of sigrok Channels to pulseview Signals
unordered_map<shared_ptr<sigrok::Channel>, shared_ptr<Signal> >
unordered_map<shared_ptr<data::SignalBase>, shared_ptr<Signal> >
signal_map;
for (const shared_ptr<Signal> &sig : sigs)
signal_map[sig->channel()] = sig;

View File

@ -273,13 +273,13 @@ private:
TraceTreeItemOwner* find_prevalent_trace_group(
const std::shared_ptr<sigrok::ChannelGroup> &group,
const std::unordered_map<std::shared_ptr<sigrok::Channel>,
const std::unordered_map<std::shared_ptr<data::SignalBase>,
std::shared_ptr<Signal> > &signal_map);
static std::vector< std::shared_ptr<Trace> >
extract_new_traces_for_channels(
const std::vector< std::shared_ptr<sigrok::Channel> > &channels,
const std::unordered_map<std::shared_ptr<sigrok::Channel>,
const std::unordered_map<std::shared_ptr<data::SignalBase>,
std::shared_ptr<Signal> > &signal_map,
std::set< std::shared_ptr<Trace> > &add_list);

View File

@ -30,6 +30,7 @@ set(pulseview_TEST_SOURCES
${PROJECT_SOURCE_DIR}/pv/data/logic.cpp
${PROJECT_SOURCE_DIR}/pv/data/logicsegment.cpp
${PROJECT_SOURCE_DIR}/pv/data/segment.cpp
${PROJECT_SOURCE_DIR}/pv/data/signalbase.cpp
${PROJECT_SOURCE_DIR}/pv/data/signaldata.cpp
${PROJECT_SOURCE_DIR}/pv/devices/device.cpp
${PROJECT_SOURCE_DIR}/pv/devices/file.cpp
@ -87,6 +88,7 @@ set(pulseview_TEST_HEADERS
${PROJECT_SOURCE_DIR}/pv/session.hpp
${PROJECT_SOURCE_DIR}/pv/storesession.hpp
${PROJECT_SOURCE_DIR}/pv/binding/device.hpp
${PROJECT_SOURCE_DIR}/pv/data/signalbase.hpp
${PROJECT_SOURCE_DIR}/pv/devices/device.hpp
${PROJECT_SOURCE_DIR}/pv/popups/channels.hpp
${PROJECT_SOURCE_DIR}/pv/popups/deviceoptions.hpp