source: flair-src/trunk/tools/FlairGCS/src/file_ui.cpp @ 248

Last change on this file since 248 was 248, checked in by Sanahuja Guillaume, 3 years ago

add orange icon to gcs

File size: 14.3 KB
Line 
1// %flair:license{
2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
4// %flair:license}
5#include "file_ui.h"
6#include "communication.h"
7
8#include <stdio.h>
9#include <cstring>
10#include <cstdlib>
11#include <fstream>
12#include <iostream>
13#include <QDir>
14#include <QDate>
15#include <QTextStream>
16#include <QGridLayout>
17#include <io_hdfile.h>
18#include <QtEndian>
19#include <QComboBox>
20#include <QPushButton>
21#include <QTextEdit>
22#include <QDialog>
23#include <QStringList>
24#include <QFormLayout>
25#include <QThread>
26
27#include <unistd.h>
28using namespace std;
29
30file_ui::file_ui(UDTSOCKET socket,QString name): QObject() {
31  this->socket=socket;
32  this->name=name;
33 
34  bool blocking = true;
35  if (UDT::setsockopt(socket, 0, UDT_SNDSYN, &blocking, sizeof(bool))!= 0) {
36    fprintf(stderr,"UDT::setsockopt error (UDT_SNDSYN) %s\n",UDT::getlasterror().getErrorMessage());
37  }
38   
39  linger _linger;
40  _linger.l_onoff=1;
41  _linger.l_linger=180;
42 
43  if (UDT::setsockopt(socket, 0, UDT_LINGER, &_linger, sizeof(struct linger)) != 0)
44    fprintf(stderr,"UDT::setsockopt error (UDT_LINGER) %s\n",UDT::getlasterror().getErrorMessage());
45   
46  dialog = new QDialog();
47
48  dialog->setWindowTitle("log files");
49  QGridLayout *main_layout = new QGridLayout(dialog);
50  ok_button = new QPushButton("Ok", dialog);
51  log_text = new QTextEdit(dialog);
52  log_text->setReadOnly(true);
53  input_text = new QTextEdit(dialog);
54  input_text->setText("add your log comment here");
55  input_cleared = false;
56  ok_button->setEnabled(false);
57
58  main_layout->addWidget(log_text, 0, 0);
59  main_layout->addWidget(input_text, 1, 0);
60
61  QWidget *widget = new QWidget(dialog);
62  QFormLayout *formLayout = new QFormLayout(widget);
63  csv_combo = new QComboBox(widget);
64  formLayout->addRow(tr("save all log with following base time"), csv_combo);
65  csv_combo->addItem("(no base time)");
66  main_layout->addWidget(widget, 2, 0);
67  main_layout->addWidget(ok_button, 3, 0);
68
69  //connect for multithreaded stuffs
70  connect(ok_button, SIGNAL(clicked()), this, SLOT(save()),Qt::QueuedConnection);
71  connect(input_text, SIGNAL(cursorPositionChanged()), this,SLOT(clearInputText()),Qt::DirectConnection);
72  connect(this, SIGNAL(appendToLog(QString)), log_text, SLOT(append(QString)));
73
74  file_names = new QStringList();
75 
76  dialog->show();
77}
78
79file_ui::~file_ui() { 
80  delete dialog;
81}
82
83void file_ui::receive(void) {
84  char *recv_buf;
85  int bytesRead;
86  bool flag_new_seq = true;
87  QString folder_name;
88//ffprintf(stderr,stderr,"file_ui thread %x\n",thread());
89  while(1) {
90    // receive file info
91    recv_buf = (char *)malloc(1024);
92    bytesRead = UDT::recvmsg(socket, recv_buf, 1024);
93    if (bytesRead <= 0) {
94      free(recv_buf);
95      break;
96    }
97
98    int size;
99    memcpy(&size, &recv_buf[1], sizeof(int));
100    if (recv_buf[0] == FILE_INFO_BIG_ENDIAN)
101      size = qFromBigEndian(size);
102
103    // fprintf(stderr,"file_ui recu %i %x\n",bytesRead,recv_buf[0]);
104    if ((recv_buf[0]==FILE_INFO_LITTLE_ENDIAN || recv_buf[0]==FILE_INFO_BIG_ENDIAN) && size>0) {
105      if (flag_new_seq == true) {
106        // create directory for storage
107        QDateTime dateTime = QDateTime::currentDateTime();
108        folder_name = dateTime.toString("yyyyMMdd_hhmm") + "_" + name;
109        if (QDir().exists(folder_name) == true) {
110          folder_name = dateTime.toString("yyyyMMdd_hhmm_ss") + "_" + name;
111        }
112        QDir().mkdir(folder_name);
113
114        flag_new_seq = false;
115        appendToLog("Creating directory " + folder_name);
116      }
117
118      QString file_name=QString::fromAscii((const char *)&recv_buf[5], bytesRead - 5);
119      QString file_path=folder_name+"/"+file_name;
120      appendToLog(QString("receiving %1 (%2 bytes)").arg(file_name).arg(size));
121      QFile fichier(file_path);
122
123      if (!fichier.open(QIODevice::WriteOnly)) {
124        appendToLog("      could not write to file!");
125      } else {
126        // receive file
127        recv_buf = (char *)realloc((void *)recv_buf, size);
128        bytesRead = UDT::recvmsg(socket, recv_buf, size);
129        if (bytesRead != size) {
130          appendToLog(QString("      error receiving file! (%1/%2)").arg(bytesRead).arg(size));
131          free(recv_buf);
132          break;
133        } else {
134          appendToLog("      ok");
135        }
136
137        QDataStream stream(&fichier);
138        stream.writeRawData(recv_buf, size);
139        fichier.close();
140
141        addFile(file_path);
142      }
143
144      free(recv_buf);
145    } else if (recv_buf[0] == END_SENDING_FILES) {
146      //end ack
147      UDT::sendmsg(socket,&recv_buf[0],1);
148      endOfFiles();
149      UDT::close(socket);
150      fprintf(stderr,"disconnected from log files\n");
151      break;
152    }
153  }
154}
155
156void file_ui::addFile(QString file_path) {
157  // framework sends dbt file then txt file
158  // when we receive txt, we have both files
159  // and we can convert it to .csv
160  if (file_path.endsWith(".dbt") == true) {
161    QString name =
162        file_path.section('/', -1); // remove path for displaying on combobox
163    csv_combo->addItem(name.replace(QString(".dbt"), QString(".csv")));
164    file_names->append(file_path.replace(QString(".dbt"), QString(".csv")));
165  }
166
167  if (file_path.endsWith(".txt") == true) {
168    dbt2csv(file_path.replace(QString(".txt"), QString(".dbt")));
169  }
170}
171
172void file_ui::endOfFiles(void) {
173  ok_button->setEnabled(true);
174
175  qint64 max_file_size = 0;
176  for (int i = 0; i < file_names->count(); i++) {
177    QFileInfo info(file_names->at(i));
178    if (info.size() > max_file_size) {
179      max_file_size = info.size();
180      csv_combo->setCurrentIndex(i+1); // first item of combobox is already taken
181    }
182  }
183}
184
185void file_ui::dbt2csv(QString file_path) {
186  hdfile_t *dbtFile = NULL;
187  char *data;
188  QStringList data_type;
189
190  QString filename =file_path.section('/', -1); // remove path for displaying on logs
191  appendToLog(QString("converting %1 to csv").arg(filename));
192
193  // open csv file
194  QString csv_filename = file_path;
195  csv_filename.replace(QString(".dbt"), QString(".csv"));
196  QFile csv_file(csv_filename);
197
198  if (!csv_file.open(QIODevice::WriteOnly | QIODevice::Text)) {
199    appendToLog("      error opening csv file!");
200    return;
201  }
202  QTextStream out(&csv_file);
203
204  // open txt file
205  QString txt_filename = file_path;
206  txt_filename.replace(QString(".dbt"), QString(".txt"));
207  QFile txt_file(txt_filename);
208
209  if (!txt_file.open(QIODevice::ReadOnly | QIODevice::Text)) {
210    appendToLog("      error opening txt file!");
211    return;
212  }
213
214  // read txt file
215  QTextStream txt_in(&txt_file);
216  txt_in.readLine(); // time us
217  txt_in.readLine(); // time ns
218  while (1) {
219    if (txt_in.atEnd() == true)
220      break;
221    QString txt_line = txt_in.readLine();
222    data_type.append(txt_line.section("(",-1)); // on part de la fin pour trouver la premiere parenthese ouvrante
223    // fprintf(stderr,"type %s\n",txt_line.section("(",-1).toLocal8Bit().constData());
224  }
225  txt_file.close();
226
227  dbtFile = open_hdfile(file_path.toLocal8Bit().data(), READ_MODE);
228
229  if (!dbtFile) {
230    appendToLog("      error opening dbt file!");
231    return;
232  }
233  data = (char *)malloc(dbtFile->h.DataSize);
234  if (data == NULL) {
235    appendToLog("      error malloc!");
236    return;
237  }
238
239  bool dataWritten = false;
240  while (1) {
241    road_time_t time;
242    road_timerange_t tr = 0;
243    int offset = 0;
244    QTextStream csv_line;
245
246    if (read_hdfile(dbtFile, (void *)data, &time, &tr) == 0) {
247      break;
248    }
249    dataWritten = true;
250
251    out << time << "," << tr;
252    for (int i = 0; i < data_type.size(); i++) {
253      if (data_type.at(i) == "double)") {
254        double *value = (double *)(data + offset);
255        offset += sizeof(double);
256        out << "," << *value;
257      } else if (data_type.at(i) == "float)") {
258        float *value = (float *)(data + offset);
259        offset += sizeof(float);
260        out << "," << *value;
261      } else if (data_type.at(i) == "int8_t)") {
262        int8_t *value = (int8_t *)(data + offset);
263        offset += sizeof(int8_t);
264        out << "," << *value;
265      } else if (data_type.at(i) == "uint8_t)") {
266        uint8_t *value = (uint8_t *)(data + offset);
267        offset += sizeof(uint8_t);
268        out << "," << *value;
269      } else if (data_type.at(i) == "int16_t)") {
270        int16_t *value = (int16_t *)(data + offset);
271        offset += sizeof(int16_t);
272        out << "," << *value;
273      } else if (data_type.at(i) == "uint16_t)") {
274        uint16_t *value = (uint16_t *)(data + offset);
275        offset += sizeof(uint16_t);
276        out << "," << *value;
277      } else {
278        appendToLog(QString("      unhandled type: %1").arg(data_type.at(i)));
279      }
280    }
281
282    out << "\n";
283  }
284
285  if (!dataWritten) {
286    // empty file!
287    out << "0,0"; // timr
288    for (int i = 0; i < data_type.size(); i++) {
289      out << ",0";
290    }
291    out << "\n";
292  }
293
294  csv_file.close();
295  close_hdfile(dbtFile);
296  if (data != NULL)
297    free(data);
298
299  appendToLog("      ok");
300}
301
302void file_ui::clearInputText(void) {
303  if (input_cleared == false) {
304    input_cleared = true;
305    input_text->clear();
306  }
307}
308
309void file_ui::save(void) {
310  save_comment();
311  if (csv_combo->currentIndex() != 0) {
312    save_csv();
313    save_txt();
314  }
315
316  emit finished();
317}
318
319void file_ui::save_comment(void) {
320  QString folder_name = file_names->at(0).section('/', 0, -2);
321
322  QString filename = folder_name + "/commentaire.txt";
323  QFile file(filename);
324  if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
325    fprintf(stderr,"file_ui::save_comment: erreur ouverture fichier %s\n",
326           filename.toLocal8Bit().constData());
327  QTextStream out(&file);
328
329  out << input_text->toPlainText();
330  file.close();
331}
332
333void file_ui::save_csv(void) {
334  // global csv file
335  QString folder_name = file_names->at(0).section('/', 0, -2);
336  QString filename = folder_name + "/all_logs.csv";
337  QFile global_file(filename);
338  if (!global_file.open(QIODevice::WriteOnly | QIODevice::Text))
339    fprintf(stderr,"file_ui::save_csv: erreur ouverture fichier %s\n",
340           filename.toLocal8Bit().constData());
341  QTextStream out(&global_file);
342
343  // reference csv file
344  filename = file_names->at(csv_combo->currentIndex() - 1);
345  QFile ref_file(filename);
346  // fprintf(stderr,"file_ui::save_csv: ref %s\n",filename.toLocal8Bit().constData());
347  if (!ref_file.open(QIODevice::ReadOnly | QIODevice::Text))
348    fprintf(stderr,"file_ui::save_csv: erreur ouverture ficher %s\n",
349           filename.toLocal8Bit().constData());
350
351  // other csv files
352  int j = 0;
353  QFile m_file[file_names->count() - 1];
354  QTextStream m_in[file_names->count() - 1];
355  for (int i = 0; i < file_names->count(); i++) {
356    if (i == csv_combo->currentIndex() - 1)
357      continue;
358    filename = file_names->at(i);
359    m_file[j].setFileName(filename);
360    if (!m_file[j].open(QIODevice::ReadOnly | QIODevice::Text))
361      fprintf(stderr,"file_ui::save_csv: erreur ouverture ficher %s\n",
362             filename.toLocal8Bit().constData());
363    m_in[j].setDevice(&m_file[j]);
364    j++;
365  }
366
367  // init
368  QTextStream ref_in(&ref_file);
369  QString m_line[file_names->count() - 1];
370  QString m_line_prev[file_names->count() - 1];
371  for (int i = 0; i < file_names->count() - 1; i++) {
372    m_line[i] = m_in[i].readLine();
373    m_line_prev[i] = m_line[i];
374  }
375
376  // organize csv files in one file
377  while (1) {
378    if (ref_in.atEnd() == true)
379      break;
380    QString ref_line = ref_in.readLine();
381
382    qint64 ref_us = ref_line.section(',', 0, 0).toLongLong();
383    int ref_ns = ref_line.section(',', 1, 1).toInt();
384    // fprintf(stderr,"ref %lld %i\n",ref_us,ref_ns);
385
386    for (int i = 0; i < file_names->count() - 1; i++) {
387      qint64 csv_us = m_line[i].section(',', 0, 0).toLongLong();
388      int csv_ns = m_line[i].section(',', 1, 1).toInt();
389      // fprintf(stderr,"m %lld %i\n",csv_us,csv_ns);
390
391      while (is_greater(ref_us, csv_us, ref_ns, csv_ns) == true) {
392        m_line_prev[i] = m_line[i];
393        if (m_in[i].atEnd() == true)
394          break;
395        m_line[i] = m_in[i].readLine();
396        csv_us = m_line[i].section(',', 0, 0).toLongLong();
397        csv_ns = m_line[i].section(',', 1, 1).toInt();
398        // fprintf(stderr,"m %lld %i\n",csv_us,csv_ns);
399      }
400      csv_us = m_line_prev[i].section(',', 0, 0).toLongLong();
401      csv_ns = m_line_prev[i].section(',', 1, 1).toInt();
402      // fprintf(stderr,"m ok %lld %i\n",csv_us,csv_ns);
403
404      ref_line += "," + m_line_prev[i].section(',', 2);
405    }
406
407    out << ref_line << "\n";
408  }
409
410  global_file.close();
411  ref_file.close();
412  for (int i = 0; i < file_names->count() - 1; i++)
413    m_file[i].close();
414}
415
416void file_ui::save_txt(void) {
417  // global txt file
418  QString folder_name = file_names->at(0).section('/', 0, -2);
419  QString filename = folder_name + "/all_logs.txt";
420  QFile global_file(filename);
421  if (!global_file.open(QIODevice::WriteOnly | QIODevice::Text))
422    fprintf(stderr,"file_ui::save_txt: erreur ouverture ficher %s\n",
423           filename.toLocal8Bit().constData());
424  QTextStream out(&global_file);
425
426  // reference txt file
427  filename = file_names->at(csv_combo->currentIndex() - 1);
428  filename.replace(QString(".csv"), QString(".txt"));
429  QFile ref_file(filename);
430  if (!ref_file.open(QIODevice::ReadOnly | QIODevice::Text))
431    fprintf(stderr,"file_ui::save_txt: erreur ouverture ficher %s\n",
432           filename.toLocal8Bit().constData());
433
434  QTextStream ref_in(&ref_file);
435  QString current_line = ref_in.readLine();
436  int nb_lines = 1;
437  while (current_line != NULL) {
438    out << current_line << "\n";
439    ;
440    current_line = ref_in.readLine();
441    nb_lines++;
442  }
443
444  // other txt files
445  for (int i = 0; i < file_names->count(); i++) {
446    if (i == csv_combo->currentIndex() - 1)
447      continue;
448    filename = file_names->at(i);
449    filename.replace(QString(".csv"), QString(".txt"));
450    QFile txt_file(filename);
451    if (!txt_file.open(QIODevice::ReadOnly | QIODevice::Text))
452      fprintf(stderr,"file_ui::save_txt: erreur ouverture ficher %s\n",
453             filename.toLocal8Bit().constData());
454    QTextStream txt_in(&txt_file);
455    txt_in.readLine(); // time us
456    txt_in.readLine(); // time ns
457    current_line = txt_in.readLine();
458    while (current_line != NULL) {
459      out << nb_lines << ":" << current_line.section(':', 1) << "\n";
460      ;
461      current_line = txt_in.readLine();
462      nb_lines++;
463    }
464    txt_file.close();
465  }
466  global_file.close();
467  ref_file.close();
468}
469
470bool file_ui::is_greater(qint64 ref_us, qint64 csv_us, int ref_ns, int csv_ns) {
471  if (ref_us == csv_us) {
472    if (ref_ns > csv_ns) {
473      return true;
474    } else {
475      return false;
476    }
477  }
478  if (ref_us > csv_us) {
479    return true;
480  } else {
481    return false;
482  }
483}
Note: See TracBrowser for help on using the repository browser.