+void Channels::enable_all_logic_channels()
+{
+ set_all_channels_conditionally([](const shared_ptr<SignalBase> signal)
+ { return signal->type() == SignalBase::LogicChannel; });
+}
+
+void Channels::enable_all_analog_channels()
+{
+ set_all_channels_conditionally([](const shared_ptr<SignalBase> signal)
+ { return signal->type() == SignalBase::AnalogChannel; });
+}
+
+void Channels::enable_all_named_channels()
+{
+ set_all_channels_conditionally([](const shared_ptr<SignalBase> signal)
+ { return signal->name() != signal->internal_name(); });
+}
+
+void Channels::enable_all_changing_channels()
+{
+ set_all_channels_conditionally([](const shared_ptr<SignalBase> signal)
+ {
+ // Never enable channels without sample data
+ if (!signal->has_samples())
+ return false;
+
+ // Non-logic channels are considered to always have a signal
+ if (signal->type() != SignalBase::LogicChannel)
+ return true;
+
+ const shared_ptr<Logic> logic = signal->logic_data();
+ assert(logic);
+
+ // If any of the segments has edges, enable this channel
+ for (shared_ptr<LogicSegment> segment : logic->logic_segments()) {
+ vector<LogicSegment::EdgePair> edges;
+
+ segment->get_subsampled_edges(edges,
+ 0, segment->get_sample_count() - 1,
+ LogicSegment::MipMapScaleFactor,
+ signal->index());
+
+ if (edges.size() > 2)
+ return true;
+ }
+
+ // No edges detected in any of the segments
+ return false;
+ });
+}
+
+} // namespace popups
+} // namespace pv