1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 Jonathan Gordon
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "lib/oldmenuapi.h"
28 static int dirs_count
;
30 #define RFA_FILE ROCKBOX_DIR "/folder_advance_list.dat"
31 #define RFADIR_FILE ROCKBOX_DIR "/folder_advance_dir.txt"
32 #define RFA_FILE_TEXT ROCKBOX_DIR "/folder_advance_list.txt"
33 #define MAX_REMOVED_DIRS 10
37 int num_replaced_dirs
= 0;
38 char removed_dirs
[MAX_REMOVED_DIRS
][MAX_PATH
];
41 char folder
[][MAX_PATH
];
43 struct file_format
*list
= NULL
;
45 void update_screen(bool clear
)
50 rb
->snprintf(buf
,sizeof(buf
),"Folders: %d",dirs_count
);
54 rb
->screens
[i
]->clear_display();
55 rb
->screens
[i
]->putsxy(0,0,buf
);
56 rb
->screens
[i
]->update();
60 void traversedir(char* location
, char* name
)
64 char fullpath
[MAX_PATH
], path
[MAX_PATH
];
68 rb
->snprintf(fullpath
, sizeof(fullpath
), "%s/%s", location
, name
);
69 dir
= rb
->opendir(fullpath
);
71 entry
= rb
->readdir(dir
);
76 if (entry
->d_name
[0] == '.')
78 if ( !rb
->strcmp(entry
->d_name
,".")
79 || !rb
->strcmp(entry
->d_name
,"..")
80 || !rb
->strcmp(entry
->d_name
,".rockbox"))
86 /* check if path is removed directory, if so dont enter it */
87 rb
->snprintf(path
, MAX_PATH
, "%s/%s", fullpath
, entry
->d_name
);
89 rb
->strncpy(path
, path
+ 1, rb
->strlen(path
));
90 for(i
= 0; i
< num_replaced_dirs
; i
++)
92 if(!rb
->strcmp(path
, removed_dirs
[i
]))
101 if (entry
->attribute
& ATTR_DIRECTORY
) {
104 rb
->snprintf(path
,MAX_PATH
,"%s/%s",fullpath
,entry
->d_name
);
105 start
= &path
[rb
->strlen(path
)];
106 rb
->memset(start
,0,&path
[MAX_PATH
-1]-start
);
107 rb
->write(fd
,path
,MAX_PATH
);
108 traversedir(fullpath
, entry
->d_name
);
111 if (*rb
->current_tick
- lasttick
> (HZ
/2)) {
112 update_screen(false);
113 lasttick
= *rb
->current_tick
;
114 if (rb
->action_userabort(TIMEOUT_NOBLOCK
))
121 entry
= rb
->readdir(dir
);
127 bool custom_dir(void)
130 char *starts
, line
[MAX_PATH
], formatted_line
[MAX_PATH
];
135 /* populate removed dirs array */
136 if((fd2
= rb
->open(RFADIR_FILE
,O_RDONLY
)) > 0)
138 while ((rb
->read_line(fd2
, line
, MAX_PATH
- 1)) > 0)
140 if ((line
[0] == '-') && (line
[1] == '/') &&
141 (num_replaced_dirs
< MAX_REMOVED_DIRS
))
143 num_replaced_dirs
++;
144 rb
->strncpy(removed_dirs
[num_replaced_dirs
- 1], line
+ 2,
151 if((fd2
= rb
->open(RFADIR_FILE
,O_RDONLY
)) > 0)
153 while ((rb
->read_line(fd2
, line
, MAX_PATH
- 1)) > 0)
155 /* blank lines and removed dirs ignored */
156 if (rb
->strlen(line
) && ((line
[0] != '-') || (line
[1] != '/')))
158 /* remove preceeding '/'s from the line */
159 while(line
[0] == '/')
160 rb
->strncpy(line
, line
+ 1, rb
->strlen(line
));
162 rb
->snprintf(formatted_line
, MAX_PATH
, "/%s", line
);
164 dir_check
= rb
->opendir(formatted_line
);
168 rb
->closedir(dir_check
);
169 starts
= &formatted_line
[rb
->strlen(formatted_line
)];
170 rb
->memset(starts
, 0, &formatted_line
[MAX_PATH
-1]-starts
);
171 bool write_line
= true;
173 for(i
= 0; i
< num_replaced_dirs
; i
++)
175 if(!rb
->strcmp(line
, removed_dirs
[i
]))
185 rb
->write(fd
, formatted_line
, MAX_PATH
);
188 traversedir("", line
);
193 rb
->snprintf(buf
,sizeof(buf
),"Not found:");
196 rb
->screens
[i
]->puts(0,0,buf
);
197 rb
->screens
[i
]->puts(0, errors
, line
);
199 update_screen(false);
205 /* Press button to continue */
206 rb
->get_action(CONTEXT_STD
, TIMEOUT_BLOCK
);
217 fd
= rb
->open(RFA_FILE
,O_CREAT
|O_WRONLY
);
218 rb
->write(fd
,&dirs_count
,sizeof(int));
221 rb
->splashf(HZ
, "Couldnt open %s", RFA_FILE
);
224 #ifndef HAVE_LCD_CHARCELLS
227 lasttick
= *rb
->current_tick
;
232 rb
->lseek(fd
,0,SEEK_SET
);
233 rb
->write(fd
,&dirs_count
,sizeof(int));
235 rb
->splash(HZ
, "Done");
237 char *list_get_name_cb(int selected_item
, void* data
, char* buf
, size_t buf_len
)
240 rb
->strncpy(buf
, list
->folder
[selected_item
], buf_len
);
246 int myfd
= rb
->open(RFA_FILE
,O_RDONLY
);
249 buffer
= rb
->plugin_get_audio_buffer((size_t *)&buffer_size
);
255 rb
->read(myfd
,buffer
,buffer_size
);
257 list
= (struct file_format
*)buffer
;
264 int myfd
= rb
->creat(RFA_FILE
);
267 rb
->splash(HZ
, "Could Not Open " RFA_FILE
);
270 int dirs_count
= 0, i
= 0;
271 rb
->write(myfd
,&dirs_count
,sizeof(int));
272 for ( ;i
<list
->count
;i
++)
274 if (list
->folder
[i
][0] != ' ')
277 rb
->write(myfd
,list
->folder
[i
],MAX_PATH
);
280 rb
->lseek(myfd
,0,SEEK_SET
);
281 rb
->write(myfd
,&dirs_count
,sizeof(int));
289 struct gui_synclist lists
;
292 int selection
, ret
= 0;
294 /* load the dat file if not already done */
295 if ((list
== NULL
|| list
->count
== 0) && (i
= load_list()) != 0)
297 rb
->splashf(HZ
*2, "Could not load %s, rv = %d", RFA_FILE
, i
);
301 dirs_count
= list
->count
;
303 rb
->gui_synclist_init(&lists
,list_get_name_cb
,0, false, 1, NULL
);
304 rb
->gui_synclist_set_icon_callback(&lists
,NULL
);
305 rb
->gui_synclist_set_nb_items(&lists
,list
->count
);
306 rb
->gui_synclist_limit_scroll(&lists
,true);
307 rb
->gui_synclist_select_item(&lists
, 0);
311 rb
->gui_synclist_draw(&lists
);
312 button
= rb
->get_action(CONTEXT_LIST
,TIMEOUT_BLOCK
);
313 if (rb
->gui_synclist_do_button(&lists
,&button
,LIST_WRAP_UNLESS_HELD
))
315 selection
= rb
->gui_synclist_get_sel_pos(&lists
);
319 list
->folder
[selection
][0] = ' ';
320 list
->folder
[selection
][1] = '\0';
322 case ACTION_STD_CONTEXT
:
325 static const struct menu_item items
[] = {
326 { "Remove Folder", NULL
},
327 { "Remove Folder Tree", NULL
},
329 m
= menu_init(items
, sizeof(items
) / sizeof(*items
),
330 NULL
, NULL
, NULL
, NULL
);
332 switch (menu_show(m
))
335 list
->folder
[selection
][0] = ' ';
336 list
->folder
[selection
][1] = '\0';
341 rb
->strcpy(temp
,list
->folder
[selection
]);
342 len
= rb
->strlen(temp
);
343 for (i
=0;i
<list
->count
;i
++)
345 if (!rb
->strncmp(list
->folder
[i
],temp
,len
))
347 list
->folder
[i
][0] = ' ';
348 list
->folder
[i
][1] = '\0';
357 case ACTION_STD_CANCEL
:
360 static const struct menu_item items
[] = {
361 { "Save and Exit", NULL
},
362 { "Ignore Changes and Exit", NULL
},
364 m
= menu_init(items
, sizeof(items
) / sizeof(*items
),
365 NULL
, NULL
, NULL
, NULL
);
367 switch (menu_show(m
))
383 int export_list_to_file_text(void)
386 /* load the dat file if not already done */
387 if ((list
== NULL
|| list
->count
== 0) && (i
= load_list()) != 0)
389 rb
->splashf(HZ
*2, "Could not load %s, rv = %d", RFA_FILE
, i
);
393 if (list
->count
<= 0)
395 rb
->splashf(HZ
*2, "no dirs in list file: %s", RFA_FILE
);
399 /* create and open the file */
400 int myfd
= rb
->creat(RFA_FILE_TEXT
);
403 rb
->splashf(HZ
*4, "failed to open: fd = %d, file = %s",
404 myfd
, RFA_FILE_TEXT
);
408 /* write each directory to file */
409 for (i
= 0; i
< list
->count
; i
++)
411 if (list
->folder
[i
][0] != ' ')
413 rb
->fdprintf(myfd
, "%s\n", list
->folder
[i
]);
418 rb
->splash(HZ
, "Done");
422 int import_list_from_file_text(void)
426 buffer
= rb
->plugin_get_audio_buffer((size_t *)&buffer_size
);
429 rb
->splash(HZ
*2, "failed to get audio buffer");
433 int myfd
= rb
->open(RFA_FILE_TEXT
, O_RDONLY
);
436 rb
->splashf(HZ
*2, "failed to open: %s", RFA_FILE_TEXT
);
440 /* set the list structure, and initialize count */
441 list
= (struct file_format
*)buffer
;
444 while ((rb
->read_line(myfd
, line
, MAX_PATH
- 1)) > 0)
446 /* copy the dir name, and skip the newline */
447 int len
= rb
->strlen(line
);
451 if (line
[len
-1] == 0x0A || line
[len
-1] == 0x0D)
454 (line
[len
-2] == 0x0A || line
[len
-2] == 0x0D))
458 rb
->strcpy(list
->folder
[list
->count
++], line
);
463 if (list
->count
== 0)
471 rb
->splash(HZ
, "Done");
479 static const struct menu_item items
[] = {
480 { "Generate Folder List", NULL
},
481 { "Edit Folder List", NULL
},
482 { "Export List To Textfile", NULL
},
483 { "Import List From Textfile", NULL
},
486 m
= menu_init(items
, sizeof(items
) / sizeof(*items
),
487 NULL
, NULL
, NULL
, NULL
);
489 switch (menu_show(m
))
491 case 0: /* generate */
492 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
496 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
497 rb
->cpu_boost(false);
499 #ifdef HAVE_REMOTE_LCD
500 rb
->remote_backlight_on();
505 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
510 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
511 rb
->cpu_boost(false);
513 #ifdef HAVE_REMOTE_LCD
514 rb
->remote_backlight_on();
518 case 2: /* export to textfile */
519 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
522 export_list_to_file_text();
523 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
524 rb
->cpu_boost(false);
526 #ifdef HAVE_REMOTE_LCD
527 rb
->remote_backlight_on();
531 case 3: /* import from textfile */
532 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
535 import_list_from_file_text();
536 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
537 rb
->cpu_boost(false);
539 #ifdef HAVE_REMOTE_LCD
540 rb
->remote_backlight_on();
552 enum plugin_status
plugin_start(const void* parameter
)