forked from len0rd/rockbox
		
	....Because INT and BOOL are already defined in mingw32. Change-Id: I28ab8189c00002c8f68bc9d0c23d2ae78d9e33d0
		
			
				
	
	
		
			688 lines
		
	
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			688 lines
		
	
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /***************************************************************************
 | |
|  *             __________               __   ___.
 | |
|  *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 | |
|  *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 | |
|  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 | |
|  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 | |
|  *                     \/            \/     \/    \/            \/
 | |
|  * $Id$
 | |
|  *
 | |
|  * This program is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU General Public License
 | |
|  * as published by the Free Software Foundation; either version 2
 | |
|  * of the License, or (at your option) any later version.
 | |
|  *
 | |
|  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 | |
|  * KIND, either express or implied.
 | |
|  *
 | |
|  ****************************************************************************/
 | |
| 
 | |
| #include "plugin.h"
 | |
| #include "lib/configfile.h"
 | |
| 
 | |
| 
 | |
| 
 | |
| /* taken from apps/gui/wps_parser.c */
 | |
| #define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps"
 | |
| #define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps"
 | |
| 
 | |
| #define CONFIG_FILENAME "theme_remove.cfg"
 | |
| #define LOG_FILENAME    "/theme_remove_log.txt"
 | |
| #define RB_FONTS_CONFIG VIEWERS_DIR "/rockbox-fonts.config"
 | |
| 
 | |
| enum remove_option {
 | |
|     ALWAYS_REMOVE,
 | |
|     NEVER_REMOVE,
 | |
|     REMOVE_IF_NOT_USED,
 | |
|     ASK_FOR_REMOVAL,
 | |
|     NUM_REMOVE_OPTION
 | |
| };
 | |
| 
 | |
| struct remove_setting {
 | |
|     const char *name;
 | |
|     const char *prefix, *suffix;
 | |
|     char value[MAX_PATH];
 | |
|     int  option;
 | |
|     int  (*func)(struct remove_setting *);
 | |
|     bool used;
 | |
| };
 | |
| 
 | |
| static int remove_wps(struct remove_setting *);
 | |
| static int remove_icons(struct remove_setting *setting);
 | |
| 
 | |
| enum remove_settings {
 | |
|     REMOVE_FONT,
 | |
|     REMOVE_WPS,
 | |
|     REMOVE_SBS,
 | |
| #ifdef HAVE_REMOTE_LCD
 | |
|     REMOVE_RWPS,
 | |
|     REMOVE_RSBS,
 | |
| #endif
 | |
| #if LCD_DEPTH > 1
 | |
|     REMOVE_BACKDROP,
 | |
| #endif
 | |
|     REMOVE_ICON,
 | |
|     REMOVE_VICON,
 | |
| #ifdef HAVE_REMOTE_LCD
 | |
|     REMOVE_RICON,
 | |
|     REMOVE_RVICON,
 | |
| #endif
 | |
| #ifdef HAVE_LCD_COLOR
 | |
|     REMOVE_COLOURS,
 | |
| #endif
 | |
|     NUM_REMOVE_ITEMS
 | |
| };
 | |
| 
 | |
| static bool create_log = true;
 | |
