File indexing completed on 2024-05-12 04:56:39
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 }