From 33d7b305a25601d4c3b87feab17d81e24e4dc2a7 Mon Sep 17 00:00:00 2001 From: David Capello Date: Sun, 24 Aug 2014 09:00:35 -0300 Subject: [PATCH] Several changes related to the location of resources - Add ResourceFinder::includeUserDir() (used by aseprite.ini, crash dump, and aseprite.log). These locations depend on App::isPortable() (if the app is portable or installed). - We don't need to change the current directory in applicationDidFinishLaunching anymore (ResourceFinder::includeDataDir() takes care about bundles now in a correct way). - Migrate old ~/.asepriterc to ~/.config/aseprite/aseprite.ini --- src/allegro/src/macosx/main.m | 24 ------ src/app/ini_file.cpp | 33 ++++---- src/app/resource_finder.cpp | 140 ++++++++++++++-------------------- src/app/resource_finder.h | 16 +++- src/app/send_crash.cpp | 8 +- 5 files changed, 89 insertions(+), 132 deletions(-) diff --git a/src/allegro/src/macosx/main.m b/src/allegro/src/macosx/main.m index d55913f2d..2363da7e7 100644 --- a/src/allegro/src/macosx/main.m +++ b/src/allegro/src/macosx/main.m @@ -65,8 +65,6 @@ static BOOL in_bundle(void) { NSAutoreleasePool *pool = NULL; CFDictionaryRef mode; - NSString* exename, *resdir; - NSFileManager* fm; BOOL isDir; /* create mutex */ @@ -75,29 +73,7 @@ static BOOL in_bundle(void) pool = [[NSAutoreleasePool alloc] init]; if (in_bundle() == YES) - { - /* In a bundle, so chdir to the containing directory, - * or to the 'magic' resource directory if it exists. - * (see the readme.osx file for more info) - */ osx_bundle = [NSBundle mainBundle]; - exename = [[osx_bundle executablePath] lastPathComponent]; - resdir = [[osx_bundle resourcePath] stringByAppendingPathComponent: exename]; - fm = [NSFileManager defaultManager]; - if ([fm fileExistsAtPath: resdir isDirectory: &isDir] && isDir) { - /* Yes, it exists inside the bundle */ - [fm changeCurrentDirectoryPath: resdir]; - } - else { - /* No, change to the 'standard' OSX resource directory if it exists*/ - if ([fm fileExistsAtPath: [osx_bundle resourcePath] isDirectory: &isDir] && isDir) - { - [fm changeCurrentDirectoryPath: [osx_bundle resourcePath]]; - } - /* It doesn't exist - this is unusual for a bundle. Don't chdir */ - } - } - /* else: not in a bundle so don't chdir */ mode = CGDisplayCurrentMode(kCGDirectMainDisplay); CFNumberGetValue(CFDictionaryGetValue(mode, kCGDisplayRefreshRate), kCFNumberSInt32Type, &refresh_rate); diff --git a/src/app/ini_file.cpp b/src/app/ini_file.cpp index b3e406d8b..19c8a349e 100644 --- a/src/app/ini_file.cpp +++ b/src/app/ini_file.cpp @@ -23,8 +23,10 @@ #include "app/ini_file.h" #include "app/resource_finder.h" + +#ifndef WIN32 #include "base/fs.h" -#include "base/path.h" +#endif #include #include @@ -39,26 +41,21 @@ static std::string g_configFilename; ConfigModule::ConfigModule() { ResourceFinder rf; - rf.includeConfFile(); + rf.includeUserDir("aseprite.ini"); + std::string fn = rf.getFirstOrCreateDefault(); - std::string config_filename; - - // Search the configuration file from first to last path - if (rf.findFirst()) - config_filename = rf.filename(); - - // If the file wasn't found, we will create configuration file - // in the first path - if (config_filename[0] == 0) { - config_filename = rf.defaultFilename(); - - std::string dir = base::get_file_path(config_filename); - if (!base::is_directory(dir)) - base::make_directory(dir); +#ifndef WIN32 // Migrate the configuration file to the new location in Unix-like systems + { + ResourceFinder old_rf; + old_rf.includeHomeDir(".asepriterc"); + std::string old_fn = old_rf.defaultFilename(); + if (base::is_file(old_fn)) + base::move_file(old_fn, fn); } +#endif - override_config_file(config_filename.c_str()); - g_configFilename = config_filename; + override_config_file(fn.c_str()); + g_configFilename = fn; } ConfigModule::~ConfigModule() diff --git a/src/app/resource_finder.cpp b/src/app/resource_finder.cpp index a3c20d1ab..e0f257751 100644 --- a/src/app/resource_finder.cpp +++ b/src/app/resource_finder.cpp @@ -21,6 +21,8 @@ #endif #include "app/resource_finder.h" + +#include "app/app.h" #include "base/fs.h" #include "base/path.h" #include "base/string.h" @@ -91,78 +93,49 @@ void ResourceFinder::includeDataDir(const char* filename) { char buf[4096]; -#if defined ALLEGRO_UNIX || defined ALLEGRO_MACOSX +#ifdef WIN32 - // $HOME/.aseprite/filename - sprintf(buf, ".aseprite/%s", filename); + // $BINDIR/data/filename + sprintf(buf, "data/%s", filename); + includeBinDir(buf); + +#else + + // $HOME/.config/aseprite/filename + sprintf(buf, ".config/aseprite/data/%s", filename); includeHomeDir(buf); // $BINDIR/data/filename sprintf(buf, "data/%s", filename); includeBinDir(buf); - // $BINDIR/../share/aseprite/data/filename - sprintf(buf, "../share/aseprite/data/%s", filename); - includeBinDir(buf); - - #ifdef ALLEGRO_MACOSX - // $BINDIR/aseprite.app/Contents/Resources/data/filename - sprintf(buf, "aseprite.app/Contents/Resources/data/%s", filename); + #ifdef __APPLE__ + // $BINDIR/../Resources/data/filename (inside a bundle) + sprintf(buf, "../Resources/data/%s", filename); + includeBinDir(buf); + #else + // $BINDIR/../share/aseprite/data/filename (installed in /usr/ or /usr/local/) + sprintf(buf, "../share/aseprite/data/%s", filename); includeBinDir(buf); #endif -#elif defined ALLEGRO_WINDOWS || defined ALLEGRO_DOS - - // $BINDIR/data/filename - sprintf(buf, "data/%s", filename); - includeBinDir(buf); - -#else - - // filename - addPath(filename); - -#endif -} - - -void ResourceFinder::includeDocsDir(const char* filename) -{ - char buf[4096]; - -#if defined ALLEGRO_UNIX || defined ALLEGRO_MACOSX - - // $BINDIR/docs/filename - sprintf(buf, "docs/%s", filename); - includeBinDir(buf); - - // $BINDIR/../share/aseprite/docs/filename - sprintf(buf, "../share/aseprite/docs/%s", filename); - includeBinDir(buf); - - #ifdef ALLEGRO_MACOSX - // $BINDIR/aseprite.app/Contents/Resources/docs/filename - sprintf(buf, "aseprite.app/Contents/Resources/docs/%s", filename); - includeBinDir(buf); - #endif - -#elif defined ALLEGRO_WINDOWS || defined ALLEGRO_DOS - - // $BINDIR/docs/filename - sprintf(buf, "docs/%s", filename); - includeBinDir(buf); - -#else - - // filename - addPath(filename); - #endif } void ResourceFinder::includeHomeDir(const char* filename) { -#if defined ALLEGRO_UNIX || defined ALLEGRO_MACOSX +#ifdef WIN32 + + // %AppData%/Aseprite/filename + wchar_t* env = _wgetenv(L"AppData"); + if (env) { + std::string path = base::join_path(base::to_utf8(env), "Aseprite"); + path = base::join_path(path, filename); + addPath(path); + m_default = path; + } + +#else char* env = getenv("HOME"); char buf[4096]; @@ -177,44 +150,49 @@ void ResourceFinder::includeHomeDir(const char* filename) addPath(filename); } -#elif defined ALLEGRO_WINDOWS || defined ALLEGRO_DOS +#endif +} - // %AppData%/Aseprite/filename - wchar_t* env = _wgetenv(L"AppData"); - if (env) { - std::string path = base::join_path(base::to_utf8(env), "Aseprite"); - path = base::join_path(path, filename); - addPath(path); - m_default = path; +void ResourceFinder::includeUserDir(const char* filename) +{ +#ifdef WIN32 + + if (App::instance()->isPortable()) { + // $BINDIR/filename + includeBinDir(filename); + } + else { + // %AppData%/Aseprite/filename + includeHomeDir(filename); } - - // $PREFIX/data/filename - includeDataDir(filename); #else - // filename - addPath(filename); + // $HOME/.config/aseprite/filename + includeHomeDir((std::string(".config/aseprite/") + filename).c_str()); #endif } -void ResourceFinder::includeConfFile() +std::string ResourceFinder::getFirstOrCreateDefault() { -#if defined ALLEGRO_UNIX || defined ALLEGRO_MACOSX + std::string fn; - // $HOME/.asepriterc - includeHomeDir(".asepriterc"); + // Search from first to last path + if (findFirst()) + fn = filename(); -#elif defined ALLEGRO_WINDOWS + // If the file wasn't found, we will create the directories for the + // default file name. + if (fn.empty()) { + fn = defaultFilename(); - // $BINDIR/aseprite.ini - includeBinDir("aseprite.ini"); + std::string dir = base::get_file_path(fn); + if (!base::is_directory(dir)) + base::make_all_directories(dir); + } - // %AppData%/Aseprite/aseprite.ini - includeHomeDir("aseprite.ini"); - -#endif + return fn; } } // namespace app diff --git a/src/app/resource_finder.h b/src/app/resource_finder.h index e746bb496..5f79d7048 100644 --- a/src/app/resource_finder.h +++ b/src/app/resource_finder.h @@ -50,11 +50,21 @@ namespace app { void addPath(const std::string& path); void includeBinDir(const char* filename); void includeDataDir(const char* filename); - void includeDocsDir(const char* filename); void includeHomeDir(const char* filename); - void includeConfFile(); - private: + // Tries to add the given filename in these locations: + // For Windows: + // - If the app is running in portable mode, the filename + // will be in the same location as the .exe file. + // - If the app is installed, the filename will be inside + // %AppData% location + // For Unix-like platforms: + // - The filename will be in $HOME/.config/aseprite/ + void includeUserDir(const char* filename); + + // Returns the first file found or creates the whole directory + // structure to create the file in its default location. + std::string getFirstOrCreateDefault(); private: bool m_log; diff --git a/src/app/send_crash.cpp b/src/app/send_crash.cpp index 4b6890d9a..95a1d6857 100644 --- a/src/app/send_crash.cpp +++ b/src/app/send_crash.cpp @@ -41,12 +41,8 @@ std::string memory_dump_filename() #ifdef WIN32 app::ResourceFinder rf; - if (App::instance()->isPortable()) - rf.includeBinDir(kDefaultCrashName); - else - rf.includeHomeDir(kDefaultCrashName); - - return rf.defaultFilename(); + rf.includeUserDir(kDefaultCrashName); + return rf.getFirstOrCreateDefault(); #else return "";