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 "oldmenuapi.h"
26 static const struct plugin_api
* rb
;
29 static int dirs_count
;
31 #define RFA_FILE ROCKBOX_DIR "/folder_advance_list.dat"
32 #define RFADIR_FILE ROCKBOX_DIR "/folder_advance_dir.txt"
33 #define RFA_FILE_TEXT ROCKBOX_DIR "/folder_advance_list.txt"
34 #define MAX_REMOVED_DIRS 10
38 int num_replaced_dirs
= 0;
39 char removed_dirs
[MAX_REMOVED_DIRS
][MAX_PATH
];
42 char folder
[][MAX_PATH
];
44 struct file_format
*list
= NULL
;
46 void update_screen(bool clear
)
51 rb
->snprintf(buf
,sizeof(buf
),"Folders: %d",dirs_count
);
55 rb
->screens
[i
]->clear_display();
56 rb
->screens
[i
]->putsxy(0,0,buf
);
57 rb
->screens
[i
]->update();
61 void traversedir(char* location
, char* name
)
65 char fullpath
[MAX_PATH
], path
[MAX_PATH
];
69 rb
->snprintf(fullpath
, sizeof(fullpath
), "%s/%s", location
, name
);
70 dir
= rb
->opendir(fullpath
);
72 entry
= rb
->readdir(dir
);
77 if (entry
->d_name
[0] == '.')
79 if ( !rb
->strcmp(entry
->d_name
,".")
80 || !rb
->strcmp(entry
->d_name
,"..")
81 || !rb
->strcmp(entry
->d_name
,".rockbox"))
87 /* check if path is removed directory, if so dont enter it */
88 rb
->snprintf(path
, MAX_PATH
, "%s/%s", fullpath
, entry
->d_name
);
90 rb
->strncpy(path
, path
+ 1, rb
->strlen(path
));
91 for(i
= 0; i
< num_replaced_dirs
; i
++)
93 if(!rb
->strcmp(path
, removed_dirs
[i
]))
102 if (entry
->attribute
& ATTR_DIRECTORY
) {
105 rb
->snprintf(path
,MAX_PATH
,"%s/%s",fullpath
,entry
->d_name
);
106 start
= &path
[rb
->strlen(path
)];
107 rb
->memset(start
,0,&path
[MAX_PATH
-1]-start
);
108 rb
->write(fd
,path
,MAX_PATH
);
109 traversedir(fullpath
, entry
->d_name
);
112 if (*rb
->current_tick
- lasttick
> (HZ
/2)) {
113 update_screen(false);
114 lasttick
= *rb
->current_tick
;
115 if (rb
->action_userabort(TIMEOUT_NOBLOCK
))
122 entry
= rb
->readdir(dir
);
128 bool custom_dir(void)
131 char *starts
, line
[MAX_PATH
], formatted_line
[MAX_PATH
];
136 /* populate removed dirs array */
137 if((fd2
= rb
->open(RFADIR_FILE
,O_RDONLY
)) > 0)
139 while ((rb
->read_line(fd2
, line
, MAX_PATH
- 1)) > 0)
141 if ((line
[0] == '-') && (line
[1] == '/') &&
142 (num_replaced_dirs
< MAX_REMOVED_DIRS
))
144 num_replaced_dirs
++;
145 rb
->strncpy(removed_dirs
[num_replaced_dirs
- 1], line
+ 2,
152 if((fd2
= rb
->open(RFADIR_FILE
,O_RDONLY
)) > 0)
154 while ((rb
->read_line(fd2
, line
, MAX_PATH
- 1)) > 0)
156 /* blank lines and removed dirs ignored */
157 if (rb
->strlen(line
) && ((line
[0] != '-') || (line
[1] != '/')))
159 /* remove preceeding '/'s from the line */
160 while(line
[0] == '/')
161 rb
->strncpy(line
, line
+ 1, rb
->strlen(line
));
163 rb
->snprintf(formatted_line
, MAX_PATH
, "/%s", line
);
165 dir_check
= rb
->opendir(formatted_line
);
169 rb
->closedir(dir_check
);
170 starts
= &formatted_line
[rb
->strlen(formatted_line
)];
171 rb
->memset(starts
, 0, &formatted_line
[MAX_PATH
-1]-starts
);
172 bool write_line
= true;
174 for(i
= 0; i
< num_replaced_dirs
; i
++)
176 if(!rb
->strcmp(line
, removed_dirs
[i
]))
186 rb
->write(fd
, formatted_line
, MAX_PATH
);
189 traversedir("", line
);
194 rb
->snprintf(buf
,sizeof(buf
),"Not found:");
197 rb
->screens
[i
]->puts(0,0,buf
);
198 rb
->screens
[i
]->puts(0, errors
, line
);
200 update_screen(false);
206 /* Press button to continue */
207 rb
->get_action(CONTEXT_STD
, TIMEOUT_BLOCK
);
218 fd
= rb
->open(RFA_FILE
,O_CREAT
|O_WRONLY
);
219 rb
->write(fd
,&dirs_count
,sizeof(int));
222 rb
->splash(HZ
, "Couldnt open %s", RFA_FILE
);
225 #ifndef HAVE_LCD_CHARCELLS
228 lasttick
= *rb
->current_tick
;
233 rb
->lseek(fd
,0,SEEK_SET
);
234 rb
->write(fd
,&dirs_count
,sizeof(int));
236 rb
->splash(HZ
, "Done");
238 char *list_get_name_cb(int selected_item
, void* data
, char* buf
, size_t buf_len
)
241 rb
->strncpy(buf
, list
->folder
[selected_item
], buf_len
);
247 int myfd
= rb
->open(RFA_FILE
,O_RDONLY
);
250 buffer
= rb
->plugin_get_audio_buffer((size_t *)&buffer_size
);
256 rb
->read(myfd
,buffer
,buffer_size
);
258 list
= (struct file_format
*)buffer
;
265 int myfd
= rb
->creat(RFA_FILE
);
268 rb
->splash(HZ
, "Could Not Open " RFA_FILE
);
271 int dirs_count
= 0, i
= 0;
272 rb
->write(myfd
,&dirs_count
,sizeof(int));
273 for ( ;i
<list
->count
;i
++)
275 if (list
->folder
[i
][0] != ' ')
278 rb
->write(myfd
,list
->folder
[i
],MAX_PATH
);
281 rb
->lseek(myfd
,0,SEEK_SET
);
282 rb
->write(myfd
,&dirs_count
,sizeof(int));
290 struct gui_synclist lists
;
293 int selection
, ret
= 0;
295 /* load the dat file if not already done */
296 if ((list
== NULL
|| list
->count
== 0) && (i
= load_list()) != 0)
298 rb
->splash(HZ
*2, "Could not load %s, rv = %d", RFA_FILE
, i
);
302 dirs_count
= list
->count
;
304 rb
->gui_synclist_init(&lists
,list_get_name_cb
,0, false, 1, NULL
);
305 rb
->gui_synclist_set_icon_callback(&lists
,NULL
);
306 rb
->gui_synclist_set_nb_items(&lists
,list
->count
);
307 rb
->gui_synclist_limit_scroll(&lists
,true);
308 rb
->gui_synclist_select_item(&lists
, 0);
312 rb
->gui_synclist_draw(&lists
);
313 button
= rb
->get_action(CONTEXT_LIST
,TIMEOUT_BLOCK
);
314 if (rb
->gui_synclist_do_button(&lists
,&button
,LIST_WRAP_UNLESS_HELD
))
316 selection
= rb
->gui_synclist_get_sel_pos(&lists
);
320 list
->folder
[selection
][0] = ' ';
321 list
->folder
[selection
][1] = '\0';
323 case ACTION_STD_CONTEXT
:
326 static const struct menu_item items
[] = {
327 { "Remove Folder", NULL
},
328 { "Remove Folder Tree", NULL
},
330 m
= menu_init(rb
, items
, sizeof(items
) / sizeof(*items
),
331 NULL
, NULL
, NULL
, NULL
);
333 switch (menu_show(m
))
336 list
->folder
[selection
][0] = ' ';
337 list
->folder
[selection
][1] = '\0';
342 rb
->strcpy(temp
,list
->folder
[selection
]);
343 len
= rb
->strlen(temp
);
344 for (i
=0;i
<list
->count
;i
++)
346 if (!rb
->strncmp(list
->folder
[i
],temp
,len
))
348 list
->folder
[i
][0] = ' ';
349 list
->folder
[i
][1] = '\0';
358 case ACTION_STD_CANCEL
:
361 static const struct menu_item items
[] = {
362 { "Save and Exit", NULL
},
363 { "Ignore Changes and Exit", NULL
},
365 m
= menu_init(rb
, items
, sizeof(items
) / sizeof(*items
),
366 NULL
, NULL
, NULL
, NULL
);
368 switch (menu_show(m
))
384 int export_list_to_file_text(void)
387 /* load the dat file if not already done */
388 if ((list
== NULL
|| list
->count
== 0) && (i
= load_list()) != 0)
390 rb
->splash(HZ
*2, "Could not load %s, rv = %d", RFA_FILE
, i
);
394 if (list
->count
<= 0)
396 rb
->splash(HZ
*2, "no dirs in list file: %s", RFA_FILE
);
400 /* create and open the file */
401 int myfd
= rb
->creat(RFA_FILE_TEXT
);
404 rb
->splash(HZ
*4, "failed to open: fd = %d, file = %s",
405 myfd
, RFA_FILE_TEXT
);
409 /* write each directory to file */
410 for (i
= 0; i
< list
->count
; i
++)
412 if (list
->folder
[i
][0] != ' ')
414 rb
->fdprintf(myfd
, "%s\n", list
->folder
[i
]);
419 rb
->splash(HZ
, "Done");
423 int import_list_from_file_text(void)
427 buffer
= rb
->plugin_get_audio_buffer((size_t *)&buffer_size
);
430 rb
->splash(HZ
*2, "failed to get audio buffer");
434 int myfd
= rb
->open(RFA_FILE_TEXT
, O_RDONLY
);
437 rb
->splash(HZ
*2, "failed to open: %s", RFA_FILE_TEXT
);
441 /* set the list structure, and initialize count */
442 list
= (struct file_format
*)buffer
;
445 while ((rb
->read_line(myfd
, line
, MAX_PATH
- 1)) > 0)
447 /* copy the dir name, and skip the newline */
448 int len
= rb
->strlen(line
);
452 if (line
[len
-1] == 0x0A || line
[len
-1] == 0x0D)
455 (line
[len
-2] == 0x0A || line
[len
-2] == 0x0D))
459 rb
->strcpy(list
->folder
[list
->count
++], line
);
464 if (list
->count
== 0)
472 rb
->splash(HZ
, "Done");
480 static const struct menu_item items
[] = {
481 { "Generate Folder List", NULL
},
482 { "Edit Folder List", NULL
},
483 { "Export List To Textfile", NULL
},
484 { "Import List From Textfile", NULL
},
487 m
= menu_init(rb
, items
, sizeof(items
) / sizeof(*items
),
488 NULL
, NULL
, NULL
, NULL
);
490 switch (menu_show(m
))
492 case 0: /* generate */
493 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
497 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
498 rb
->cpu_boost(false);
500 #ifdef HAVE_REMOTE_LCD
501 rb
->remote_backlight_on();
506 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
511 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
512 rb
->cpu_boost(false);
514 #ifdef HAVE_REMOTE_LCD
515 rb
->remote_backlight_on();
519 case 2: /* export to textfile */
520 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
523 export_list_to_file_text();
524 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
525 rb
->cpu_boost(false);
527 #ifdef HAVE_REMOTE_LCD
528 rb
->remote_backlight_on();
532 case 3: /* import from textfile */
533 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
536 import_list_from_file_text();
537 #ifdef HAVE_ADJUSTABLE_CPU_FREQ
538 rb
->cpu_boost(false);
540 #ifdef HAVE_REMOTE_LCD
541 rb
->remote_backlight_on();
553 enum plugin_status
plugin_start(const struct plugin_api
* api
, const void* parameter
)