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

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