A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita audio rust zig deno mpris rockbox mpd

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

+858
+1
apps/plugins/CATEGORIES
··· 103 103 test_viewports,apps 104 104 test_greylib_bitmap_scale,viewers 105 105 text_editor,apps 106 + theme_remove,viewers 106 107 vbrfix,viewers 107 108 video,viewers 108 109 viewer,viewers
+1
apps/plugins/SOURCES
··· 16 16 sort.c 17 17 stats.c 18 18 stopwatch.c 19 + theme_remove.c 19 20 vbrfix.c 20 21 viewer.c 21 22 #ifdef HAVE_BACKLIGHT
+73
apps/plugins/rockbox-fonts.config
··· 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
+702
apps/plugins/theme_remove.c
··· 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 + }
+1
apps/plugins/viewers.config
··· 50 50 tzx,viewers/zxbox,12 51 51 z80,viewers/zxbox,12 52 52 ppm,viewers/ppmviewer,2 53 + cfg,viewers/theme_remove,- 53 54 *,viewers/properties,- 54 55 colours,apps/text_editor,11 55 56 ssg,games/superdom,-
+2
manual/plugins/main.tex
··· 182 182 183 183 {\input{plugins/text_viewer.tex}} 184 184 185 + {\input{plugins/theme_remove.tex}} 186 + 185 187 {\input{plugins/vbrfix.tex}} 186 188 187 189 \opt{recorder,recorderv2fm,ondio}{\input{plugins/wavplay.tex}}
+77
manual/plugins/theme_remove.tex
··· 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}
+1
tools/buildzip.pl
··· 357 357 if($bitmap) { 358 358 copy("$ROOT/apps/plugins/sokoban.levels", "$rbdir/rocks/games/sokoban.levels"); # sokoban levels 359 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 363 if(-e "$rbdir/rocks/demos/pictureflow.rock") {