ultimatepp/uppsrc/Core/App.cpp
cxl afdd829721 CtrlLib: FileSel now has a left bar with common folders (adjustable by client code)
git-svn-id: svn://ultimatepp.org/upp/trunk@2191 f0d560ea-af0d-0410-9eb7-867de7ffcac7
2010-03-08 00:03:10 +00:00

538 lines
12 KiB
C++

#include "Core.h"
#ifdef PLATFORM_WIN32
#include <shellapi.h>
#endif
NAMESPACE_UPP
#ifdef PLATFORM_WIN32
String GetEnv(const char *id)
{
return WString(_wgetenv(WString(id))).ToString();
}
String GetExeFilePath()
{
return GetModuleFileName();
}
String GetHomeDirectory() {
return GetEnv("HOMEDRIVE") + GetEnv("HOMEPATH");
}
#endif
#ifdef PLATFORM_POSIX
String GetEnv(const char *id)
{
return FromSystemCharset(getenv(id));
}
char Argv0__[_MAX_PATH + 1];
static void sSetArgv0__(const char *title)
{
strcpy(Argv0__, title);
}
extern char Argv0__[];
const char *procexepath_() {
static char h[_MAX_PATH + 1];
ONCELOCK {
char link[100];
#ifdef PLATFORM_BSD
sprintf(link, "/proc/%d/file", getpid());
#else
sprintf(link, "/proc/%d/exe", getpid());
#endif
int ret = readlink(link, h, _MAX_PATH);
if(ret > 0 && ret < _MAX_PATH)
h[ret] = '\0';
else
*h = '\0';
}
return h;
}
String GetExeFilePath()
{
static String exepath;
ONCELOCK {
const char *exe = procexepath_();
if(*exe)
exepath = exe;
else {
String x = Argv0__;
if(IsFullPath(x) && FileExists(x))
exepath = x;
else {
exepath = GetHomeDirFile("upp");
Vector<String> p = Split(FromSystemCharset(Environment().Get("PATH")), ':');
if(x.Find('/') >= 0)
p.Add(GetCurrentDirectory());
for(int i = 0; i < p.GetCount(); i++) {
String ep = NormalizePath(AppendFileName(p[i], x));
if(FileExists(ep))
exepath = ep;
}
}
}
}
return exepath;
}
#endif
String GetExeDirFile(const char *filename)
{
return AppendFileName(GetFileFolder(GetExeFilePath()), filename);
}
String GetExeTitle()
{
return GetFileTitle(GetExeFilePath());
}
#ifdef PLATFORM_POSIX
static StaticCriticalSection sHlock;
String& sHomeDir() {
static String s;
return s;
}
String GetHomeDirectory() {
String r;
INTERLOCKED_(sHlock) {
String& s = sHomeDir();
if(s.IsEmpty()) {
s = Nvl(GetEnv("HOME"), "/root");
}
r = s;
}
return r;
}
void SetHomeDirectory(const char *dir)
{
INTERLOCKED_(sHlock) {
sHomeDir() = dir;
}
}
#endif//PLATFORM_POSIX
String GetHomeDirFile(const char *fp) {
return AppendFileName(GetHomeDirectory(), fp);
}
static bool sHomecfg;
void UseHomeDirectoryConfig(bool b)
{
sHomecfg = b;
}
String ConfigFile(const char *file) {
#if defined(PLATFORM_WIN32)
if(sHomecfg) {
String p = GetHomeDirFile(GetExeTitle());
ONCELOCK
RealizeDirectory(p);
return AppendFileName(p, file);
}
return GetExeDirFile(file);
#elif defined(PLATFORM_POSIX)
String p = GetHomeDirFile(".upp/" + GetExeTitle());
ONCELOCK
RealizeDirectory(p);
return AppendFileName(p, file);
#else
#error ConfigFile not implemented for this platform, comment this line to get input string back
return file;
#endif//PLATFORM
}
String ConfigFile() {
return ConfigFile(GetExeTitle() + ".cfg");
}
GLOBAL_VAR(Vector<String>, coreCmdLine__)
const Vector<String>& CommandLine()
{
return coreCmdLine__();
}
VectorMap<WString, WString>& EnvMap()
{
static VectorMap<WString, WString> x;
return x;
}
const VectorMap<String, String>& Environment()
{
static VectorMap<String, String> *ptr = NULL;
INTERLOCKED {
static VectorMap<String, String> env;
static int echrset;
if(!ptr || GetDefaultCharset() != echrset) {
env.Clear();
echrset = GetDefaultCharset();
for(int i = 0; i < EnvMap().GetCount(); i++)
env.Add(EnvMap().GetKey(i).ToString(), EnvMap()[i].ToString());
ptr = &env;
}
}
return *ptr;
}
static int exitcode;
static bool sMainRunning;
void SetExitCode(int code) { exitcode = code; }
int GetExitCode() { return exitcode; }
bool IsMainRunning()
{
return sMainRunning;
}
void LoadLangFiles(const char *dir)
{
FindFile ff(AppendFileName(dir, "*.tr"));
while(ff) {
LoadLngFile(AppendFileName(dir, ff.GetName()));
ff.Next();
}
}
void CommonInit()
{
#ifdef PLATFORM_WIN32
LoadLangFiles(GetFileFolder(GetExeFilePath()));
#else
LoadLangFiles(GetHomeDirectory());
#endif
Vector<String>& cmd = coreCmdLine__();
for(int i = 0; i < cmd.GetCount();) {
if(cmd[i] == "--export-tr") {
{
i++;
int lang = 0;
byte charset = CHARSET_UTF8;
String fn = "all";
if(i < cmd.GetCount())
if(cmd[i].GetLength() != 4 && cmd[i].GetLength() != 5)
lang = 0;
else {
lang = LNGFromText(cmd[i]);
fn = cmd[i];
int c = cmd[i][4];
if(c >= '0' && c <= '8')
charset = c - '0' + CHARSET_WIN1250;
if(c >= 'A' && c <= 'J')
charset = c - 'A' + CHARSET_ISO8859_1;
}
fn << ".tr";
#ifdef PLATFORM_WIN32
FileOut out(GetExeDirFile(fn));
#else
FileOut out(GetHomeDirFile(fn));
#endif
if(lang)
SaveLngFile(out, SetLNGCharset(lang, charset));
else {
Index<int> l = GetLngSet();
for(int i = 0; i < l.GetCount(); i++)
SaveLngFile(out, SetLNGCharset(l[i], charset));
}
}
exit(0);
}
#if defined(_DEBUG) && defined(UPP_HEAP)
if(cmd[i] == "--memory-breakpoint__" && i + 1 < cmd.GetCount()) {
MemoryBreakpoint(atoi(cmd[i + 1]));
cmd.Remove(i, 2);
}
else
i++;
#else
i++;
#endif
}
sMainRunning = true;
}
#ifdef PLATFORM_POSIX
void s_ill_handler(int)
{
Panic("Illegal instruction!");
}
void s_segv_handler(int)
{
Panic("Invalid memory access!");
}
void s_fpe_handler(int)
{
Panic("Invalid arithmetic operation!");
}
void AppInit__(int argc, const char **argv, const char **envptr)
{
SetLanguage(LNG_ENGLISH);
sSetArgv0__(argv[0]);
for(const char *var; (var = *envptr) != 0; envptr++)
{
const char *b = var;
while(*var && *var != '=')
var++;
String varname(b, var);
if(*var == '=')
var++;
EnvMap().Add(varname.ToWString(), String(var).ToWString());
}
Vector<String>& cmd = coreCmdLine__();
for(int i = 1; i < argc; i++)
cmd.Add(argv[i]);
CommonInit();
signal(SIGILL, s_ill_handler);
signal(SIGSEGV, s_segv_handler);
signal(SIGBUS, s_segv_handler);
signal(SIGFPE, s_fpe_handler);
}
#endif
#if defined(PLATFORM_WIN32)
void AppInitEnvironment__()
{
#ifndef PLATFORM_WINCE
wchar *env = GetEnvironmentStringsW();
for(wchar *ptr = env; *ptr; ptr++)
{
const wchar *b = ptr;
if(*ptr)
ptr++;
while(*ptr && *ptr != '=')
ptr++;
WString varname(b, ptr);
if(*ptr)
ptr++;
b = ptr;
while(*ptr)
ptr++;
EnvMap().GetAdd(ToUpper(varname)) = WString(b, ptr);
}
FreeEnvironmentStringsW(env);
#endif
CommonInit();
}
void AppInit__(int argc, const char **argv)
{
SetLanguage(LNG_ENGLISH);
Vector<String>& cmd = coreCmdLine__();
for(int i = 1; i < argc; i++)
cmd.Add(argv[i]);
AppInitEnvironment__();
}
#endif
void AppExit__()
{
sMainRunning = false;
#ifdef PLATFORM_POSIX
MemoryIgnoreLeaksBegin(); // Qt leaks on app exit...
#endif
}
void LaunchWebBrowser(const String& url)
{
#if defined(PLATFORM_WIN32) && !defined(PLATFORM_WINCE)
ShellExecute(NULL, "open", url, NULL, ".", SW_SHOWDEFAULT);
#endif
#ifdef PLATFORM_POSIX
const char * browser[] = {
"htmlview", "xdg-open", "x-www-browser", "firefox", "konqueror", "opera", "epiphany", "galeon", "netscape"
};
for(int i = 0; i < __countof(browser); i++)
if(system("which " + String(browser[i])) == 0) {
system(String(browser[i]) + " " + url + " &");
break;
}
#endif
}
String GetDataFile(const char *filename)
{
String s = GetEnv("UPP_MAIN__");
return s.GetCount() ? AppendFileName(s, filename) : GetExeDirFile(filename);
}
String GetComputerName()
{
char temp[256];
*temp = 0;
#if defined(PLATFORM_WIN32)
dword w = 255;
::GetComputerNameA(temp, &w);
#else
gethostname(temp, sizeof(temp));
#endif
return FromSystemCharset(temp);
}
String GetUserName()
{
char temp[256];
*temp = 0;
#if defined(PLATFORM_WIN32)
dword w = 255;
::GetUserNameA(temp, &w);
return FromSystemCharset(temp);
#else
return Nvl(GetEnv("USER"), "boot");
#endif
}
String GetDesktopManager()
{
#if defined(PLATFORM_WIN32) && !defined(PLATFORM_WINCE)
return "windows";
#endif
#ifdef PLATFORM_POSIX
if(GetEnv("GNOME_DESKTOP_SESSION_ID").GetCount())
return "gnome";
if(GetEnv("KDE_FULL_SESSION").GetCount() || GetEnv("KDEDIR").GetCount())
return "kde";
return GetEnv("DESKTOP_SESSION");
#endif
}
#if defined(PLATFORM_WIN32)
String GetShellFolder(const char *local, const char *users)
{
String ret = FromSystemCharset(GetWinRegString(local, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
HKEY_CURRENT_USER));
if (ret == "" && *users != '\0')
return FromSystemCharset(GetWinRegString(users, "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders",
HKEY_LOCAL_MACHINE));
return ret;
}
String GetDesktopFolder() {return GetShellFolder("Desktop", "Common Desktop");}
String GetProgramsFolder() {return FromSystemCharset(GetWinRegString("ProgramFilesDir", "Software\\Microsoft\\Windows\\CurrentVersion", HKEY_LOCAL_MACHINE));}
String GetAppDataFolder() {return GetShellFolder("AppData", "Common AppData");}
String GetMusicFolder() {return GetShellFolder("My Music", "CommonMusic");}
String GetPicturesFolder() {return GetShellFolder("My Pictures", "CommonPictures");}
String GetVideoFolder() {return GetShellFolder("My Video", "CommonVideo");}
String GetPersonalFolder() {return GetShellFolder("Personal", 0);}
String GetTemplatesFolder() {return GetShellFolder("Templates", "Common Templates");}
String GetDownloadFolder()
{
String ret = FromSystemCharset(GetWinRegString("Download Directory", "Software\\Microsoft\\Internet Explorer", HKEY_CURRENT_USER));
if (ret == "")
ret = FromSystemCharset(GetWinRegString("Save Directory", "Software\\Microsoft\\Internet Explorer\\Main", HKEY_CURRENT_USER));
return ret;
};
String GetOsFolder()
{
char ret[MAX_PATH];
::GetWindowsDirectory(ret, MAX_PATH);
return String(ret);
}
String GetSystemFolder()
{
char ret[MAX_PATH];
::GetSystemDirectory(ret, MAX_PATH);
return String(ret);
}
#endif
#ifdef PLATFORM_POSIX
String GetPathXdg(String xdgConfigHome, String xdgConfigDirs)
{
String ret = "";
if (FileExists(ret = AppendFileName(xdgConfigHome, "user-dirs.dirs"))) ;
else if (FileExists(ret = AppendFileName(xdgConfigDirs, "user-dirs.defaults"))) ;
else if (FileExists(ret = AppendFileName(xdgConfigDirs, "user-dirs.dirs"))) ;
return ret;
}
String GetPathDataXdg(String fileConfig, const char *folder)
{
StringParse fileData = LoadFile(fileConfig);
if (!fileData.GoAfter(folder)) return "";
if (!fileData.GoAfter("=")) return "";
String ret = "";
StringParse path = fileData.GetText();
if(path.GoAfter("$HOME/"))
ret = AppendFileName(GetHomeDirectory(), path.Right());
else if (!FileExists(path))
ret = AppendFileName(GetHomeDirectory(), path);
return ret;
}
String GetShellFolder(const char *local, const char *users)
{
String xdgConfigHome = GetEnv("XDG_CONFIG_HOME");
if (xdgConfigHome == "") // By default
xdgConfigHome = AppendFileName(GetHomeDirectory(), ".config");
String xdgConfigDirs = GetEnv("XDG_CONFIG_DIRS");
if (xdgConfigDirs == "") // By default
xdgConfigDirs = "/etc/xdg";
String xdgFileConfigData = GetPathXdg(xdgConfigHome, xdgConfigDirs);
String ret = GetPathDataXdg(xdgFileConfigData, local);
if (ret == "" && *users != '\0')
return GetPathDataXdg(xdgFileConfigData, users);
else
return ret;
}
String GetDesktopFolder()
{
String ret = GetShellFolder("XDG_DESKTOP_DIR", "DESKTOP");
if (ret.IsEmpty())
return AppendFileName(GetHomeDirectory(), "Desktop");
else
return ret;
}
String GetProgramsFolder() {return String("/usr/bin");}
String GetAppDataFolder() {return GetHomeDirectory();};
String GetMusicFolder() {return GetShellFolder("XDG_MUSIC_DIR", "MUSIC");}
String GetPicturesFolder() {return GetShellFolder("XDG_PICTURES_DIR", "PICTURES");}
String GetVideoFolder() {return GetShellFolder("XDG_VIDEOS_DIR", "VIDEOS");}
String GetPersonalFolder() {return GetShellFolder("XDG_DOCUMENTS_DIR", "DOCUMENTS");}
String GetTemplatesFolder() {return GetShellFolder("XDG_TEMPLATES_DIR", "XDG_TEMPLATES_DIR");}
String GetDownloadFolder()
{
return GetHomeDirFile("Downloads"); // wrong!
};
String GetTempFolder()
{
return GetHomeDirectory();
}
String GetOsFolder()
{
return String("/bin");
}
String GetSystemFolder()
{
return String("");
}
#endif
END_UPP_NAMESPACE