| static struct remove_setting remove_list[NUM_REMOVE_ITEMS] = {
 | |
|     [REMOVE_FONT] = { "font", FONT_DIR "/", ".fnt", "",
 | |
|         ASK_FOR_REMOVAL, NULL, false },
 | |
|     [REMOVE_WPS] = { "wps", WPS_DIR "/", ".wps", "",
 | |
|         REMOVE_IF_NOT_USED, remove_wps, false },
 | |
|     [REMOVE_SBS] = { "sbs", SBS_DIR "/", ".sbs", "",
 | |
|         REMOVE_IF_NOT_USED, remove_wps, false },
 | |
| #ifdef HAVE_REMOTE_LCD
 | |
|     [REMOVE_RWPS] = { "rwps", WPS_DIR "/", ".rwps", "",
 | |
|         REMOVE_IF_NOT_USED, remove_wps, false },
 | |
|     [REMOVE_RSBS] = { "rsbs", SBS_DIR "/", ".rsbs", "",
 | |
|         REMOVE_IF_NOT_USED, remove_wps, false },
 | |
| #endif
 | |
| #if LCD_DEPTH > 1
 | |
|     [REMOVE_BACKDROP] = { "backdrop", BACKDROP_DIR "/", ".bmp", "",
 | |
|         REMOVE_IF_NOT_USED, NULL, false },
 | |
| #endif
 | |
|     [REMOVE_ICON] = { "iconset", ICON_DIR "/", ".bmp", "",
 | |
|         ASK_FOR_REMOVAL, NULL, false },
 | |
|     [REMOVE_VICON] = { "viewers iconset", ICON_DIR "/", ".bmp", "",
 | |
|         ASK_FOR_REMOVAL, remove_icons, false },
 | |
| #ifdef HAVE_REMOTE_LCD
 | |
|     [REMOVE_RICON] = { "remote iconset", ICON_DIR "/", ".bmp", "",
 | |
|         ASK_FOR_REMOVAL, NULL, false },
 | |
|     [REMOVE_RVICON] = { "remote viewers iconset", ICON_DIR "/", ".bmp", "",
 | |
|         ASK_FOR_REMOVAL, NULL, false },
 | |
| #endif
 | |
| #ifdef HAVE_LCD_COLOR
 | |
|     [REMOVE_COLOURS] = { "filetype colours", THEME_DIR "/", ".colours", "",
 | |
|         ASK_FOR_REMOVAL, NULL, false },
 | |
| #endif
 | |
| };
 | |
| static char *option_names[NUM_REMOVE_OPTION] = {
 | |
|     "always", "never", "not used", "ask",
 | |
| };
 | |
| static struct configdata config[] = {
 | |
|     { TYPE_INT, 0, NUM_REMOVE_OPTION,
 | |
|         { .int_p = &remove_list[REMOVE_FONT].option },
 | |
|         "remove font", option_names },
 | |
|     { TYPE_INT, 0, NUM_REMOVE_OPTION,
 | |
|         { .int_p = &remove_list[REMOVE_WPS].option },
 | |
|         "remove wps", option_names },
 | |
|     { TYPE_INT, 0, NUM_REMOVE_OPTION,
 | |
|         { .int_p = &remove_list[REMOVE_SBS].option },
 | |
|         "remove sbs", option_names },
 | |
| #ifdef HAVE_REMOTE_LCD
 | |
|     { TYPE_INT, 0, NUM_REMOVE_OPTION,
 | |
|         { .int_p = &remove_list[REMOVE_RWPS].option },
 | |
|         "remove rwps", option_names },
 | |
|     { TYPE_INT, 0, NUM_REMOVE_OPTION,
 | |
|         { .int_p = &remove_list[REMOVE_RSBS].option },
 | |
|         "remove rsbs", option_names },
 | |
| #endif
 | |
| #if LCD_DEPTH > 1
 | |
|     { TYPE_INT, 0, NUM_REMOVE_OPTION,
 | |
|         { .int_p = &remove_list[REMOVE_BACKDROP].option },
 | |
|         "remove backdrop", option_names },
 | |
| #endif
 | |
|     { TYPE_INT, 0, NUM_REMOVE_OPTION,
 | |
|         { .int_p = &remove_list[REMOVE_ICON].option },
 | |
|         "remove iconset", option_names },
 | |
|     { TYPE_INT, 0, NUM_REMOVE_OPTION,
 | |
|         { .int_p = &remove_list[REMOVE_VICON].option },
 | |
|         "remove viconset", option_names },
 | |
| #ifdef HAVE_REMOTE_LCD
 | |
|     { TYPE_INT, 0, NUM_REMOVE_OPTION,
 | |
|         { .int_p = &remove_list[REMOVE_RICON].option },
 | |
|         "remove riconset", option_names },
 | |
|     { TYPE_INT, 0, NUM_REMOVE_OPTION,
 | |
|         { .int_p = &remove_list[REMOVE_RVICON].option },
 | |
|         "remove rviconset", option_names },
 | |
| #endif
 | |
| #ifdef HAVE_LCD_COLOR
 | |
|     { TYPE_INT, 0, NUM_REMOVE_OPTION,
 | |
|         { .int_p = &remove_list[REMOVE_COLOURS].option },
 | |
|         "remove colours", option_names },
 | |
| #endif
 | |
|     {TYPE_BOOL, 0, 1, { .bool_p = &create_log },
 | |
|         "create log", NULL},
 | |
| };
 | |
