]> sigrok.org Git - pulseview.git/blobdiff - pv/session.cpp
Add a new action to save to the last .sr file, and use it for control-S saving
[pulseview.git] / pv / session.cpp
index fb8ee5fe9a3456dc2533078cdcbdad59b040e36a..840773d1aa7115bd4dcc7594496c776231bcdd15 100644 (file)
@@ -105,6 +105,7 @@ using Gst::ElementFactory;
 using Gst::Pipeline;
 #endif
 
+using pv::data::SignalGroup;
 using pv::util::Timestamp;
 using pv::views::trace::Signal;
 using pv::views::trace::AnalogSignal;
@@ -115,6 +116,7 @@ namespace pv {
 shared_ptr<sigrok::Context> Session::sr_context;
 
 Session::Session(DeviceManager &device_manager, QString name) :
+       shutting_down_(false),
        device_manager_(device_manager),
        default_name_(name),
        name_(name),
@@ -126,8 +128,15 @@ Session::Session(DeviceManager &device_manager, QString name) :
 
 Session::~Session()
 {
+       shutting_down_ = true;
+
        // Stop and join to the thread
        stop_capture();
+
+       for (SignalGroup* group : signal_groups_) {
+               group->clear();
+               delete group;
+       }
 }
 
 DeviceManager& Session::device_manager()
@@ -167,6 +176,17 @@ void Session::set_name(QString name)
        name_changed();
 }
 
+QString Session::path() const
+{
+       return path_;
+}
+
+void Session::set_path(QString path)
+{
+       path_ = path;
+       set_name(QFileInfo(path).fileName());
+}
+
 const vector< shared_ptr<views::ViewBase> > Session::views() const
 {
        return views_;
@@ -435,6 +455,8 @@ void Session::restore_settings(QSettings &settings)
                settings.endGroup();
        }
 
+
+       QString path;
        if ((device_type == "sessionfile") || (device_type == "inputfile")) {
                if (device_type == "sessionfile") {
                        settings.beginGroup("device");
@@ -442,6 +464,7 @@ void Session::restore_settings(QSettings &settings)
                        settings.endGroup();
 
                        if (QFileInfo(filename).isReadable()) {
+                       path = filename;
                                device = make_shared<devices::SessionFile>(device_manager_.context(),
                                        filename.toStdString());
                        }
@@ -463,6 +486,9 @@ void Session::restore_settings(QSettings &settings)
 
                        set_name(QString::fromStdString(
                                dynamic_pointer_cast<devices::File>(device)->display_name(device_manager_)));
+
+                       if (!path.isEmpty())
+                               set_path(path);
                }
        }
 
@@ -506,8 +532,16 @@ void Session::set_device(shared_ptr<devices::Device> device)
 #endif
                view->reset_view_state();
        }
+
+       for (SignalGroup* group : signal_groups_) {
+               group->clear();
+               delete group;
+       }
+       signal_groups_.clear();
+
        for (const shared_ptr<data::SignalData>& d : all_signal_data_)
                d->clear();
+
        all_signal_data_.clear();
        signalbases_.clear();
        cur_logic_segment_.reset();
@@ -604,8 +638,12 @@ Session::input_format_options(vector<string> user_spec,
                 * data type.
                 */
                auto found = fmt_opts.find(key);
-               if (found == fmt_opts.end())
+               if (found == fmt_opts.end()) {
+                       qCritical() << "Supplied input option" << QString::fromStdString(key) <<
+                               "is not a valid option for this input module, it will be ignored!";
                        continue;
+               }
+
                shared_ptr<Option> opt = found->second;
                result[key] = opt->parse_string(val);
        }
@@ -630,7 +668,7 @@ void Session::load_init_file(const string &file_name,
                                return f.first == user_name; });
                if (iter == formats.end()) {
                        MainWindow::show_session_error(tr("Error"),
-                               tr("Unexpected input format: %s").arg(QString::fromStdString(format)));
+                               tr("Unexpected input format: %1").arg(QString::fromStdString(format)));
                        return;
                }
                input_format = (*iter).second;
@@ -688,7 +726,7 @@ void Session::load_file(QString file_name, QString setup_file_name,
        start_capture([&, errorMessage](QString infoMessage) {
                MainWindow::show_session_error(errorMessage, infoMessage); });
 
-       set_name(QFileInfo(file_name).fileName());
+       set_path(file_name);
 }
 
 Session::capture_state Session::get_capture_state() const
@@ -857,15 +895,29 @@ const vector< shared_ptr<data::SignalBase> > Session::signalbases() const
        return signalbases_;
 }
 
