diff --git a/trick_source/data_products/Apps/trkConvert/DocWindow.cpp b/trick_source/data_products/Apps/trkConvert/DocWindow.cpp new file mode 100644 index 00000000..79d123bb --- /dev/null +++ b/trick_source/data_products/Apps/trkConvert/DocWindow.cpp @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include +#include + +#include + +#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 ; indexisChecked(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(); +} diff --git a/trick_source/data_products/Apps/trkConvert/DocWindow.h b/trick_source/data_products/Apps/trkConvert/DocWindow.h new file mode 100644 index 00000000..c539da5b --- /dev/null +++ b/trick_source/data_products/Apps/trkConvert/DocWindow.h @@ -0,0 +1,28 @@ +#ifndef DOC_WINDOW +#define DOC_WINDOW + +#include +#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 diff --git a/trick_source/data_products/Apps/trkConvert/TRK_DataLog.cpp b/trick_source/data_products/Apps/trkConvert/TRK_DataLog.cpp index a2e00782..86509ee2 100644 --- a/trick_source/data_products/Apps/trkConvert/TRK_DataLog.cpp +++ b/trick_source/data_products/Apps/trkConvert/TRK_DataLog.cpp @@ -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 ) { diff --git a/trick_source/data_products/Apps/trkConvert/VarTableWidget.cpp b/trick_source/data_products/Apps/trkConvert/VarTableWidget.cpp new file mode 100644 index 00000000..f5a3eb80 --- /dev/null +++ b/trick_source/data_products/Apps/trkConvert/VarTableWidget.cpp @@ -0,0 +1,90 @@ +#include +#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; isetCheckState(Qt::Checked); + } +} + +void VarTableWidget::unCheckAll() { + int num_rows = rowCount(); + // Note that we don't clear sys.exec.out.time + for (int i=1; isetCheckState(Qt::Unchecked); + } +} diff --git a/trick_source/data_products/Apps/trkConvert/VarTableWidget.h b/trick_source/data_products/Apps/trkConvert/VarTableWidget.h new file mode 100644 index 00000000..13dbcdac --- /dev/null +++ b/trick_source/data_products/Apps/trkConvert/VarTableWidget.h @@ -0,0 +1,22 @@ +#ifndef VARIABLE_TABLE_WIDGET_H +#define VARIABLE_TABLE_WIDGET_H + +#include +#include // 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 diff --git a/trick_source/data_products/Apps/trkConvert/main.cpp b/trick_source/data_products/Apps/trkConvert/main.cpp new file mode 100644 index 00000000..f999f364 --- /dev/null +++ b/trick_source/data_products/Apps/trkConvert/main.cpp @@ -0,0 +1,99 @@ +#include +#include +#include +#include +#include +#include "DocWindow.h" +#include +#include + +#include +static const char *usage_doc[] = { +"----------------------------------------------------------------------------", +" trkConvert - ", +" ", +" USAGE: trkConvert -help ", +" trkConvert [-csv|-varlist] [-o ] ", +" 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(); + + } +} diff --git a/trick_source/data_products/Apps/trkConvert/makefile b/trick_source/data_products/Apps/trkConvert/makefile deleted file mode 100644 index 7decf266..00000000 --- a/trick_source/data_products/Apps/trkConvert/makefile +++ /dev/null @@ -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 diff --git a/trick_source/data_products/Apps/trkConvert/trkConvert.cpp b/trick_source/data_products/Apps/trkConvert/trkConvert.cpp deleted file mode 100644 index 4b191d6c..00000000 --- a/trick_source/data_products/Apps/trkConvert/trkConvert.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include -#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 ] ", -" 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 (iextension(); - } - - 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; -} diff --git a/trick_source/data_products/Apps/trkConvert/trkConvert.pro b/trick_source/data_products/Apps/trkConvert/trkConvert.pro new file mode 100644 index 00000000..d539c350 --- /dev/null +++ b/trick_source/data_products/Apps/trkConvert/trkConvert.pro @@ -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 diff --git a/trick_source/data_products/makefile b/trick_source/data_products/makefile index 85b39c45..f9514b33 100644 --- a/trick_source/data_products/makefile +++ b/trick_source/data_products/makefile @@ -18,7 +18,6 @@ LIBDIRS += fermi-ware endif APPDIRS = DPX \ - Apps/trkConvert \ Apps/Trk2csv \ Apps/ExternalPrograms