]> sigrok.org Git - pulseview.git/blobdiff - pv/views/decoder_output/view.cpp
Fix #1505 by always updating the DecodeTrace height when needed
[pulseview.git] / pv / views / decoder_output / view.cpp
index 951bc06ef296712c65c467548736a1eb62e421eb..0f127c8751d72340530f0a940a407c255f725115 100644 (file)
 using pv::data::DecodeSignal;
 using pv::data::SignalBase;
 using pv::data::decode::Decoder;
-using pv::util::TimeUnit;
 using pv::util::Timestamp;
 
-using std::dynamic_pointer_cast;
-using std::numeric_limits;
 using std::shared_ptr;
 
 namespace pv {
@@ -54,7 +51,9 @@ namespace decoder_output {
 
 const char* SaveTypeNames[SaveTypeCount] = {
        "Binary",
-       "Hex Dump"
+       "Hex Dump, plain",
+       "Hex Dump, with offset",
+       "Hex Dump, canonical"
 };
 
 
@@ -133,10 +132,6 @@ View::View(Session &session, bool is_main_view, QMainWindow *parent) :
        reset_view_state();
 }
 
-View::~View()
-{
-}
-
 ViewType View::get_type() const
 {
        return ViewTypeDecoderOutput;
@@ -236,13 +231,13 @@ void View::update_data()
        if (!signal_)
                return;
 
-       if (!binary_data_exists_)
-               return;
-
        const DecodeBinaryClass* bin_class =
                signal_->get_binary_data_class(current_segment_, decoder_, bin_class_id_);
 
-       hex_view_->setData(bin_class);
+       hex_view_->set_data(bin_class);
+
+       if (!binary_data_exists_)
+               return;
 
        if (!save_button_->isEnabled())
                save_button_->setEnabled(true);
@@ -270,6 +265,8 @@ void View::save_data() const
                pair<size_t, size_t> selection = hex_view_->get_selection();
 
                vector<uint8_t> data;
+               data.resize(selection.second - selection.first + 1);
+
                signal_->get_merged_binary_data_chunks_by_offset(current_segment_, decoder_,
                        bin_class_id_, selection.first, selection.second, &data);
 
@@ -286,9 +283,56 @@ void View::save_data() const
        }
 }
 
-void View::save_data_as_hex_dump() const
+void View::save_data_as_hex_dump(bool with_offset, bool with_ascii) const
 {
+       assert(decoder_);
+       assert(signal_);
+
+       if (!signal_)
+               return;
+
+       GlobalSettings settings;
+       const QString dir = settings.value("MainWindow/SaveDirectory").toString();
+
+       const QString file_name = QFileDialog::getSaveFileName(
+               parent_, tr("Save Binary Data"), dir, tr("Hex Dumps (*.txt);;All Files (*)"));
+
+       if (file_name.isEmpty())
+               return;
 
+       QFile file(file_name);
+       if (file.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
+               pair<size_t, size_t> selection = hex_view_->get_selection();
+
+               vector<uint8_t> data;
+               data.resize(selection.second - selection.first + 1);
+
+               signal_->get_merged_binary_data_chunks_by_offset(current_segment_, decoder_,
+                       bin_class_id_, selection.first, selection.second, &data);
+
+               QTextStream out_stream(&file);
+
+               uint64_t offset = selection.first;
+               uint64_t n = hex_view_->get_bytes_per_line();
+               QString s;
+
+               while (offset < selection.second) {
+                       size_t end = std::min((uint64_t)(selection.second), offset + n);
+                       offset = hex_view_->create_hex_line(offset, end, &s, with_offset, with_ascii);
+                       out_stream << s << endl;
+               }
+
+               out_stream << endl;
+
+               if (out_stream.status() != QTextStream::Ok) {
+                       QMessageBox msg(parent_);
+                       msg.setText(tr("Error") + "\n\n" + tr("File %1 could not be written to.").arg(file_name));
+                       msg.setStandardButtons(QMessageBox::Ok);
+                       msg.setIcon(QMessageBox::Warning);
+                       msg.exec();
+                       return;
+               }
+       }
 }
 
 void View::on_selected_decoder_changed(int index)
@@ -412,15 +456,18 @@ void View::on_actionSave_triggered(QAction* action)
        if (action)
                save_type = action->data().toInt();
 
-       if (save_type == SaveTypeBinary)
-               save_data();
-       if (save_type == SaveTypeHexDump)
-               save_data_as_hex_dump();
+       switch (save_type)
+       {
+       case SaveTypeBinary: save_data(); break;
+       case SaveTypeHexDumpPlain: save_data_as_hex_dump(false, false); break;
+       case SaveTypeHexDumpWithOffset: save_data_as_hex_dump(true, false); break;
+       case SaveTypeHexDumpComplete: save_data_as_hex_dump(true, true); break;
+       }
 }
 
 void View::perform_delayed_view_update()
 {
-       if (!binary_data_exists_)
+       if (signal_ && !binary_data_exists_)
                if (signal_->get_binary_data_chunk_count(current_segment_, decoder_, bin_class_id_))
                        binary_data_exists_ = true;