Currently playing playlist can now be overwritten. Save playlist screen defaults to this.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8641 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
f1c4152ac3
commit
0cca6caa8a
5 changed files with 208 additions and 44 deletions
|
@ -61,6 +61,7 @@
|
|||
#if CONFIG_CODEC == SWCODEC
|
||||
#include "eq_menu.h"
|
||||
#endif
|
||||
#include "playlist_menu.h"
|
||||
|
||||
static int context;
|
||||
static char* selected_file = NULL;
|
||||
|
@ -152,18 +153,7 @@ static bool shuffle_playlist(void)
|
|||
|
||||
static bool save_playlist(void)
|
||||
{
|
||||
char filename[MAX_PATH+1];
|
||||
|
||||
strncpy(filename, DEFAULT_DYNAMIC_PLAYLIST_NAME, sizeof(filename));
|
||||
|
||||
if (!kbd_input(filename, sizeof(filename)))
|
||||
{
|
||||
playlist_save(NULL, filename);
|
||||
|
||||
/* reload in case playlist was saved to cwd */
|
||||
onplay_result = ONPLAY_RELOAD_DIR;
|
||||
}
|
||||
|
||||
save_playlist_screen(NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
184
apps/playlist.c
184
apps/playlist.c
|
@ -143,6 +143,7 @@ static void new_playlist(struct playlist_info* playlist, const char *dir,
|
|||
const char *file);
|
||||
static void create_control(struct playlist_info* playlist);
|
||||
static int check_control(struct playlist_info* playlist);
|
||||
static int recreate_control(struct playlist_info* playlist);
|
||||
static void update_playlist_filename(struct playlist_info* playlist,
|
||||
const char *dir, const char *file);
|
||||
static int add_indices_to_playlist(struct playlist_info* playlist,
|
||||
|
@ -321,6 +322,107 @@ static int check_control(struct playlist_info* playlist)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* recreate the control file based on current playlist entries
|
||||
*/
|
||||
static int recreate_control(struct playlist_info* playlist)
|
||||
{
|
||||
char temp_file[MAX_PATH+1];
|
||||
int temp_fd = -1;
|
||||
int i;
|
||||
int result = 0;
|
||||
|
||||
if(playlist->control_fd >= 0)
|
||||
{
|
||||
char* dir = playlist->filename;
|
||||
char* file = playlist->filename+playlist->dirlen;
|
||||
char c = playlist->filename[playlist->dirlen-1];
|
||||
|
||||
close(playlist->control_fd);
|
||||
|
||||
snprintf(temp_file, sizeof(temp_file), "%s_temp",
|
||||
playlist->control_filename);
|
||||
|
||||
if (rename(playlist->control_filename, temp_file) < 0)
|
||||
return -1;
|
||||
|
||||
temp_fd = open(temp_file, O_RDONLY);
|
||||
if (temp_fd < 0)
|
||||
return -1;
|
||||
|
||||
playlist->control_fd = open(playlist->control_filename,
|
||||
O_CREAT|O_RDWR|O_TRUNC);
|
||||
if (playlist->control_fd < 0)
|
||||
return -1;
|
||||
|
||||
playlist->filename[playlist->dirlen-1] = '\0';
|
||||
|
||||
/* cannot call update_control() because of mutex */
|
||||
result = fdprintf(playlist->control_fd, "P:%d:%s:%s\n",
|
||||
PLAYLIST_CONTROL_FILE_VERSION, dir, file);
|
||||
|
||||
playlist->filename[playlist->dirlen-1] = c;
|
||||
|
||||
if (result < 0)
|
||||
{
|
||||
close(temp_fd);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
playlist->seed = 0;
|
||||
playlist->shuffle_modified = false;
|
||||
playlist->deleted = false;
|
||||
playlist->num_inserted_tracks = 0;
|
||||
|
||||
if (playlist->current)
|
||||
{
|
||||
global_settings.resume_seed = -1;
|
||||
settings_save();
|
||||
}
|
||||
|
||||
for (i=0; i<playlist->amount; i++)
|
||||
{
|
||||
if (playlist->indices[i] & PLAYLIST_INSERT_TYPE_MASK)
|
||||
{
|
||||
bool queue = playlist->indices[i] & PLAYLIST_QUEUE_MASK;
|
||||
char inserted_file[MAX_PATH+1];
|
||||
|
||||
lseek(temp_fd, playlist->indices[i] & PLAYLIST_SEEK_MASK,
|
||||
SEEK_SET);
|
||||
read_line(temp_fd, inserted_file, sizeof(inserted_file));
|
||||
|
||||
result = fdprintf(playlist->control_fd, "%c:%d:%d:",
|
||||
queue?'Q':'A', i, playlist->last_insert_pos);
|
||||
if (result > 0)
|
||||
{
|
||||
/* save the position in file where name is written */
|
||||
int seek_pos = lseek(playlist->control_fd, 0, SEEK_CUR);
|
||||
|
||||
result = fdprintf(playlist->control_fd, "%s\n",
|
||||
inserted_file);
|
||||
|
||||
playlist->indices[i] =
|
||||
(playlist->indices[i] & ~PLAYLIST_SEEK_MASK) | seek_pos;
|
||||
}
|
||||
|
||||
if (result < 0)
|
||||
break;
|
||||
|
||||
playlist->num_inserted_tracks++;
|
||||
}
|
||||
}
|
||||
|
||||
close(temp_fd);
|
||||
remove(temp_file);
|
||||
fsync(playlist->control_fd);
|
||||
|
||||
if (result < 0)
|
||||
return result;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* store directory and name of playlist file
|
||||
*/
|
||||
|
@ -1183,6 +1285,8 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
|
|||
}
|
||||
else if (max < 0)
|
||||
{
|
||||
mutex_lock(&playlist->control_mutex);
|
||||
|
||||
if (control_file)
|
||||
fd = playlist->control_fd;
|
||||
else
|
||||
|
@ -1195,18 +1299,15 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
|
|||
|
||||
if(-1 != fd)
|
||||
{
|
||||
if (control_file)
|
||||
mutex_lock(&playlist->control_mutex);
|
||||
|
||||
if (lseek(fd, seek, SEEK_SET) != seek)
|
||||
max = -1;
|
||||
else
|
||||
max = read(fd, tmp_buf, buf_length);
|
||||
|
||||
if (control_file)
|
||||
mutex_unlock(&playlist->control_mutex);
|
||||
}
|
||||
|
||||
mutex_unlock(&playlist->control_mutex);
|
||||
|
||||
if (max < 0)
|
||||
{
|
||||
if (control_file)
|
||||
|
@ -3114,8 +3215,11 @@ int playlist_save(struct playlist_info* playlist, char *filename)
|
|||
int fd;
|
||||
int i, index;
|
||||
int count = 0;
|
||||
char path[MAX_PATH+1];
|
||||
char tmp_buf[MAX_PATH+1];
|
||||
int result = 0;
|
||||
bool overwrite_current = false;
|
||||
int* index_buf = NULL;
|
||||
|
||||
if (!playlist)
|
||||
playlist = ¤t_playlist;
|
||||
|
@ -3124,11 +3228,31 @@ int playlist_save(struct playlist_info* playlist, char *filename)
|
|||
return -1;
|
||||
|
||||
/* use current working directory as base for pathname */
|
||||
if (format_track_path(tmp_buf, filename, sizeof(tmp_buf),
|
||||
if (format_track_path(path, filename, sizeof(tmp_buf),
|
||||
strlen(filename)+1, getcwd(NULL, -1)) < 0)
|
||||
return -1;
|
||||
|
||||
fd = open(tmp_buf, O_CREAT|O_WRONLY|O_TRUNC);
|
||||
if (!strncmp(playlist->filename, path, strlen(path)))
|
||||
{
|
||||
/* Attempting to overwrite current playlist file.*/
|
||||
|
||||
if (playlist->buffer_size < (int)(playlist->amount * sizeof(int)))
|
||||
{
|
||||
/* not enough buffer space to store updated indices */
|
||||
gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR));
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* in_ram buffer is unused for m3u files so we'll use for storing
|
||||
updated indices */
|
||||
index_buf = (int*)playlist->buffer;
|
||||
|
||||
/* use temporary pathname */
|
||||
snprintf(path, sizeof(path), "%s_temp", playlist->filename);
|
||||
overwrite_current = true;
|
||||
}
|
||||
|
||||
fd = open(path, O_CREAT|O_WRONLY|O_TRUNC);
|
||||
if (fd < 0)
|
||||
{
|
||||
gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR));
|
||||
|
@ -3146,7 +3270,10 @@ int playlist_save(struct playlist_info* playlist, char *filename)
|
|||
|
||||
/* user abort */
|
||||
if (button_get(false) == SETTINGS_CANCEL)
|
||||
{
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK;
|
||||
queue = playlist->indices[index] & PLAYLIST_QUEUE_MASK;
|
||||
|
@ -3162,9 +3289,12 @@ int playlist_save(struct playlist_info* playlist, char *filename)
|
|||
break;
|
||||
}
|
||||
|
||||
if (overwrite_current)
|
||||
index_buf[count] = lseek(fd, 0, SEEK_CUR);
|
||||
|
||||
if (fdprintf(fd, "%s\n", tmp_buf) < 0)
|
||||
{
|
||||
gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_UPDATE_ERROR));
|
||||
gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR));
|
||||
result = -1;
|
||||
break;
|
||||
}
|
||||
|
@ -3184,5 +3314,43 @@ int playlist_save(struct playlist_info* playlist, char *filename)
|
|||
|
||||
close(fd);
|
||||
|
||||
if (overwrite_current && result >= 0)
|
||||
{
|
||||
result = -1;
|
||||
|
||||
mutex_lock(&playlist->control_mutex);
|
||||
|
||||
/* Replace the current playlist with the new one and update indices */
|
||||
close(playlist->fd);
|
||||
if (remove(playlist->filename) >= 0)
|
||||
{
|
||||
if (rename(path, playlist->filename) >= 0)
|
||||
{
|
||||
playlist->fd = open(playlist->filename, O_RDONLY);
|
||||
if (playlist->fd >= 0)
|
||||
{
|
||||
index = playlist->first_index;
|
||||
for (i=0, count=0; i<playlist->amount; i++)
|
||||
{
|
||||
if (!(playlist->indices[index] & PLAYLIST_QUEUE_MASK))
|
||||
{
|
||||
playlist->indices[index] = index_buf[count];
|
||||
count++;
|
||||
}
|
||||
index = (index+1)%playlist->amount;
|
||||
}
|
||||
|
||||
/* we need to recreate control because inserted tracks are
|
||||
now part of the playlist and shuffle has been
|
||||
invalidated */
|
||||
result = recreate_control(playlist);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mutex_unlock(&playlist->control_mutex);
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -28,22 +28,11 @@
|
|||
#include "playlist_viewer.h"
|
||||
#include "talk.h"
|
||||
#include "lang.h"
|
||||
#include "playlist_menu.h"
|
||||
|
||||
/* FIXME: there is a very similar function in onplay.c */
|
||||
static bool save_playlist(void)
|
||||
{
|
||||
char filename[MAX_PATH+1];
|
||||
|
||||
strncpy(filename, DEFAULT_DYNAMIC_PLAYLIST_NAME, sizeof(filename));
|
||||
|
||||
if (!kbd_input(filename, sizeof(filename)))
|
||||
{
|
||||
playlist_save(NULL, filename);
|
||||
|
||||
/* reload in case playlist was saved to cwd */
|
||||
reload_directory();
|
||||
}
|
||||
|
||||
save_playlist_screen(NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -85,3 +74,26 @@ bool playlist_menu(void)
|
|||
menu_exit(m);
|
||||
return result;
|
||||
}
|
||||
|
||||
int save_playlist_screen(struct playlist_info* playlist)
|
||||
{
|
||||
char* filename;
|
||||
char temp[MAX_PATH+1];
|
||||
int len;
|
||||
|
||||
filename = playlist_get_name(playlist, temp, sizeof(temp));
|
||||
|
||||
if (!filename || (len=strlen(filename)) <= 4 ||
|
||||
strcasecmp(&filename[len-4], ".m3u"))
|
||||
filename = DEFAULT_DYNAMIC_PLAYLIST_NAME;
|
||||
|
||||
if (!kbd_input(filename, sizeof(filename)))
|
||||
{
|
||||
playlist_save(playlist, filename);
|
||||
|
||||
/* reload in case playlist was saved to cwd */
|
||||
reload_directory();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
#ifndef _PLAYLIST_MENU_H
|
||||
#define _PLAYLIST_MENU_H
|
||||
|
||||
#include "playlist.h"
|
||||
|
||||
bool playlist_menu(void);
|
||||
int save_playlist_screen(struct playlist_info* playlist);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include "list.h"
|
||||
#include "statusbar.h"
|
||||
#include "splash.h"
|
||||
#include "playlist_menu.h"
|
||||
|
||||
/* Maximum number of tracks we can have loaded at one time */
|
||||
#define MAX_PLAYLIST_ENTRIES 200
|
||||
|
@ -543,17 +544,7 @@ static bool track_display(void)
|
|||
/* Save playlist to disk */
|
||||
static bool save_playlist(void)
|
||||
{
|
||||
char filename[MAX_PATH+1];
|
||||
|
||||
strncpy(filename, DEFAULT_VIEWER_PLAYLIST_NAME, sizeof(filename));
|
||||
|
||||
if (!kbd_input(filename, sizeof(filename)))
|
||||
{
|
||||
playlist_save(viewer.playlist, filename);
|
||||
/* reload in case playlist was saved to cwd */
|
||||
reload_directory();
|
||||
}
|
||||
|
||||
save_playlist_screen(viewer.playlist);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue