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
This commit is contained in:
David Capello 2014-08-24 09:00:35 -03:00
parent b291f22c48
commit 33d7b305a2
5 changed files with 89 additions and 132 deletions

View File

@ -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);

View File

@ -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 <allegro/config.h>
#include <allegro/file.h>
@ -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()

View File

@ -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

View File

@ -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;

View File

@ -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 "";