1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2002 Björn Stenberg
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
43 #include "playlist_viewer.h"
46 #include "filetypes.h"
49 static char* selected_file
= NULL
;
50 static int selected_file_attr
= 0;
51 static int onplay_result
= ONPLAY_OK
;
53 static bool list_viewers(void)
55 struct menu_item menu
[8];
59 i
=filetype_load_menu(menu
,sizeof(menu
)/sizeof(*menu
));
62 m
= menu_init( menu
, i
, NULL
, NULL
, NULL
, NULL
);
63 result
= menu_show(m
);
66 ret
= filetype_load_plugin(menu
[result
].desc
,selected_file
);
70 splash(HZ
*2, true, "No viewers found");
73 if(ret
== PLUGIN_USB_CONNECTED
)
74 onplay_result
= ONPLAY_RELOAD_DIR
;
79 /* For playlist options */
80 struct playlist_args
{
85 static bool add_to_playlist(int position
, bool queue
)
87 bool new_playlist
= !(mpeg_status() & MPEG_STATUS_PLAY
);
90 playlist_create(NULL
, NULL
);
92 if ((selected_file_attr
& TREE_ATTR_MASK
) == TREE_ATTR_MPA
)
93 playlist_insert_track(NULL
, selected_file
, position
, queue
);
94 else if (selected_file_attr
& ATTR_DIRECTORY
)
98 if (global_settings
.recursive_dir_insert
!= RECURSE_ASK
)
99 recurse
= (bool)global_settings
.recursive_dir_insert
;
102 /* Ask if user wants to recurse directory */
106 lcd_puts_scroll(0,0,str(LANG_RECURSE_DIRECTORY_QUESTION
));
107 lcd_puts_scroll(0,1,selected_file
);
109 #ifdef HAVE_LCD_BITMAP
110 lcd_puts(0,3,str(LANG_CONFIRM_WITH_PLAY_RECORDER
));
111 lcd_puts(0,4,str(LANG_CANCEL_WITH_ANY_RECORDER
));
117 int btn
= button_get(true);
125 /* ignore button releases */
126 if (!(btn
& BUTTON_REL
))
133 playlist_insert_directory(NULL
, selected_file
, position
, queue
,
136 else if ((selected_file_attr
& TREE_ATTR_MASK
) == TREE_ATTR_M3U
)
137 playlist_insert_playlist(NULL
, selected_file
, position
, queue
);
139 if (new_playlist
&& (playlist_amount() > 0))
141 /* nothing is currently playing so begin playing what we just
143 if (global_settings
.playlist_shuffle
)
144 playlist_shuffle(current_tick
, -1);
147 onplay_result
= ONPLAY_START_PLAY
;
153 static bool view_playlist(void)
155 bool was_playing
= mpeg_status() & MPEG_STATUS_PLAY
;
158 result
= playlist_viewer_ex(selected_file
);
160 if (!was_playing
&& (mpeg_status() & MPEG_STATUS_PLAY
) &&
161 onplay_result
== ONPLAY_OK
)
162 /* playlist was started from viewer */
163 onplay_result
= ONPLAY_START_PLAY
;
168 /* Sub-menu for playlist options */
169 static bool playlist_options(void)
171 struct menu_item items
[7];
172 struct playlist_args args
[7]; /* increase these 2 if you add entries! */
173 int m
, i
=0, pstart
=0, result
;
176 if ((selected_file_attr
& TREE_ATTR_MASK
) == TREE_ATTR_M3U
)
178 items
[i
].desc
= ID2P(LANG_VIEW
);
179 items
[i
].function
= view_playlist
;
184 if (mpeg_status() & MPEG_STATUS_PLAY
)
186 items
[i
].desc
= ID2P(LANG_INSERT
);
187 args
[i
].position
= PLAYLIST_INSERT
;
188 args
[i
].queue
= false;
191 items
[i
].desc
= ID2P(LANG_INSERT_FIRST
);
192 args
[i
].position
= PLAYLIST_INSERT_FIRST
;
193 args
[i
].queue
= false;
196 items
[i
].desc
= ID2P(LANG_INSERT_LAST
);
197 args
[i
].position
= PLAYLIST_INSERT_LAST
;
198 args
[i
].queue
= false;
201 items
[i
].desc
= ID2P(LANG_QUEUE
);
202 args
[i
].position
= PLAYLIST_INSERT
;
203 args
[i
].queue
= true;
206 items
[i
].desc
= ID2P(LANG_QUEUE_FIRST
);
207 args
[i
].position
= PLAYLIST_INSERT_FIRST
;
208 args
[i
].queue
= true;
211 items
[i
].desc
= ID2P(LANG_QUEUE_LAST
);
212 args
[i
].position
= PLAYLIST_INSERT_LAST
;
213 args
[i
].queue
= true;
216 else if (((selected_file_attr
& TREE_ATTR_MASK
) == TREE_ATTR_MPA
) ||
217 (selected_file_attr
& ATTR_DIRECTORY
))
219 items
[i
].desc
= ID2P(LANG_INSERT
);
220 args
[i
].position
= PLAYLIST_INSERT
;
221 args
[i
].queue
= false;
225 m
= menu_init( items
, i
, NULL
, NULL
, NULL
, NULL
);
226 result
= menu_show(m
);
227 if (result
>= 0 && result
< pstart
)
228 ret
= items
[result
].function();
229 else if (result
>= pstart
)
230 ret
= add_to_playlist(args
[result
].position
, args
[result
].queue
);
237 /* helper function to remove a non-empty directory */
238 static int remove_dir(char* dirname
, int len
)
242 int dirlen
= strlen(dirname
);
244 dir
= opendir(dirname
);
246 return -1; /* open error */
250 struct dirent
* entry
;
251 /* walk through the directory content */
252 entry
= readdir(dir
);
256 /* append name to current directory */
257 snprintf(dirname
+dirlen
, len
-dirlen
, "/%s", entry
->d_name
);
259 if (entry
->attribute
& ATTR_DIRECTORY
)
260 { /* remove a subdirectory */
261 if (!strcmp(entry
->d_name
, ".") ||
262 !strcmp(entry
->d_name
, ".."))
263 continue; /* skip these */
265 result
= remove_dir(dirname
, len
); /* recursion */
267 break; /* or better continue, delete what we can? */
270 { /* remove a file */
271 result
= remove(dirname
);
277 { /* remove the now empty directory */
278 dirname
[dirlen
] = '\0'; /* terminate to original length */
280 result
= rmdir(dirname
);
287 /* share code for file and directory deletion, saves space */
288 static bool delete_handler(bool is_dir
)
294 lcd_puts(0,0,str(LANG_REALLY_DELETE
));
295 lcd_puts_scroll(0,1,selected_file
);
297 #ifdef HAVE_LCD_BITMAP
298 lcd_puts(0,3,str(LANG_CONFIRM_WITH_PLAY_RECORDER
));
299 lcd_puts(0,4,str(LANG_CANCEL_WITH_ANY_RECORDER
));
305 int btn
= button_get(true);
310 char pathname
[MAX_PATH
]; /* space to go deep */
311 strncpy(pathname
, selected_file
, sizeof pathname
);
312 res
= remove_dir(pathname
, sizeof(pathname
));
316 res
= remove(selected_file
);
320 onplay_result
= ONPLAY_RELOAD_DIR
;
322 lcd_puts(0,0,str(LANG_DELETED
));
323 lcd_puts_scroll(0,1,selected_file
);
331 /* ignore button releases */
332 if (!(btn
& BUTTON_REL
))
341 static bool delete_file(void)
343 return delete_handler(false);
346 static bool delete_dir(void)
348 return delete_handler(true);
351 static bool rename_file(void)
353 char newname
[MAX_PATH
];
354 char* ptr
= strrchr(selected_file
, '/') + 1;
355 int pathlen
= (ptr
- selected_file
);
356 strncpy(newname
, selected_file
, sizeof newname
);
357 if (!kbd_input(newname
+ pathlen
, (sizeof newname
)-pathlen
)) {
358 if (!strlen(selected_file
+pathlen
) ||
359 (rename(selected_file
, newname
) < 0)) {
361 lcd_puts(0,0,str(LANG_RENAME
));
362 lcd_puts(0,1,str(LANG_FAILED
));
367 onplay_result
= ONPLAY_RELOAD_DIR
;
373 bool create_dir(void)
375 char dirname
[MAX_PATH
];
380 cwd
= getcwd(NULL
, 0);
381 memset(dirname
, 0, sizeof dirname
);
383 snprintf(dirname
, sizeof dirname
, "%s/",
386 pathlen
= strlen(dirname
);
387 rc
= kbd_input(dirname
+ pathlen
, (sizeof dirname
)-pathlen
);
391 rc
= mkdir(dirname
, 0);
393 splash(HZ
, true, "%s %s", str(LANG_CREATE_DIR
), str(LANG_FAILED
));
395 onplay_result
= ONPLAY_RELOAD_DIR
;
401 int onplay(char* file
, int attr
)
403 struct menu_item items
[6]; /* increase this if you add entries! */
406 onplay_result
= ONPLAY_OK
;
410 selected_file
= file
;
411 selected_file_attr
= attr
;
413 if (((attr
& TREE_ATTR_MASK
) == TREE_ATTR_MPA
) ||
414 (attr
& ATTR_DIRECTORY
) ||
415 ((attr
& TREE_ATTR_MASK
) == TREE_ATTR_M3U
))
417 items
[i
].desc
= ID2P(LANG_PLAYINDICES_PLAYLIST
);
418 items
[i
].function
= playlist_options
;
422 items
[i
].desc
= ID2P(LANG_RENAME
);
423 items
[i
].function
= rename_file
;
426 if (!(attr
& ATTR_DIRECTORY
))
428 items
[i
].desc
= ID2P(LANG_DELETE
);
429 items
[i
].function
= delete_file
;
434 items
[i
].desc
= ID2P(LANG_DELETE_DIR
);
435 items
[i
].function
= delete_dir
;
439 if (!(attr
& ATTR_DIRECTORY
))
441 items
[i
].desc
= ID2P(LANG_ONPLAY_OPEN_WITH
);
442 items
[i
].function
= list_viewers
;
447 items
[i
].desc
= ID2P(LANG_CREATE_DIR
);
448 items
[i
].function
= create_dir
;
451 /* DIY menu handling, since we want to exit after selection */
452 m
= menu_init( items
, i
, NULL
, NULL
, NULL
, NULL
);
453 result
= menu_show(m
);
455 items
[result
].function();
458 return onplay_result
;