diff --git a/DSView/pv/data/decode/annotation.cpp b/DSView/pv/data/decode/annotation.cpp index d3db6df5..6e70dfa8 100644 --- a/DSView/pv/data/decode/annotation.cpp +++ b/DSView/pv/data/decode/annotation.cpp @@ -54,7 +54,7 @@ Annotation::Annotation(const srd_proto_data *const pdata, DecoderStatus *status) _end_sample = pdata->end_sample; _format = pda->ann_class; _type = pda->ann_type; - _resIndex = 0; + _resIndex = -1; _status = status; //make resource find key @@ -100,8 +100,13 @@ Annotation::Annotation() { _start_sample = 0; _end_sample = 0; + _resIndex = -1; } +Annotation::Annotation(Annotation &o) +{ +} + Annotation::~Annotation() { diff --git a/DSView/pv/data/decode/annotation.h b/DSView/pv/data/decode/annotation.h index 1279dbc0..2037d283 100644 --- a/DSView/pv/data/decode/annotation.h +++ b/DSView/pv/data/decode/annotation.h @@ -43,10 +43,13 @@ class Annotation public: Annotation(const srd_proto_data *const pdata, DecoderStatus *status); Annotation(); + ~Annotation(); + +private: + /* disable copy construct */ + Annotation(Annotation &o); + public: - - ~Annotation(); - inline uint64_t start_sample() const{ return _start_sample; } @@ -65,7 +68,6 @@ public: bool is_numberic(); -public: const std::vector& annotations() const; private: @@ -73,7 +75,7 @@ private: uint64_t _end_sample; short _format; short _type; - short _resIndex; + int _resIndex; DecoderStatus *_status; /*a global variable*/ }; diff --git a/DSView/pv/data/decode/rowdata.cpp b/DSView/pv/data/decode/rowdata.cpp index fe148f8e..abcd4c2f 100644 --- a/DSView/pv/data/decode/rowdata.cpp +++ b/DSView/pv/data/decode/rowdata.cpp @@ -81,16 +81,16 @@ uint64_t RowData::get_min_annotation() return _min_annotation; } -void RowData::get_annotation_subset(std::vector &dest, +void RowData::get_annotation_subset(std::vector &dest, uint64_t start_sample, uint64_t end_sample) { std::lock_guard lock(_global_visitor_mutex); - for (Annotation *p : _annotations){ - if (p->end_sample() > start_sample && - p->start_sample() <= end_sample){ - Annotation a = *p; - dest.push_back(a); + for (Annotation *p : _annotations) + { + if (p->end_sample() > start_sample && p->start_sample() <= end_sample) + { + dest.push_back(p); } } } diff --git a/DSView/pv/data/decode/rowdata.h b/DSView/pv/data/decode/rowdata.h index c7ca611f..8314eb6b 100644 --- a/DSView/pv/data/decode/rowdata.h +++ b/DSView/pv/data/decode/rowdata.h @@ -57,7 +57,7 @@ public: /** * Extracts sorted annotations between two period into a vector. */ - void get_annotation_subset(std::vector &dest, + void get_annotation_subset(std::vector &dest, uint64_t start_sample, uint64_t end_sample); void clear(); diff --git a/DSView/pv/data/decoderstack.cpp b/DSView/pv/data/decoderstack.cpp index 8a255ddc..8809bfa8 100644 --- a/DSView/pv/data/decoderstack.cpp +++ b/DSView/pv/data/decoderstack.cpp @@ -215,7 +215,7 @@ int64_t DecoderStack::samples_decoded() } void DecoderStack::get_annotation_subset( - std::vector &dest, + std::vector &dest, const Row &row, uint64_t start_sample, uint64_t end_sample) { diff --git a/DSView/pv/data/decoderstack.h b/DSView/pv/data/decoderstack.h index 8efdd931..bbee2ba7 100644 --- a/DSView/pv/data/decoderstack.h +++ b/DSView/pv/data/decoderstack.h @@ -108,7 +108,7 @@ public: * Extracts sorted annotations between two period into a vector. */ void get_annotation_subset( - std::vector &dest, + std::vector &dest, const decode::Row &row, uint64_t start_sample, uint64_t end_sample); diff --git a/DSView/pv/dialogs/protocolexp.cpp b/DSView/pv/dialogs/protocolexp.cpp index 739467ad..7835ec84 100644 --- a/DSView/pv/dialogs/protocolexp.cpp +++ b/DSView/pv/dialogs/protocolexp.cpp @@ -41,8 +41,7 @@ #include "../utility/encoding.h" #include "../utility/path.h" -using namespace boost; -using namespace std; +using namespace pv::data::decode; namespace pv { namespace dialogs { @@ -103,127 +102,149 @@ ProtocolExp::ProtocolExp(QWidget *parent, SigSession *session) : } void ProtocolExp::accept() -{ - using namespace Qt; - using namespace pv::data::decode; - +{ QDialog::accept(); - if (!_row_sel_list.empty()) { - QList supportedFormats; - for (int i = _format_combobox->count() - 1; i >= 0; i--) { - supportedFormats.push_back(_format_combobox->itemText(i)); - } - QString filter; - for(int i = 0; i < supportedFormats.count();i++){ - filter.append(supportedFormats[i]); - if(i < supportedFormats.count() - 1) - filter.append(";;"); - } + if (_row_sel_list.empty()){ + return; + } - AppConfig &app = AppConfig::Instance(); - - QString default_filter = _format_combobox->currentText(); + QList supportedFormats; + for (int i = _format_combobox->count() - 1; i >= 0; i--) + { + supportedFormats.push_back(_format_combobox->itemText(i)); + } - QString default_name = app._userHistory.protocolExportPath + "/" + "decoder-"; - default_name += _session->get_session_time().toString("-yyMMdd-hhmmss"); + QString filter; + for (int i = 0; i < supportedFormats.count(); i++) + { + filter.append(supportedFormats[i]); + if (i < supportedFormats.count() - 1) + filter.append(";;"); + } - QString file_name = QFileDialog::getSaveFileName( - this, - tr("Export Data"), - default_name,filter, - &default_filter); + AppConfig &app = AppConfig::Instance(); + QString default_filter = _format_combobox->currentText(); + QString default_name = app._userHistory.protocolExportPath + "/" + "decoder-"; + default_name += _session->get_session_time().toString("-yyMMdd-hhmmss"); - if (!file_name.isEmpty()) { - QFileInfo f(file_name); - QStringList list = default_filter.split('.').last().split(')'); - QString ext = list.first(); - if(f.suffix().compare(ext)) - file_name+=tr(".")+ext; + QString file_name = QFileDialog::getSaveFileName( + this, + tr("Export Data"), + default_name, filter, + &default_filter); - QString fname = path::GetDirectoryName(file_name); - if (fname != app._userHistory.openDir) - { - app._userHistory.protocolExportPath = fname; - app.SaveHistory(); - } + if (file_name == ""){ + return; + } - QFile file(file_name); - file.open(QIODevice::WriteOnly | QIODevice::Text); - QTextStream out(&file); - encoding::set_utf8(out); - //out.setGenerateByteOrderMark(true); // UTF-8 without BOM + QFileInfo f(file_name); + QStringList list = default_filter.split('.').last().split(')'); + QString ext = list.first(); + if (f.suffix().compare(ext)) + file_name += tr(".") + ext; - QFuture future; - future = QtConcurrent::run([&]{ - _export_cancel = false; - QString title; - int index = 0; - for (std::list::const_iterator i = _row_sel_list.begin(); - i != _row_sel_list.end(); i++) { - if ((*i)->isChecked()) { - title = (*i)->property("title").toString(); - index = (*i)->property("index").toULongLong(); - break; - } - } - out << QString("%1,%2,%3\n") - .arg("Id") - .arg("Time[ns]") - .arg(title); + QString fname = path::GetDirectoryName(file_name); + if (fname != app._userHistory.openDir) + { + app._userHistory.protocolExportPath = fname; + app.SaveHistory(); + } + _fileName = file_name; + + QFuture future; + future = QtConcurrent::run([&]{ + save_proc(); + }); - pv::data::DecoderModel* decoder_model = _session->get_decoder_model(); - const auto decoder_stack = decoder_model->getDecoderStack(); - int row_index = 0; - Row row; - const std::map rows_lshow = decoder_stack->get_rows_lshow(); - for (std::map::const_iterator i = rows_lshow.begin(); - i != rows_lshow.end(); i++) { - if ((*i).second) { - if (index == row_index) { - row = (*i).first; - break; - } - row_index++; - } - } + Qt::WindowFlags flags = Qt::CustomizeWindowHint; + QProgressDialog dlg(tr("Export Protocol List Result... It can take a while."), + tr("Cancel"), 0, 100, this, flags); + dlg.setWindowModality(Qt::WindowModal); + dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | + Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); - uint64_t exported = 0; - double ns_per_sample = SR_SEC(1) * 1.0 / decoder_stack->samplerate(); - std::vector annotations; - decoder_stack->get_annotation_subset(annotations, row, - 0, decoder_stack->sample_count()-1); - if (!annotations.empty()) { - for(auto &a : annotations) { - out << QString("%1,%2,%3\n") - .arg(QString::number(exported)) - .arg(QString::number(a.start_sample()*ns_per_sample, 'f', 20)) - .arg(a.annotations().at(0)); - exported++; - emit export_progress(exported*100/annotations.size()); - if (_export_cancel) - break; - } - } - }); - Qt::WindowFlags flags = Qt::CustomizeWindowHint; - QProgressDialog dlg(tr("Export Protocol List Result... It can take a while."), - tr("Cancel"),0,100,this,flags); - dlg.setWindowModality(Qt::WindowModal); - dlg.setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowSystemMenuHint | - Qt::WindowMinimizeButtonHint | Qt::WindowMaximizeButtonHint); + QFutureWatcher watcher; - QFutureWatcher watcher; - connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel())); - connect(this,SIGNAL(export_progress(int)),&dlg,SLOT(setValue(int))); - connect(&dlg,SIGNAL(canceled()),this,SLOT(cancel_export())); - watcher.setFuture(future); - dlg.exec(); + connect(&watcher, SIGNAL(finished()), &dlg, SLOT(cancel())); + connect(this, SIGNAL(export_progress(int)), &dlg, SLOT(setValue(int))); + connect(&dlg, SIGNAL(canceled()), this, SLOT(cancel_export())); - future.waitForFinished(); - file.close(); + watcher.setFuture(future); + dlg.exec(); + + future.waitForFinished(); +} + +void ProtocolExp::save_proc() +{ + _export_cancel = false; + + QFile file(_fileName); + file.open(QIODevice::WriteOnly | QIODevice::Text); + QTextStream out(&file); + encoding::set_utf8(out); + // out.setGenerateByteOrderMark(true); // UTF-8 without BOM + + QString title; + int index = 0; + for (std::list::const_iterator i = _row_sel_list.begin(); + i != _row_sel_list.end(); i++) + { + if ((*i)->isChecked()) + { + title = (*i)->property("title").toString(); + index = (*i)->property("index").toULongLong(); + break; } } + + out << QString("%1,%2,%3\n") + .arg("Id") + .arg("Time[ns]") + .arg(title); + + pv::data::DecoderModel *decoder_model = _session->get_decoder_model(); + const auto decoder_stack = decoder_model->getDecoderStack(); + int row_index = 0; + Row row; + + const std::map rows_lshow = decoder_stack->get_rows_lshow(); + for (std::map::const_iterator i = rows_lshow.begin(); + i != rows_lshow.end(); i++) + { + if ((*i).second) + { + if (index == row_index) + { + row = (*i).first; + break; + } + row_index++; + } + } + + uint64_t exported = 0; + double ns_per_sample = SR_SEC(1) * 1.0 / decoder_stack->samplerate(); + std::vector annotations; + decoder_stack->get_annotation_subset(annotations, row, + 0, decoder_stack->sample_count() - 1); + if (annotations.size() > 0 ) + { + for (Annotation *a : annotations) + { + out << QString("%1,%2,%3\n") + .arg(QString::number(exported)) + .arg(QString::number(a->start_sample() * ns_per_sample, 'f', 20)) + .arg(a->annotations().at(0)); + exported++; + emit export_progress(exported * 100 / annotations.size()); + if (_export_cancel) + break; + } + } + + file.close(); } void ProtocolExp::reject() diff --git a/DSView/pv/dialogs/protocolexp.h b/DSView/pv/dialogs/protocolexp.h index a4894459..7789d6c0 100644 --- a/DSView/pv/dialogs/protocolexp.h +++ b/DSView/pv/dialogs/protocolexp.h @@ -27,7 +27,8 @@ #include #include #include -#include +#include +#include #include "../device/devinst.h" #include "../prop/binding/deviceoptions.h" @@ -57,6 +58,7 @@ public: protected: void accept(); void reject(); + void save_proc(); signals: void export_progress(int percent); @@ -76,6 +78,7 @@ private: QDialogButtonBox _button_box; bool _export_cancel; + QString _fileName; }; } // namespace dialogs diff --git a/DSView/pv/view/decodetrace.cpp b/DSView/pv/view/decodetrace.cpp index 92805025..48485781 100644 --- a/DSView/pv/view/decodetrace.cpp +++ b/DSView/pv/view/decodetrace.cpp @@ -298,13 +298,13 @@ void DecodeTrace::paint_mid(QPainter &p, int left, int right, QColor fore, QColo if ((max_annWidth > 100) || (max_annWidth > 10 && min_annWidth > 1) || (max_annWidth == 0 && samples_per_pixel < 10)) { - std::vector annotations; + std::vector annotations; _decoder_stack->get_annotation_subset(annotations, row, start_sample, end_sample); if (!annotations.empty()) { - for(Annotation &a : annotations) - draw_annotation(a, p, get_text_colour(), + for(Annotation *a : annotations) + draw_annotation(*a, p, get_text_colour(), annotation_height, left, right, samples_per_pixel, pixels_offset, y, 0, min_annWidth, fore, back);