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

Last change on this file since 9 was 9, checked in by Sanahuja Guillaume, 5 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.