mirror of
https://github.com/nasa/trick.git
synced 2025-02-22 17:52:38 +00:00
Add Search and Documentation for trkConvert (#646)
* Add Export of variable list to file. * Create DocWindow:formattedSave, and implement saveAsCSV etc in terms of it. * Minor spacing changes * Add text text UI parts to DocWindow. * Add foreward and reverse search by pattern. * Document and configuration for Mac.
This commit is contained in:
parent
8a4c8e3dd9
commit
b0b0cdf21b
@ -3,6 +3,7 @@
|
|||||||
#include <QMenuBar>
|
#include <QMenuBar>
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
#include <QLineEdit>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
@ -11,10 +12,19 @@
|
|||||||
#include "DocWindow.h"
|
#include "DocWindow.h"
|
||||||
#include "VarTableWidget.h"
|
#include "VarTableWidget.h"
|
||||||
#include "CSV_Formatter.hh"
|
#include "CSV_Formatter.hh"
|
||||||
|
#include "Varlist_Formatter.hh"
|
||||||
|
|
||||||
|
// Notes:
|
||||||
|
// Need to be able to search for a variable by pattern.
|
||||||
|
// Use a QLineEdit widget for the text box.
|
||||||
|
|
||||||
DocWindow::DocWindow(const QString &name)
|
DocWindow::DocWindow(const QString &name)
|
||||||
: QMainWindow( 0, 0) {
|
: QMainWindow( 0, 0) {
|
||||||
|
|
||||||
|
QTextStream out(stdout);
|
||||||
|
|
||||||
|
foundItemIndex = 0;
|
||||||
|
|
||||||
trkFileName = name;
|
trkFileName = name;
|
||||||
|
|
||||||
// Build the Menus
|
// Build the Menus
|
||||||
@ -22,14 +32,19 @@ DocWindow::DocWindow(const QString &name)
|
|||||||
fileLoadAction->setShortcut(tr("CTRL+O"));
|
fileLoadAction->setShortcut(tr("CTRL+O"));
|
||||||
connect( fileLoadAction, &QAction::triggered , this, &DocWindow::load );
|
connect( fileLoadAction, &QAction::triggered , this, &DocWindow::load );
|
||||||
|
|
||||||
QAction * fileSaveAction = new QAction( "&Export as CSV...", this );
|
QAction * csvSaveAction = new QAction( "&Export as CSV...", this );
|
||||||
connect( fileSaveAction, &QAction::triggered, this, &DocWindow::saveAsCSV );
|
connect( csvSaveAction, &QAction::triggered, this, &DocWindow::saveAsCSV );
|
||||||
|
|
||||||
|
QAction * varListSaveAction = new QAction( "&Export as Variable List...", this );
|
||||||
|
connect( varListSaveAction, &QAction::triggered, this, &DocWindow::saveAsVarList );
|
||||||
|
|
||||||
QMenu *fileMenu = menuBar()->addMenu("&File");
|
QMenu *fileMenu = menuBar()->addMenu("&File");
|
||||||
|
|
||||||
fileMenu->addAction(fileLoadAction);
|
fileMenu->addAction(fileLoadAction);
|
||||||
fileMenu->addSeparator();
|
fileMenu->addSeparator();
|
||||||
fileMenu->addAction(fileSaveAction);
|
fileMenu->addAction(csvSaveAction);
|
||||||
|
fileMenu->addAction(varListSaveAction);
|
||||||
|
|
||||||
|
|
||||||
QAction * editSelectAction = new QAction( "&Select All", this );
|
QAction * editSelectAction = new QAction( "&Select All", this );
|
||||||
editSelectAction->setShortcut(tr("CTRL+A"));
|
editSelectAction->setShortcut(tr("CTRL+A"));
|
||||||
@ -43,6 +58,23 @@ DocWindow::DocWindow(const QString &name)
|
|||||||
editMenu->addAction(editSelectAction);
|
editMenu->addAction(editSelectAction);
|
||||||
editMenu->addAction(editClearAction);
|
editMenu->addAction(editClearAction);
|
||||||
|
|
||||||
|
QHBoxLayout *hbox = new QHBoxLayout();
|
||||||
|
|
||||||
|
QPushButton *backward = new QPushButton(QChar(0x25C0), this);
|
||||||
|
connect( backward, &QPushButton::released, this, &DocWindow::findAgainBackward);
|
||||||
|
|
||||||
|
QPushButton *forward = new QPushButton(QChar(0x25B6), this);
|
||||||
|
connect( forward, &QPushButton::released, this, &DocWindow::findAgainForward);
|
||||||
|
|
||||||
|
searchLineEdit = new QLineEdit;
|
||||||
|
searchLineEdit->setPlaceholderText("Search Pattern");
|
||||||
|
connect(searchLineEdit, SIGNAL(returnPressed()), this, SLOT(find()));
|
||||||
|
|
||||||
|
hbox->addWidget(backward);
|
||||||
|
hbox->addWidget(forward);
|
||||||
|
hbox->addWidget(searchLineEdit);
|
||||||
|
|
||||||
|
QVBoxLayout *vbox = new QVBoxLayout();
|
||||||
|
|
||||||
// Build the Table Widget that displays the variable names, types, and units.
|
// Build the Table Widget that displays the variable names, types, and units.
|
||||||
varTable = new VarTableWidget(this);
|
varTable = new VarTableWidget(this);
|
||||||
@ -56,7 +88,13 @@ DocWindow::DocWindow(const QString &name)
|
|||||||
datalog->parameterUnits(ii));
|
datalog->parameterUnits(ii));
|
||||||
}
|
}
|
||||||
|
|
||||||
setCentralWidget(varTable);
|
vbox->addWidget(varTable);
|
||||||
|
vbox->addLayout(hbox);
|
||||||
|
|
||||||
|
QWidget *window = new QWidget;
|
||||||
|
window->setLayout(vbox);
|
||||||
|
|
||||||
|
setCentralWidget(window);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocWindow::load() {
|
void DocWindow::load() {
|
||||||
@ -74,32 +112,41 @@ void DocWindow::load() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocWindow::saveAsCSV() {
|
void DocWindow::formattedSave(LogFormatter &formatter) {
|
||||||
|
|
||||||
QTextStream out(stdout);
|
|
||||||
|
|
||||||
CSV_Formatter csv_formatter;
|
|
||||||
|
|
||||||
QFileInfo trkFileInfo( trkFileName);
|
QFileInfo trkFileInfo( trkFileName);
|
||||||
|
|
||||||
QString csvFileName = trkFileInfo.canonicalPath();
|
QString outFileName = trkFileInfo.canonicalPath();
|
||||||
csvFileName += "/";
|
outFileName += "/";
|
||||||
csvFileName += trkFileInfo.completeBaseName();
|
outFileName += trkFileInfo.completeBaseName();
|
||||||
csvFileName += csv_formatter.extension();
|
outFileName += formatter.extension();
|
||||||
out << "csvFileName = \"" << csvFileName << "\"" << endl;
|
|
||||||
|
QTextStream out(stdout);
|
||||||
|
out << "outFileName = \"" << outFileName << "\"" << endl;
|
||||||
|
|
||||||
int count = varTable->recordCount();
|
int count = varTable->recordCount();
|
||||||
for (int index=0 ; index<count ; index++) {
|
for (int index=0 ; index<count ; index++) {
|
||||||
if (varTable->isChecked(index)) {
|
if (varTable->isChecked(index)) {
|
||||||
datalog->selectParameter(index);
|
datalog->selectParameter(index);
|
||||||
|
} else {
|
||||||
|
datalog->deselectParameter(index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
if (( fp = fopen(csvFileName.toStdString().c_str(), "w") ) != NULL) {
|
if (( fp = fopen(outFileName.toStdString().c_str(), "w") ) != NULL) {
|
||||||
datalog->formattedWrite(fp, &csv_formatter);
|
datalog->formattedWrite(fp, &formatter);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocWindow::saveAsCSV() {
|
||||||
|
CSV_Formatter csv_formatter;
|
||||||
|
formattedSave(csv_formatter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocWindow::saveAsVarList() {
|
||||||
|
Varlist_Formatter varlist_formatter;
|
||||||
|
formattedSave(varlist_formatter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocWindow::checkAll() {
|
void DocWindow::checkAll() {
|
||||||
@ -109,3 +156,50 @@ void DocWindow::checkAll() {
|
|||||||
void DocWindow::unCheckAll() {
|
void DocWindow::unCheckAll() {
|
||||||
varTable->unCheckAll();
|
varTable->unCheckAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DocWindow::findAgain(int direction) {
|
||||||
|
if (foundItemIndex >= 0) {
|
||||||
|
varTable->unHighLightRecord(foundItemIndex);
|
||||||
|
int count = varTable->recordCount();
|
||||||
|
int startIndex = (count + foundItemIndex + direction) % count;
|
||||||
|
if ((foundItemIndex = textSearch(searchPattern, startIndex, direction)) >= 0) {
|
||||||
|
varTable->scrollToRecord(foundItemIndex);
|
||||||
|
varTable->highLightRecord(foundItemIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocWindow::findAgainForward() {
|
||||||
|
findAgain(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocWindow::findAgainBackward() {
|
||||||
|
findAgain(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DocWindow::find() {
|
||||||
|
searchPattern = searchLineEdit->text();
|
||||||
|
|
||||||
|
if (foundItemIndex >= 0) {
|
||||||
|
varTable->unHighLightRecord(foundItemIndex);
|
||||||
|
}
|
||||||
|
if ((foundItemIndex = textSearch(searchPattern, 0, 1)) >= 0) {
|
||||||
|
varTable->scrollToRecord(foundItemIndex);
|
||||||
|
varTable->highLightRecord(foundItemIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int DocWindow::textSearch(QString pattern, int startIndex, int direction) {
|
||||||
|
|
||||||
|
QRegExp rx(pattern);
|
||||||
|
int count = varTable->recordCount();
|
||||||
|
int foundIx = -1;
|
||||||
|
for (int i=0 ; i<count ; i++) {
|
||||||
|
int index = (count + startIndex + direction * i) % count;
|
||||||
|
if ((rx.indexIn(datalog->parameterName(index),0)) >= 0) {
|
||||||
|
foundIx = index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return foundIx;
|
||||||
|
}
|
||||||
|
@ -13,14 +13,27 @@ class DocWindow : public QMainWindow {
|
|||||||
DocWindow(const QString &name);
|
DocWindow(const QString &name);
|
||||||
~DocWindow(){};
|
~DocWindow(){};
|
||||||
|
|
||||||
|
void formattedSave(LogFormatter &formatter);
|
||||||
|
void textSearch();
|
||||||
|
int textSearch(QString searchText, int startIndex, int direction);
|
||||||
|
void findAgain(int direction);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void load();
|
void load();
|
||||||
void saveAsCSV();
|
void saveAsCSV();
|
||||||
|
void saveAsVarList();
|
||||||
void checkAll();
|
void checkAll();
|
||||||
void unCheckAll();
|
void unCheckAll();
|
||||||
|
void find();
|
||||||
|
|
||||||
|
void findAgainForward();
|
||||||
|
void findAgainBackward();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QString searchPattern;
|
||||||
|
int foundItemIndex;
|
||||||
QString trkFileName;
|
QString trkFileName;
|
||||||
|
QLineEdit* searchLineEdit;
|
||||||
VarTableWidget* varTable;
|
VarTableWidget* varTable;
|
||||||
TRK_DataLog* datalog;
|
TRK_DataLog* datalog;
|
||||||
};
|
};
|
||||||
|
49
trick_source/data_products/Apps/trkConvert/README.md
Normal file
49
trick_source/data_products/Apps/trkConvert/README.md
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# trkConvert
|
||||||
|
|
||||||
|
Convert selected sets of variables in Trick binary data recording files (.trk) to comma separated values (.csv). In the future, more formats may be added as needed.
|
||||||
|
|
||||||
|
## Building trkConvert
|
||||||
|
|
||||||
|
trkConvert requires the [Qt Application Framework](https://www.qt.io).
|
||||||
|
|
||||||
|
When Qt is installed, building the application is as simple as:
|
||||||
|
|
||||||
|
```
|
||||||
|
% qmake
|
||||||
|
% make
|
||||||
|
% cp trkConvert $TRICK_HOME/bin/trkConvert
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running trkConvert
|
||||||
|
|
||||||
|
**% trkConvert [name.trk] &**
|
||||||
|
|
||||||
|
```
|
||||||
|
% trkConvert &
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
```
|
||||||
|
% trkConvert log_helios.trk &
|
||||||
|
```
|
||||||
|
The resulting window displays the names, data types and units of the variables recorded in the .trk file. The check marks, to the left indicate which variables would be recorded in an exported format.
|
||||||
|
|
||||||
|

|
||||||
|
The check boxes can be individually selected and cleared with a mouse-click.
|
||||||
|
They can be collectively selected and cleared from the Edit menu.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## Variable Search
|
||||||
|
|
||||||
|
Python-like regular expressions
|
||||||
|
A search pattern is Python-like regular expression that matches any part of a variable name. To search, type the pattern, and press **Return** or **Enter**.
|
||||||
|
|
||||||
|
Subsequent searches for the pattern can be performed using the arrow buttons.
|
||||||
|
|
||||||
|
* Right arror searches forward
|
||||||
|
* Left arrow searches backward.
|
||||||
|
|
||||||
|
## Exporting Selected Values
|
||||||
|
Export selected values to CSV, or other format from the **File** menu.
|
@ -66,6 +66,20 @@ void VarTableWidget::addRecord( Qt::CheckState checkState,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VarTableWidget::highLightRecord(int index) {
|
||||||
|
QBrush brush(Qt::yellow);
|
||||||
|
item(index, 1)->setBackground(brush);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VarTableWidget::unHighLightRecord(int index) {
|
||||||
|
QBrush brush(Qt::white);
|
||||||
|
item(index, 1)->setBackground(brush);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VarTableWidget::scrollToRecord(int index) {
|
||||||
|
scrollToItem(item(index, 0));
|
||||||
|
}
|
||||||
|
|
||||||
bool VarTableWidget::isChecked(int index) {
|
bool VarTableWidget::isChecked(int index) {
|
||||||
return (item(index, 0)->checkState() == Qt::Checked) ? true : false;
|
return (item(index, 0)->checkState() == Qt::Checked) ? true : false;
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,9 @@ class VarTableWidget : public QTableWidget {
|
|||||||
void addRecord( Qt::CheckState checkState, std::string name, std::string type, std::string units );
|
void addRecord( Qt::CheckState checkState, std::string name, std::string type, std::string units );
|
||||||
bool isChecked(int index);
|
bool isChecked(int index);
|
||||||
int recordCount();
|
int recordCount();
|
||||||
|
void scrollToRecord(int index);
|
||||||
|
void highLightRecord(int index);
|
||||||
|
void unHighLightRecord(int index);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void checkAll();
|
void checkAll();
|
||||||
|
BIN
trick_source/data_products/Apps/trkConvert/images/DocWindow.png
Normal file
BIN
trick_source/data_products/Apps/trkConvert/images/DocWindow.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 157 KiB |
BIN
trick_source/data_products/Apps/trkConvert/images/DocWindow2.png
Normal file
BIN
trick_source/data_products/Apps/trkConvert/images/DocWindow2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 149 KiB |
Binary file not shown.
After Width: | Height: | Size: 101 KiB |
@ -13,14 +13,9 @@ static const char *usage_doc[] = {
|
|||||||
" trkConvert - ",
|
" trkConvert - ",
|
||||||
" ",
|
" ",
|
||||||
" USAGE: trkConvert -help ",
|
" USAGE: trkConvert -help ",
|
||||||
" trkConvert [-csv|-varlist] [-o <outfile>] <trk_file_name> ",
|
" trkConvert <trk_file_name> ",
|
||||||
" Options: ",
|
" Options: ",
|
||||||
" -help Print this message and exit. ",
|
" -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]))
|
#define N_USAGE_LINES (sizeof(usage_doc)/sizeof(usage_doc[0]))
|
||||||
|
|
||||||
@ -56,20 +51,6 @@ int main(int argc, char *argv[]) {
|
|||||||
(QString::compare(arg, "--help") == 0) ) {
|
(QString::compare(arg, "--help") == 0) ) {
|
||||||
usage();
|
usage();
|
||||||
exit(0);
|
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)) {
|
} else if ((QString::compare(arg.right(4), ".trk") == 0)) {
|
||||||
trkFilePath = arg;
|
trkFilePath = arg;
|
||||||
} else {
|
} else {
|
||||||
@ -80,7 +61,6 @@ int main(int argc, char *argv[]) {
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a .trk file has been specified
|
|
||||||
if (trkFilePath.isEmpty()) {
|
if (trkFilePath.isEmpty()) {
|
||||||
trkFilePath = QFileDialog::getOpenFileName(0, "Open Data File", ".", "Data Files (*.trk)");
|
trkFilePath = QFileDialog::getOpenFileName(0, "Open Data File", ".", "Data Files (*.trk)");
|
||||||
}
|
}
|
||||||
@ -94,6 +74,5 @@ int main(int argc, char *argv[]) {
|
|||||||
w1->show();
|
w1->show();
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,4 +32,8 @@ SOURCES += CSV_Formatter.cpp \
|
|||||||
TRK_DataLog.cpp \
|
TRK_DataLog.cpp \
|
||||||
Varlist_Formatter.cpp \
|
Varlist_Formatter.cpp \
|
||||||
VarTableWidget.cpp
|
VarTableWidget.cpp
|
||||||
|
|
||||||
QT += widgets
|
QT += widgets
|
||||||
|
|
||||||
|
# Inhibit creation of an Mac OS X App bundle.
|
||||||
|
CONFIG -= app_bundle
|
||||||
|
Loading…
x
Reference in New Issue
Block a user