diff --git a/game/settings.cpp b/game/settings.cpp index 8e0c839..9362432 100644 --- a/game/settings.cpp +++ b/game/settings.cpp @@ -64,66 +64,65 @@ void Settings::Destroy() } -namespace +string Settings::GetConfigFileDir() { - string getConfigFileName() - { - string fileName; + string fileName; #ifdef WIN32 - char szPath[MAX_PATH]; - // Get the AppData directory - if (SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, - NULL, 0, szPath) == S_OK) - { - fileName = szPath + string("\\eliot"); + char szPath[MAX_PATH]; + // Get the AppData directory + if (SHGetFolderPath(NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE, + NULL, 0, szPath) == S_OK) + { + fileName = szPath + string("\\eliot"); #if 1 - strncpy(szPath, fileName.c_str(), MAX_PATH); - // Try to create the directory - // We don't care about the results - CreateDirectory(fileName.c_str(), NULL); + strncpy(szPath, fileName.c_str(), MAX_PATH); + // Try to create the directory + // We don't care about the results + CreateDirectory(fileName.c_str(), NULL); #endif - } - if (fileName != "") - fileName += "\\"; - fileName += "eliot.cfg"; + } + if (fileName != "") + fileName += "\\"; #else - // Follow the XDG Base Directory Specification (from freedesktop.org) - // XXX: In fact we don't follow it to the letter, because the location - // of the config file could be different when reading and writing. - // But in the case of Eliot it's not very important (we don't try to - // merge config files)... - const char *configDir = getenv("XDG_CONFIG_HOME"); - if (configDir != NULL) - fileName = configDir; - else - { - // Fallback to the default value: $HOME/.config - configDir = getenv("HOME"); - if (configDir) - fileName = configDir + string("/.config"); - } - fileName += "/eliot"; + // Follow the XDG Base Directory Specification (from freedesktop.org) + // XXX: In fact we don't follow it to the letter, because the location + // of the config file could be different when reading and writing. + // But in the case of Eliot it's not very important (we don't try to + // merge config files)... + const char *configDir = getenv("XDG_CONFIG_HOME"); + if (configDir != NULL) + fileName = configDir; + else + { + // Fallback to the default value: $HOME/.config + configDir = getenv("HOME"); + if (configDir) + fileName = configDir + string("/.config"); + } + fileName += "/eliot"; #if defined(HAVE_SYS_STAT_H) && defined(HAVE_SYS_TYPES_H) - // Create the directory if it doesn't exist - struct stat sb; - if (fileName != "" && stat(fileName.c_str(), &sb) == -1) + // Create the directory if it doesn't exist + struct stat sb; + if (fileName != "" && stat(fileName.c_str(), &sb) == -1) + { + // Try to create the directory with mode 0700 + if (mkdir(fileName.c_str(), S_IRWXU)) { - // Try to create the directory with mode 0700 - if (mkdir(fileName.c_str(), S_IRWXU)) - { - // The directory could not be created. Too bad... - // Saving the configuration file will definitely fail. - } + // The directory could not be created. Too bad... + // Saving the configuration file will definitely fail. } -#endif - - fileName += "/eliot.cfg"; -#endif - return fileName; } +#endif + + fileName += "/"; +#endif + return fileName; +} +namespace +{ #ifdef HAVE_LIBCONFIG template void copySetting(const Config &srcConf, Config &dstConf, const char *path) @@ -142,7 +141,7 @@ namespace Settings::Settings() { #ifdef HAVE_LIBCONFIG - m_fileName = ::getConfigFileName(); + m_fileName = GetConfigFileDir() + "eliot.cfg"; m_conf = new Config; // ============== General options ============== diff --git a/game/settings.h b/game/settings.h index 7a67a40..fe9b796 100644 --- a/game/settings.h +++ b/game/settings.h @@ -53,6 +53,9 @@ public: /// Destroy the singleton cleanly static void Destroy(); + /// Return the config file directory, with a '/' (or '\') appended to it + static string GetConfigFileDir(); + ~Settings(); /// Save the current value of the settings to a configuration file diff --git a/qt/main_window.cpp b/qt/main_window.cpp index 5a0f0a5..51924b8 100644 --- a/qt/main_window.cpp +++ b/qt/main_window.cpp @@ -46,6 +46,9 @@ #include "turn.h" #include "move.h" #include "debug.h" +#include "round.h" +#include "settings.h" + #include "new_game.h" #include "tables_dialog.h" #include "prefs_dialog.h" @@ -64,9 +67,6 @@ #include "aux_window.h" #include "qtcommon.h" -#include "round.h" -#include "coord.h" - INIT_LOGGER(qt, MainWindow); @@ -87,6 +87,9 @@ MainWindow::MainWindow(QWidget *iParent) QtCommon::CheckConversions(); #endif + // Path to the auto-saved game + m_autoSaveGame = Settings::GetConfigFileDir() + "autosave.xml"; + LOG_DEBUG("Creating main window"); m_ui.setupUi(this); createMenu(); @@ -258,6 +261,10 @@ void MainWindow::refresh() m_currentTurn = currTurn; emit turnChanged(currTurn, isLastTurn); } + + // Update the auto-saved game + m_game->save(m_autoSaveGame); + #ifdef DEBUG m_game->printTurns(); #endif @@ -610,6 +617,9 @@ void MainWindow::createMenu() menuFile->addSeparator(); addMenuAction(menuFile, _q("&Load..."), _q("Ctrl+O"), _q("Load an existing game"), SLOT(onGameLoad())); + addMenuAction(menuFile, _q("Load the auto-saved game"), QString(""), + _q("Load the automatically saved game (useful after a crash)"), + SLOT(onGameLoadAutoSave())); m_actionGameSaveAs = addMenuAction(menuFile, _q("&Save as..."), _q("Ctrl+S"), _q("Save the current game"), SLOT(onGameSaveAs())); menuFile->addSeparator(); @@ -740,6 +750,18 @@ void MainWindow::onGameNew() void MainWindow::onGameLoad() +{ + loadGame(""); +} + + +void MainWindow::onGameLoadAutoSave() +{ + loadGame(qfl(m_autoSaveGame)); +} + + +void MainWindow::loadGame(QString fileName) { if (m_dic == NULL) { @@ -754,7 +776,8 @@ void MainWindow::onGameLoad() return; } - QString fileName = QFileDialog::getOpenFileName(this, _q("Load a game")); + if (fileName == "") + fileName = QFileDialog::getOpenFileName(this, _q("Load a game")); if (fileName != "") { try diff --git a/qt/main_window.h b/qt/main_window.h index fa238a1..feb6aab 100644 --- a/qt/main_window.h +++ b/qt/main_window.h @@ -21,6 +21,7 @@ #ifndef MAIN_WINDOW_H_ #define MAIN_WINDOW_H_ +#include #include #include @@ -28,6 +29,9 @@ #include "coord_model.h" +using std::string; + + class Dictionary; class Bag; class Board; @@ -71,6 +75,7 @@ protected: private slots: void onGameNew(); void onGameLoad(); + void onGameLoadAutoSave(); void onGameSaveAs(); void onGamePrint(); void onGameQuit(); @@ -152,6 +157,8 @@ private: static const char * m_windowName; + string m_autoSaveGame; + /// Auxiliary windows //@{ QAction *m_actionWindowsBag; @@ -205,6 +212,12 @@ private: */ void linkArbitrationAnd7P1(); + /** + * Load the game saved in the given file. If iFileName is an empty string, + * the auto-saved game will be loaded. + */ + void loadGame(QString iFileName); + }; #endif