return getLevelDirFromTreeInfo(leveldir_current);
}
+char *getNewUserLevelSubdir()
+{
+ static char *new_level_subdir = NULL;
+ char *subdir_prefix = getLoginName();
+ char subdir_suffix[10];
+ int max_suffix_number = 1000;
+ int i = 0;
+
+ while (++i < max_suffix_number)
+ {
+ sprintf(subdir_suffix, "_%d", i);
+
+ checked_free(new_level_subdir);
+ new_level_subdir = getStringCat2(subdir_prefix, subdir_suffix);
+
+ if (!directoryExists(getUserLevelDir(new_level_subdir)))
+ break;
+ }
+
+ return new_level_subdir;
+}
+
static char *getTapeDir(char *level_subdir)
{
static char *tape_dir = NULL;
return LEVELDIR_ARTWORK_PATH(leveldir_current, type);
}
-char *getProgramConfigFilename(char *command_filename_ptr)
+char *getProgramMainDataPath(char *command_filename, char *base_path)
{
- char *command_filename_1 = getStringCopy(command_filename_ptr);
+ /* check if the program's main data base directory is configured */
+ if (!strEqual(base_path, "."))
+ return base_path;
+
+ /* if the program is configured to start from current directory (default),
+ determine program package directory from program binary (some versions
+ of KDE/Konqueror and Mac OS X (especially "Mavericks") apparently do not
+ set the current working directory to the program package directory) */
+ char *main_data_path = getBasePath(command_filename);
+
+#if defined(PLATFORM_MACOSX)
+ if (strSuffix(main_data_path, MAC_APP_BINARY_SUBDIR))
+ {
+ char *main_data_path_old = main_data_path;
+
+ // cut relative path to Mac OS X application binary directory from path
+ main_data_path[strlen(main_data_path) -
+ strlen(MAC_APP_BINARY_SUBDIR)] = '\0';
+
+ // cut trailing path separator from path (but not if path is root directory)
+ if (strSuffix(main_data_path, "/") && !strEqual(main_data_path, "/"))
+ main_data_path[strlen(main_data_path) - 1] = '\0';
+
+ // replace empty path with current directory
+ if (strEqual(main_data_path, ""))
+ main_data_path = ".";
+
+ // add relative path to Mac OS X application resources directory to path
+ main_data_path = getPath2(main_data_path, MAC_APP_FILES_SUBDIR);
+
+ free(main_data_path_old);
+ }
+#endif
+
+ return main_data_path;
+}
+
+char *getProgramConfigFilename(char *command_filename)
+{
+ char *command_filename_1 = getStringCopy(command_filename);
// strip trailing executable suffix from command filename
if (strSuffix(command_filename_1, ".exe"))
command_filename_1[strlen(command_filename_1) - 4] = '\0';
- char *command_basepath = getBasePath(command_filename_ptr);
- char *command_basename = getBaseNameNoSuffix(command_filename_ptr);
+ char *ro_base_path = getProgramMainDataPath(command_filename, RO_BASE_PATH);
+ char *conf_directory = getPath2(ro_base_path, CONF_DIRECTORY);
+
+ char *command_basepath = getBasePath(command_filename);
+ char *command_basename = getBaseNameNoSuffix(command_filename);
char *command_filename_2 = getPath2(command_basepath, command_basename);
char *config_filename_1 = getStringCat2(command_filename_1, ".conf");
char *config_filename_2 = getStringCat2(command_filename_2, ".conf");
+ char *config_filename_3 = getPath2(conf_directory, SETUP_FILENAME);
// 1st try: look for config file that exactly matches the binary filename
if (fileExists(config_filename_1))
return config_filename_1;
- // 2nd try: return config filename that matches binary filename without suffix
- return config_filename_2;
+ // 2nd try: look for config file that matches binary filename without suffix
+ if (fileExists(config_filename_2))
+ return config_filename_2;
+
+ // 3rd try: return setup config filename in global program config directory
+ return config_filename_3;
}
char *getTapeFilename(int nr)
setString(&ti_new->name_sorting, ti_new->name);
setString(&ti_new->subdir, STRING_TOP_DIRECTORY);
- setString(&ti_new->fullpath, node_first->fullpath);
+ setString(&ti_new->fullpath, ".");
ti_new->sort_priority = node_first->sort_priority;;
ti_new->latest_engine = node_first->latest_engine;
print_timestamp_done("LoadLevelArtworkInfo");
}
-boolean UpdateUserLevelSet(char *level_subdir,
- char *level_name, char *level_author,
- int num_levels, int first_level_nr)
+static boolean AddUserLevelSetToLevelInfoExt(char *level_subdir_new)
+{
+ // get level info tree node of first (original) user level set
+ char *level_subdir_old = getLoginName();
+ LevelDirTree *leveldir_old = getTreeInfoFromIdentifier(leveldir_first,
+ level_subdir_old);
+ if (leveldir_old == NULL) // should not happen
+ return FALSE;
+
+ int draw_deactivation_mask = GetDrawDeactivationMask();
+
+ // override draw deactivation mask (temporarily disable drawing)
+ SetDrawDeactivationMask(REDRAW_ALL);
+
+ // load new level set config and add it next to first user level set
+ LoadLevelInfoFromLevelConf(&leveldir_old->next, NULL,
+ leveldir_old->basepath, level_subdir_new);
+
+ // set draw deactivation mask to previous value
+ SetDrawDeactivationMask(draw_deactivation_mask);
+
+ // get level info tree node of newly added user level set
+ LevelDirTree *leveldir_new = getTreeInfoFromIdentifier(leveldir_first,
+ level_subdir_new);
+ if (leveldir_new == NULL) // should not happen
+ return FALSE;
+
+ // correct top link and parent node link of newly created tree node
+ leveldir_new->node_top = leveldir_old->node_top;
+ leveldir_new->node_parent = leveldir_old->node_parent;
+
+ // sort level info tree to adjust position of newly added level set
+ sortTreeInfo(&leveldir_first);
+
+ return TRUE;
+}
+
+void AddUserLevelSetToLevelInfo(char *level_subdir_new)
+{
+ if (!AddUserLevelSetToLevelInfoExt(level_subdir_new))
+ Error(ERR_EXIT, "internal level set structure corrupted -- aborting");
+}
+
+boolean UpdateUserLevelSet(char *level_subdir, char *level_name,
+ char *level_author, int num_levels)
{
char *filename = getPath2(getUserLevelDir(level_subdir), LEVELINFO_FILENAME);
char *filename_tmp = getStringCat2(filename, ".tmp");
FILE *file = NULL;
FILE *file_tmp = NULL;
char line[MAX_LINE_LEN];
- boolean update_num_levels_only = FALSE;
boolean success = FALSE;
+ LevelDirTree *leveldir = getTreeInfoFromIdentifier(leveldir_first,
+ level_subdir);
+ // update values in level directory tree
+
+ if (level_name != NULL)
+ setString(&leveldir->name, level_name);
- if (level_name == NULL || level_author == NULL || first_level_nr == -1)
- update_num_levels_only = TRUE;
+ if (level_author != NULL)
+ setString(&leveldir->author, level_author);
+
+ if (num_levels != -1)
+ leveldir->levels = num_levels;
+
+ // update values that depend on other values
+
+ setString(&leveldir->name_sorting, leveldir->name);
+
+ leveldir->last_level = leveldir->first_level + leveldir->levels - 1;
+
+ // sort order of level sets may have changed
+ sortTreeInfo(&leveldir_first);
if ((file = fopen(filename, MODE_READ)) &&
(file_tmp = fopen(filename_tmp, MODE_WRITE)))
{
while (fgets(line, MAX_LINE_LEN, file))
{
- if (strPrefix(line, "name:") && !update_num_levels_only)
+ if (strPrefix(line, "name:") && level_name != NULL)
fprintf(file_tmp, "%-32s%s\n", "name:", level_name);
- else if (strPrefix(line, "author:") && !update_num_levels_only)
+ else if (strPrefix(line, "author:") && level_author != NULL)
fprintf(file_tmp, "%-32s%s\n", "author:", level_author);
- else if (strPrefix(line, "levels:"))
+ else if (strPrefix(line, "levels:") && num_levels != -1)
fprintf(file_tmp, "%-32s%d\n", "levels:", num_levels);
- else if (strPrefix(line, "first_level:") && !update_num_levels_only)
- fprintf(file_tmp, "%-32s%d\n", "first_level:", first_level_nr);
else
fputs(line, file_tmp);
}
return success;
}
-boolean CreateUserLevelSet(char *level_subdir,
- char *level_name, char *level_author,
- int num_levels, int first_level_nr)
+boolean CreateUserLevelSet(char *level_subdir, char *level_name,
+ char *level_author, int num_levels)
{
LevelDirTree *level_info;
char *filename;
setString(&level_info->name, level_name);
setString(&level_info->author, level_author);
level_info->levels = num_levels;
- level_info->first_level = first_level_nr;
+ level_info->first_level = 1;
level_info->sort_priority = LEVELCLASS_PRIVATE_START;
level_info->readonly = FALSE;
fprintf(file, "%s\n", getSetupLine(levelinfo_tokens, "", i));
/* just to make things nicer :) */
- if (i == LEVELINFO_TOKEN_AUTHOR)
+ if (i == LEVELINFO_TOKEN_AUTHOR ||
+ i == LEVELINFO_TOKEN_FIRST_LEVEL)
fprintf(file, "\n");
}
static void SaveUserLevelInfo()
{
- CreateUserLevelSet(getLoginName(), getLoginName(), getRealName(), 100, 1);
+ CreateUserLevelSet(getLoginName(), getLoginName(), getRealName(), 100);
}
char *getSetupValue(int type, void *value)