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

Last change on this file since 9 was 9, checked in by Sanahuja Guillaume, 7 years ago

gcs

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