Added GUI to trkConvert. (#641)

This commit is contained in:
jmpenn 2018-06-28 16:16:48 -05:00 committed by GitHub
parent 34dcffa7f7
commit 402f7c152b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 387 additions and 152 deletions

View File

@ -0,0 +1,111 @@
#include <QAction>
#include <QFileDialog>
#include <QMenuBar>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>
#include <iostream>
#include <QTextStream>
#include "DocWindow.h"
#include "VarTableWidget.h"
#include "CSV_Formatter.hh"
DocWindow::DocWindow(const QString &name)
: QMainWindow( 0, 0) {
trkFileName = name;
// Build the Menus
QAction * fileLoadAction = new QAction( "&Open File...", this );
fileLoadAction->setShortcut(tr("CTRL+O"));
connect( fileLoadAction, &QAction::triggered , this, &DocWindow::load );
QAction * fileSaveAction = new QAction( "&Export as CSV...", this );
connect( fileSaveAction, &QAction::triggered, this, &DocWindow::saveAsCSV );
QMenu *fileMenu = menuBar()->addMenu("&File");
fileMenu->addAction(fileLoadAction);
fileMenu->addSeparator();
fileMenu->addAction(fileSaveAction);
QAction * editSelectAction = new QAction( "&Select All", this );
editSelectAction->setShortcut(tr("CTRL+A"));
connect( editSelectAction, &QAction::triggered, this, &DocWindow::checkAll );
QAction * editClearAction = new QAction( "&Clear All", this );
connect( editClearAction, &QAction::triggered, this, &DocWindow::unCheckAll );
QMenu *editMenu = menuBar()->addMenu("&Edit");
editMenu->addAction(editSelectAction);
editMenu->addAction(editClearAction);
// Build the Table Widget that displays the variable names, types, and units.
varTable = new VarTableWidget(this);
datalog = new TRK_DataLog( trkFileName.toStdString().c_str() );
int recordCount = datalog->parameterCount();
for (int ii = 0; ii < recordCount; ii++) {
varTable->addRecord( Qt::Checked,
datalog->parameterName(ii),
datalog->parameterType(ii),
datalog->parameterUnits(ii));
}
setCentralWidget(varTable);
}
void DocWindow::load() {
QString newFileName;
newFileName = QFileDialog::getOpenFileName(this,
tr("Open Data File"), ".", tr("Data Files (*.trk)"));
if (!newFileName.isEmpty()) {
DocWindow* w = new DocWindow(newFileName);
w->setWindowTitle(newFileName);
w->resize(800, 500);
w->show();
}
}
void DocWindow::saveAsCSV() {
QTextStream out(stdout);
CSV_Formatter csv_formatter;
QFileInfo trkFileInfo( trkFileName);
QString csvFileName = trkFileInfo.canonicalPath();
csvFileName += "/";
csvFileName += trkFileInfo.completeBaseName();
csvFileName += csv_formatter.extension();
out << "csvFileName = \"" << csvFileName << "\"" << endl;
int count = varTable->recordCount();
for (int index=0 ; index<count ; index++) {
if (varTable->isChecked(index)) {
datalog->selectParameter(index);
}
}
FILE *fp;
if (( fp = fopen(csvFileName.toStdString().c_str(), "w") ) != NULL) {
datalog->formattedWrite(fp, &csv_formatter);
}
}
void DocWindow::checkAll() {
varTable->checkAll();
}
void DocWindow::unCheckAll() {
varTable->unCheckAll();
}

View File

@ -0,0 +1,28 @@
#ifndef DOC_WINDOW
#define DOC_WINDOW
#include <QMainWindow>
#include "VarTableWidget.h"
#include "TRK_DataLog.hh"
class DocWindow : public QMainWindow {
Q_OBJECT
public:
DocWindow(const QString &name);
~DocWindow(){};
private slots:
void load();
void saveAsCSV();
void checkAll();
void unCheckAll();
private:
QString trkFileName;
VarTableWidget* varTable;
TRK_DataLog* datalog;
};
#endif

View File

@ -183,9 +183,10 @@ void TRK_DataLog::formattedWrite(FILE* out_fp, LogFormatter* formatter) {
formatter->writeHeader(out_fp, version, endianness);
formatter->writeColumnLabel(out_fp, paramDescriptions[0]->parameterName, paramDescriptions[0]->unitsName);
for (int ii = 1; ii < (int)N_params ; ii++) {
if (paramSelected[ii])
if (paramSelected[ii]) {
formatter->writeColumnLabelSeparator(out_fp);
formatter->writeColumnLabel(out_fp, paramDescriptions[ii]->parameterName, paramDescriptions[ii]->unitsName);
}
}
if ( fsetpos(in_fp, &dataPosition) != 0 ) {

View File

@ -0,0 +1,90 @@
#include <QTableWidgetItem>
#include "VarTableWidget.h"
VarTableWidget::VarTableWidget (QWidget* parent)
: QTableWidget(parent) {
setRowCount(0);
setColumnCount(4);
QStringList strList;
strList << "" << "Name" << "Type" << "Units";
setHorizontalHeaderLabels( strList);
setColumnWidth(0,25);
setColumnWidth(1,200);
setColumnWidth(2,80);
setColumnWidth(3,80);
setShowGrid(false);
}
void VarTableWidget::addRecord( Qt::CheckState checkState,
std::string nameStr,
std::string typeStr,
std::string unitsStr ) {
// Consider cloning prototype items, as in this example:
// https://stackoverflow.com/questions/15827886/set-default-alignment-for-cells-in-qtablewidget
int row = rowCount();
insertRow(row);
Qt::ItemFlags flags;
QTableWidgetItem * const selectItem = new QTableWidgetItem;
flags = selectItem->flags();
flags &= ~Qt::ItemIsSelectable & ~Qt::ItemIsEditable;
if (row != 0) // FIXME: This doesn't seem to work as expected. Row 0 still seems to be user editable.
flags |= Qt::ItemIsUserCheckable;
selectItem->setFlags(flags);
selectItem->setCheckState(checkState);
setItem(row, 0, selectItem);
QTableWidgetItem * const nameItem = new QTableWidgetItem;
flags = nameItem->flags();
flags &= ~Qt::ItemIsSelectable & ~Qt::ItemIsEditable;
nameItem->setFlags(flags);
nameItem->setText(nameStr.c_str());
setItem(row, 1, nameItem);
QTableWidgetItem * const typeItem = new QTableWidgetItem;
flags = typeItem->flags();
flags &= ~Qt::ItemIsSelectable & ~Qt::ItemIsEditable;
typeItem->setFlags(flags);
typeItem->setTextAlignment(Qt::AlignCenter);
typeItem->setText(typeStr.c_str());
setItem(row, 2, typeItem);
QTableWidgetItem * const unitsItem = new QTableWidgetItem;
flags = unitsItem->flags();
flags &= ~Qt::ItemIsSelectable & ~Qt::ItemIsEditable;
unitsItem->setFlags(flags);
unitsItem->setTextAlignment(Qt::AlignCenter);
unitsItem->setText(unitsStr.c_str());
setItem(row, 3, unitsItem);
}
bool VarTableWidget::isChecked(int index) {
return (item(index, 0)->checkState() == Qt::Checked) ? true : false;
}
int VarTableWidget::recordCount() {
return rowCount();
}
void VarTableWidget::checkAll() {
int num_rows = rowCount();
for (int i=0; i<num_rows; i++) {
item(i,0)->setCheckState(Qt::Checked);
}
}
void VarTableWidget::unCheckAll() {
int num_rows = rowCount();
// Note that we don't clear sys.exec.out.time
for (int i=1; i<num_rows; i++) {
item(i,0)->setCheckState(Qt::Unchecked);
}
}

View File

@ -0,0 +1,22 @@
#ifndef VARIABLE_TABLE_WIDGET_H
#define VARIABLE_TABLE_WIDGET_H
#include <string>
#include <QTableWidget> // widgets
class VarTableWidget : public QTableWidget {
Q_OBJECT
public:
// Constructors
VarTableWidget(QWidget* parent = 0);
void addRecord( Qt::CheckState checkState, std::string name, std::string type, std::string units );
bool isChecked(int index);
int recordCount();
public slots:
void checkAll();
void unCheckAll();
};
#endif

View File

@ -0,0 +1,99 @@
#include <QApplication>
#include <QListView>
#include <QMenu>
#include <QMenuBar>
#include <QFileDialog>
#include "DocWindow.h"
#include <QTextStream>
#include <QFileInfo>
#include <stdio.h>
static const char *usage_doc[] = {
"----------------------------------------------------------------------------",
" trkConvert - ",
" ",
" USAGE: trkConvert -help ",
" trkConvert [-csv|-varlist] [-o <outfile>] <trk_file_name> ",
" Options: ",
" -help Print this message and exit. ",
" -csv (the default) Generates a comma-separated value (CSV) file from ",
" a Trick binary data file. CSV files are a common ",
" means of sharing data between applications. ",
" -varlist Generates a list of the names of the variables ",
" the are recorded in the Trick binary data file. ",
"----------------------------------------------------------------------------"};
#define N_USAGE_LINES (sizeof(usage_doc)/sizeof(usage_doc[0]))
void print_doc(char *doc[], int nlines) {
int i;
for (i=0; i < nlines; i++) {
printf("%s\n",doc[i]);
}
fflush(stdout);
}
void usage() {
print_doc((char **)usage_doc,N_USAGE_LINES);
}
int main(int argc, char *argv[]) {
QTextStream out(stdout);
QApplication app(argc, argv);
QStringList args = app.arguments();
QString programName = args.at(0);
QString trkFilePath;
QString outputName;
int i = 1;
QString arg;
while (i < argc) {
arg = args.at(i);
if ( (QString::compare(arg, "-help") == 0) |
(QString::compare(arg, "--help") == 0) ) {
usage();
exit(0);
} else if ((QString::compare(arg, "-csv") == 0)) {
out << "CSV selected." << endl;
} else if ((QString::compare(arg, "-varlist") == 0)) {
out << "Varlist selected." << endl;
} else if ((QString::compare(arg, "-o") == 0)) {
i++;
if (i < argc) {
arg = args.at(i);
outputName = arg;
} else {
out << programName << ": -o option requires a filename." << endl;
usage();
exit(1);
}
} else if ((QString::compare(arg.right(4), ".trk") == 0)) {
trkFilePath = arg;
} else {
out << programName << ": Invalid argument \"" << arg << "\"." << endl;
usage();
exit(1);
}
i++;
}
// If a .trk file has been specified
if (trkFilePath.isEmpty()) {
trkFilePath = QFileDialog::getOpenFileName(0, "Open Data File", ".", "Data Files (*.trk)");
}
if (!trkFilePath.isEmpty()) {
QFileInfo trkFileInfo( trkFilePath);
DocWindow* w1 = new DocWindow( trkFileInfo.absoluteFilePath());
w1->setWindowTitle( trkFileInfo.fileName());
w1->resize(800, 500);
w1->show();
return app.exec();
}
}

View File

@ -1,26 +0,0 @@
CPP = g++
CC = gcc
CXXFLAGS =
MAIN = trkConvert
OBJECTS = CSV_Formatter.o Varlist_Formatter.o ParamDescription.o TRK_DataLog.o trkConvert.o
.c.o:
${CC} ${CFLAGS} ${INCDIRS} -c $<
.cpp.o:
${CPP} ${CFLAGS} ${INCDIRS} -c $<
all: install
trkConvert: $(OBJECTS)
$(CPP) -o trkConvert $(OBJECTS)
install: trkConvert
cp trkConvert $${TRICK_HOME}/bin/trick-trkConvert
clean:
rm -f *.o
rm -f trkConvert

View File

@ -1,124 +0,0 @@
#include <stdio.h>
#include <iostream>
#include <string>
#include "LogFormatter.hh"
#include "CSV_Formatter.hh"
#include "Varlist_Formatter.hh"
#include "TRK_DataLog.hh"
static const char *usage_doc[] = {
"----------------------------------------------------------------------------",
" trkConvert - ",
" ",
" USAGE: trkConvert -help ",
" trkConvert [-csv|-varlist] [-o <outfile>] <trk_file_name> ",
" Options: ",
" -help Print this message and exit. ",
" -csv (the default) Generates a comma-separated value (CSV) file from ",
" a Trick binary data file. CSV files are a common ",
" means of sharing data between applications. ",
" -varlist Generates a list of the names of the variables ",
" the are recorded in the Trick binary data file. ",
"----------------------------------------------------------------------------"};
#define N_USAGE_LINES (sizeof(usage_doc)/sizeof(usage_doc[0]))
void print_doc(char *doc[], int nlines) {
int i;
for (i=0; i < nlines; i++) {
std::cerr << doc[i] << '\n';
}
std::cerr.flush();
}
void usage() {
print_doc((char **)usage_doc,N_USAGE_LINES);
}
int main(int argc, char* argv[]) {
std::string programName = argv[0];
std::string trkFilePath;
std::string trkBaseName;
std::string outputName;
FILE *fp;
CSV_Formatter csv_formatter;
LogFormatter* logFormatter = &csv_formatter; // default formatter.
Varlist_Formatter varlist_formatter;
if (argc <= 1 ) {
std::cerr << programName << ": No arguments were supplied.\n";
std::cerr.flush();
usage();
exit(1);
} else {
int i = 1;
std::string arg;
while ( i < argc ) {
arg = argv[i];
if (arg.find("-") == 0) {
if (arg == "-help" | arg == "--help" ) {
usage();
exit(0);
} else if (arg == "-csv") {
logFormatter = &csv_formatter;
} else if (arg == "-varlist") {
logFormatter = &varlist_formatter;
} else if (arg == "-o") {
i++;
if (i<argc) {
arg = argv[i];
outputName = arg;
} else {
std::cerr << programName << ": -o option requires a filename." << std::endl;
usage();
exit(1);
}
} else {
std::cerr << programName << ": Invalid option \"" << arg << "\"." << std::endl;
usage();
exit(1);
}
} else if (arg.substr(arg.find_last_of(".")) == ".trk") {
size_t pos;
std::string trkFileName;
trkFilePath = arg;
if ((pos = trkFilePath.find_last_of("/")) != std::string::npos) {
trkFileName = trkFilePath.substr(pos+1);
} else {
trkFileName = trkFilePath;
}
trkBaseName = trkFileName.substr(0, trkFileName.length()-4);
} else {
std::cerr << programName << ": Invalid argument \"" << arg << "\"." << std::endl;
usage();
exit(1);
}
i++;
}
}
if (trkFilePath.empty()) {
std::cerr << programName << ": Missing .trk filename." << std::endl;
usage();
exit(1);
}
if (outputName.empty()) {
outputName = trkBaseName + logFormatter->extension();
}
std::cout << programName << ": Input = \"" << trkFilePath << "\"." << std::endl;
std::cout << programName << ": Output = \"" << outputName << "\"." << std::endl;
TRK_DataLog* datalog = new TRK_DataLog(trkFilePath.c_str());
datalog->selectAllParameters();
if (( fp = fopen(outputName.c_str(), "w") ) != NULL) {
datalog->formattedWrite(fp, logFormatter);
return 0;
}
return 1;
}

View File

@ -0,0 +1,35 @@
######################################################################
# Automatically generated by qmake (3.1) Wed Jun 27 14:55:58 2018
######################################################################
TEMPLATE = app
TARGET = trkConvert
INCLUDEPATH += .
# The following define makes your compiler warn you if you use any
# feature of Qt which has been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
# Input
HEADERS += CSV_Formatter.hh \
DocWindow.h \
LogFormatter.hh \
ParamDescription.hh \
TRK_DataLog.hh \
Varlist_Formatter.hh \
VarTableWidget.h
SOURCES += CSV_Formatter.cpp \
DocWindow.cpp \
main.cpp \
ParamDescription.cpp \
TRK_DataLog.cpp \
Varlist_Formatter.cpp \
VarTableWidget.cpp
QT += widgets

View File

@ -18,7 +18,6 @@ LIBDIRS += fermi-ware
endif
APPDIRS = DPX \
Apps/trkConvert \
Apps/Trk2csv \
Apps/ExternalPrograms