#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <errno.h>
#include "../ui/toolkit.h"
#include "properties.h"
#include <cx/string.h>
#include <cx/buffer.h>
#include <cx/hash_map.h>
#include "ucx_properties.h"
static CxMap *application_properties;
static CxMap *language;
#ifndef UI_COCOA
static char *locales_dir;
static char *pixmaps_dir;
#endif
char* ui_getappdir(
void) {
if(ui_appname() ==
NULL) {
return NULL;
}
return ui_configfile(
NULL);
}
#ifndef _WIN32
#define UI_PATH_SEPARATOR '/'
#define UI_ENV_HOME "HOME"
#else
#define UI_PATH_SEPARATOR '\\'
#define UI_ENV_HOME "USERPROFILE"
#endif
char* ui_configfile(
char *name) {
const char *appname = ui_appname();
if(!appname) {
return NULL;
}
CxBuffer buf;
cxBufferInit(&buf,
NULL,
128, cxDefaultAllocator,
CX_BUFFER_FREE_CONTENTS|
CX_BUFFER_AUTO_EXTEND);
char *homeenv = getenv(
UI_ENV_HOME);
if(homeenv ==
NULL) {
cxBufferDestroy(&buf);
return NULL;
}
cxstring home = cx_str(homeenv);
cxBufferWrite(home.ptr,
1, home.length, &buf);
if(home.ptr[home.length-
1] !=
UI_PATH_SEPARATOR) {
cxBufferPut(&buf,
UI_PATH_SEPARATOR);
}
#ifdef UI_COCOA
cxBufferPutString(&buf,
"Library/Application Support/");
#elif defined(
_WIN32)
cxBufferPutString(&buf,
"AppData\\Local\\");
#else
cxBufferPut(&buf,
'.');
#endif
cxBufferPutString(&buf, appname);
cxBufferPut(&buf,
UI_PATH_SEPARATOR);
if(name) {
cxBufferPutString(&buf, name);
}
cxBufferPut(&buf,
0);
return buf.space;
}
static int ui_mkdir(
char *path) {
#ifdef _WIN32
return mkdir(path);
#else
return mkdir(path,
S_IRWXU);
#endif
}
void uic_load_app_properties() {
application_properties = cxHashMapCreate(cxDefaultAllocator,
CX_STORE_POINTERS,
128);
if(!ui_appname()) {
return;
}
char *dir = ui_configfile(
NULL);
if(!dir) {
return;
}
if(ui_mkdir(dir)) {
if(errno !=
EEXIST) {
fprintf(stderr,
"Ui Error: Cannot create directory %s\n", dir);
free(dir);
return;
}
}
free(dir);
char *path = ui_configfile(
"application.properties");
if(!path) {
return;
}
FILE *file = fopen(path,
"r");
if(!file) {
free(path);
return;
}
if(ucx_properties_load(application_properties, file)) {
fprintf(stderr,
"Ui Error: Cannot load application properties.\n");
}
fclose(file);
free(path);
}
int uic_store_app_properties() {
char *path = ui_configfile(
"application.properties");
if(!path) {
return 1;
}
FILE *file = fopen(path,
"w");
if(!file) {
fprintf(stderr,
"Ui Error: Cannot open properties file: %s\n", path);
free(path);
return 1;
}
int ret =
0;
if(ucx_properties_store(application_properties, file)) {
fprintf(stderr,
"Ui Error: Cannot store application properties.\n");
ret =
1;
}
fclose(file);
free(path);
return ret;
}
const char* ui_get_property(
const char *name) {
return cxMapGet(application_properties, name);
}
void ui_set_property(
const char *name,
const char *value) {
cxMapPut(application_properties, name, (
char*)value);
}
const char* ui_set_default_property(
const char *name,
const char *value) {
const char *v = cxMapGet(application_properties, name);
if(!v) {
cxMapPut(application_properties, name, (
char*)value);
v = value;
}
return v;
}
int ui_properties_store(
void) {
return uic_store_app_properties();
}
static char* uic_concat_path(
const char *base,
const char *p,
const char *ext) {
size_t baselen = strlen(base);
CxBuffer *buf = cxBufferCreate(
NULL,
32, cxDefaultAllocator,
CX_BUFFER_FREE_CONTENTS|
CX_BUFFER_AUTO_EXTEND);
if(baselen >
0) {
cxBufferWrite(base,
1, baselen, buf);
if(base[baselen -
1] !=
'/') {
cxBufferPut(buf,
'/');
}
}
cxBufferWrite(p,
1, strlen(p), buf);
if(ext) {
cxBufferWrite(ext,
1, strlen(ext), buf);
}
char *str = buf->space;
free(buf);
return str;
}
#ifndef UI_COCOA
void ui_locales_dir(
char *path) {
locales_dir = path;
}
void ui_pixmaps_dir(
char *path) {
pixmaps_dir = path;
}
char* uic_get_image_path(
const char *imgfilename) {
if(pixmaps_dir) {
return uic_concat_path(pixmaps_dir, imgfilename,
NULL);
}
else {
return NULL;
}
}
void ui_load_lang(
char *locale) {
if(!locale) {
locale =
"en_EN";
}
char *path = uic_concat_path(locales_dir, locale,
".properties");
uic_load_language_file(path);
free(path);
}
void ui_load_lang_def(
char *locale,
char *default_locale) {
char tmp[
6];
if(!locale) {
char *lang = getenv(
"LANG");
if(lang && strlen(lang) >=
5) {
memcpy(tmp, lang,
5);
tmp[
5] =
'\0';
locale = tmp;
}
else {
locale = default_locale;
}
}
char *path = uic_concat_path(locales_dir, locale,
".properties");
if(uic_load_language_file(path)) {
if(default_locale) {
ui_load_lang_def(default_locale,
NULL);
}
else {
fprintf(stderr,
"Ui Error: Cannot load language.\n");
free(path);
exit(-
1);
}
}
free(path);
}
#endif
int uic_load_language_file(
const char *path) {
CxMap *lang = cxHashMapCreate(cxDefaultAllocator,
CX_STORE_POINTERS,
256);
FILE *file = fopen(path,
"r");
if(!file) {
return 1;
}
if(ucx_properties_load(lang, file)) {
fprintf(stderr,
"Ui Error: Cannot parse language file: %s.\n", path);
}
fclose(file);
cxMapRehash(lang);
language = lang;
return 0;
}
char* uistr(
char *name) {
char *value = uistr_n(name);
return value ? value :
"missing string";
}
char* uistr_n(
char *name) {
if(!language) {
return NULL;
}
return cxMapGet(language, name);
}