| static const int nb_config = sizeof(config)/sizeof(*config);
 | |
| static char themefile[MAX_PATH];
 | |
| static int log_fd = -1;
 | |
| 
 | |
| static int show_mess(const char *text, const char *file)
 | |
| {
 | |
|     static char buf[MAX_PATH*2];
 | |
| 
 | |
|     if (file)
 | |
|         rb->snprintf(buf, sizeof(buf), "%s: %s", text, file);
 | |
|     else
 | |
|         rb->snprintf(buf, sizeof(buf), "%s", text);
 | |
| 
 | |
|     DEBUGF("%s\n", buf);
 | |
|     if (log_fd >= 0)
 | |
|         rb->fdprintf(log_fd, "%s\n", buf);
 | |
| 
 | |
|     rb->splash(0, buf);
 | |
|     rb->sleep(HZ/4);
 | |
| 
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| /* set full path of file. */
 | |
| static void set_file_name(char *buf, const char*file,
 | |
|                           struct remove_setting *setting)
 | |
| {
 | |
|     int len1, len2;
 | |
|     if (rb->strncasecmp(file, setting->prefix, rb->strlen(setting->prefix)))
 | |
|         rb->snprintf(buf, MAX_PATH, "%s%s", setting->prefix, file);
 | |
|     else
 | |
|         rb->strlcpy(buf, file, MAX_PATH);
 | |
|     len1 = rb->strlen(buf);
 | |
|     len2 = rb->strlen(setting->suffix);
 | |
|     if (rb->strcasecmp(buf+len1-len2, setting->suffix))
 | |
|         rb->strlcpy(&buf[len1], setting->suffix, MAX_PATH-len1);
 | |
| }
 | |
| 
 | |
| /* taken from apps/onplay.c */
 | |
| /* helper function to remove a non-empty directory */
 | |
| static int remove_dir(char* dirname, int len)
 | |
| {
 | |
|     int result = 0;
 | |
|     DIR* dir;
 | |
|     int dirlen = rb->strlen(dirname);
 | |
| 
 | |
|     dir = rb->opendir(dirname);
 | |
|     if (!dir)
 | |
|         return -1; /* open error */
 | |
| 
 | |
|     while (true)
 | |
|     {
 | |
|         struct dirent* entry;
 | |
|         /* walk through the directory content */
 | |
|         entry = rb->readdir(dir);
 | |
|         if (!entry)
 | |
|             break;
 | |
| 
 | |
|         dirname[dirlen] ='\0';
 | |
| 
 | |
|         /* append name to current directory */
 | |
|         rb->snprintf(dirname+dirlen, len-dirlen, "/%s", entry->d_name);
 | |
|         struct dirinfo info = rb->dir_get_info(dir, entry);
 | |
|         if (info.attribute & ATTR_DIRECTORY)
 | |
|         {
 | |
|             /* remove a subdirectory */
 | |
|             if (!rb->strcmp((char *)entry->d_name, ".") ||
 | |
|                 !rb->strcmp((char *)entry->d_name, ".."))
 | |
|                 continue; /* skip these */
 | |
| 
 | |
|             result = remove_dir(dirname, len); /* recursion */
 | |
|             if (result)
 | |
|                 break;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             /* remove a file */
 | |
|             result = rb->remove(dirname);
 | |
|         }
 | |
|         if (ACTION_STD_CANCEL == rb->get_action(CONTEXT_STD, TIMEOUT_NOBLOCK))
 | |
|         {
 | |
|             show_mess("Canceled", NULL);
 | |
|             result = -1;
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
|     rb->closedir(dir);
 | |
| 
 | |
|     if (!result)
 | |
|     {   /* remove the now empty directory */
 | |
|         dirname[dirlen] = '\0'; /* terminate to original length */
 | |
| 
 | |
|         result = rb->rmdir(dirname);
 | |
|         show_mess("Removed", dirname);
 | |
|     }
 | |
| 
 | |
|     return result;
 | |
| }
 | |
| 
 | |
| static int remove_wps(struct remove_setting *setting)
 | |
| {
 | |
|     char bmpdir[MAX_PATH];
 | |
|     char *p;
 | |
|     rb->strcpy(bmpdir, setting->value);
 | |
|     p = rb->strrchr(bmpdir, '.');
 | |
|     if (p) *p = 0;
 | |
|     if (!rb->dir_exists(bmpdir))
 | |
|         return 0;
 | |
|     return remove_dir(bmpdir, MAX_PATH);
 | |
| }
 | |
| 
 | |
| static int remove_icons(struct remove_setting *setting)
 | |
| {
 | |
|     char path[MAX_PATH];
 | |
|     char *p;
 | |
|     rb->strcpy(path, setting->value);
 | |
|     p = rb->strrchr(path, '.');
 | |
|     rb->strlcpy(p, ".icons", path+MAX_PATH-p);
 | |
| 
 | |
|     if (!rb->file_exists(path))
 | |
|     {
 | |
|         return 0;
 | |
|     }
 | |
|     if (rb->remove(path))
 | |
|     {
 | |
|         show_mess("Failed", path);
 | |
|         return 1;
 | |
|     }
 | |
|     show_mess("Removed", path);
 | |
|     return 0;
 | |
| }
 | |
| 
 | |
| static char font_file[MAX_PATH];
 | |
| 
 | |
| static bool is_deny_file(const char *file)
 | |
| {
 | |
|     const char *deny_files[] = {
 | |
|         WPS_DEFAULTCFG,
 | |
|         RWPS_DEFAULTCFG,
 | |
|         font_file,
 | |
|         NULL
 | |
|     };
 | |
|     const char **p = deny_files;
 | |
|     while ( *p )
 | |
|     {
 | |
|         if (!rb->strcmp(file, *p))
 | |
|             return true;
 | |
|         p++;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| static void check_whether_used_in_setting(void)
 | |
| {
 | |
|     const char *setting_files[] = {
 | |
|         rb->global_settings->font_file,
 | |
|         rb->global_settings->wps_file,
 | |
|         rb->global_settings->sbs_file,
 | |
| #ifdef HAVE_REMOTE_LCD
 | |
|         rb->global_settings->rwps_file,
 | |
|         rb->global_settings->rsbs_file,
 | |
| #endif
 | |
| #if LCD_DEPTH > 1
 | |
|         rb->global_settings->backdrop_file,
 | |
| #endif
 | |
|         rb->global_settings->icon_file,
 | |
|         rb->global_settings->viewers_icon_file,
 | |
| #ifdef HAVE_REMOTE_LCD
 | |
|         rb->global_settings->remote_icon_file,
 | |
|         rb->global_settings->remote_viewers_icon_file,
 | |
| #endif
 | |
| #ifdef HAVE_LCD_COLOR
 | |
|         rb->global_settings->colors_file,
 | |
| #endif
 | |
|     };
 | |
|     char tempfile[MAX_PATH];
 | |
|     int i;
 | |
|     for (i=0; i<NUM_REMOVE_ITEMS; i++)
 | |
|     {
 | |
|         struct remove_setting *setting = &remove_list[i];
 | |
|         if (setting->value[0])
 | |
|         {
 | |
|             set_file_name(tempfile, setting_files[i], setting);
 | |
|             if (!rb->strcasecmp(tempfile, setting->value))
 | |
|                 setting->used = true;
 | |
|         }
 | |
|     }
 | |
| }
 | |
| static void check_whether_used_in_file(const char *cfgfile)
 | |
| {
 | |
|     char line[MAX_PATH];
 | |
|     char settingfile[MAX_PATH];
 | |
|     char *p;
 | |
|     int fd;
 | |
|     char *name, *value;
 | |
|     int i;
 | |
| 
 | |
|     if (!rb->strcasecmp(themefile, cfgfile))
 | |
|         return;
 | |
|     fd = rb->open(cfgfile, O_RDONLY);
 | |
|     if (fd < 0)
 | |
|         return;
 | |
|     while (rb->read_line(fd, line, sizeof(line)) > 0)
 | |
|     {
 | |
|         if (!rb->settings_parseline(line, &name, &value))
 | |
|             continue;
 | |
|         /* remove trailing spaces. */
 | |
|         p = value+rb->strlen(value)-1;
 | |
|         while (*p == ' ') *p-- = 0;
 | |
|         if (*value == 0 || !rb->strcmp(value, "-"))
 | |
|             continue;
 | |
|         for (i=0; i<NUM_REMOVE_ITEMS; i++)
 | |
|         {
 | |
|             struct remove_setting *setting = &remove_list[i];
 | |
|             if (!rb->strcmp(name, setting->name))
 | |
|             {
 | |
|                 if (setting->value[0])
 | |
|                 {
 | |
|                     set_file_name(settingfile, value, setting);
 | |
|                     if (!rb->strcasecmp(settingfile, setting->value))
 | |
|                         setting->used = true;
 | |
|                 }
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     rb->close(fd);
 | |
| }
 | |
| static void check_whether_used(void)
 | |
| {
 | |
|     char cfgfile[MAX_PATH];
 | |
|     DIR *dir;
 | |
| 
 | |
|     check_whether_used_in_setting();
 | |
|     /* mark font files come from rockbox-font.zip as used and don't remove
 | |
|      * them automatically as themes may depend on those fonts. */
 | |
|     if (remove_list[REMOVE_FONT].option == REMOVE_IF_NOT_USED)
 | |
|         check_whether_used_in_file(RB_FONTS_CONFIG);
 | |
| 
 | |
|     dir = rb->opendir(THEME_DIR);
 | |
|     if (!dir)
 | |
|         return; /* open error */
 | |
| 
 | |
|     while (true)
 | |
|     {
 | |
|         struct dirent* entry;
 | |
|         char *p;
 | |
|         int i;
 | |
|         /* walk through the directory content */
 | |
|         entry = rb->readdir(dir);
 | |
|         if (!entry)
 | |
|             break;
 | |
|         p = rb->strrchr(entry->d_name, '.');
 | |
|         if (!p || rb->strcmp(p, ".cfg"))
 | |
|             continue;
 | |
| 
 | |
|         rb->snprintf(cfgfile, MAX_PATH, "%s/%s", THEME_DIR, entry->d_name);
 | |
|         check_whether_used_in_file(cfgfile);
 | |
|         /* break the loop if all files need to be checked in the theme
 | |
|          * turned out to be used. */
 | |
|         for (i = 0; i < NUM_REMOVE_ITEMS; i++)
 | |
|         {
 | |
|             struct remove_setting *setting = &remove_list[i];
 | |
|             if (setting->option == REMOVE_IF_NOT_USED)
 | |
|             {
 | |
|                 if (setting->value[0] && !setting->used)
 | |
|                     break;
 | |
|             }
 | |
|         }
 | |
|         if (i == NUM_REMOVE_ITEMS)
 | |
|             break;
 | |
|     }
 | |
|     rb->closedir(dir);
 | |
| }
 | |
| 
 | |
| static int remove_file(struct remove_setting *setting)
 | |
| {
 | |
|     if (!rb->file_exists(setting->value))
 | |
|     {
 | |
|         show_mess("Doesn't exist", setting->value);
 | |
|         return 0;
 | |
|     }
 | |
|     if (is_deny_file(setting->value))
 | |
|     {
 | |
|         show_mess("Denied", setting->value);
 | |
|         return 0;
 | |
|     }
 | |
|     switch (setting->option)
 | |
|     {
 | |
|         case ALWAYS_REMOVE:
 | |
|             break;
 | |
|         case NEVER_REMOVE:
 | |
|             show_mess("Skipped", setting->value);
 | |
|             return 0;
 | |
|             break;
 | |
|         case REMOVE_IF_NOT_USED:
 | |
|             if (setting->used)
 | |
|             {
 | |
|                 show_mess("Used", setting->value);
 | |
|                 return 0;
 | |
|             }
 | |
|             break;
 | |
|         case ASK_FOR_REMOVAL:
 | |
|         default:
 | |
|         {
 | |
|             const char *message_lines[] = { "Delete?", setting->value };
 | |
|             const struct text_message text_message = { message_lines, 2 };
 | |
|             if (rb->gui_syncyesno_run(&text_message, NULL, NULL) != YESNO_YES)
 | |
|             {
 | |
|                 show_mess("Skipped", setting->value);
 | |
|                 return 0;
 | |
|             }
 | |
|         }
 | |
|             break;
 | |
|     }
 | |
|     if (rb->remove(setting->value))
 | |
|     {
 | |
|         show_mess("Failed", setting->value);
 | |
|         return -1;
 | |
|     }
 | |
|     if (setting->func && setting->func(setting))
 | |
|         return -1;
 | |
|     show_mess("Removed", setting->value);
 | |
|     return 1;
 | |
| }
 | |
| static int remove_theme(void)
 | |
| {
 | |
|     static char line[MAX_PATH];
 | |
|     int fd;
 | |
|     int i, num_removed = 0;
 | |
|     char *name, *value;
 | |
|     bool needs_to_check_whether_used = false;
 | |
| 
 | |
|     /* initialize for safe */
 | |
|     for (i=0; i<NUM_REMOVE_ITEMS; i++)
 | |
|         remove_list[i].value[0] = 0;
 | |
| 
 | |
|     /* load settings */
 | |
|     fd = rb->open(themefile, O_RDONLY);
 | |
|     if (fd < 0) return fd;
 | |
|     while (rb->read_line(fd, line, sizeof(line)) > 0)
 | |
|     {
 | |
|         if (!rb->settings_parseline(line, &name, &value))
 | |
|             continue;
 | |
|         /* remove trailing spaces. */
 | |
|         char *p = value+rb->strlen(value)-1;
 | |
|         while (*p == ' ') *p-- = 0;
 | |
|         if (*value == 0 || !rb->strcmp(value, "-"))
 | |
|             continue;
 | |
|         for (i=0; i<NUM_REMOVE_ITEMS; i++)
 | |
|         {
 | |
|             struct remove_setting *setting = &remove_list[i];
 | |
|             if (!rb->strcmp(name, setting->name))
 | |
|             {
 | |
|                 set_file_name(setting->value, value, setting);
 | |
|                 if(setting->option == REMOVE_IF_NOT_USED)
 | |
|                     needs_to_check_whether_used = true;
 | |
|                 break;
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     rb->close(fd);
 | |
| 
 | |
|     if(needs_to_check_whether_used)
 | |
|         check_whether_used();
 | |
| 
 | |
|     /* now remove file assosiated to the theme. */
 | |
|     for (i=0; i<NUM_REMOVE_ITEMS; i++)
 | |
|     {
 | |
|         if (remove_list[i].value[0])
 | |
|         {
 | |
|             int ret = remove_file(&remove_list[i]);
 | |
|             if (ret < 0)
 | |
|                 return ret;
 | |
|             num_removed += ret;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /* remove the setting file iff it is in theme directory to protect
 | |
|      * aginst accidental removal of non theme cfg file. if the file is
 | |
|      * not in the theme directory, the file may not be a theme cfg file. */
 | |
|     if (rb->strncasecmp(themefile, THEME_DIR "/", sizeof(THEME_DIR "/")-1))
 | |
|     {
 | |
|         show_mess("Skipped", themefile);
 | |
|     }
 | |
|     else if (rb->remove(themefile))
 | |
|     {
 | |
|         show_mess("Failed", themefile);
 | |
|         return -1;
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         show_mess("Removed", themefile);
 | |
|         rb->reload_directory();
 | |
|         num_removed++;
 | |
|     }
 | |
|     return num_removed;
 | |
| }
 | |
| 
 | |
| static bool option_changed = false;
 | |
| static bool option_menu(void)
 | |
| {
 | |
|     MENUITEM_STRINGLIST(option_menu, "Remove Options", NULL,
 | |
|                         /* same order as remove_list */
 | |
|                         "Font",
 | |
|                         "WPS",
 | |
|                         "Statusbar Skin",
 | |
| #ifdef HAVE_REMOTE_LCD
 | |
|                         "Remote WPS",
 | |
|                         "Remote Statusbar Skin",
 | |
| #endif
 | |
| #if LCD_DEPTH > 1
 | |
|                         "Backdrop",
 | |
| #endif
 | |
|                         "Iconset", "Viewers Iconset",
 | |
| #ifdef HAVE_REMOTE_LCD
 | |
|                         "Remote Iconset", "Remote Viewers Iconset",
 | |
| #endif
 | |
| #ifdef HAVE_LCD_COLOR
 | |
|                         "Filetype Colours",
 | |
| #endif
 | |
|                         "Create Log File");
 | |
|     struct opt_items remove_names[] = {
 | |
|         {"Always Remove", -1}, {"Never Remove", -1},
 | |
|         {"Remove if not Used", -1}, {"Ask for Removal", -1},
 | |
|     };
 | |
|     int selected = 0, result;
 | |
| 
 | |
|     while (1)
 | |
|     {
 | |
|         result = rb->do_menu(&option_menu, &selected, NULL, false);
 | |
|         if (result >= 0 && result < NUM_REMOVE_ITEMS)
 | |
|         {
 | |
|             struct remove_setting *setting = &remove_list[result];
 | |
|             int prev_option = setting->option;
 | |
|             if (rb->set_option(option_menu_[result], &setting->option, RB_INT,
 | |
|                                remove_names, NUM_REMOVE_OPTION, NULL))
 | |
|                 return true;
 | |
|             if (prev_option != setting->option)
 | |
|                 option_changed = true;
 | |
|         }
 | |
|         else if (result == NUM_REMOVE_ITEMS)
 | |
|         {
 | |
|             bool prev_value = create_log;
 | |
|             if(rb->set_bool("Create Log File", &create_log))
 | |
|                 return true;
 | |
|             if (prev_value != create_log)
 | |
|                 option_changed = true;
 | |
|         }
 | |
|         else if (result == MENU_ATTACHED_USB)
 | |
|             return true;
 | |
|         else
 | |
|             return false;
 | |
|     }
 | |
| 
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| enum plugin_status plugin_start(const void* parameter)
 | |
| {
 | |
|     static char title[64];
 | |
|     char *p;
 | |
|     MENUITEM_STRINGLIST(menu, title, NULL,
 | |
|                         "Remove Theme", "Remove Options",
 | |
|                         "Quit");
 | |
|     int selected = 0, ret;
 | |
|     bool exit = false;
 | |
| 
 | |
|     if (!parameter)
 | |
|         return PLUGIN_ERROR;
 | |
| 
 | |
|     rb->snprintf(title, sizeof(title), "Remove %s",
 | |
|                  rb->strrchr(parameter, '/')+1);
 | |
|     if((p = rb->strrchr(title, '.')))
 | |
|         *p = 0;
 | |
| 
 | |
|     rb->snprintf(font_file, MAX_PATH, FONT_DIR "/%s.fnt",
 | |
|                     rb->global_settings->font_file);
 | |
|     rb->strlcpy(themefile, parameter, MAX_PATH);
 | |
|     if (!rb->file_exists(themefile))
 | |
|     {
 | |
|         rb->splash(HZ, "File open error!");
 | |
|         return PLUGIN_ERROR;
 | |
|     }
 | |
|     configfile_load(CONFIG_FILENAME, config, nb_config, 0);
 | |
|     while (!exit)
 | |
|     {
 | |
|         switch (rb->do_menu(&menu, &selected, NULL, false))
 | |
|         {
 | |
|             case 0:
 | |
|                 if(create_log)
 | |
|                 {
 | |
|                     log_fd = rb->open(LOG_FILENAME, O_WRONLY|O_CREAT|O_APPEND, 0666);
 | |
|                     if(log_fd >= 0)
 | |
|                         rb->fdprintf(log_fd, "---- %s ----\n", title);
 | |
|                     else
 | |
|                         show_mess("Couldn't open log file.", NULL);
 | |
|                 }
 | |
|                 ret = remove_theme();
 | |
|                 p = (ret >= 0? "Successfully removed!": "Remove failure");
 | |
|                 show_mess(p, NULL);
 | |
|                 if(log_fd >= 0)
 | |
|                 {
 | |
|                     rb->fdprintf(log_fd, "----------------\n");
 | |
|                     rb->close(log_fd);
 | |
|                     log_fd = -1;
 | |
|                 }
 | |
|                 rb->lcd_clear_display();
 | |
|                 rb->lcd_update();
 | |
|                 rb->splashf(0, "%s %s", p, "Press any key to exit.");
 | |
|                 rb->button_clear_queue();
 | |
|                 rb->button_get(true);
 | |
|                 exit = true;
 | |
|                 break;
 | |
|             case 1:
 | |
|                 if (option_menu())
 | |
|                     return PLUGIN_USB_CONNECTED;
 | |
|                 break;
 | |
|             case 2:
 | |
|                 exit = true;
 | |
|                 break;
 | |
|             case MENU_ATTACHED_USB:
 | |
|                 return PLUGIN_USB_CONNECTED;
 | |
|                 break;
 | |
|             default:
 | |
|                 break;
 | |
|         }
 | |
|     }
 | |
|     if(option_changed)
 | |
|         configfile_save(CONFIG_FILENAME, config, nb_config, 0);
 | |
|     return PLUGIN_OK;
 | |
| }
 |