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

Last change on this file since 10 was 10, checked in by Sanahuja Guillaume, 8 years ago

lic

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