File indexing completed on 2024-04-28 16:08:33

0001 /***************************************************************************
0002  *   Copyright (C) 2005-2017 by Linuxstopmotion contributors;              *
0003  *   see the AUTHORS file for details.                                     *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 #include "domainfacade.h"
0021 
0022 #include "animation/animation.h"
0023 #include "animation/workspacefile.h"
0024 #include "src/foundation/logger.h"
0025 #include "src/foundation/preferencestool.h"
0026 #include "src/foundation/uiexception.h"
0027 #include "src/presentation/frontends/frontend.h"
0028 #include "technical/util.h"
0029 
0030 #include <stdio.h>
0031 #include <sys/file.h>
0032 #include <exception>
0033 
0034 DomainFacade* DomainFacade::domainFacade = 0;
0035 
0036 const char* DomainFacade::getImagePath(int scene, int frame) {
0037     try {
0038         return animationModel->getImagePath(scene, frame);
0039     } catch (UiException& e) {
0040         animationModel->resync(e);
0041     } catch (std::exception& e) {
0042         animationModel->resync(e);
0043     }
0044     return 0;
0045 }
0046 
0047 int DomainFacade::soundCount(int scene, int frame) const {
0048     try {
0049         return animationModel->soundCount(scene, frame);
0050     } catch (UiException& e) {
0051         animationModel->resync(e);
0052     } catch (std::exception& e) {
0053         animationModel->resync(e);
0054     }
0055     return 0;
0056 }
0057 
0058 bool DomainFacade::loadProject(const char* datFilename,
0059         const char* projectFilename) {
0060     return animationModel->loadFromDat(datFilename, projectFilename);
0061 }
0062 
0063 void DomainFacade::setMostRecentProject() {
0064     const char *first = DomainFacade::getFacade()->getProjectFile();
0065     PreferencesTool *prefs = PreferencesTool::get();
0066     if (first) {
0067         prefs->setPreference("projectFile", first);
0068     } else {
0069         prefs->removePreference("projectFile");
0070     }
0071     if (first != 0) {
0072         Preference prefsFirst("mostRecent");
0073         if (!prefsFirst.equals(first)) {
0074             Preference second("secondMostRecent");
0075             prefs->setPreference("mostRecent", first);
0076             prefs->setPreference("secondMostRecent", prefsFirst.get());
0077             if (!second.equals(first)) {
0078                 prefs->setPreference("thirdMostRecent", second.get());
0079             }
0080         }
0081     }
0082     try {
0083         prefs->flush();
0084     } catch (UiException& ex) {
0085         DomainFacade::getFacade()->getFrontend()->handleException(ex);
0086     }
0087 }
0088 
0089 DomainFacade::DomainFacade() {
0090     animationModel = new Animation();
0091     domainFacade = NULL;
0092 }
0093 
0094 
0095 DomainFacade::~DomainFacade() {
0096     delete animationModel;
0097     animationModel = NULL;
0098 }
0099 
0100 
0101 DomainFacade* DomainFacade::getFacade() {
0102     if(domainFacade == NULL) {
0103         domainFacade = new DomainFacade();
0104     }
0105     return domainFacade;
0106 }
0107 
0108 
0109 void DomainFacade::attach(Observer *o) {
0110     animationModel->attach(o);
0111 }
0112 
0113 
0114 void DomainFacade::detach(Observer *o) {
0115     animationModel->detach(o);
0116 }
0117 
0118 
0119 void DomainFacade::registerFrontend(Frontend *frontend) {
0120     animationModel->registerFrontend(frontend);
0121 }
0122 
0123 
0124 Frontend* DomainFacade::getFrontend() {
0125     return animationModel->getFrontend();
0126 }
0127 
0128 
0129 void DomainFacade::addFrames(int scene, int frame,
0130         StringIterator& frameNames) {
0131     try {
0132         Logger::get().logDebug("Adding frames in the domainfacade");
0133         animationModel->addFrames(scene, frame, frameNames);
0134     } catch (UiException& e) {
0135         animationModel->resync(e);
0136     } catch (std::exception& e) {
0137         animationModel->resync(e);
0138     }
0139 }
0140 
0141 
0142 void DomainFacade::removeFrames(int scene, int frame, int count) {
0143     try {
0144         Logger::get().logDebug("Removing frames in the domainfacade");
0145         animationModel->removeFrames(scene, frame, count);
0146     } catch (UiException& e) {
0147         animationModel->resync(e);
0148     } catch (std::exception& e) {
0149         animationModel->resync(e);
0150     }
0151 }
0152 
0153 
0154 void DomainFacade::moveFrames(int fromScene, int fromFrame,
0155         int count, int toScene, int toFrame) {
0156     try {
0157         animationModel->moveFrames(fromScene, fromFrame, count,
0158                 toScene, toFrame);
0159     } catch (UiException& e) {
0160         animationModel->resync(e);
0161     } catch (std::exception& e) {
0162         animationModel->resync(e);
0163     }
0164 }
0165 
0166 
0167 void DomainFacade::addSound(int scene, int frame, const char *filename) {
0168     try {
0169         Logger::get().logDebug("Adding sound in domainfacade");
0170         animationModel->addSound(scene, frame, filename);
0171     } catch (UiException& e) {
0172         animationModel->resync(e);
0173     } catch (std::exception& e) {
0174         animationModel->resync(e);
0175     }
0176 }
0177 
0178 
0179 void DomainFacade::removeSound(int sceneNumber, int frameNumber,
0180         int soundNumber) {
0181     try {
0182         animationModel->removeSound(sceneNumber, frameNumber, soundNumber);
0183     } catch (UiException& e) {
0184         animationModel->resync(e);
0185     } catch (std::exception& e) {
0186         animationModel->resync(e);
0187     }
0188 }
0189 
0190 
0191 void DomainFacade::setSoundName(int sceneNumber, int frameNumber,
0192         int soundNumber, const char* soundName) {
0193     try {
0194         animationModel->setSoundName(sceneNumber, frameNumber, soundNumber,
0195                 soundName);
0196     } catch (UiException& e) {
0197         animationModel->resync(e);
0198     } catch (std::exception& e) {
0199         animationModel->resync(e);
0200     }
0201 }
0202 
0203 
0204 void DomainFacade::openProject(const char *filename) {
0205     animationModel->openProject(filename);
0206 }
0207 
0208 
0209 void DomainFacade::saveProject(const char *directory) {
0210     animationModel->saveProject(directory);
0211 }
0212 
0213 
0214 bool DomainFacade::newProject() {
0215     animationModel->newProject();
0216     setMostRecentProject();
0217     return true;
0218 }
0219 
0220 
0221 bool DomainFacade::isUnsavedChanges() {
0222     return animationModel->isUnsavedChanges();
0223 }
0224 
0225 
0226 int DomainFacade::getModelSize() const {
0227     return animationModel->frameCount();
0228 }
0229 
0230 
0231 int DomainFacade::getSceneSize(int sceneNumber) const {
0232     try {
0233         return animationModel->frameCount(sceneNumber);
0234     } catch (UiException& e) {
0235         animationModel->resync(e);
0236     } catch (std::exception& e) {
0237         animationModel->resync(e);
0238     }
0239     return 0;
0240 }
0241 
0242 
0243 int DomainFacade::getNumberOfScenes() const {
0244     return animationModel->sceneCount();
0245 }
0246 
0247 
0248 int DomainFacade::getNumberOfSounds(int scene, int frame) const {
0249     try {
0250         return animationModel->soundCount(scene, frame);
0251     } catch (UiException& e) {
0252         animationModel->resync(e);
0253     } catch (std::exception& e) {
0254         animationModel->resync(e);
0255     }
0256     return 0;
0257 }
0258 
0259 
0260 const char* DomainFacade::getProjectFile() {
0261     return animationModel->getProjectFile();
0262 }
0263 
0264 
0265 void DomainFacade::undo() {
0266     animationModel->undo();
0267 }
0268 
0269 
0270 void DomainFacade::redo() {
0271     animationModel->redo();
0272 }
0273 
0274 
0275 void DomainFacade::clearHistory() {
0276     animationModel->clearHistory();
0277 }
0278 
0279 
0280 void DomainFacade::newScene(int index) {
0281     try {
0282         animationModel->newScene(index);
0283     } catch (UiException& e) {
0284         animationModel->resync(e);
0285     } catch (std::exception& e) {
0286         animationModel->resync(e);
0287     }
0288 }
0289 
0290 
0291 void DomainFacade::removeScene(int sceneNumber) {
0292     try {
0293         animationModel->removeScene(sceneNumber);
0294     } catch (UiException& e) {
0295         animationModel->resync(e);
0296     } catch (std::exception& e) {
0297         animationModel->resync(e);
0298     }
0299 }
0300 
0301 
0302 void DomainFacade::moveScene(int sceneNumber, int movePosition) {
0303     try {
0304         animationModel->moveScene(sceneNumber, movePosition);
0305     } catch (UiException& e) {
0306         animationModel->resync(e);
0307     } catch (std::exception& e) {
0308         animationModel->resync(e);
0309     }
0310 }
0311 
0312 
0313 bool DomainFacade::initAudioDevice() {
0314     return animationModel->initAudioDevice();
0315 }
0316 
0317 
0318 void DomainFacade::shutdownAudioDevice() {
0319     return animationModel->shutdownAudioDevice();
0320 }
0321 
0322 
0323 bool DomainFacade::exportToVideo(VideoEncoder *encoder, int playbackSpeed) {
0324     return animationModel->exportToVideo(encoder, playbackSpeed);
0325 }
0326 
0327 
0328 bool DomainFacade::exportToCinerella(const char *file) {
0329     return animationModel->exportToCinerella(file);
0330 }
0331 
0332 
0333 const vector<GrabberDevice> DomainFacade::getGrabberDevices() {
0334     return Util::getGrabberDevices();
0335 }
0336 
0337 const char* DomainFacade::getSoundName(int sceneNumber, int frameNumber,
0338         int soundNumber) const {
0339     try {
0340         return animationModel->getSoundName(sceneNumber, frameNumber,
0341                 soundNumber);
0342     } catch (UiException& e) {
0343         animationModel->resync(e);
0344     } catch (std::exception& e) {
0345         animationModel->resync(e);
0346     }
0347     return 0;
0348 }
0349 
0350 void DomainFacade::duplicateImage(int scene, int frame) {
0351     animationModel->duplicateImage(scene, frame);
0352 }
0353 
0354 void DomainFacade::initializeCommandLoggerFile() {
0355     WorkspaceFile wslf(WorkspaceFile::commandLogFile);
0356     FILE* log = fopen(wslf.path(), "a");
0357     if (!log)
0358         throw FailedToInitializeCommandLogger();
0359     if (flock(fileno(log), LOCK_EX | LOCK_NB)) {
0360         fclose(log);
0361         throw (UiException(UiException::failedToGetExclusiveLock));
0362     }
0363     animationModel->setCommandLoggerFile(log);
0364 }
0365 
0366 bool DomainFacade::replayCommandLog(const char* filename) {
0367     FILE* log = fopen(filename, "r");
0368     if (!log)
0369         return false;
0370     try {
0371         animationModel->replayCommandLog(log);
0372     } catch (UiException& e) {
0373         animationModel->resync(e);
0374         return false;
0375     } catch (std::exception& e) {
0376         Logger::get().logFatal("Recovery failed: %s", e.what());
0377         fclose(log);
0378         return false;
0379     }
0380     return true;
0381 }
0382 
0383 bool DomainFacade::canUndo() {
0384     return animationModel->canUndo();
0385 }
0386 
0387 bool DomainFacade::canRedo() {
0388     return animationModel->canRedo();
0389 }
0390 
0391 void DomainFacade::setUndoRedoObserver(UndoRedoObserver* observer) {
0392     animationModel->setUndoRedoObserver(observer);
0393 }
0394 
0395 void DomainFacade::playSounds(int scene, int frame) const {
0396     animationModel->playSounds(scene, frame);
0397 }