diff options
author | Teruaki Kawashima <teru@rockbox.org> | 2009-10-12 13:55:59 +0000 |
---|---|---|
committer | Teruaki Kawashima <teru@rockbox.org> | 2009-10-12 13:55:59 +0000 |
commit | 4d900bd786b37a2d9a5bdff0d557c667d6d897ba (patch) | |
tree | c481ab7a733ad2c6f5617a554afa56e208c0093c | |
parent | 7a5904cf1c7fbe27bdb383322d0c45eebb401f33 (diff) | |
download | rockbox-4d900bd786b37a2d9a5bdff0d557c667d6d897ba.tar.gz rockbox-4d900bd786b37a2d9a5bdff0d557c667d6d897ba.zip |
New plugin theme_remove which offers a way to remove specified theme.
See the manual for usage.
Flyspray: FS#10187
Author: myself, manual by David Kauffmann
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23130 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r-- | apps/plugins/CATEGORIES | 1 | ||||
-rw-r--r-- | apps/plugins/SOURCES | 1 | ||||
-rw-r--r-- | apps/plugins/rockbox-fonts.config | 73 | ||||
-rw-r--r-- | apps/plugins/theme_remove.c | 702 | ||||
-rw-r--r-- | apps/plugins/viewers.config | 1 | ||||
-rw-r--r-- | manual/plugins/main.tex | 2 | ||||
-rw-r--r-- | manual/plugins/theme_remove.tex | 77 | ||||
-rwxr-xr-x | tools/buildzip.pl | 1 |
8 files changed, 858 insertions, 0 deletions
diff --git a/apps/plugins/CATEGORIES b/apps/plugins/CATEGORIES index ae764ca125..6809844efb 100644 --- a/apps/plugins/CATEGORIES +++ b/apps/plugins/CATEGORIES | |||
@@ -103,6 +103,7 @@ test_touchscreen,apps | |||
103 | test_viewports,apps | 103 | test_viewports,apps |
104 | test_greylib_bitmap_scale,viewers | 104 | test_greylib_bitmap_scale,viewers |
105 | text_editor,apps | 105 | text_editor,apps |
106 | theme_remove,viewers | ||
106 | vbrfix,viewers | 107 | vbrfix,viewers |
107 | video,viewers | 108 | video,viewers |
108 | viewer,viewers | 109 | viewer,viewers |
diff --git a/apps/plugins/SOURCES b/apps/plugins/SOURCES index a15564d0be..d89b0b6e5f 100644 --- a/apps/plugins/SOURCES +++ b/apps/plugins/SOURCES | |||
@@ -16,6 +16,7 @@ snow.c | |||
16 | sort.c | 16 | sort.c |
17 | stats.c | 17 | stats.c |
18 | stopwatch.c | 18 | stopwatch.c |
19 | theme_remove.c | ||
19 | vbrfix.c | 20 | vbrfix.c |
20 | viewer.c | 21 | viewer.c |
21 | #ifdef HAVE_BACKLIGHT | 22 | #ifdef HAVE_BACKLIGHT |
diff --git a/apps/plugins/rockbox-fonts.config b/apps/plugins/rockbox-fonts.config new file mode 100644 index 0000000000..4995d71864 --- /dev/null +++ b/apps/plugins/rockbox-fonts.config | |||
@@ -0,0 +1,73 @@ | |||
1 | font: 05-Tiny | ||
2 | font: 06-Tiny | ||
3 | font: 07-Fixed | ||
4 | font: 08-Atadore | ||
5 | font: 08-Fixed | ||
6 | font: 08-Namil | ||
7 | font: 08-Nedore | ||
8 | font: 08-Rockbox-Propfont | ||
9 | font: 08-Rockfont | ||
10 | font: 08-Sazanami-Mincho | ||
11 | font: 08-Schumacher-Clean | ||
12 | font: 09-Fixed | ||
13 | font: 09-Nedore | ||
14 | font: 09-Sazanami-Mincho | ||
15 | font: 10-Adobe-Helvetica | ||
16 | font: 10-Adobe-Helvetica-Bold | ||
17 | font: 10-Artwiz-Snap | ||
18 | font: 10-Fixed | ||
19 | font: 10-Nimbus | ||
20 | font: 10-ProFont | ||
21 | font: 10-Sazanami-Mincho | ||
22 | font: 11-Nimbus | ||
23 | font: 11-ProFont | ||
24 | font: 11-Sazanami-Mincho | ||
25 | font: 12-Adobe-Helvetica | ||
26 | font: 12-Adobe-Helvetica-Bold | ||
27 | font: 12-Fixed-SemiCond | ||
28 | font: 12-Nimbus | ||
29 | font: 12-ProFont | ||
30 | font: 12-Sazanami-Mincho | ||
31 | font: 12-Terminus | ||
32 | font: 13-Fixed | ||
33 | font: 13-Fixed-Bold | ||
34 | font: 13-Fixed-SemiCond | ||
35 | font: 13-Fixed-SemiCond-Bold | ||
36 | font: 13-Nimbus | ||
37 | font: 13-Sazanami-Mincho | ||
38 | font: 14-Adobe-Helvetica-Bold | ||
39 | font: 14-Nimbus | ||
40 | font: 14-Rockbox-Mix | ||
41 | font: 14-Sazanami-Mincho | ||
42 | font: 14-Terminus | ||
43 | font: 14-Terminus-Bold | ||
44 | font: 15-Adobe-Helvetica | ||
45 | font: 15-ProFont | ||
46 | font: 16-Adobe-Helvetica | ||
47 | font: 16-Adobe-Helvetica-Bold | ||
48 | font: 16-GNU-Unifont | ||
49 | font: 16-Jackash | ||
50 | font: 16-Terminus | ||
51 | font: 16-Terminus-Bold | ||
52 | font: 17-ProFont | ||
53 | font: 18-Adobe-Helvetica | ||
54 | font: 18-Adobe-Helvetica-Bold | ||
55 | font: 18-Fixed | ||
56 | font: 18-Fixed-Bold | ||
57 | font: 19-Nimbus | ||
58 | font: 20-Terminus | ||
59 | font: 20-Terminus-Bold | ||
60 | font: 21-Adobe-Helvetica | ||
61 | font: 21-Adobe-Helvetica-Bold | ||
62 | font: 22-ProFont | ||
63 | font: 24-Terminus | ||
64 | font: 24-Terminus-Bold | ||
65 | font: 27-Adobe-Helvetica | ||
66 | font: 27-Adobe-Helvetica-Bold | ||
67 | font: 28-Terminus | ||
68 | font: 28-Terminus-Bold | ||
69 | font: 29-ProFont | ||
70 | font: 32-Terminus | ||
71 | font: 32-Terminus-Bold | ||
72 | font: 35-Adobe-Helvetica | ||
73 | font: 35-Adobe-Helvetica-Bold | ||
diff --git a/apps/plugins/theme_remove.c b/apps/plugins/theme_remove.c new file mode 100644 index 0000000000..a2e7bf21a5 --- /dev/null +++ b/apps/plugins/theme_remove.c | |||
@@ -0,0 +1,702 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version 2 | ||
13 | * of the License, or (at your option) any later version. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | |||
20 | #include "plugin.h" | ||
21 | #include "lib/configfile.h" | ||
22 | |||
23 | PLUGIN_HEADER | ||
24 | |||
25 | /* taken from apps/gui/wps_parser.c */ | ||
26 | #define WPS_DEFAULTCFG WPS_DIR "/rockbox_default.wps" | ||
27 | #define RWPS_DEFAULTCFG WPS_DIR "/rockbox_default.rwps" | ||
28 | |||
29 | #define CONFIG_FILENAME "theme_remove.cfg" | ||
30 | #define LOG_FILENAME "/theme_remove_log.txt" | ||
31 | #define RB_FONTS_CONFIG VIEWERS_DIR "/rockbox-fonts.config" | ||
32 | |||
33 | enum remove_option { | ||
34 | ALWAYS_REMOVE, | ||
35 | NEVER_REMOVE, | ||
36 | REMOVE_IF_NOT_USED, | ||
37 | ASK_FOR_REMOVAL, | ||
38 | NUM_REMOVE_OPTION | ||
39 | }; | ||
40 | |||
41 | struct remove_setting { | ||
42 | const char *name; | ||
43 | const char *prefix, *suffix; | ||
44 | char value[MAX_PATH]; | ||
45 | int option; | ||
46 | int (*func)(struct remove_setting *); | ||
47 | bool used; | ||
48 | }; | ||
49 | |||
50 | static int remove_wps(struct remove_setting *); | ||
51 | #ifdef HAVE_LCD_BITMAP | ||
52 | static int remove_icons(struct remove_setting *setting); | ||
53 | #endif | ||
54 | |||
55 | enum remove_settings { | ||
56 | #ifdef HAVE_LCD_BITMAP | ||
57 | REMOVE_FONT, | ||
58 | #endif | ||
59 | REMOVE_WPS, | ||
60 | #ifdef HAVE_REMOTE_LCD | ||
61 | REMOVE_RWPS, | ||
62 | #endif | ||
63 | #if LCD_DEPTH > 1 | ||
64 | REMOVE_BACKDROP, | ||
65 | #endif | ||
66 | #ifdef HAVE_LCD_BITMAP | ||
67 | REMOVE_ICON, | ||
68 | REMOVE_VICON, | ||
69 | #endif | ||
70 | #ifdef HAVE_REMOTE_LCD | ||
71 | REMOVE_RICON, | ||
72 | REMOVE_RVICON, | ||
73 | #endif | ||
74 | #ifdef HAVE_LCD_COLOR | ||
75 | REMOVE_COLOURS, | ||
76 | #endif | ||
77 | NUM_REMOVE_ITEMS | ||
78 | }; | ||
79 | |||
80 | static bool create_log = true; | ||
81 | static struct remove_setting remove_list[NUM_REMOVE_ITEMS] = { | ||
82 | #ifdef HAVE_LCD_BITMAP | ||
83 | [REMOVE_FONT] = { "font", FONT_DIR "/", ".fnt", "", | ||
84 | ASK_FOR_REMOVAL, NULL, false }, | ||
85 | #endif | ||
86 | [REMOVE_WPS] = { "wps", WPS_DIR "/", ".wps", "", | ||
87 | REMOVE_IF_NOT_USED, remove_wps, false }, | ||
88 | #ifdef HAVE_REMOTE_LCD | ||
89 | [REMOVE_RWPS] = { "rwps", WPS_DIR "/", ".rwps", "", | ||
90 | REMOVE_IF_NOT_USED, remove_wps, false }, | ||
91 | #endif | ||
92 | #if LCD_DEPTH > 1 | ||
93 | [REMOVE_BACKDROP] = { "backdrop", BACKDROP_DIR "/", ".bmp", "", | ||
94 | REMOVE_IF_NOT_USED, NULL, false }, | ||
95 | #endif | ||
96 | #ifdef HAVE_LCD_BITMAP | ||
97 | [REMOVE_ICON] = { "iconset", ICON_DIR "/", ".bmp", "", | ||
98 | ASK_FOR_REMOVAL, NULL, false }, | ||
99 | [REMOVE_VICON] = { "viewers iconset", ICON_DIR "/", ".bmp", "", | ||
100 | ASK_FOR_REMOVAL, remove_icons, false }, | ||
101 | #endif | ||
102 | #ifdef HAVE_REMOTE_LCD | ||
103 | [REMOVE_RICON] = { "remote iconset", ICON_DIR "/", ".bmp", "", | ||
104 | ASK_FOR_REMOVAL, NULL, false }, | ||
105 | [REMOVE_RVICON] = { "remote viewers iconset", ICON_DIR "/", ".bmp", "", | ||
106 | ASK_FOR_REMOVAL, NULL, false }, | ||
107 | #endif | ||
108 | #ifdef HAVE_LCD_COLOR | ||
109 | [REMOVE_COLOURS] = { "filetype colours", THEME_DIR "/", ".colours", "", | ||
110 | ASK_FOR_REMOVAL, NULL, false }, | ||
111 | #endif | ||
112 | }; | ||
113 | static char *option_names[NUM_REMOVE_OPTION] = { | ||
114 | "always", "never", "not used", "ask", | ||
115 | }; | ||
116 | static struct configdata config[] = { | ||
117 | #ifdef HAVE_LCD_BITMAP | ||
118 | { TYPE_INT, 0, NUM_REMOVE_OPTION, | ||
119 | { .int_p = &remove_list[REMOVE_FONT].option }, | ||
120 | "remove font", option_names }, | ||
121 | #endif | ||
122 | { TYPE_INT, 0, NUM_REMOVE_OPTION, | ||
123 | { .int_p = &remove_list[REMOVE_WPS].option }, | ||
124 | "remove wps", option_names }, | ||
125 | #ifdef HAVE_REMOTE_LCD | ||
126 | { TYPE_INT, 0, NUM_REMOVE_OPTION, | ||
127 | { .int_p = &remove_list[REMOVE_RWPS].option }, | ||
128 | "remove rwps", option_names }, | ||
129 | #endif | ||
130 | #if LCD_DEPTH > 1 | ||
131 | { TYPE_INT, 0, NUM_REMOVE_OPTION, | ||
132 | { .int_p = &remove_list[REMOVE_BACKDROP].option }, | ||
133 | "remove backdrop", option_names }, | ||
134 | #endif | ||
135 | #ifdef HAVE_LCD_BITMAP | ||
136 | { TYPE_INT, 0, NUM_REMOVE_OPTION, | ||
137 | { .int_p = &remove_list[REMOVE_ICON].option }, | ||
138 | "remove iconset", option_names }, | ||
139 | { TYPE_INT, 0, NUM_REMOVE_OPTION, | ||
140 | { .int_p = &remove_list[REMOVE_VICON].option }, | ||
141 | "remove viconset", option_names }, | ||
142 | #endif | ||
143 | #ifdef HAVE_REMOTE_LCD | ||
144 | { TYPE_INT, 0, NUM_REMOVE_OPTION, | ||
145 | { .int_p = &remove_list[REMOVE_RICON].option }, | ||
146 | "remove riconset", option_names }, | ||
147 | { TYPE_INT, 0, NUM_REMOVE_OPTION, | ||
148 | { .int_p = &remove_list[REMOVE_RVICON].option }, | ||
149 | "remove rviconset", option_names }, | ||
150 | #endif | ||
151 | #ifdef HAVE_LCD_COLOR | ||
152 | { TYPE_INT, 0, NUM_REMOVE_OPTION, | ||
153 | { .int_p = &remove_list[REMOVE_COLOURS].option }, | ||
154 | "remove colours", option_names }, | ||
155 | #endif | ||
156 | {TYPE_BOOL, 0, 1, { .bool_p = &create_log }, | ||
157 | "create log", NULL}, | ||
158 | }; | ||
159 | static const int nb_config = sizeof(config)/sizeof(*config); | ||
160 | static char themefile[MAX_PATH]; | ||
161 | static int log_fd = -1; | ||
162 | |||
163 | static int show_mess(const char *text, const char *file) | ||
164 | { | ||
165 | static char buf[MAX_PATH*2]; | ||
166 | |||
167 | if (file) | ||
168 | rb->snprintf(buf, sizeof(buf), "%s: %s", text, file); | ||
169 | else | ||
170 | rb->snprintf(buf, sizeof(buf), "%s", text); | ||
171 | |||
172 | DEBUGF("%s\n", buf); | ||
173 | if (log_fd >= 0) | ||
174 | rb->fdprintf(log_fd, "%s\n", buf); | ||
175 | |||
176 | rb->splash(0, buf); | ||
177 | rb->sleep(HZ/4); | ||
178 | |||
179 | return 0; | ||
180 | } | ||
181 | |||
182 | /* set full path of file. */ | ||
183 | static void set_file_name(char *buf, const char*file, | ||
184 | struct remove_setting *setting) | ||
185 | { | ||
186 | int len1, len2; | ||
187 | if (rb->strncasecmp(file, setting->prefix, rb->strlen(setting->prefix))) | ||
188 | rb->snprintf(buf, MAX_PATH, "%s%s", setting->prefix, file); | ||
189 | else | ||
190 | rb->strlcpy(buf, file, MAX_PATH); | ||
191 | len1 = rb->strlen(buf); | ||
192 | len2 = rb->strlen(setting->suffix); | ||
193 | if (rb->strcasecmp(buf+len1-len2, setting->suffix)) | ||
194 | rb->strlcpy(&buf[len1], setting->suffix, MAX_PATH-len1); | ||
195 | } | ||
196 | |||
197 | /* taken from apps/onplay.c */ | ||
198 | /* helper function to remove a non-empty directory */ | ||
199 | static int remove_dir(char* dirname, int len) | ||
200 | { | ||
201 | int result = 0; | ||
202 | DIR* dir; | ||
203 | int dirlen = rb->strlen(dirname); | ||
204 | |||
205 | dir = rb->opendir(dirname); | ||
206 | if (!dir) | ||
207 | return -1; /* open error */ | ||
208 | |||
209 | while (true) | ||
210 | { | ||
211 | struct dirent* entry; | ||
212 | /* walk through the directory content */ | ||
213 | entry = rb->readdir(dir); | ||
214 | if (!entry) | ||
215 | break; | ||
216 | |||
217 | dirname[dirlen] ='\0'; | ||
218 | |||
219 | /* append name to current directory */ | ||
220 | rb->snprintf(dirname+dirlen, len-dirlen, "/%s", entry->d_name); | ||
221 | if (entry->attribute & ATTR_DIRECTORY) | ||
222 | { | ||
223 | /* remove a subdirectory */ | ||
224 | if (!rb->strcmp((char *)entry->d_name, ".") || | ||
225 | !rb->strcmp((char *)entry->d_name, "..")) | ||
226 | continue; /* skip these */ | ||
227 | |||
228 | result = remove_dir(dirname, len); /* recursion */ | ||
229 | if (result) | ||
230 | break; | ||
231 | } | ||
232 | else | ||
233 | { | ||
234 | /* remove a file */ | ||
235 | result = rb->remove(dirname); | ||
236 | } | ||
237 | if (ACTION_STD_CANCEL == rb->get_action(CONTEXT_STD, TIMEOUT_NOBLOCK)) | ||
238 | { | ||
239 | show_mess("Canceled", NULL); | ||
240 | result = -1; | ||
241 | break; | ||
242 | } | ||
243 | } | ||
244 | rb->closedir(dir); | ||
245 | |||
246 | if (!result) | ||
247 | { /* remove the now empty directory */ | ||
248 | dirname[dirlen] = '\0'; /* terminate to original length */ | ||
249 | |||
250 | result = rb->rmdir(dirname); | ||
251 | show_mess("Removed", dirname); | ||
252 | } | ||
253 | |||
254 | return result; | ||
255 | } | ||
256 | |||
257 | static int remove_wps(struct remove_setting *setting) | ||
258 | { | ||
259 | char bmpdir[MAX_PATH]; | ||
260 | char *p; | ||
261 | rb->strcpy(bmpdir, setting->value); | ||
262 | p = rb->strrchr(bmpdir, '.'); | ||
263 | if (p) *p = 0; | ||
264 | if (!rb->dir_exists(bmpdir)) | ||
265 | return 0; | ||
266 | return remove_dir(bmpdir, MAX_PATH); | ||
267 | } | ||
268 | |||
269 | #ifdef HAVE_LCD_BITMAP | ||
270 | static int remove_icons(struct remove_setting *setting) | ||
271 | { | ||
272 | char path[MAX_PATH]; | ||
273 | char *p; | ||
274 | rb->strcpy(path, setting->value); | ||
275 | p = rb->strrchr(path, '.'); | ||
276 | rb->strlcpy(p, ".icons", path+MAX_PATH-p); | ||
277 | |||
278 | if (!rb->file_exists(path)) | ||
279 | { | ||
280 | return 0; | ||
281 | } | ||
282 | if (rb->remove(path)) | ||
283 | { | ||
284 | show_mess("Failed", path); | ||
285 | return 1; | ||
286 | } | ||
287 | show_mess("Removed", path); | ||
288 | return 0; | ||
289 | } | ||
290 | #endif | ||
291 | |||
292 | #ifdef HAVE_LCD_BITMAP | ||
293 | static char font_file[MAX_PATH]; | ||
294 | #endif | ||
295 | static bool is_deny_file(const char *file) | ||
296 | { | ||
297 | const char *deny_files[] = { | ||
298 | WPS_DEFAULTCFG, | ||
299 | RWPS_DEFAULTCFG, | ||
300 | #ifdef HAVE_LCD_BITMAP | ||
301 | font_file, | ||
302 | #endif | ||
303 | NULL | ||
304 | }; | ||
305 | const char **p = deny_files; | ||
306 | while ( *p ) | ||
307 | { | ||
308 | if (!rb->strcmp(file, *p)) | ||
309 | return true; | ||
310 | p++; | ||
311 | } | ||
312 | return false; | ||
313 | } | ||
314 | |||
315 | static void check_whether_used_in_setting(void) | ||
316 | { | ||
317 | const char *setting_files[] = { | ||
318 | #ifdef HAVE_LCD_BITMAP | ||
319 | rb->global_settings->font_file, | ||
320 | #endif | ||
321 | rb->global_settings->wps_file, | ||
322 | #ifdef HAVE_REMOTE_LCD | ||
323 | rb->global_settings->rwps_file, | ||
324 | #endif | ||
325 | #if LCD_DEPTH > 1 | ||
326 | rb->global_settings->backdrop_file, | ||
327 | #endif | ||
328 | #ifdef HAVE_LCD_BITMAP | ||
329 | rb->global_settings->icon_file, | ||
330 | rb->global_settings->viewers_icon_file, | ||
331 | #endif | ||
332 | #ifdef HAVE_REMOTE_LCD | ||
333 | rb->global_settings->remote_icon_file, | ||
334 | rb->global_settings->remote_viewers_icon_file, | ||
335 | #endif | ||
336 | #ifdef HAVE_LCD_COLOR | ||
337 | rb->global_settings->colors_file, | ||
338 | #endif | ||
339 | }; | ||
340 | char tempfile[MAX_PATH]; | ||
341 | int i; | ||
342 | for (i=0; i<NUM_REMOVE_ITEMS; i++) | ||
343 | { | ||
344 | struct remove_setting *setting = &remove_list[i]; | ||
345 | if (setting->value[0]) | ||
346 | { | ||
347 | set_file_name(tempfile, setting_files[i], setting); | ||
348 | if (!rb->strcasecmp(tempfile, setting->value)) | ||
349 | setting->used = true; | ||
350 | } | ||
351 | } | ||
352 | } | ||
353 | static void check_whether_used_in_file(const char *cfgfile) | ||
354 | { | ||
355 | char line[MAX_PATH]; | ||
356 | char settingfile[MAX_PATH]; | ||
357 | char *p; | ||
358 | int fd; | ||
359 | char *name, *value; | ||
360 | int i; | ||
361 | |||
362 | if (!rb->strcasecmp(themefile, cfgfile)) | ||
363 | return; | ||
364 | fd = rb->open(cfgfile, O_RDONLY); | ||
365 | if (fd < 0) | ||
366 | return; | ||
367 | while (rb->read_line(fd, line, sizeof(line)) > 0) | ||
368 | { | ||
369 | if (!rb->settings_parseline(line, &name, &value)) | ||
370 | continue; | ||
371 | /* remove trailing spaces. */ | ||
372 | p = value+rb->strlen(value)-1; | ||
373 | while (*p == ' ') *p-- = 0; | ||
374 | if (*value == 0 || !rb->strcmp(value, "-")) | ||
375 | continue; | ||
376 | for (i=0; i<NUM_REMOVE_ITEMS; i++) | ||
377 | { | ||
378 | struct remove_setting *setting = &remove_list[i]; | ||
379 | if (!rb->strcmp(name, setting->name)) | ||
380 | { | ||
381 | if (setting->value[0]) | ||
382 | { | ||
383 | set_file_name(settingfile, value, setting); | ||
384 | if (!rb->strcasecmp(settingfile, setting->value)) | ||
385 | setting->used = true; | ||
386 | } | ||
387 | break; | ||
388 | } | ||
389 | } | ||
390 | } | ||
391 | rb->close(fd); | ||
392 | } | ||
393 | static void check_whether_used(void) | ||
394 | { | ||
395 | char cfgfile[MAX_PATH]; | ||
396 | DIR *dir; | ||
397 | |||
398 | check_whether_used_in_setting(); | ||
399 | #ifdef HAVE_LCD_BITMAP | ||
400 | /* mark font files come from rockbox-font.zip as used and don't remove | ||
401 | * them automatically as themes may depend on those fonts. */ | ||
402 | if (remove_list[REMOVE_FONT].option == REMOVE_IF_NOT_USED) | ||
403 | check_whether_used_in_file(RB_FONTS_CONFIG); | ||
404 | #endif | ||
405 | |||
406 | dir = rb->opendir(THEME_DIR); | ||
407 | if (!dir) | ||
408 | return; /* open error */ | ||
409 | |||
410 | while (true) | ||
411 | { | ||
412 | struct dirent* entry; | ||
413 | char *p; | ||
414 | int i; | ||
415 | /* walk through the directory content */ | ||
416 | entry = rb->readdir(dir); | ||
417 | if (!entry) | ||
418 | break; | ||
419 | p = rb->strrchr(entry->d_name, '.'); | ||
420 | if (!p || rb->strcmp(p, ".cfg")) | ||
421 | continue; | ||
422 | |||
423 | rb->snprintf(cfgfile, MAX_PATH, "%s/%s", THEME_DIR, entry->d_name); | ||
424 | check_whether_used_in_file(cfgfile); | ||
425 | /* break the loop if all files need to be checked in the theme | ||
426 | * turned out to be used. */ | ||
427 | for (i = 0; i < NUM_REMOVE_ITEMS; i++) | ||
428 | { | ||
429 | struct remove_setting *setting = &remove_list[i]; | ||
430 | if (setting->option == REMOVE_IF_NOT_USED) | ||
431 | { | ||
432 | if (setting->value[0] && !setting->used) | ||
433 | break; | ||
434 | } | ||
435 | } | ||
436 | if (i == NUM_REMOVE_ITEMS) | ||
437 | break; | ||
438 | } | ||
439 | rb->closedir(dir); | ||
440 | } | ||
441 | |||
442 | static int remove_file(struct remove_setting *setting) | ||
443 | { | ||
444 | if (!rb->file_exists(setting->value)) | ||
445 | { | ||
446 | show_mess("Doesn't exist", setting->value); | ||
447 | return 0; | ||
448 | } | ||
449 | if (is_deny_file(setting->value)) | ||
450 | { | ||
451 | show_mess("Denied", setting->value); | ||
452 | return 0; | ||
453 | } | ||
454 | switch (setting->option) | ||
455 | { | ||
456 | case ALWAYS_REMOVE: | ||
457 | break; | ||
458 | case NEVER_REMOVE: | ||
459 | show_mess("Skipped", setting->value); | ||
460 | return 0; | ||
461 | break; | ||
462 | case REMOVE_IF_NOT_USED: | ||
463 | if (setting->used) | ||
464 | { | ||
465 | show_mess("Used", setting->value); | ||
466 | return 0; | ||
467 | } | ||
468 | break; | ||
469 | case ASK_FOR_REMOVAL: | ||
470 | default: | ||
471 | { | ||
472 | const char *message_lines[] = { "Delete?", setting->value }; | ||
473 | const struct text_message text_message = { message_lines, 2 }; | ||
474 | if (rb->gui_syncyesno_run(&text_message, NULL, NULL) != YESNO_YES) | ||
475 | { | ||
476 | show_mess("Skipped", setting->value); | ||
477 | return 0; | ||
478 | } | ||
479 | } | ||
480 | break; | ||
481 | } | ||
482 | if (rb->remove(setting->value)) | ||
483 | { | ||
484 | show_mess("Failed", setting->value); | ||
485 | return -1; | ||
486 | } | ||
487 | if (setting->func && setting->func(setting)) | ||
488 | return -1; | ||
489 | show_mess("Removed", setting->value); | ||
490 | return 1; | ||
491 | } | ||
492 | static int remove_theme(void) | ||
493 | { | ||
494 | static char line[MAX_PATH]; | ||
495 | int fd; | ||
496 | int i, num_removed = 0; | ||
497 | char *name, *value; | ||
498 | bool needs_to_check_whether_used = false; | ||
499 | |||
500 | /* initialize for safe */ | ||
501 | for (i=0; i<NUM_REMOVE_ITEMS; i++) | ||
502 | remove_list[i].value[0] = 0; | ||
503 | |||
504 | /* load settings */ | ||
505 | fd = rb->open(themefile, O_RDONLY); | ||
506 | if (fd < 0) return fd; | ||
507 | while (rb->read_line(fd, line, sizeof(line)) > 0) | ||
508 | { | ||
509 | if (!rb->settings_parseline(line, &name, &value)) | ||
510 | continue; | ||
511 | /* remove trailing spaces. */ | ||
512 | char *p = value+rb->strlen(value)-1; | ||
513 | while (*p == ' ') *p-- = 0; | ||
514 | if (*value == 0 || !rb->strcmp(value, "-")) | ||
515 | continue; | ||
516 | for (i=0; i<NUM_REMOVE_ITEMS; i++) | ||
517 | { | ||
518 | struct remove_setting *setting = &remove_list[i]; | ||
519 | if (!rb->strcmp(name, setting->name)) | ||
520 | { | ||
521 | set_file_name(setting->value, value, setting); | ||
522 | if(setting->option == REMOVE_IF_NOT_USED) | ||
523 | needs_to_check_whether_used = true; | ||
524 | break; | ||
525 | } | ||
526 | } | ||
527 | } | ||
528 | rb->close(fd); | ||
529 | |||
530 | if(needs_to_check_whether_used) | ||
531 | check_whether_used(); | ||
532 | |||
533 | /* now remove file assosiated to the theme. */ | ||
534 | for (i=0; i<NUM_REMOVE_ITEMS; i++) | ||
535 | { | ||
536 | if (remove_list[i].value[0]) | ||
537 | { | ||
538 | int ret = remove_file(&remove_list[i]); | ||
539 | if (ret < 0) | ||
540 | return ret; | ||
541 | num_removed += ret; | ||
542 | } | ||
543 | } | ||
544 | |||
545 | /* remove the setting file iff it is in theme directory to protect | ||
546 | * aginst accidental removal of non theme cfg file. if the file is | ||
547 | * not in the theme directory, the file may not be a theme cfg file. */ | ||
548 | if (rb->strncasecmp(themefile, THEME_DIR "/", sizeof(THEME_DIR "/")-1)) | ||
549 | { | ||
550 | show_mess("Skipped", themefile); | ||
551 | } | ||
552 | else if (rb->remove(themefile)) | ||
553 | { | ||
554 | show_mess("Failed", themefile); | ||
555 | return -1; | ||
556 | } | ||
557 | else | ||
558 | { | ||
559 | show_mess("Removed", themefile); | ||
560 | rb->reload_directory(); | ||
561 | num_removed++; | ||
562 | } | ||
563 | return num_removed; | ||
564 | } | ||
565 | |||
566 | static bool option_changed = false; | ||
567 | static bool option_menu(void) | ||
568 | { | ||
569 | MENUITEM_STRINGLIST(option_menu, "Remove Options", NULL, | ||
570 | /* same order as remove_list */ | ||
571 | #ifdef HAVE_LCD_BITMAP | ||
572 | "Font", | ||
573 | #endif | ||
574 | "WPS", | ||
575 | #ifdef HAVE_REMOTE_LCD | ||
576 | "Remote WPS", | ||
577 | #endif | ||
578 | #if LCD_DEPTH > 1 | ||
579 | "Backdrop", | ||
580 | #endif | ||
581 | #ifdef HAVE_LCD_BITMAP | ||
582 | "Iconset", "Viewers Iconset", | ||
583 | #endif | ||
584 | #ifdef HAVE_REMOTE_LCD | ||
585 | "Remote Iconset", "Remote Viewers Iconset", | ||
586 | #endif | ||
587 | #ifdef HAVE_LCD_COLOR | ||
588 | "Filetype Colours", | ||
589 | #endif | ||
590 | "Create Log File"); | ||
591 | struct opt_items remove_names[] = { | ||
592 | {"Always Remove", -1}, {"Never Remove", -1}, | ||
593 | {"Remove if not Used", -1}, {"Ask for Removal", -1}, | ||
594 | }; | ||
595 | int selected = 0, result; | ||
596 | |||
597 | while (1) | ||
598 | { | ||
599 | result = rb->do_menu(&option_menu, &selected, NULL, false); | ||
600 | if (result >= 0 && result < NUM_REMOVE_ITEMS) | ||
601 | { | ||
602 | struct remove_setting *setting = &remove_list[result]; | ||
603 | int prev_option = setting->option; | ||
604 | if (rb->set_option(option_menu_[result], &setting->option, INT, | ||
605 | remove_names, NUM_REMOVE_OPTION, NULL)) | ||
606 | return true; | ||
607 | if (prev_option != setting->option) | ||
608 | option_changed = true; | ||
609 | } | ||
610 | else if (result == NUM_REMOVE_ITEMS) | ||
611 | { | ||
612 | bool prev_value = create_log; | ||
613 | if(rb->set_bool("Create Log File", &create_log)) | ||
614 | return true; | ||
615 | if (prev_value != create_log) | ||
616 | option_changed = true; | ||
617 | } | ||
618 | else if (result == MENU_ATTACHED_USB) | ||
619 | return true; | ||
620 | else | ||
621 | return false; | ||
622 | } | ||
623 | |||
624 | return false; | ||
625 | } | ||
626 | |||
627 | enum plugin_status plugin_start(const void* parameter) | ||
628 | { | ||
629 | static char title[64]; | ||
630 | char *p; | ||
631 | MENUITEM_STRINGLIST(menu, title, NULL, | ||
632 | "Remove Theme", "Remove Options", | ||
633 | "Quit"); | ||
634 | int selected = 0, ret; | ||
635 | bool exit = false; | ||
636 | |||
637 | if (!parameter) | ||
638 | return PLUGIN_ERROR; | ||
639 | |||
640 | rb->snprintf(title, sizeof(title), "Remove %s", | ||
641 | rb->strrchr(parameter, '/')+1); | ||
642 | if((p = rb->strrchr(title, '.'))) | ||
643 | *p = 0; | ||
644 | |||
645 | #ifdef HAVE_LCD_BITMAP | ||
646 | rb->snprintf(font_file, MAX_PATH, FONT_DIR "/%s.fnt", | ||
647 | rb->global_settings->font_file); | ||
648 | #endif | ||
649 | rb->strlcpy(themefile, parameter, MAX_PATH); | ||
650 | if (!rb->file_exists(themefile)) | ||
651 | { | ||
652 | rb->splash(HZ, "File open error!"); | ||
653 | return PLUGIN_ERROR; | ||
654 | } | ||
655 | configfile_load(CONFIG_FILENAME, config, nb_config, 0); | ||
656 | while (!exit) | ||
657 | { | ||
658 | switch (rb->do_menu(&menu, &selected, NULL, false)) | ||
659 | { | ||
660 | case 0: | ||
661 | if(create_log) | ||
662 | { | ||
663 | log_fd = rb->open(LOG_FILENAME, O_WRONLY|O_CREAT|O_APPEND); | ||
664 | if(log_fd >= 0) | ||
665 | rb->fdprintf(log_fd, "---- %s ----\n", title); | ||
666 | else | ||
667 | show_mess("Couldn't open log file.", NULL); | ||
668 | } | ||
669 | ret = remove_theme(); | ||
670 | p = (ret >= 0? "Successfully removed!": "Remove failure"); | ||
671 | show_mess(p, NULL); | ||
672 | if(log_fd >= 0) | ||
673 | { | ||
674 | rb->fdprintf(log_fd, "----------------\n"); | ||
675 | rb->close(log_fd); | ||
676 | log_fd = -1; | ||
677 | } | ||
678 | rb->lcd_clear_display(); | ||
679 | rb->lcd_update(); | ||
680 | rb->splashf(0, "%s %s", p, "Press any key to exit."); | ||
681 | rb->button_clear_queue(); | ||
682 | rb->button_get(true); | ||
683 | exit = true; | ||
684 | break; | ||
685 | case 1: | ||
686 | if (option_menu()) | ||
687 | return PLUGIN_USB_CONNECTED; | ||
688 | break; | ||
689 | case 2: | ||
690 | exit = true; | ||
691 | break; | ||
692 | case MENU_ATTACHED_USB: | ||
693 | return PLUGIN_USB_CONNECTED; | ||
694 | break; | ||
695 | default: | ||
696 | break; | ||
697 | } | ||
698 | } | ||
699 | if(option_changed) | ||
700 | configfile_save(CONFIG_FILENAME, config, nb_config, 0); | ||
701 | return PLUGIN_OK; | ||
702 | } | ||
diff --git a/apps/plugins/viewers.config b/apps/plugins/viewers.config index e3b15fe116..205bafb12a 100644 --- a/apps/plugins/viewers.config +++ b/apps/plugins/viewers.config | |||
@@ -50,6 +50,7 @@ sna,viewers/zxbox,12 | |||
50 | tzx,viewers/zxbox,12 | 50 | tzx,viewers/zxbox,12 |
51 | z80,viewers/zxbox,12 | 51 | z80,viewers/zxbox,12 |
52 | ppm,viewers/ppmviewer,2 | 52 | ppm,viewers/ppmviewer,2 |
53 | cfg,viewers/theme_remove,- | ||
53 | *,viewers/properties,- | 54 | *,viewers/properties,- |
54 | colours,apps/text_editor,11 | 55 | colours,apps/text_editor,11 |
55 | ssg,games/superdom,- | 56 | ssg,games/superdom,- |
diff --git a/manual/plugins/main.tex b/manual/plugins/main.tex index 00eb836abf..cad7436b63 100644 --- a/manual/plugins/main.tex +++ b/manual/plugins/main.tex | |||
@@ -182,6 +182,8 @@ option from the \setting{Context Menu} (see \reference{ref:Contextmenu}).} | |||
182 | 182 | ||
183 | {\input{plugins/text_viewer.tex}} | 183 | {\input{plugins/text_viewer.tex}} |
184 | 184 | ||
185 | {\input{plugins/theme_remove.tex}} | ||
186 | |||
185 | {\input{plugins/vbrfix.tex}} | 187 | {\input{plugins/vbrfix.tex}} |
186 | 188 | ||
187 | \opt{recorder,recorderv2fm,ondio}{\input{plugins/wavplay.tex}} | 189 | \opt{recorder,recorderv2fm,ondio}{\input{plugins/wavplay.tex}} |
diff --git a/manual/plugins/theme_remove.tex b/manual/plugins/theme_remove.tex new file mode 100644 index 0000000000..b4d45dfc7a --- /dev/null +++ b/manual/plugins/theme_remove.tex | |||
@@ -0,0 +1,77 @@ | |||
1 | % $Id $ % | ||
2 | \subsection{\label{ref:ThemeRemove}Theme Remove} | ||
3 | This plugin offers a way to remove a theme. Open the \setting{Context Menu} (see \reference{ref:Contextmenu}) | ||
4 | upon a theme\fname{.cfg} file and select \setting{Open With... $\rightarrow$ theme\_remove}. | ||
5 | Some files are not removed regardless of the \setting{Remove Options} such as | ||
6 | \fname{rockbox\_default.wps}\opt{lcd_bitmap}{ and the font file currently in use}. | ||
7 | |||
8 | \subsubsection{Theme Remove menu} | ||
9 | \begin{description} | ||
10 | \item[Remove Theme.] | ||
11 | Selecting this will delete the files specified in the \setting{Remove Options}. | ||
12 | After a theme has been succesfully removed, a log message is displayed listing | ||
13 | which items have been deleted and which are being kept. Exit this screen by | ||
14 | pressing any key. A file called \fname{theme\_remove\_log.txt} is created in | ||
15 | the root directory of your \dap{} listing all the changes. | ||
16 | |||
17 | \item[Remove Options.] | ||
18 | This menu specifies which items are removed if | ||
19 | \setting{Remove Theme} is selected in the menu. | ||
20 | |||
21 | One of the following options can be chosen for each setting. | ||
22 | \begin{description} | ||
23 | \item[Ask for Removal.] | ||
24 | Selecting this option brings up a dialogue with two options: | ||
25 | press \ActionYesNoAccept{} to confirm deletion or any other key to cancel. | ||
26 | \item[Remove if not Used.] | ||
27 | Selecting this option will remove the file automatically, if it is not | ||
28 | used by another theme in the theme directory and not currently used. | ||
29 | \item[Never Remove.] | ||
30 | Selecting this option will always skip deleting the file. | ||
31 | \item[Always Remove.] | ||
32 | Selecting this option will remove the file with no regard to | ||
33 | whether it's used by another theme or not. | ||
34 | \end{description} | ||
35 | |||
36 | \begin{description} | ||
37 | \opt{lcd_bitmap}{ | ||
38 | \item[Font.] | ||
39 | Specifies how the \fname{.fnt} file belonging to a theme \fname{.cfg} file is handled. | ||
40 | If this option is set to \setting{Remove if not Used}, the fonts came from rockbox-fonts.zip | ||
41 | will not be removed as themes may depend on those fonts. | ||
42 | }% | ||
43 | \item[WPS.] | ||
44 | Specifies how the \fname{.wps} file belonging to a theme \fname{.cfg} file is handled. | ||
45 | \opt{HAVE_REMOTE_LCD}{ | ||
46 | \item[Remote WPS.] | ||
47 | Specifies how the \fname{.rwps} file belonging to a theme \fname{.cfg} file is handled. | ||
48 | }% | ||
49 | \opt{lcd_non-mono}{ | ||
50 | \item[Backdrop.] | ||
51 | Specifies how the backdrop \fname{.bmp} file belonging to a theme \fname{.cfg} file is handled. | ||
52 | }% | ||
53 | \opt{lcd_bitmap}{ | ||
54 | \item[Iconset.] | ||
55 | Specifies how the iconset \fname{.bmp} file belonging to a theme \fname{.cfg} file is handled. | ||
56 | \item[Viewers Iconset.] | ||
57 | Specifies how the viewers iconset \fname{.bmp} file belonging to a theme \fname{.cfg} file is handled. | ||
58 | }% | ||
59 | \opt{HAVE_REMOTE_LCD}{ | ||
60 | \item[Remote Iconset.] | ||
61 | Specifies how the remote iconset \fname{.bmp} file belonging to | ||
62 | a theme \fname{.cfg} file is handled. | ||
63 | \item[Remote Viewers Iconset.] | ||
64 | Specifies how the remote viewers iconset \fname{.bmp} file belonging to | ||
65 | a theme \fname{.cfg} file is handled. | ||
66 | }% HAVE_REMOTE_LCD | ||
67 | \opt{lcd_color}{ | ||
68 | \item[Filetype Colours.] | ||
69 | Specifies how the colours \fname{.colours} file belonging to a theme \fname{.cfg} file is handled. | ||
70 | }% | ||
71 | |||
72 | \item[Create Log File.] | ||
73 | Setting this to \setting{No} prevents the log file from being created. | ||
74 | \end{description} | ||
75 | \item[Quit.] | ||
76 | Exits this plugin. | ||
77 | \end{description} | ||
diff --git a/tools/buildzip.pl b/tools/buildzip.pl index a3ac75fa30..09d6d87290 100755 --- a/tools/buildzip.pl +++ b/tools/buildzip.pl | |||
@@ -357,6 +357,7 @@ STOP | |||
357 | if($bitmap) { | 357 | if($bitmap) { |
358 | copy("$ROOT/apps/plugins/sokoban.levels", "$rbdir/rocks/games/sokoban.levels"); # sokoban levels | 358 | copy("$ROOT/apps/plugins/sokoban.levels", "$rbdir/rocks/games/sokoban.levels"); # sokoban levels |
359 | copy("$ROOT/apps/plugins/snake2.levels", "$rbdir/rocks/games/snake2.levels"); # snake2 levels | 359 | copy("$ROOT/apps/plugins/snake2.levels", "$rbdir/rocks/games/snake2.levels"); # snake2 levels |
360 | copy("$ROOT/apps/plugins/rockbox-fonts.config", "$rbdir/rocks/viewers/"); | ||
360 | } | 361 | } |
361 | 362 | ||
362 | if(-e "$rbdir/rocks/demos/pictureflow.rock") { | 363 | if(-e "$rbdir/rocks/demos/pictureflow.rock") { |