-bool Session::all_segments_complete(uint32_t segment_id) const
+void Session::add_generated_signal(shared_ptr<data::SignalBase> signal)
 {
-       bool all_complete = true;
+       signalbases_.push_back(signal);
 
-       for (const shared_ptr<data::SignalBase>& base : signalbases_)
-               if (!base->segment_is_complete(segment_id))
-                       all_complete = false;
+       for (shared_ptr<views::ViewBase>& view : views_)
+               view->add_signalbase(signal);
 
-       return all_complete;
+       update_signals();
+}
+
+void Session::remove_generated_signal(shared_ptr<data::SignalBase> signal)
+{
+       if (shutting_down_)
+               return;
+
+       signalbases_.erase(std::remove_if(signalbases_.begin(), signalbases_.end(),
+               [&](shared_ptr<data::SignalBase> s) { return s == signal; }),
+               signalbases_.end());
+
+       for (shared_ptr<views::ViewBase>& view : views_)
+               view->remove_signalbase(signal);
+
+       update_signals();
 }
 
 #ifdef ENABLE_DECODE
@@ -894,6 +946,9 @@ shared_ptr<data::DecodeSignal> Session::add_decode_signal()
 
 void Session::remove_decode_signal(shared_ptr<data::DecodeSignal> signal)
 {
+       if (shutting_down_)
+               return;
+
        signalbases_.erase(std::remove_if(signalbases_.begin(), signalbases_.end(),
                [&](shared_ptr<data::SignalBase> s) { return s == signal; }),
                signalbases_.end());
@@ -905,6 +960,17 @@ void Session::remove_decode_signal(shared_ptr<data::DecodeSignal> signal)
 }
 #endif
 
+bool Session::all_segments_complete(uint32_t segment_id) const
+{
+       bool all_complete = true;
+
+       for (const shared_ptr<data::SignalBase>& base : signalbases_)
+               if (!base->segment_is_complete(segment_id))
+                       all_complete = false;
+
+       return all_complete;
+}
+
 MetadataObjManager* Session::metadata_obj_manager()
 {
        return &metadata_obj_manager_;
@@ -997,7 +1063,7 @@ void Session::update_signals()
                                signalbase->set_data(logic_data_);
 
                                connect(this, SIGNAL(capture_state_changed(int)),
-                                               signalbase.get(), SLOT(on_capture_state_changed(int)));
+                                       signalbase.get(), SLOT(on_capture_state_changed(int)));
                                break;
 
                        case SR_CHANNEL_ANALOG:
@@ -1009,12 +1075,34 @@ void Session::update_signals()
                                signalbase->set_data(data);
 
                                connect(this, SIGNAL(capture_state_changed(int)),
-                                               signalbase.get(), SLOT(on_capture_state_changed(int)));
+                                       signalbase.get(), SLOT(on_capture_state_changed(int)));
                                break;
                        }
                }
        }
 
+       // Create and assign default signal groups if needed
+       if (signal_groups_.empty()) {
+               for (auto& entry : sr_dev->channel_groups()) {
+                       const shared_ptr<sigrok::ChannelGroup>& group = entry.second;
+
+                       if (group->channels().size() <= 1)
+                               continue;
+
+                       SignalGroup* sg = new SignalGroup(QString::fromStdString(entry.first));
+                       for (const shared_ptr<sigrok::Channel>& channel : group->channels()) {
+                               for (shared_ptr<data::SignalBase> s : signalbases_) {
+                                       if (s->channel() == channel) {
+                                               sg->append_signal(s);
+                                               break;
+                                       }
+                               }
+                       }
+                       signal_groups_.emplace_back(sg);
+               }
+       }
+
+       // Update all views
        for (shared_ptr<views::ViewBase>& viewbase : views_) {
                vector< shared_ptr<SignalBase> > view_signalbases =
                                viewbase->signalbases();
@@ -1106,6 +1194,8 @@ void Session::sample_thread_proc(function<void (const QString)> error_handler)
                lock_guard<recursive_mutex> lock(data_mutex_);
                cur_logic_segment_.reset();
                cur_analog_segments_.clear();
+               for (shared_ptr<data::SignalBase> sb : signalbases_)
+                       sb->clear_sample_data();
        }
        highest_segment_id_ = -1;
        frame_began_ = false;
@@ -1348,7 +1438,7 @@ void Session::feed_in_frame_end()
        signal_segment_completed();
 }
 
-void Session::feed_in_logic(shared_ptr<Logic> logic)
+void Session::feed_in_logic(shared_ptr<sigrok::Logic> logic)
 {
        if (logic->data_length() == 0) {
                qDebug() << "WARNING: Received logic packet with 0 samples.";
@@ -1392,7 +1482,7 @@ void Session::feed_in_logic(shared_ptr<Logic> logic)
        data_received();
 }
 
-void Session::feed_in_analog(shared_ptr<Analog> analog)
+void Session::feed_in_analog(shared_ptr<sigrok::Analog> analog)
 {
        if (analog->num_samples() == 0) {
                qDebug() << "WARNING: Received analog packet with 0 samples.";