File indexing completed on 2024-04-21 15:38:54
0001 /*************************************************************************** 0002 * Copyright (C) 2005-2014 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 "config.h" 0021 #include "src/domain/domainfacade.h" 0022 0023 #ifdef QTGUI 0024 #include "presentation/frontends/qtfrontend/qtfrontend.h" 0025 #endif 0026 0027 #include "presentation/frontends/nonguifrontend/nonguifrontend.h" 0028 #include "src/foundation/preferencestool.h" 0029 #include "src/domain/animation/workspacefile.h" 0030 #include "uiexception.h" 0031 0032 #include <unistd.h> 0033 #include <stdio.h> 0034 #include <string.h> 0035 #include <sys/stat.h> 0036 #include <stddef.h> 0037 #include <errno.h> 0038 #include <exception> 0039 #include <iostream> 0040 0041 class CouldNotInitializeRecoveryFiles : public std::exception { 0042 int error; 0043 char buffer[1024]; 0044 public: 0045 CouldNotInitializeRecoveryFiles(int err) : error(err) { 0046 snprintf(buffer, sizeof(buffer), 0047 "Could not initialize recovery files (%s)." 0048 " You need permission to read and write in a ~/.stopmotion" 0049 " directory.", strerror(err)); 0050 } 0051 const char* what() const throw() { 0052 return buffer; 0053 } 0054 }; 0055 0056 class RecoveryIncompleteException : public std::exception { 0057 char buffer[1024]; 0058 public: 0059 RecoveryIncompleteException(const char* filename) { 0060 snprintf(buffer, sizeof(buffer), 0061 "Failed to recover previous project from command log file %s." 0062 " Perhaps the file is corrupt or you don't have permission" 0063 " to read it.", filename); 0064 } 0065 const char* what() const throw() { 0066 return buffer; 0067 } 0068 }; 0069 0070 /** 0071 * Recover the project. An exception will be throw if recovery fails. 0072 */ 0073 void recover(DomainFacade *facadePtr) { 0074 struct stat st; 0075 WorkspaceFile commandLog(WorkspaceFile::commandLogFile); 0076 bool commandLogExists = 0 <= stat(commandLog.path(), &st); 0077 WorkspaceFile currentDat(WorkspaceFile::currentModelFile); 0078 if (stat(currentDat.path(), &st) < 0) { 0079 WorkspaceFile newDat(WorkspaceFile::newModelFile); 0080 if (stat(newDat.path(), &st) < 0) { 0081 if (!commandLogExists) { 0082 // None of the files are present; clear and start afresh 0083 WorkspaceFile::clear(); 0084 } 0085 } else { 0086 // Program must have crashed in the middle of saving. 0087 if (unlink(commandLog.path()) < 0 && errno != ENOENT) { 0088 throw CouldNotInitializeRecoveryFiles(errno); 0089 } 0090 commandLogExists = false; 0091 if (!facadePtr->loadProject(newDat.path(), 0)) { 0092 throw RecoveryIncompleteException(newDat.path()); 0093 } 0094 } 0095 } else { 0096 Preference projectFile("projectFile"); 0097 if (!facadePtr->loadProject(currentDat.path(), projectFile.get())) { 0098 throw RecoveryIncompleteException(currentDat.path()); 0099 } 0100 } 0101 if (commandLogExists) { 0102 facadePtr->replayCommandLog(commandLog.path()); 0103 } 0104 } 0105 0106 int main(int argc, char **argv) { 0107 int ret = 1; 0108 0109 DomainFacade *facadePtr = DomainFacade::getFacade(); 0110 0111 // if program is started with --nonGUI 0112 if ( argc > 1 && strcmp(argv[1], "--nonGUI") == 0 ) { 0113 NonGUIFrontend nonGUIFrontend(facadePtr); 0114 try { 0115 recover(facadePtr); 0116 facadePtr->registerFrontend(&nonGUIFrontend); 0117 ret = nonGUIFrontend.run(argc, argv); 0118 } catch (std::exception& e) { 0119 std::cerr << e.what(); 0120 } 0121 } 0122 else { 0123 #ifdef QTGUI 0124 QtFrontend qtFrontend(argc, argv); 0125 qtFrontend.processEvents(); 0126 try { 0127 facadePtr->registerFrontend(&qtFrontend); 0128 recover(facadePtr); 0129 qtFrontend.setUndoRedoEnabled(); 0130 facadePtr->initializeCommandLoggerFile(); 0131 if (argc > 1 && access(argv[1], R_OK) == 0) { 0132 qtFrontend.openProject(argv[1]); 0133 facadePtr->setMostRecentProject(); 0134 } 0135 ret = qtFrontend.run(argc, argv); 0136 } catch (UiException& e) { 0137 qtFrontend.handleException(e); 0138 } catch (std::exception& e) { 0139 UiException uie(UiException::ArbitraryError, e.what()); 0140 qtFrontend.handleException(uie); 0141 } 0142 #endif 0143 } 0144 0145 delete facadePtr; 0146 facadePtr = NULL; 0147 return ret; 0148 }