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

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

sources reformatted with flair-format-dir script

File size: 9.2 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 "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
27#include <arpa/inet.h>
28#else
29#include <winsock2.h>
30#include <ws2tcpip.h>
31#endif
32
33using namespace std;
34
35Manager::Manager(QString name, int port) : QWidget() {
36 qRegisterMetaType<QModelIndex>("QModelIndex"); // pour le file ui??
37 this->name = name;
38
39 setWindowTitle(name);
40
41 // manager layout
42 managerLayout = new QVBoxLayout;
43 setLayout(managerLayout);
44
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;
51
52 // layout boutons
53 button_layout = new QGridLayout();
54 managerLayout->addLayout(button_layout);
55
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);
65
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()));
70
71 UDT::startup();
72 serv = UDT::socket(AF_INET, SOCK_DGRAM, 0);
73
74 // for non blocking accept
75 bool blocking = false;
76 UDT::setsockopt(serv, 0, UDT_RCVSYN, &blocking, sizeof(bool));
77
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);
83
84 if (UDT::ERROR == UDT::bind(serv, (sockaddr *)&my_addr, sizeof(my_addr))) {
85 printf("bind error, %s\n", UDT::getlasterror().getErrorMessage());
86 }
87
88 if (UDT::ERROR == UDT::listen(serv, 1)) {
89 printf("listen error, %s\n", UDT::getlasterror().getErrorMessage());
90 }
91
92 QTimer *timer = new QTimer(this);
93 connect(timer, SIGNAL(timeout()), this, SLOT(acceptConnections()));
94 timer->start(20);
95}
96
97Manager::~Manager() {
98 emit killUdtSockets();
99
100 // delete main_layout;
101 UDT::cleanup();
102}
103
104void Manager::acceptConnections(void) {
105 static UDTSOCKET first_socket = 0;
106 UDTSOCKET socket;
107
108 sockaddr_in their_addr;
109 int namelen = sizeof(their_addr);
110
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;
124 } else {
125 QThread *thread = new QThread(this);
126 UdtSocket *new_udt = new UdtSocket(first_socket, socket, name);
127 new_udt->moveToThread(thread);
128
129 newConnection(new_udt);
130
131 connect(this, SIGNAL(killUdtSockets()), thread, SLOT(quit()));
132 connect(this, SIGNAL(killUdtSockets()), new_udt, SLOT(kill()),
133 Qt::BlockingQueuedConnection);
134
135 connect(thread, SIGNAL(started()), new_udt, SLOT(handleConnections()));
136
137 thread->start();
138 first_socket = 0;
139 }
140 }
141}
142
143void Manager::newConnection(UdtSocket *socket) {
144
145 // no tabs to 2 tabs
146 if (connectionsLayout.count() == 1) {
147 tabBar->addTab(hiddenTabName);
148 currentTab = 0;
149 connectionsWidget.at(0)->show();
150 }
151
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()));
162
163 // widget
164 QWidget *newWidget = new QWidget();
165 connectionsWidget.append(newWidget);
166 newWidget->setLayout(newLayout->getQGridLayout());
167 managerLayout->insertWidget(1, newWidget);
168 newWidget->hide();
169
170 if (connectionsLayout.count() == 1) { // first connection
171 newWidget->show();
172 } else { // add a tab for the new connection
173 tabBar->addTab("unknown");
174 }
175}
176
177void Manager::tabBarCurrentChanged(int index) {
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 }
186}
187
188void Manager::tabName(QString name) {
189 int index = connectionsLayout.indexOf((ConnectionLayout *)sender());
190 if (tabBar->count() == 0) {
191 hiddenTabName = name;
192 } else {
193 tabBar->setTabText(index, name);
194 }
195}
196
197void Manager::layoutDestroyed(QObject *obj) {
198 int index = connectionsLayout.indexOf((ConnectionLayout *)obj);
199
200 if (tabBar->count() > 1) {
201 tabBar->removeTab(index);
202 }
203
204 delete connectionsWidget.at(index);
205 connectionsWidget.removeAt(index);
206 connectionsLayout.removeOne((ConnectionLayout *)obj);
207
208 if (connectionsLayout.count() == 1) {
209 hiddenTabName = tabBar->tabText(0);
210 tabBar->removeTab(0);
211 }
212}
213
214void Manager::load(void) {
215 QString dir_name =
216 QFileDialog::getExistingDirectory(this, "Select a directory", 0, 0);
217
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 }
230
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;
245 }
246 }
247}
248
249void Manager::save(void) {
250 bool isUptodate = true;
251
252 for (int i = 0; i < connectionsLayout.count(); i++) {
253 if (!connectionsLayout.at(i)->IsUptodate()) {
254 isUptodate = false;
255 break;
256 }
257 }
258
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();
266
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;
277 }
278 }
279
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);
288
289 for (int i = 0; i < connectionsLayout.count(); i++) {
290 QDomDocument *xml = new QDomDocument("remote_ui_xml");
291
292 connectionsLayout.at(i)->GetFullXml((QDomElement *)xml);
293
294 QFile fichier(dir_name + "/" + connectionsLayout.at(i)->getRemoteName() +
295 ".xml");
296 QString write_doc = (xml->ownerDocument()).toString();
297
298 if (!fichier.open(QIODevice::WriteOnly)) {
299 fichier.close();
300 QMessageBox::critical(this, "Error", "Enable to write XML");
301 continue;
302 }
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();
307
308 delete xml;
309 }
310
311 QMessageBox::information(this, "save all", "saved to ./" + dir_name);
312}
313
314void Manager::send(void) {
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());
319
320 connectionsLayout.at(i)->XmlToSend(doc);
321 }
322}
323
324void Manager::reset() {
325 for (int i = 0; i < connectionsLayout.count(); i++)
326 connectionsLayout.at(i)->ResetAllChilds();
327}
Note: See TracBrowser for help on using the repository browser.