1 /***************************************************************************
2 * Copyright (C) 2007 by David Cuadrado *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
21 #include "networkhandler.h"
24 #include <QXmlStreamReader>
25 #include <QXmlStreamWriter>
26 #include <QTemporaryFile>
29 #include <dcore/debug.h>
35 #include <yamf/model/command/processor.h>
36 #include <yamf/model/command/base.h>
39 #include "dash/project.h"
41 #include "dash/network/socket.h"
42 #include "dash/network/filereceiver.h"
44 #include "dash/network/package/newproject.h"
45 #include "dash/network/package/connect.h"
46 #include "dash/network/package/listprojects.h"
47 #include "dash/network/package/openproject.h"
49 #include "dash/network/parser/ackparser.h"
51 #include "dash/network/parser/projectlistparser.h"
52 #include "dash/network/parser/projectparser.h"
54 #include "projectmanager.h"
56 #include "ui_displayprojects.h"
58 #include "comm/comm.h"
59 #include "comm/chatwindow.h"
61 NetworkHandler::NetworkHandler(ProjectManager
*manager
, QObject
*parent
) : QObject(parent
), m_manager(manager
), m_socket(new Dash::Network::Socket
), m_dispatcher(new Dash::Network::Package::Dispatcher
), m_waitingResponse(false)
63 m_processor
= new YAMF::Command::Processor(manager
->project());
64 m_socket
->addObserver(this);
65 m_receiver
= new Dash::Network::FileReceiver
;
66 m_socket
->addObserver(m_receiver
);
68 m_comm
= new Comm(this);
71 connect(m_receiver
, SIGNAL(finished(const QString
&)), this, SLOT(onReceiverFinished(const QString
&)));
75 NetworkHandler::~NetworkHandler()
83 void NetworkHandler::connectToHost(const QString
&host
, quint16 port
, const QString
&login
, const QString
&password
)
87 m_socket
->connectToHost(host
, port
);
88 Dash::Network::Package::Connect
cnx(login
, password
, 0);
89 m_socket
->send(cnx
.toString().toLocal8Bit());
92 bool NetworkHandler::send(const QString
&xml
)
95 if( !m_sign
.isEmpty() )
97 QXmlStreamReader
reader(xml
);
98 QXmlStreamWriter
writer(&tosend
);
101 while( ! reader
.atEnd() )
105 writer
.writeCurrentToken(reader
);
106 if( reader
.tokenType() == QXmlStreamReader::StartElement
&& !isRoot
)
108 dfDebug
<< "Writing sing on " << reader
.name().toString();
109 writer
.writeAttribute("sign", m_sign
);
119 dfDebug
<< "SENDING: " << tosend
.left(100) << " SIGN IS : " << m_sign
;
121 return m_socket
->send(tosend
.toLocal8Bit());
124 void NetworkHandler::addObserver(Dash::Network::Package::Observer
*observer
)
126 m_dispatcher
->addObserver(observer
);
129 void NetworkHandler::removeObserver(Dash::Network::Package::Observer
*observer
)
131 m_dispatcher
->removeObserver(observer
);
134 void NetworkHandler::execute(YAMF::Command::Base
*cmd
)
136 bool isEmpty
= m_commands
.isEmpty();
138 dfDebug
<< "ENCOLANDO: " << cmd
->toXml().left(100);
140 m_commands
.enqueue(cmd
);
141 if( isEmpty
&& !m_waitingResponse
&& !m_sign
.isEmpty() )
143 m_waitingResponse
= send(cmd
->toXml());
145 if( !m_waitingResponse
)
147 m_commands
.dequeue();
152 void NetworkHandler::newProject(const ProjectParams
*params
)
154 Dash::Network::Package::NewProject
newProjectPackage(params
->projectName
, params
->author
, params
->description
);
155 this->send(newProjectPackage
.toString());
158 void NetworkHandler::openProject()
160 Dash::Network::Package::ListProjects list
;
161 this->send(list
.toString());
164 void NetworkHandler::openProject(const QString
&projectName
)
166 m_currentPackage
= "openproject";
167 Dash::Network::Package::OpenProject
project(projectName
);
168 this->send(project
.toString());
171 bool NetworkHandler::isOpen() const
173 return m_socket
->state() == QAbstractSocket::ConnectedState
;
176 bool NetworkHandler::isValid() const
178 return this->isOpen() && !m_sign
.isEmpty();
181 void NetworkHandler::showChatWindow()
185 m_comm
->chatWindow()->show();
189 DGui::Osd::self()->display(tr("You are not authenticated."), DGui::Osd::Error
);
193 void NetworkHandler::readed(const QString
&txt
)
195 dfDebug
<< "READED: " << txt
.left(100);
200 QXmlStreamReader
reader(txt
);
201 while( !reader
.atEnd() )
203 if( reader
.readNext() == QXmlStreamReader::StartElement
)
205 root
= reader
.name().toString();
212 dWarning() << "Invalid package: " << txt
.left(100)+"...."+txt
.right(100);
213 dWarning() << "Error was: " << reader
.errorString();
218 if( !root
.isEmpty() )
222 Dash::Network::Parser::AckParser parser
;
223 if( parser
.parse(txt
) )
225 m_sign
= parser
.sign();
226 DGui::Osd::self()->display(parser
.motd(), DGui::Osd::Info
);
228 if( !m_commands
.isEmpty() )
230 m_waitingResponse
= true;
231 send(m_commands
.first()->toXml());
235 else if( root
== "command" )
237 D_SHOW_VAR(m_commands
.size());
238 bool executed
= false;
240 if( m_waitingResponse
&& !m_commands
.isEmpty() )
242 m_waitingResponse
= false;
244 QXmlStreamReader
reader(txt
);
248 QString sign
= reader
.attributes().value("sign").toString();
252 m_manager
->setLocal(true);
253 m_commands
.dequeue()->redo(); // FIXME: add to stack?
254 m_manager
->setLocal(false);
258 if( ! m_commands
.isEmpty() )
260 m_waitingResponse
= true;
261 send(m_commands
.first()->toXml());
266 if( !executed
) // External command
268 m_manager
->setLocal(true);
269 m_processor
->execute(txt
);
270 m_manager
->setLocal(false);
273 else if( root
== "projectlist" )
275 Dash::Network::Parser::ProjectList projectList
;
277 if( projectList
.parse(txt
) )
280 Ui::DisplayProjects ui
;
283 foreach( Dash::Network::Parser::ProjectList::Project p
, projectList
.projects())
285 QTreeWidgetItem
*item
= new QTreeWidgetItem(ui
.projects
);
286 item
->setText(0, p
.name
);
287 item
->setText(1, p
.author
);
288 item
->setText(2, p
.description
);
291 if( choose
.exec() == QDialog::Accepted
)
293 if( QTreeWidgetItem
*ci
= ui
.projects
->currentItem() )
295 QString projectName
= ci
->text(0);
297 openProject(projectName
);
303 DGui::Osd::self()->display(QObject::tr("Error displaying the project list"), DGui::Osd::Error
);
306 else if( root
== "project" ) // FIXME: Remove
309 Dash::Network::Parser::Project projectParser
;
313 if( projectParser
.parse(txt
) && file
.open() )
315 file
.write(projectParser
.projectData());
318 m_manager
->setLocal(true);
319 m_manager
->loadProject(file
.fileName());
320 m_manager
->setLocal(false);
324 DGui::Osd::self()->display(QObject::tr("Error loading project"), DGui::Osd::Error
);
327 else if( root
== "transfer" )
329 QXmlStreamReader
reader(txt
);
330 while(! reader
.atEnd() )
332 if( reader
.readNext() == QXmlStreamReader::StartElement
)
334 int bytes
= reader
.attributes().value("bytes").toString().toInt();
336 m_socket
->setFormat(Dash::Network::Socket::Binary
);
337 m_receiver
->start(bytes
);
341 else if( root
== "connected" )
343 QXmlStreamReader
reader(txt
);
345 while(! reader
.atEnd() )
347 if( reader
.readNext() == QXmlStreamReader::StartElement
)
349 if(reader
.name() == "user")
351 logins
<< reader
.attributes().value("login").toString();
355 m_comm
->chatWindow()->addUsers(logins
);
357 else if( root
== "disconnected" )
361 QXmlStreamReader
reader(txt
);
362 while(! reader
.atEnd() )
364 if( reader
.readNext() == QXmlStreamReader::StartElement
)
366 if(reader
.name() == "user")
368 login
= reader
.attributes().value("login").toString();
374 m_comm
->chatWindow()->removeUser(login
);
378 m_dispatcher
->addSource(root
, txt
);
379 m_dispatcher
->process();
384 void NetworkHandler::dataReaded(const QByteArray
&data
)
393 void NetworkHandler::onReceiverFinished(const QString
&fileName
)
395 m_socket
->setFormat(Dash::Network::Socket::Text
);
397 dfDebug
<< m_currentPackage
<< " file: " << fileName
;
399 if( m_currentPackage
== "openproject" )
401 m_manager
->setLocal(true);
403 qDebug() << QFile::exists(fileName
);
405 if( !m_manager
->loadProject(fileName
) )
407 qFatal("Cannot load the project!");
409 m_manager
->setLocal(false);
410 QFile::remove(fileName
);