forked from Ivasoft/DSView
add export option to the user interface
This commit is contained in:
@@ -54,6 +54,9 @@
|
||||
|
||||
#include <QDebug>
|
||||
#include <QMessageBox>
|
||||
#include <QProgressDialog>
|
||||
#include <QFile>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
@@ -179,6 +182,104 @@ void SigSession::save_file(const std::string &name){
|
||||
snapshot->get_sample_count());
|
||||
}
|
||||
|
||||
QList<QString> SigSession::getSuportedExportFormats(){
|
||||
// TODO: uncomment this
|
||||
//const struct sr_output_module** supportedModules = sr_output_list();
|
||||
QList<QString> list;
|
||||
/*while(*supportedModules){
|
||||
if(*supportedModules == NULL)
|
||||
break;
|
||||
QString format((*supportedModules)->desc);
|
||||
format.append(" (*.");
|
||||
format.append((*supportedModules)->id);
|
||||
format.append(")");
|
||||
list.append(format);
|
||||
*supportedModules++;
|
||||
}*/
|
||||
return list;
|
||||
}
|
||||
|
||||
void SigSession::cancelSaveFile(){
|
||||
saveFileThreadRunning = false;
|
||||
}
|
||||
|
||||
void SigSession::export_file(const std::string &name, QWidget* parent, const std::string &ext){
|
||||
/*const deque< boost::shared_ptr<pv::data::LogicSnapshot> > &snapshots =
|
||||
_logic_data->get_snapshots();
|
||||
if(snapshots.empty())
|
||||
return;
|
||||
const boost::shared_ptr<pv::data::LogicSnapshot> & snapshot =
|
||||
snapshots.front();
|
||||
const struct sr_output_module** supportedModules = sr_output_list();
|
||||
const struct sr_output_module* outModule = NULL;
|
||||
while(*supportedModules){
|
||||
if(*supportedModules == NULL)
|
||||
break;
|
||||
if(!strcmp((*supportedModules)->id, ext.c_str())){
|
||||
outModule = *supportedModules;
|
||||
break;
|
||||
}
|
||||
*supportedModules++;
|
||||
}
|
||||
if(outModule == NULL)
|
||||
return;
|
||||
struct sr_output output;
|
||||
GHashTable *params = g_hash_table_new(g_str_hash, g_str_equal);
|
||||
GVariant* filenameGVariant = g_variant_new_string(name.c_str());
|
||||
g_hash_table_insert(params, (char*)"filename", filenameGVariant);
|
||||
output.module = (sr_output_module*) outModule;
|
||||
output.sdi = _dev_inst->dev_inst();
|
||||
output.param = NULL;
|
||||
if(outModule->init)
|
||||
outModule->init(&output, params);
|
||||
QFile file(name.c_str());
|
||||
file.open(QIODevice::WriteOnly | QIODevice::Text);
|
||||
QTextStream out(&file);
|
||||
QFuture<void> future = QtConcurrent::run([&]{
|
||||
saveFileThreadRunning = true;
|
||||
unsigned char* datat = (unsigned char*)snapshot->get_data();
|
||||
int numsamples = snapshot->get_sample_count()*snapshot->unit_size();
|
||||
GString *data_out;
|
||||
int usize = 1024;
|
||||
int size = usize;
|
||||
struct sr_datafeed_logic lp;
|
||||
struct sr_datafeed_packet p;
|
||||
for(uint64_t i = 0; i < numsamples; i+=usize){
|
||||
if(numsamples - i < usize)
|
||||
size = numsamples - i;
|
||||
lp.data = &datat[i];
|
||||
lp.length = size;
|
||||
lp.unitsize = snapshot->unit_size();
|
||||
p.type = SR_DF_LOGIC;
|
||||
p.payload = &lp;
|
||||
outModule->receive(&output, &p, &data_out);
|
||||
if(data_out){
|
||||
out << (char*) data_out->str;
|
||||
g_string_free(data_out,TRUE);
|
||||
}
|
||||
emit progressValueChanged(i*100/numsamples);
|
||||
if(!saveFileThreadRunning)
|
||||
break;
|
||||
}
|
||||
});
|
||||
QFutureWatcher<void> watcher;
|
||||
Qt::WindowFlags flags = Qt::CustomizeWindowHint;
|
||||
QProgressDialog dlg(QString::fromUtf8("Exporting data... It can take a while."),
|
||||
QString::fromUtf8("Cancel"),0,100,parent,flags);
|
||||
dlg.setWindowModality(Qt::WindowModal);
|
||||
watcher.setFuture(future);
|
||||
connect(&watcher,SIGNAL(finished()),&dlg,SLOT(cancel()));
|
||||
connect(this,SIGNAL(progressValueChanged(int)),&dlg,SLOT(setValue(int)));
|
||||
connect(&dlg,SIGNAL(canceled()),this,SLOT(cancelSaveFile()));
|
||||
dlg.exec();
|
||||
future.waitForFinished();
|
||||
// optional, as QFile destructor will already do it:
|
||||
file.close();
|
||||
outModule->cleanup(&output);
|
||||
g_hash_table_destroy(params);
|
||||
g_variant_unref(filenameGVariant);*/
|
||||
}
|
||||
|
||||
void SigSession::set_default_device(boost::function<void (const QString)> error_handler)
|
||||
{
|
||||
shared_ptr<pv::device::DevInst> default_device;
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <QMap>
|
||||
#include <QVariant>
|
||||
#include <QTimer>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
#include <libsigrok4DSL/libsigrok.h>
|
||||
#include <libusb.h>
|
||||
@@ -88,6 +89,7 @@ class SigSession : public QObject
|
||||
private:
|
||||
static const float Oversampling = 2.0f;
|
||||
static const int ViewTime = 800;
|
||||
bool saveFileThreadRunning = false;
|
||||
|
||||
public:
|
||||
enum capture_state {
|
||||
@@ -115,6 +117,9 @@ public:
|
||||
void save_file(const std::string &name);
|
||||
|
||||
void set_default_device(boost::function<void (const QString)> error_handler);
|
||||
void export_file(const std::string &name, QWidget* parent, const std::string &ext);
|
||||
|
||||
void set_default_device();
|
||||
|
||||
void release_device(device::DevInst *dev_inst);
|
||||
|
||||
@@ -132,6 +137,7 @@ public:
|
||||
|
||||
std::vector< boost::shared_ptr<view::GroupSignal> >
|
||||
get_group_signals();
|
||||
QList<QString> getSuportedExportFormats();
|
||||
|
||||
#ifdef ENABLE_DECODE
|
||||
bool add_decoder(srd_decoder *const dec);
|
||||
@@ -282,11 +288,15 @@ signals:
|
||||
void malloc_error();
|
||||
|
||||
void zero_adj();
|
||||
void progressSaveFileValueChanged(int percent);
|
||||
|
||||
public slots:
|
||||
void reload();
|
||||
void refresh();
|
||||
|
||||
private slots:
|
||||
void cancelSaveFile();
|
||||
|
||||
private:
|
||||
// TODO: This should not be necessary. Multiple concurrent
|
||||
// sessions should should be supported and it should be
|
||||
|
||||
@@ -64,6 +64,14 @@ FileBar::FileBar(SigSession &session, QWidget *parent) :
|
||||
_file_button.addAction(_action_save);
|
||||
connect(_action_save, SIGNAL(triggered()), this, SLOT(on_actionSave_triggered()));
|
||||
|
||||
_action_export = new QAction(this);
|
||||
_action_export->setText(QApplication::translate("File", "&Export...", 0));
|
||||
_action_export->setIcon(QIcon::fromTheme("file",QIcon(":/icons/instant.png")));
|
||||
_action_export->setObjectName(QString::fromUtf8("actionExport"));
|
||||
_file_button.addAction(_action_export);
|
||||
connect(_action_export, SIGNAL(triggered()), this, SLOT(on_actionExport_triggered()));
|
||||
|
||||
|
||||
_action_capture = new QAction(this);
|
||||
_action_capture->setText(QApplication::translate(
|
||||
"File", "&Capture...", 0));
|
||||
@@ -84,7 +92,7 @@ void FileBar::on_actionOpen_triggered()
|
||||
// Show the dialog
|
||||
const QString file_name = QFileDialog::getOpenFileName(
|
||||
this, tr("Open File"), "", tr(
|
||||
"DSView Sessions (*.dsl)"));
|
||||
"DSView Sessions (*.dsl);;All Files (*.*)"));
|
||||
if (!file_name.isEmpty())
|
||||
load_file(file_name);
|
||||
}
|
||||
@@ -108,6 +116,45 @@ void FileBar::show_session_error(
|
||||
msg.exec();
|
||||
}
|
||||
|
||||
void FileBar::on_actionExport_triggered(){
|
||||
int unit_size;
|
||||
uint64_t length;
|
||||
void* buf = _session.get_buf(unit_size, length);
|
||||
if (!buf) {
|
||||
QMessageBox msg(this);
|
||||
msg.setText("Data Export");
|
||||
msg.setInformativeText("No Data to Save!");
|
||||
msg.setStandardButtons(QMessageBox::Ok);
|
||||
msg.setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
} else if (_session.get_device()->dev_inst()->mode != LOGIC) {
|
||||
QMessageBox msg(this);
|
||||
msg.setText("Export Data");
|
||||
msg.setInformativeText("DSLogic currently only support exporting logic data to file!");
|
||||
msg.setStandardButtons(QMessageBox::Ok);
|
||||
msg.setIcon(QMessageBox::Warning);
|
||||
msg.exec();
|
||||
}else {
|
||||
QList<QString> supportedFormats = _session.getSuportedExportFormats();
|
||||
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"), "",filter,&filter);
|
||||
if (!file_name.isEmpty()) {
|
||||
QFileInfo f(file_name);
|
||||
QStringList list = filter.split('.').last().split(')');
|
||||
QString ext = list.first();
|
||||
if(f.suffix().compare(ext))
|
||||
file_name+=tr(".")+ext;
|
||||
_session.export_file(file_name.toStdString(), this, ext.toStdString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileBar::on_actionSave_triggered()
|
||||
{
|
||||
//save();
|
||||
|
||||
@@ -58,6 +58,7 @@ private slots:
|
||||
void on_actionOpen_triggered();
|
||||
void on_actionSave_triggered();
|
||||
void on_actionCapture_triggered();
|
||||
void on_actionExport_triggered();
|
||||
|
||||
private:
|
||||
bool _enable;
|
||||
@@ -67,6 +68,7 @@ private:
|
||||
|
||||
QAction *_action_open;
|
||||
QAction *_action_save;
|
||||
QAction *_action_export;
|
||||
QAction *_action_capture;
|
||||
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user