/****************************************************************************** * Copyright (C) 2005-2015 by * * Bjoern Erik Nilsen (bjoern.nilsen@bjoernen.com), * * Fredrik Berg Kjoelstad (fredrikbk@hotmail.com), * * Ralf Lange (ralf.lange@longsoft.de) * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ******************************************************************************/ #include "projectserializer.h" #include "domain/domainfacade.h" #include "technical/preferencestool.h" #include #include #include #include #include #include #include ProjectSerializer::ProjectSerializer(Frontend* f) { frontend = f; //Create the xml tree QDomImplementation domImpl; QDomDocumentType dtd = domImpl.createDocumentType("qsmd", "-//qStopMotion//DTD QSMD 1.0//EN", "http://www.qstopmotion.org/xmltemplates/qsmd1.dtd"); doc = QDomDocument(dtd); // rootNode = NULL; cleanup(); } ProjectSerializer::~ProjectSerializer() { doc.clear(); versionElement.clear(); animationElement.clear(); cleanup(); } bool ProjectSerializer::read() { qDebug() << "ProjectSerializer::read --> Start"; QString errorStr; int errorLine; int errorColumn; QDomElement rootElement; QDomElement element; QFile file(newProjectFilePath); if (!file.open(QIODevice::ReadOnly)) { frontend->showWarning(tr("DOM Parser"), QString(tr("Couldn't open XML file:\n%1")).arg(newProjectFilePath)); return false; } if (!doc.setContent(&file, true, &errorStr, &errorLine, &errorColumn)) { file.close(); frontend->showWarning(tr("DOM Parser"), QString(tr("Parse error at line %1, column %2:\n%3\n%4")) .arg(errorLine) .arg(errorColumn) .arg(errorStr) .arg(newProjectFilePath)); return false; } file.close(); rootElement = doc.documentElement(); element = rootElement.firstChildElement(); while (!element.isNull()) { if (element.nodeName().compare("version") == 0) { versionElement = element; } if (element.nodeName().compare("settings") == 0) { settingsElement = element; } if (element.nodeName().compare("animation") == 0) { animationElement = element; } element = element.nextSiblingElement(); } if (versionElement.isNull()) { qWarning() << "ProjectSerializer::read --> Error while parsing project file"; return false; } qDebug() << "ProjectSerializer::read --> End"; return true; } // check if the user wants to save an opened project to an another file. bool ProjectSerializer::save(AnimationProject *animation, bool saveAs) { qDebug() << "ProjectSerializer::save --> Start"; bool isSaved = false; QDomElement rootElement; QDomElement versionElement; // QDomImplementation *domImpl = new QDomImplementation(); // QDomDocumentType dtd = domImpl->createDocumentType("smil", // "-//W3C//DTD SMIL 2.0//EN", // "http://www.w3.org/2001/SMIL20/SMIL20.dtd"); doc.clear(); // doc = QDomDocument(dtd); QDomNode xmlNode = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"ISO-8859-1\""); doc.insertBefore(xmlNode, doc.firstChild()); rootElement = doc.createElement("qsmd"); rootElement.setAttribute("xmlns", "http://www.qstopmotion.org/xmltemplates/Language"); rootElement.setAttribute("xml:lang", "en"); rootElement.setAttribute("title", "qStopMotion"); doc.appendChild(rootElement); versionElement = doc.createElement("version"); QDomText versionText = doc.createTextNode("1.0"); versionElement.appendChild(versionText); rootElement.appendChild(versionElement); // Save settings settingsElement = doc.createElement("settings"); rootElement.appendChild(settingsElement); animation->saveSettingsToProject(doc, settingsElement); // Save animation animationElement = doc.createElement("animation"); rootElement.appendChild(animationElement); if (saveAs) { animation->saveAsScenesToProject(doc, animationElement); } else { animation->saveScenesToProject(doc, animationElement); } if (QFile::exists(newProjectFilePath)) { QString backup(newProjectFilePath + "." + PreferencesTool::backupSuffix); if (QFile::exists(backup)) { if (!QFile::remove(backup)) { // Not successful frontend->showCritical(tr("Critical"), tr("Can't remove old backup of project file!")); } } if (!QFile::rename(newProjectFilePath, backup)) { // Rename not successful --> copy and remove if (!QFile::copy(newProjectFilePath, backup)) { frontend->showCritical(tr("Critical"), tr("Can't copy the project file to backup!")); } if (!QFile::remove(newProjectFilePath)) { frontend->showCritical(tr("Critical"), tr("Can't remove the old project file!")); } } } QFile file(newProjectFilePath); if (!file.open(QIODevice::ReadWrite | QIODevice::Truncate)) { qWarning() << "ProjectSerializer::save --> Can't open project file"; return isSaved; } QTextStream out(&file); doc.save(out, 2); out.flush(); file.close(); isSaved = true; unsigned int numElem = animation->getTotalExposureSize(); animation->getFrontend()->updateProgress(numElem); animation->getFrontend()->hideProgress(); qDebug() << "ProjectSerializer::save --> End"; return isSaved; } /* void ProjectSerializer::saveDOMToFile(const QDomDocument &doc) { QFile file(projectFilePath); QTextStream out(&file); const int Ident = 4; doc.save(out, Ident); } */ void ProjectSerializer::setNewProjectFilePath(const QString &pfp) { qDebug() << "ProjectSerializer::setNewProjectFilePath --> Start"; Q_ASSERT(!pfp.isEmpty()); if(newProjectFilePath.compare(pfp) == 0) { // No new file path return; } // This is a new project file name oldProjectFilePath.append(newProjectFilePath); newProjectFilePath.clear(); oldArchiveFilePath.append(newArchiveFilePath); newArchiveFilePath.clear(); oldProjectPath.append(newProjectPath); newProjectPath.clear(); oldImagePath.append(newImagePath); newImagePath.clear(); oldSoundPath.append(newSoundPath); newSoundPath.clear(); QString rootDir; QFileInfo projectFileInfo(pfp); // Get the absolute path of the project file rootDir.append(projectFileInfo.absoluteDir().absolutePath()); newProjectPath.append(rootDir); newProjectFilePath.append(pfp); newArchiveFilePath.append(pfp); newArchiveFilePath.replace(PreferencesTool::projectSuffix, PreferencesTool::archiveSuffix); newImagePath.append(QString("%1%2%3") .arg(newProjectPath) .arg(QLatin1String("/")) .arg(PreferencesTool::imageDirectory)); newSoundPath.append(QString("%1%2%3") .arg(newProjectPath) .arg(QLatin1String("/")) .arg(PreferencesTool::soundDirectory)); if (!QFile::exists(newProjectPath)) { if (!QDir::root().mkpath(newProjectPath)) { this->frontend->showCritical(tr("Critical"), tr("Can't create project directory!")); } if (!QFile::setPermissions(newProjectPath, QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | QFile::ReadGroup | QFile::WriteGroup | QFile::ReadOther | QFile::WriteOther)) { this->frontend->showCritical(tr("Critical"), tr("Can't change permissions of the project directory!")); } } if (!QFile::exists(newImagePath)) { if (!QDir::root().mkpath(newImagePath)) { this->frontend->showCritical(tr("Critical"), tr("Can't create image directory!")); } // Set permissions to 0755 if (!QFile::setPermissions(newImagePath, QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | QFile::ReadGroup | QFile::WriteGroup | QFile::ReadOther | QFile::WriteOther)) { this->frontend->showCritical(tr("Critical"), tr("Can't change permissions of the image directory!")); } } if (!QFile::exists(newSoundPath)) { if (!QDir::root().mkpath(newSoundPath)) { this->frontend->showCritical(tr("Critical"), tr("Can't create sound directory!")); } if (!QFile::setPermissions(newSoundPath, QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | QFile::ReadGroup | QFile::WriteGroup | QFile::ReadOther | QFile::WriteOther)) { this->frontend->showCritical(tr("Critical"), tr("Can't change permissions of the sound directory!")); } } qDebug() << "ProjectSerializer::setNewProjectFilePath --> End"; } const QString ProjectSerializer::getNewProjectFilePath() const { return newProjectFilePath; } const QString ProjectSerializer::getNewProjectPath() const { return newProjectPath; } const QString ProjectSerializer::getNewImagePath() const { return newImagePath; } const QString ProjectSerializer::getOldImagePath() const { if (!oldImagePath.isEmpty()) { return oldImagePath; } return newImagePath; } const QString ProjectSerializer::getNewSoundPath() const { return newSoundPath; } const QString ProjectSerializer::getOldSoundPath() const { if (!oldSoundPath.isEmpty()) { return oldSoundPath; } return newSoundPath; } QDomElement &ProjectSerializer::getAnimationElement() { return animationElement; } QDomElement &ProjectSerializer::getSettingsElement() { return settingsElement; } const QDomElement ProjectSerializer::getVersionElement() const { return versionElement; } void ProjectSerializer::cleanup() { newProjectFilePath.clear(); newArchiveFilePath.clear(); newProjectPath.clear(); newImagePath.clear(); newSoundPath.clear(); cleanupOldFiles(); } void ProjectSerializer::cleanupOldFiles() { oldProjectFilePath.clear(); oldArchiveFilePath.clear(); oldProjectPath.clear(); oldImagePath.clear(); oldSoundPath.clear(); }