source: flair-src/trunk/tools/FlairGCS/src/Manager.cpp @ 15

Last change on this file since 15 was 15, checked in by Bayard Gildas, 5 years ago

sources reformatted with flair-format-dir script

File size: 9.2 KB
RevLine 
[10]1// %flair:license{
[15]2// This file is part of the Flair framework distributed under the
3// CECILL-C License, Version 1.0.
[10]4// %flair:license}
[9]5#include "Manager.h"
6#include "UdtSocket.h"
7#include "ConnectionLayout.h"
8#include "communication.h"
9#include <QDate>
10#include <QFileDialog>
11#include <QMessageBox>
12#include <QPushButton>
13#include <QTabBar>
14#include <QTimer>
15#include <QThread>
16#include <QTextStream>
17#include <QVBoxLayout>
18#include <QModelIndex>
19//#include <qmetatype.h>
20#include <qendian.h>
21#include <iostream>
22#include <string>
23#include <fstream>
24#include <stdio.h>
25
26#ifndef WIN32
[15]27#include <arpa/inet.h>
[9]28#else
[15]29#include <winsock2.h>
30#include <ws2tcpip.h>
[9]31#endif
32
33using namespace std;
34
[15]35Manager::Manager(QString name, int port) : QWidget() {
36  qRegisterMetaType<QModelIndex>("QModelIndex"); // pour le file ui??
37  this->name = name;
[9]38
[15]39  setWindowTitle(name);
[9]40
[15]41  // manager layout
42  managerLayout = new QVBoxLayout;
43  setLayout(managerLayout);
[9]44
[15]45  // tab bar for multiple connections
46  tabBar = new QTabBar();
47  managerLayout->addWidget(tabBar);
48  connect(tabBar, SIGNAL(currentChanged(int)), this,
49          SLOT(tabBarCurrentChanged(int)));
50  currentTab = 0;
[9]51
[15]52  // layout boutons
53  button_layout = new QGridLayout();
54  managerLayout->addLayout(button_layout);
[9]55
[15]56  // boutons du button_Layout
57  send_button = new QPushButton("apply all");
58  reset_button = new QPushButton("reset all");
59  load_button = new QPushButton("load all locally");
60  save_button = new QPushButton("save all locally");
61  button_layout->addWidget(send_button, 0, 0);
62  button_layout->addWidget(reset_button, 0, 1);
63  button_layout->addWidget(load_button, 0, 2);
64  button_layout->addWidget(save_button, 0, 3);
[9]65
[15]66  connect(send_button, SIGNAL(clicked(bool)), this, SLOT(send()));
67  connect(reset_button, SIGNAL(clicked(bool)), this, SLOT(reset()));
68  connect(load_button, SIGNAL(clicked(bool)), this, SLOT(load()));
69  connect(save_button, SIGNAL(clicked(bool)), this, SLOT(save()));
[9]70
[15]71  UDT::startup();
72  serv = UDT::socket(AF_INET, SOCK_DGRAM, 0);
[9]73
[15]74  // for non blocking accept
75  bool blocking = false;
76  UDT::setsockopt(serv, 0, UDT_RCVSYN, &blocking, sizeof(bool));
[9]77
[15]78  sockaddr_in my_addr;
79  my_addr.sin_family = AF_INET;
80  my_addr.sin_port = htons(port);
81  my_addr.sin_addr.s_addr = INADDR_ANY;
82  memset(&(my_addr.sin_zero), '\0', 8);
[9]83
[15]84  if (UDT::ERROR == UDT::bind(serv, (sockaddr *)&my_addr, sizeof(my_addr))) {
85    printf("bind error, %s\n", UDT::getlasterror().getErrorMessage());
86  }
[9]87
[15]88  if (UDT::ERROR == UDT::listen(serv, 1)) {
89    printf("listen error, %s\n", UDT::getlasterror().getErrorMessage());
90  }
[9]91
[15]92  QTimer *timer = new QTimer(this);
93  connect(timer, SIGNAL(timeout()), this, SLOT(acceptConnections()));
94  timer->start(20);
[9]95}
96
97Manager::~Manager() {
[15]98  emit killUdtSockets();
[9]99
[15]100  // delete main_layout;
101  UDT::cleanup();
[9]102}
103
104void Manager::acceptConnections(void) {
[15]105  static UDTSOCKET first_socket = 0;
106  UDTSOCKET socket;
[9]107
[15]108  sockaddr_in their_addr;
109  int namelen = sizeof(their_addr);
[9]110
[15]111  if (UDT::INVALID_SOCK ==
112      (socket = UDT::accept(serv, (sockaddr *)&their_addr, &namelen))) {
113    if (UDT::getlasterror().getErrorCode() != 6002)
114      printf("accept: %s, code %i\n", UDT::getlasterror().getErrorMessage(),
115             UDT::getlasterror().getErrorCode());
116    return;
117  } else {
118    printf("connected to %s:%i\n", inet_ntoa(their_addr.sin_addr),
119           their_addr.sin_port);
120
121    if (!first_socket) {
122      first_socket = socket;
123      return;
[9]124    } else {
[15]125      QThread *thread = new QThread(this);
126      UdtSocket *new_udt = new UdtSocket(first_socket, socket, name);
127      new_udt->moveToThread(thread);
[9]128
[15]129      newConnection(new_udt);
[9]130
[15]131      connect(this, SIGNAL(killUdtSockets()), thread, SLOT(quit()));
132      connect(this, SIGNAL(killUdtSockets()), new_udt, SLOT(kill()),
133              Qt::BlockingQueuedConnection);
[9]134
[15]135      connect(thread, SIGNAL(started()), new_udt, SLOT(handleConnections()));
[9]136
[15]137      thread->start();
138      first_socket = 0;
[9]139    }
[15]140  }
[9]141}
142
[15]143void Manager::newConnection(UdtSocket *socket) {
[9]144
[15]145  // no tabs to 2 tabs
146  if (connectionsLayout.count() == 1) {
147    tabBar->addTab(hiddenTabName);
148    currentTab = 0;
149    connectionsWidget.at(0)->show();
150  }
[9]151
[15]152  // layout utilisateur
153  ConnectionLayout *newLayout = new ConnectionLayout(socket, "interface");
154  connectionsLayout.append(newLayout);
155  connect(newLayout, SIGNAL(setRemoteName(QString)), this,
156          SLOT(tabName(QString)));
157  connect(socket, SIGNAL(dataReady(char *, int)), newLayout,
158          SLOT(receive(char *, int)));
159  connect(newLayout, SIGNAL(destroyed(QObject *)), this,
160          SLOT(layoutDestroyed(QObject *)));
161  connect(socket, SIGNAL(destroyed()), newLayout, SLOT(deleteLater()));
[9]162
[15]163  // widget
164  QWidget *newWidget = new QWidget();
165  connectionsWidget.append(newWidget);
166  newWidget->setLayout(newLayout->getQGridLayout());
167  managerLayout->insertWidget(1, newWidget);
168  newWidget->hide();
[9]169
[15]170  if (connectionsLayout.count() == 1) { // first connection
171    newWidget->show();
172  } else { // add a tab for the new connection
173    tabBar->addTab("unknown");
174  }
[9]175}
176
177void Manager::tabBarCurrentChanged(int index) {
[15]178  if (index >= 0) {
179    connectionsWidget.at(currentTab)->hide();
180    connectionsWidget.at(index)->show();
181    currentTab = index;
182  } else {
183    currentTab = 0;
184    connectionsWidget.at(0)->show();
185  }
[9]186}
187
188void Manager::tabName(QString name) {
[15]189  int index = connectionsLayout.indexOf((ConnectionLayout *)sender());
190  if (tabBar->count() == 0) {
191    hiddenTabName = name;
192  } else {
193    tabBar->setTabText(index, name);
194  }
[9]195}
196
[15]197void Manager::layoutDestroyed(QObject *obj) {
198  int index = connectionsLayout.indexOf((ConnectionLayout *)obj);
[9]199
[15]200  if (tabBar->count() > 1) {
201    tabBar->removeTab(index);
202  }
[9]203
[15]204  delete connectionsWidget.at(index);
205  connectionsWidget.removeAt(index);
206  connectionsLayout.removeOne((ConnectionLayout *)obj);
[9]207
[15]208  if (connectionsLayout.count() == 1) {
209    hiddenTabName = tabBar->tabText(0);
210    tabBar->removeTab(0);
211  }
[9]212}
213
214void Manager::load(void) {
[15]215  QString dir_name =
216      QFileDialog::getExistingDirectory(this, "Select a directory", 0, 0);
[9]217
[15]218  if (dir_name != "") {
219    for (int i = 0; i < connectionsLayout.count(); i++) {
220      QFile *file;
221      file = new QFile(dir_name + "/" +
222                       connectionsLayout.at(i)->getRemoteName() + ".xml");
223      if (!file->open(QIODevice::ReadOnly | QIODevice::Text)) {
224        QMessageBox::warning(this, "Warning",
225                             "Enable to load " +
226                                 connectionsLayout.at(i)->getRemoteName() +
227                                 ".xml");
228        continue;
229      }
[9]230
[15]231      QDomDocument doc;
232      QString errorMsg;
233      int errorLine;
234      int errorColumn;
235      if (!doc.setContent(file, &errorMsg, &errorLine, &errorColumn)) {
236        QMessageBox::critical(
237            this, "Error",
238            "unable to read " + connectionsLayout.at(i)->getRemoteName() +
239                ".xml" + " (" + errorMsg + " at " + QString::number(errorLine) +
240                "," + QString::number(errorColumn) + ")");
241      } else {
242        connectionsLayout.at(i)->LoadXml(doc);
243      }
244      delete file;
[9]245    }
[15]246  }
[9]247}
248
249void Manager::save(void) {
[15]250  bool isUptodate = true;
[9]251
[15]252  for (int i = 0; i < connectionsLayout.count(); i++) {
253    if (!connectionsLayout.at(i)->IsUptodate()) {
254      isUptodate = false;
255      break;
[9]256    }
[15]257  }
[9]258
[15]259  if (!isUptodate) {
260    QMessageBox msgBox;
261    msgBox.setText("There are pending modifications");
262    msgBox.setInformativeText("Apply and save?");
263    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
264    msgBox.setDefaultButton(QMessageBox::Yes);
265    int ret = msgBox.exec();
[9]266
[15]267    switch (ret) {
268    case QMessageBox::Yes:
269      send();
270      break;
271    case QMessageBox::Cancel:
272      return;
273      break;
274    default:
275      // should never be reached
276      break;
[9]277    }
[15]278  }
[9]279
[15]280  // create dirctory for storage
281  QDateTime dateTime = QDateTime::currentDateTime();
282  QString dir_name =
283      "configs_" + dateTime.toString("yyyyMMdd_hhmm") + "_" + name;
284  if (QDir().exists(dir_name) == true) {
285    dir_name = "configs_" + dateTime.toString("yyyyMMdd_hhmm_ss") + "_" + name;
286  }
287  QDir().mkdir(dir_name);
[9]288
[15]289  for (int i = 0; i < connectionsLayout.count(); i++) {
290    QDomDocument *xml = new QDomDocument("remote_ui_xml");
[9]291
[15]292    connectionsLayout.at(i)->GetFullXml((QDomElement *)xml);
[9]293
[15]294    QFile fichier(dir_name + "/" + connectionsLayout.at(i)->getRemoteName() +
295                  ".xml");
296    QString write_doc = (xml->ownerDocument()).toString();
[9]297
[15]298    if (!fichier.open(QIODevice::WriteOnly)) {
299      fichier.close();
300      QMessageBox::critical(this, "Error", "Enable to write XML");
301      continue;
[9]302    }
[15]303    QTextStream stream(&fichier);
304    stream << write_doc; // On utilise l'opérateur << pour écrire write_doc dans
305                         // le document XML.
306    fichier.close();
[9]307
[15]308    delete xml;
309  }
310
311  QMessageBox::information(this, "save all", "saved to ./" + dir_name);
[9]312}
313
314void Manager::send(void) {
[15]315  for (int i = 0; i < connectionsLayout.count(); i++) {
316    QDomDocument doc("remote_ui_xml");
317    connectionsLayout.at(i)->GetUpdateXml((QDomElement *)&doc);
318    // printf("merge\n%s\n",doc.toString().toLocal8Bit().constData());
[9]319
[15]320    connectionsLayout.at(i)->XmlToSend(doc);
321  }
[9]322}
323
324void Manager::reset() {
[15]325  for (int i = 0; i < connectionsLayout.count(); i++)
326    connectionsLayout.at(i)->ResetAllChilds();
[9]327}
Note: See TracBrowser for help on using the repository browser.