From: Joel Holdsworth Date: Sun, 2 Nov 2014 16:14:34 +0000 (+0000) Subject: View: Create trace groups from channel groups X-Git-Tag: pulseview-0.3.0~447 X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=commitdiff_plain;h=448a72cf7f0225eace2335ec05b979c4e9a6b882;hp=7ff0145fbf19de010232ea5edadea5df6c28ed8e View: Create trace groups from channel groups --- diff --git a/pv/view/view.cpp b/pv/view/view.cpp index 615235ef..3b850832 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -32,11 +32,15 @@ #include #include +#include + #include "cursorheader.h" #include "decodetrace.h" #include "header.h" +#include "logicsignal.h" #include "ruler.h" #include "signal.h" +#include "tracegroup.h" #include "view.h" #include "viewport.h" @@ -49,6 +53,7 @@ using boost::shared_mutex; using pv::data::SignalData; using std::back_inserter; using std::deque; +using std::dynamic_pointer_cast; using std::list; using std::lock_guard; using std::max; @@ -57,6 +62,7 @@ using std::min; using std::pair; using std::set; using std::shared_ptr; +using std::unordered_map; using std::unordered_set; using std::vector; using std::weak_ptr; @@ -437,6 +443,45 @@ QRectF View::label_rect(int right) return QRectF(); } +bool View::add_channels_to_owner( + const vector< shared_ptr > &channels, + RowItemOwner *owner, int &offset, + unordered_map, shared_ptr > + &signal_map, + std::function)> filter_func) +{ + bool any_added = false; + + assert(owner); + + for (const auto &channel : channels) + { + const auto iter = signal_map.find(channel); + if (iter == signal_map.end() || + (filter_func && !filter_func((*iter).second))) + continue; + + shared_ptr row_item = (*iter).second; + owner->add_child_item(row_item); + apply_offset(row_item, offset); + signal_map.erase(iter); + + any_added = true; + } + + return any_added; +} + +void View::apply_offset(shared_ptr row_item, int &offset) { + assert(row_item); + const pair extents = row_item->v_extents(); + if (row_item->enabled()) + offset += -extents.first; + row_item->force_to_v_offset(offset); + if (row_item->enabled()) + offset += extents.second; +} + bool View::eventFilter(QObject *object, QEvent *event) { const QEvent::Type type = event->type(); @@ -530,31 +575,70 @@ void View::v_scroll_value_changed(int value) void View::signals_changed() { + int offset = 0; + // Populate the traces clear_child_items(); - shared_lock lock(session().signals_mutex()); - const vector< shared_ptr > &sigs(session().signals()); - for (auto s : sigs) - add_child_item(s); + shared_ptr device = _session.device(); + assert(device); + + // Collect a set of signals + unordered_map, shared_ptr > + signal_map; + + shared_lock lock(_session.signals_mutex()); + const vector< shared_ptr > &sigs(_session.signals()); + + for (const shared_ptr &sig : sigs) + signal_map[sig->channel()] = sig; + + // Populate channel groups + for (auto entry : device->channel_groups()) + { + const shared_ptr &group = entry.second; + + if (group->channels().size() <= 1) + continue; + + shared_ptr trace_group(new TraceGroup()); + int child_offset = 0; + if (add_channels_to_owner(group->channels(), + trace_group.get(), child_offset, signal_map)) + { + add_child_item(trace_group); + apply_offset(trace_group, offset); + } + } + + // Add the remaining logic channels + shared_ptr logic_trace_group(new TraceGroup()); + int child_offset = 0; + + if (add_channels_to_owner(device->channels(), + logic_trace_group.get(), child_offset, signal_map, + [](shared_ptr r) -> bool { + return dynamic_pointer_cast(r) != nullptr; + })) + { + add_child_item(logic_trace_group); + apply_offset(logic_trace_group, offset); + } + + // Add the remaining channels + add_channels_to_owner(device->channels(), this, offset, signal_map); + assert(signal_map.empty()); + + // Add decode signals #ifdef ENABLE_DECODE const vector< shared_ptr > decode_sigs( session().get_decode_signals()); - for (auto s : decode_sigs) + for (auto s : decode_sigs) { add_child_item(s); -#endif - - // Create the initial layout - int offset = 0; - for (shared_ptr r : *this) { - const pair extents = r->v_extents(); - if (r->enabled()) - offset += -extents.first; - r->force_to_v_offset(offset); - if (r->enabled()) - offset += extents.second; + apply_offset(s, offset); } +#endif update_layout(); } diff --git a/pv/view/view.h b/pv/view/view.h index eb60ab1a..8664ba8d 100644 --- a/pv/view/view.h +++ b/pv/view/view.h @@ -25,6 +25,7 @@ #include #include +#include #include #include @@ -195,6 +196,17 @@ private: */ QRectF label_rect(int right); + static bool add_channels_to_owner( + const std::vector< std::shared_ptr > &channels, + RowItemOwner *owner, int &offset, + std::unordered_map, + std::shared_ptr > &signal_map, + std::function)> filter_func = + std::function)>()); + + static void apply_offset( + std::shared_ptr row_item, int &offset); + private: bool eventFilter(QObject *object, QEvent *event);