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 ***************************************************************************/
25 #include <QXmlStreamReader>
27 #include <yamf/model/command/processor.h>
29 #include "dashserver/connection.h"
30 #include "dashserver/logger.h"
31 #include "dashserver/xdbms/manager.h"
33 #include "dash/projectsaver.h"
34 #include "dash/network/package/transfer.h"
37 #include "commandprocessor.h"
39 #include <dcore/debug.h>
41 namespace DashServer
{
44 struct Project::Private
46 Private(Project
*q
) : q(q
), initialized(false) {}
50 CommandProcessor
*processor
;
52 QSet
<DashServer::Connection
*> connections
;
54 QHash
<QString
, Member
*> members
;
60 void Project::Private::loadMembers()
64 QList
<XDBMS::Object
*> objects
= q
->objects();
66 foreach(XDBMS::Object
*obj
, objects
)
68 if( obj
->klass() == "member" )
70 Member
*member
= static_cast<Member
*>(obj
);
71 members
[member
->id()] = member
;
78 Project::Project(QObject
*parent
) : Dash::Project(parent
), XDBMS::Object(), d(new Private(this))
80 d
->processor
= new CommandProcessor(this);
92 void Project::execute(const QString
&xml
, DashServer::Connection
*source
)
94 if( d
->connections
.contains(source
) )
99 QXmlStreamReader
reader(xml
);
100 while(!reader
.atEnd())
102 if( reader
.readNext() == QXmlStreamReader::StartElement
)
104 if( reader
.name() == "command" )
106 cmdname
= reader
.attributes().value("name").toString();
113 Member
*member
= d
->members
.value(source
->user()->login());
114 int part
= Project::partFromCommand(cmdname
);
116 if( ! member
->canWriteOn(part
) )
118 DashServer::Logger::self()->info(QString("Permission denied: User %1 trying to write on %2").arg(member
->id(), Project::partName(part
)));
120 source
->sendToClient( "<command />\n", true );
121 source
->sendError(tr("Permission denied"), Dash::Network::Package::Error::Err
);
125 if( d
->processor
->execute(xml
) )
127 QString tosend
= source
->signXml(xml
);
129 foreach(DashServer::Connection
*cnx
, d
->connections
)
131 if( d
->members
[cnx
->user()->login()]->canReadOn(part
) )
133 cnx
->sendToClient( tosend
, false );
139 source
->sendToClient( "<command />", true ); // FIXME: create a package
144 qWarning("INVALID SOURCE");
148 void Project::addClient(DashServer::Connection
*cnx
)
150 d
->connections
<< cnx
;
153 void Project::removeClient(DashServer::Connection
*client
)
155 d
->connections
.remove(client
);
157 if( d
->connections
.isEmpty() )
163 void Project::sendToClient(DashServer::Connection
*client
)
165 // FIXME: Poner en un thread
167 QFile
f(this->fileName());
168 Dash::Network::Package::Transfer
transfer(f
.size());
169 client
->sendToClient(transfer
.toString(), true);
171 if( f
.open(QIODevice::ReadOnly
) )
175 client
->sendBinaryData(f
.read(1024));
181 void Project::sendToAll()
186 QFile
f(this->fileName());
188 foreach(DashServer::Connection
*client
, d
->connections
)
190 Dash::Network::Package::Transfer
transfer(f
.size());
191 client
->sendToClient(transfer
.toString(), true);
194 if( f
.open(QIODevice::ReadOnly
) )
198 foreach(DashServer::Connection
*client
, d
->connections
)
200 client
->sendBinaryData(f
.read(1024));
207 QHash
<QString
, Member
*> Project::members() const
212 QSet
<DashServer::Connection
*> Project::connections() const
214 return d
->connections
;
217 int Project::clientCount() const
219 return d
->connections
.size();
222 void Project::aboutToSave()
224 if( projectName().isEmpty() ) return;
226 setId(projectName());
228 add("description", description());
229 add("author", author());
231 if(!d
->initialized
) d
->loadMembers();
234 void Project::afterLoad()
236 setProjectName(id());
237 setDescription(value("description"));
238 setAuthor(value("author"));
240 if(!d
->initialized
) d
->loadMembers();
245 if(!d
->initialized
) d
->loadMembers();
247 QString pname
= projectName();
249 if( pname
.isEmpty() ) return false;
251 return Dash::ProjectSaver::save(this, fileName());
256 if(!d
->initialized
) d
->loadMembers();
258 QString pname
= projectName();
260 if( pname
.isEmpty() )
262 qWarning("Warning: Project name is empty");
268 return Dash::ProjectSaver::load(this, fileName());
271 QString
Project::fileName() const
273 QString pname
= projectName();
275 if( pname
.isEmpty() )
278 return XDBMS::Manager::self()->databaseDir().absoluteFilePath(pname
+".dsh");
281 void Project::addMember(Member
*member
)
283 if( d
->members
.contains(member
->id()) )
285 d
->members
.remove(member
->id());
289 d
->members
[member
->id()] = member
;
293 QString
Project::partName(int part
)
328 int Project::partFromCommand(const QString
&pkgname
)
330 Project::Part part
= Project::None
;
333 if( pkgname
== "addlibraryfolder" )
335 part
= Project::Library
;
337 else if( pkgname
== "addlibraryobject" )
339 part
= Project::Library
;
341 else if( pkgname
== "modifysymbol" )
343 part
= Project::Library
;
345 else if( pkgname
== "renamelibraryobject" )
347 part
= Project::Library
;
352 if( pkgname
== "additemfilter" )
354 part
= Project::Object
;
356 else if( pkgname
== "addobject" )
358 part
= Project::Object
;
360 else if( pkgname
== "addtweening" )
362 part
= Project::Object
;
364 else if( pkgname
== "bringforwardsitem" )
366 part
= Project::Object
;
368 else if( pkgname
== "bringtofrontitem" )
370 part
= Project::Object
;
372 else if( pkgname
== "changelayervisibility" )
374 part
= Project::Object
;
376 else if( pkgname
== "changetextfont" )
378 part
= Project::Object
;
380 else if( pkgname
== "changetext" )
382 part
= Project::Object
;
384 else if( pkgname
== "changetextwidth" )
386 part
= Project::Object
;
388 else if( pkgname
== "convertitem" )
390 part
= Project::Object
;
392 else if( pkgname
== "editnodesitem" )
394 part
= Project::Object
;
396 else if( pkgname
== "changeitembrush" )
398 part
= Project::Object
;
400 else if( pkgname
== "changeitempen" )
402 part
= Project::Object
;
404 else if( pkgname
== "groupitem" )
406 part
= Project::Object
;
408 else if( pkgname
== "modifyfilter" )
410 part
= Project::Object
;
412 else if( pkgname
== "modifyitem" )
414 part
= Project::Object
;
416 else if( pkgname
== "removelibraryobject" )
418 part
= Project::Object
;
420 else if( pkgname
== "removeobject" )
422 part
= Project::Object
;
424 else if( pkgname
== "sendbackwardsitem" )
426 part
= Project::Object
;
428 else if( pkgname
== "sendtobackitem" )
430 part
= Project::Object
;
432 else if( pkgname
== "ungroupitem" )
434 part
= Project::Object
;
439 if( pkgname
== "changeframevisibility" )
441 part
= Project::Frame
;
443 else if( pkgname
== "expandframe" )
445 part
= Project::Frame
;
447 else if( pkgname
== "insertframe" )
449 part
= Project::Frame
;
451 else if( pkgname
== "lockframe" )
453 part
= Project::Frame
;
455 else if( pkgname
== "moveframe" )
457 part
= Project::Frame
;
459 else if( pkgname
== "removeframe" )
461 part
= Project::Frame
;
463 else if( pkgname
== "renameframe" )
465 part
= Project::Frame
;
469 if( pkgname
== "insertlayer" )
471 part
= Project::Layer
;
473 else if( pkgname
== "locklayer" )
475 part
= Project::Layer
;
477 else if( pkgname
== "movelayer" )
479 part
= Project::Layer
;
481 else if( pkgname
== "removelayer" )
483 part
= Project::Layer
;
485 else if( pkgname
== "renamelayer" )
487 part
= Project::Layer
;
492 if( pkgname
== "insertscene" )
494 part
= Project::Scene
;
496 else if( pkgname
== "movescene" )
498 part
= Project::Scene
;
500 else if( pkgname
== "removescene" )
502 part
= Project::Scene
;
504 else if( pkgname
== "renamescene" )
506 part
= Project::Scene
;