Selected layer properly on TimeLine
[dashstudio.git] / src / shell / projectmanager.cpp
blob1b5752eeb799a345b2c9c3f20d9513af79ce719c
1 /***************************************************************************
2 * Copyright (C) 2007 by David Cuadrado *
3 * krawek@gmail.com *
4 * *
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. *
9 * *
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. *
14 * *
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 ***************************************************************************/
22 #include "projectmanager.h"
24 // DLIB
25 #include <dcore/algorithm.h>
26 #include <dcore/zipper.h>
28 // YAMF
29 #include <yamf/model/project.h>
30 #include <yamf/model/scene.h>
31 #include <yamf/model/layer.h>
32 #include <yamf/model/audiolayer.h>
33 #include <yamf/model/frame.h>
34 #include <yamf/model/object.h>
35 #include <yamf/model/library.h>
37 #include <yamf/model/command/manager.h>
38 #include <yamf/model/command/base.h>
40 // DASH
41 #include "dash/module.h"
42 #include "dash/commandparser.h"
45 // Qt
46 #include <QWidget>
47 #include <QDir>
48 #include <QFileInfo>
50 struct ProjectManager::Private
52 Private() : isLocal(true), project(0), commandCounter(0) {}
54 bool isLocal;
55 YAMF::Model::Project *project;
57 QList<Dash::Module *> modules;
59 bool deleteProjectDir(const QString &projectDir);
60 int commandCounter;
63 bool ProjectManager::Private::deleteProjectDir(const QString &projectDir)
65 if(!projectDir.startsWith(".") && QFile::exists( projectDir ) )
67 QDir dir(projectDir);
69 if( (dir.exists("audio") && dir.exists("video") && dir.exists("images")) || dir.exists("project") )
71 dDebug() << "Removing " << dir.absolutePath() << "...";
73 dir.remove("project");
74 dir.remove("library");
76 foreach(QString scene, dir.entryList(QStringList() << "scene*", QDir::Files ))
78 dir.remove(scene);
81 foreach( QString subdir, QStringList() << "audio" << "video" << "images" << "svg" )
83 if( dir.exists(subdir) )
85 dir.cd(subdir);
86 foreach(QString file, dir.entryList() )
88 QString absolute = dir.absolutePath() + "/" + file;
90 if( !file.startsWith(".") )
92 QFileInfo finfo(absolute);
94 if( finfo.isFile() )
96 QFile::remove(absolute);
100 dir.cdUp();
101 dir.rmdir(subdir);
105 if( ! dir.rmdir(dir.absolutePath()) )
107 dError("project") << "Cannot remove project data directory!";
110 return true;
113 return false;
116 ProjectManager::ProjectManager(QObject *parent)
117 : QObject(parent), d(new Private)
119 d->project = new YAMF::Model::Project(this);
120 d->project->commandManager()->setObserver(this);
124 ProjectManager::~ProjectManager()
126 delete d;
129 void ProjectManager::createProject(const QString &name, const QString &author, const QString &description)
131 d->project->clear();
132 d->project->setProjectName(name);
133 d->project->setAuthor(author);
134 d->project->setDescription(description);
136 d->project->setOpen(true);
139 void ProjectManager::createScene(const QString &name, int frames)
141 if( ! d->project->isOpen() ) return;
143 YAMF::Model::Scene *scn = d->project->createScene(-1, name);
144 YAMF::Model::Layer *lyr = scn->createLayer();
146 if( frames < 1 ) frames = 1;
148 while(frames--)
149 lyr->createFrame();
152 void ProjectManager::closeProject()
154 d->project->clear();
156 foreach(Dash::Module *module, d->modules)
158 module->reset();
161 d->project->setOpen(false);
164 YAMF::Model::Project *ProjectManager::project() const
166 return d->project;
169 void ProjectManager::registerModule(Dash::Module *module)
171 d->modules << module;
174 bool ProjectManager::aboutToRedo(const YAMF::Command::Base *command)
176 if( d->isLocal )
178 return false;
181 QString xml = command->toXml();
183 // TODO: Enviar por socket
185 return true;
188 bool ProjectManager::aboutToUndo(const YAMF::Command::Base *command)
190 if( d->isLocal )
192 return false;
195 QString xml = command->toXml();
197 // TODO: Enviar por socket
199 return true;
202 void ProjectManager::executed(const YAMF::Command::Base *command)
204 if( d->isLocal )
206 Dash::CommandParser parser;
207 Dash::DataSource *source = parser.build(command);
209 if( !source ) return;
211 foreach(Dash::Module *module, d->modules)
213 if( module->sources() & source->type() )
215 module->update(source, false);
219 delete source;
221 d->commandCounter++;
225 void ProjectManager::unexecuted(const YAMF::Command::Base *command)
227 if( d->isLocal )
229 Dash::CommandParser parser;
231 Dash::DataSource *source = parser.build(command);
233 if( !source ) return;
235 foreach(Dash::Module *module, d->modules)
237 if( module->sources() & source->type() )
239 module->update(source, true);
243 d->commandCounter--;
244 delete source;
248 bool ProjectManager::isModified() const
250 return d->commandCounter > 0;
253 bool ProjectManager::saveProject(const QString &path)
255 if( d->isLocal )
257 QDir projectDir = QDir::tempPath()+"/dash."+QString::number(DCore::Algorithm::random());
259 if ( !projectDir.exists() )
261 if ( ! projectDir.mkpath(projectDir.absolutePath()) )
263 dError() << "Cannot create: " << projectDir.absolutePath();
264 return false;
268 QString current = QDir::currentPath();
269 QDir::setCurrent(projectDir.absolutePath());
271 QStringList filesToZip;
273 // Save project
274 QFile prj(projectDir.absolutePath()+"/project");
276 if ( prj.open(QIODevice::WriteOnly | QIODevice::Text))
278 QTextStream ts(&prj);
280 QDomDocument doc;
281 doc.appendChild(d->project->toXml(doc));
283 ts << doc.toString();
285 prj.close();
287 QFileInfo finfo(prj);
288 filesToZip << finfo.absoluteFilePath();
292 // Save scenes
294 int index = 0;
295 foreach ( YAMF::Model::Scene *scene, d->project->scenes().visualValues() )
297 QDomDocument doc;
298 doc.appendChild(scene->toXml(doc));
300 QFile scn(projectDir.path()+"/scene"+QString::number(index));
302 if ( scn.open(QIODevice::WriteOnly | QIODevice::Text) )
304 QTextStream st(&scn);
305 st << doc.toString();
306 scn.close();
307 index++;
309 QFileInfo finfo(scn);
310 filesToZip << finfo.absoluteFilePath();
315 // Save library
317 QString libraryPath = projectDir.path()+"/library";
318 d->project->library()->save(libraryPath);
320 filesToZip << libraryPath;
322 QStringList dirs;
323 dirs << "audio" << "video" << "images" << "svg";
325 foreach(QString dir, dirs)
327 QString path = dir;
328 if( QFile::exists(projectDir.absoluteFilePath(dir)) )
330 filesToZip << path;
335 DCore::Zipper zipper;
337 D_SHOW_VAR(QDir::currentPath());
338 bool ok = zipper.write(filesToZip, path);
339 QDir::setCurrent(current);
341 if( ! ok )
342 return false;
344 d->deleteProjectDir(projectDir.absolutePath());
346 d->commandCounter = 0;
348 return true;
351 // TODO: Network
353 return false;
356 bool ProjectManager::loadProject(const QString &path)
358 QDir projectDir = QDir::tempPath()+"/dash."+QString::number(DCore::Algorithm::random());
360 DCore::Zipper zipper;
362 if( ! zipper.read(path, projectDir.absolutePath() ) )
363 return false;
365 // Load project
366 if( projectDir.exists("project") )
368 QFile prj(projectDir.absoluteFilePath("project"));
370 if ( prj.open(QIODevice::ReadOnly | QIODevice::Text) )
372 d->project->fromXml(QString::fromLocal8Bit(prj.readAll()));
373 prj.close();
377 // Cargar libreria!
379 d->project->loadLibrary(projectDir.path()+"/library");
382 // Load scenes
384 QStringList scenes = projectDir.entryList(QStringList() << "scene*", QDir::Readable | QDir::Files);
386 foreach(QString scenePath, scenes)
388 scenePath = projectDir.absoluteFilePath(scenePath);
389 YAMF::Model::Scene *scene = d->project->createScene();
391 QFile f(scenePath);
393 if ( f.open(QIODevice::ReadOnly | QIODevice::Text) )
395 QString xml = QString::fromLocal8Bit(f.readAll());
396 scene->fromXml(xml);
398 f.close();
403 d->commandCounter = 0;
404 d->project->setOpen(true);
405 d->deleteProjectDir(projectDir.absolutePath());
407 return true;