summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHardeep Sidhu <dyp@pobox.com>2006-02-09 09:09:32 +0000
committerHardeep Sidhu <dyp@pobox.com>2006-02-09 09:09:32 +0000
commit0cca6caa8a52bcfeb2a9d77a4b4f0593082417d7 (patch)
tree18c10d90f3c8d4b75bde7e4fa39593240b033079
parentf1c4152ac33bdf9dda2e89c35179242a079da371 (diff)
downloadrockbox-0cca6caa8a52bcfeb2a9d77a4b4f0593082417d7.tar.gz
rockbox-0cca6caa8a52bcfeb2a9d77a4b4f0593082417d7.zip
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
-rw-r--r--apps/onplay.c14
-rw-r--r--apps/playlist.c184
-rw-r--r--apps/playlist_menu.c38
-rw-r--r--apps/playlist_menu.h3
-rw-r--r--apps/playlist_viewer.c13
5 files changed, 208 insertions, 44 deletions
diff --git a/apps/onplay.c b/apps/onplay.c
index 9b94be0959..88607f7754 100644
--- a/apps/onplay.c
+++ b/apps/onplay.c
@@ -61,6 +61,7 @@
61#if CONFIG_CODEC == SWCODEC 61#if CONFIG_CODEC == SWCODEC
62#include "eq_menu.h" 62#include "eq_menu.h"
63#endif 63#endif
64#include "playlist_menu.h"
64 65
65static int context; 66static int context;
66static char* selected_file = NULL; 67static char* selected_file = NULL;
@@ -152,18 +153,7 @@ static bool shuffle_playlist(void)
152 153
153static bool save_playlist(void) 154static bool save_playlist(void)
154{ 155{
155 char filename[MAX_PATH+1]; 156 save_playlist_screen(NULL);
156
157 strncpy(filename, DEFAULT_DYNAMIC_PLAYLIST_NAME, sizeof(filename));
158
159 if (!kbd_input(filename, sizeof(filename)))
160 {
161 playlist_save(NULL, filename);
162
163 /* reload in case playlist was saved to cwd */
164 onplay_result = ONPLAY_RELOAD_DIR;
165 }
166
167 return false; 157 return false;
168} 158}
169 159
diff --git a/apps/playlist.c b/apps/playlist.c
index 25939bb3ee..84160195b7 100644
--- a/apps/playlist.c
+++ b/apps/playlist.c
@@ -143,6 +143,7 @@ static void new_playlist(struct playlist_info* playlist, const char *dir,
143 const char *file); 143 const char *file);
144static void create_control(struct playlist_info* playlist); 144static void create_control(struct playlist_info* playlist);
145static int check_control(struct playlist_info* playlist); 145static int check_control(struct playlist_info* playlist);
146static int recreate_control(struct playlist_info* playlist);
146static void update_playlist_filename(struct playlist_info* playlist, 147static void update_playlist_filename(struct playlist_info* playlist,
147 const char *dir, const char *file); 148 const char *dir, const char *file);
148static int add_indices_to_playlist(struct playlist_info* playlist, 149static int add_indices_to_playlist(struct playlist_info* playlist,
@@ -322,6 +323,107 @@ static int check_control(struct playlist_info* playlist)
322} 323}
323 324
324/* 325/*
326 * recreate the control file based on current playlist entries
327 */
328static int recreate_control(struct playlist_info* playlist)
329{
330 char temp_file[MAX_PATH+1];
331 int temp_fd = -1;
332 int i;
333 int result = 0;
334
335 if(playlist->control_fd >= 0)
336 {
337 char* dir = playlist->filename;
338 char* file = playlist->filename+playlist->dirlen;
339 char c = playlist->filename[playlist->dirlen-1];
340
341 close(playlist->control_fd);
342
343 snprintf(temp_file, sizeof(temp_file), "%s_temp",
344 playlist->control_filename);
345
346 if (rename(playlist->control_filename, temp_file) < 0)
347 return -1;
348
349 temp_fd = open(temp_file, O_RDONLY);
350 if (temp_fd < 0)
351 return -1;
352
353 playlist->control_fd = open(playlist->control_filename,
354 O_CREAT|O_RDWR|O_TRUNC);
355 if (playlist->control_fd < 0)
356 return -1;
357
358 playlist->filename[playlist->dirlen-1] = '\0';
359
360 /* cannot call update_control() because of mutex */
361 result = fdprintf(playlist->control_fd, "P:%d:%s:%s\n",
362 PLAYLIST_CONTROL_FILE_VERSION, dir, file);
363
364 playlist->filename[playlist->dirlen-1] = c;
365
366 if (result < 0)
367 {
368 close(temp_fd);
369 return result;
370 }
371 }
372
373 playlist->seed = 0;
374 playlist->shuffle_modified = false;
375 playlist->deleted = false;
376 playlist->num_inserted_tracks = 0;
377
378 if (playlist->current)
379 {
380 global_settings.resume_seed = -1;
381 settings_save();
382 }
383
384 for (i=0; i<playlist->amount; i++)
385 {
386 if (playlist->indices[i] & PLAYLIST_INSERT_TYPE_MASK)
387 {
388 bool queue = playlist->indices[i] & PLAYLIST_QUEUE_MASK;
389 char inserted_file[MAX_PATH+1];
390
391 lseek(temp_fd, playlist->indices[i] & PLAYLIST_SEEK_MASK,
392 SEEK_SET);
393 read_line(temp_fd, inserted_file, sizeof(inserted_file));
394
395 result = fdprintf(playlist->control_fd, "%c:%d:%d:",
396 queue?'Q':'A', i, playlist->last_insert_pos);
397 if (result > 0)
398 {
399 /* save the position in file where name is written */
400 int seek_pos = lseek(playlist->control_fd, 0, SEEK_CUR);
401
402 result = fdprintf(playlist->control_fd, "%s\n",
403 inserted_file);
404
405 playlist->indices[i] =
406 (playlist->indices[i] & ~PLAYLIST_SEEK_MASK) | seek_pos;
407 }
408
409 if (result < 0)
410 break;
411
412 playlist->num_inserted_tracks++;
413 }
414 }
415
416 close(temp_fd);
417 remove(temp_file);
418 fsync(playlist->control_fd);
419
420 if (result < 0)
421 return result;
422
423 return 0;
424}
425
426/*
325 * store directory and name of playlist file 427 * store directory and name of playlist file
326 */ 428 */
327static void update_playlist_filename(struct playlist_info* playlist, 429static void update_playlist_filename(struct playlist_info* playlist,
@@ -1183,6 +1285,8 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
1183 } 1285 }
1184 else if (max < 0) 1286 else if (max < 0)
1185 { 1287 {
1288 mutex_lock(&playlist->control_mutex);
1289
1186 if (control_file) 1290 if (control_file)
1187 fd = playlist->control_fd; 1291 fd = playlist->control_fd;
1188 else 1292 else
@@ -1195,18 +1299,15 @@ static int get_filename(struct playlist_info* playlist, int index, int seek,
1195 1299
1196 if(-1 != fd) 1300 if(-1 != fd)
1197 { 1301 {
1198 if (control_file)
1199 mutex_lock(&playlist->control_mutex);
1200 1302
1201 if (lseek(fd, seek, SEEK_SET) != seek) 1303 if (lseek(fd, seek, SEEK_SET) != seek)
1202 max = -1; 1304 max = -1;
1203 else 1305 else
1204 max = read(fd, tmp_buf, buf_length); 1306 max = read(fd, tmp_buf, buf_length);
1205
1206 if (control_file)
1207 mutex_unlock(&playlist->control_mutex);
1208 } 1307 }
1209 1308
1309 mutex_unlock(&playlist->control_mutex);
1310
1210 if (max < 0) 1311 if (max < 0)
1211 { 1312 {
1212 if (control_file) 1313 if (control_file)
@@ -3114,8 +3215,11 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3114 int fd; 3215 int fd;
3115 int i, index; 3216 int i, index;
3116 int count = 0; 3217 int count = 0;
3218 char path[MAX_PATH+1];
3117 char tmp_buf[MAX_PATH+1]; 3219 char tmp_buf[MAX_PATH+1];
3118 int result = 0; 3220 int result = 0;
3221 bool overwrite_current = false;
3222 int* index_buf = NULL;
3119 3223
3120 if (!playlist) 3224 if (!playlist)
3121 playlist = &current_playlist; 3225 playlist = &current_playlist;
@@ -3124,11 +3228,31 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3124 return -1; 3228 return -1;
3125 3229
3126 /* use current working directory as base for pathname */ 3230 /* use current working directory as base for pathname */
3127 if (format_track_path(tmp_buf, filename, sizeof(tmp_buf), 3231 if (format_track_path(path, filename, sizeof(tmp_buf),
3128 strlen(filename)+1, getcwd(NULL, -1)) < 0) 3232 strlen(filename)+1, getcwd(NULL, -1)) < 0)
3129 return -1; 3233 return -1;
3130 3234
3131 fd = open(tmp_buf, O_CREAT|O_WRONLY|O_TRUNC); 3235 if (!strncmp(playlist->filename, path, strlen(path)))
3236 {
3237 /* Attempting to overwrite current playlist file.*/
3238
3239 if (playlist->buffer_size < (int)(playlist->amount * sizeof(int)))
3240 {
3241 /* not enough buffer space to store updated indices */
3242 gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR));
3243 return -1;
3244 }
3245
3246 /* in_ram buffer is unused for m3u files so we'll use for storing
3247 updated indices */
3248 index_buf = (int*)playlist->buffer;
3249
3250 /* use temporary pathname */
3251 snprintf(path, sizeof(path), "%s_temp", playlist->filename);
3252 overwrite_current = true;
3253 }
3254
3255 fd = open(path, O_CREAT|O_WRONLY|O_TRUNC);
3132 if (fd < 0) 3256 if (fd < 0)
3133 { 3257 {
3134 gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR)); 3258 gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR));
@@ -3146,7 +3270,10 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3146 3270
3147 /* user abort */ 3271 /* user abort */
3148 if (button_get(false) == SETTINGS_CANCEL) 3272 if (button_get(false) == SETTINGS_CANCEL)
3273 {
3274 result = -1;
3149 break; 3275 break;
3276 }
3150 3277
3151 control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK; 3278 control_file = playlist->indices[index] & PLAYLIST_INSERT_TYPE_MASK;
3152 queue = playlist->indices[index] & PLAYLIST_QUEUE_MASK; 3279 queue = playlist->indices[index] & PLAYLIST_QUEUE_MASK;
@@ -3162,9 +3289,12 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3162 break; 3289 break;
3163 } 3290 }
3164 3291
3292 if (overwrite_current)
3293 index_buf[count] = lseek(fd, 0, SEEK_CUR);
3294
3165 if (fdprintf(fd, "%s\n", tmp_buf) < 0) 3295 if (fdprintf(fd, "%s\n", tmp_buf) < 0)
3166 { 3296 {
3167 gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_CONTROL_UPDATE_ERROR)); 3297 gui_syncsplash(HZ*2, true, str(LANG_PLAYLIST_ACCESS_ERROR));
3168 result = -1; 3298 result = -1;
3169 break; 3299 break;
3170 } 3300 }
@@ -3184,5 +3314,43 @@ int playlist_save(struct playlist_info* playlist, char *filename)
3184 3314
3185 close(fd); 3315 close(fd);
3186 3316
3317 if (overwrite_current && result >= 0)
3318 {
3319 result = -1;
3320
3321 mutex_lock(&playlist->control_mutex);
3322
3323 /* Replace the current playlist with the new one and update indices */
3324 close(playlist->fd);
3325 if (remove(playlist->filename) >= 0)
3326 {
3327 if (rename(path, playlist->filename) >= 0)
3328 {
3329 playlist->fd = open(playlist->filename, O_RDONLY);
3330 if (playlist->fd >= 0)
3331 {
3332 index = playlist->first_index;
3333 for (i=0, count=0; i<playlist->amount; i++)
3334 {
3335 if (!(playlist->indices[index] & PLAYLIST_QUEUE_MASK))
3336 {
3337 playlist->indices[index] = index_buf[count];
3338 count++;
3339 }
3340 index = (index+1)%playlist->amount;
3341 }
3342
3343 /* we need to recreate control because inserted tracks are
3344 now part of the playlist and shuffle has been
3345 invalidated */
3346 result = recreate_control(playlist);
3347 }
3348 }
3349 }
3350
3351 mutex_unlock(&playlist->control_mutex);
3352
3353 }
3354
3187 return result; 3355 return result;
3188} 3356}
diff --git a/apps/playlist_menu.c b/apps/playlist_menu.c
index c70a510a6e..c390e8077d 100644
--- a/apps/playlist_menu.c
+++ b/apps/playlist_menu.c
@@ -28,22 +28,11 @@
28#include "playlist_viewer.h" 28#include "playlist_viewer.h"
29#include "talk.h" 29#include "talk.h"
30#include "lang.h" 30#include "lang.h"
31#include "playlist_menu.h"
31 32
32/* FIXME: there is a very similar function in onplay.c */
33static bool save_playlist(void) 33static bool save_playlist(void)
34{ 34{
35 char filename[MAX_PATH+1]; 35 save_playlist_screen(NULL);
36
37 strncpy(filename, DEFAULT_DYNAMIC_PLAYLIST_NAME, sizeof(filename));
38
39 if (!kbd_input(filename, sizeof(filename)))
40 {
41 playlist_save(NULL, filename);
42
43 /* reload in case playlist was saved to cwd */
44 reload_directory();
45 }
46
47 return false; 36 return false;
48} 37}
49 38
@@ -85,3 +74,26 @@ bool playlist_menu(void)
85 menu_exit(m); 74 menu_exit(m);
86 return result; 75 return result;
87} 76}
77
78int save_playlist_screen(struct playlist_info* playlist)
79{
80 char* filename;
81 char temp[MAX_PATH+1];
82 int len;
83
84 filename = playlist_get_name(playlist, temp, sizeof(temp));
85
86 if (!filename || (len=strlen(filename)) <= 4 ||
87 strcasecmp(&filename[len-4], ".m3u"))
88 filename = DEFAULT_DYNAMIC_PLAYLIST_NAME;
89
90 if (!kbd_input(filename, sizeof(filename)))
91 {
92 playlist_save(playlist, filename);
93
94 /* reload in case playlist was saved to cwd */
95 reload_directory();
96 }
97
98 return 0;
99}
diff --git a/apps/playlist_menu.h b/apps/playlist_menu.h
index e10fc81299..db841c371d 100644
--- a/apps/playlist_menu.h
+++ b/apps/playlist_menu.h
@@ -19,6 +19,9 @@
19#ifndef _PLAYLIST_MENU_H 19#ifndef _PLAYLIST_MENU_H
20#define _PLAYLIST_MENU_H 20#define _PLAYLIST_MENU_H
21 21
22#include "playlist.h"
23
22bool playlist_menu(void); 24bool playlist_menu(void);
25int save_playlist_screen(struct playlist_info* playlist);
23 26
24#endif 27#endif
diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c
index 6dc168d49a..ddc238cb27 100644
--- a/apps/playlist_viewer.c
+++ b/apps/playlist_viewer.c
@@ -46,6 +46,7 @@
46#include "list.h" 46#include "list.h"
47#include "statusbar.h" 47#include "statusbar.h"
48#include "splash.h" 48#include "splash.h"
49#include "playlist_menu.h"
49 50
50/* Maximum number of tracks we can have loaded at one time */ 51/* Maximum number of tracks we can have loaded at one time */
51#define MAX_PLAYLIST_ENTRIES 200 52#define MAX_PLAYLIST_ENTRIES 200
@@ -543,17 +544,7 @@ static bool track_display(void)
543/* Save playlist to disk */ 544/* Save playlist to disk */
544static bool save_playlist(void) 545static bool save_playlist(void)
545{ 546{
546 char filename[MAX_PATH+1]; 547 save_playlist_screen(viewer.playlist);
547
548 strncpy(filename, DEFAULT_VIEWER_PLAYLIST_NAME, sizeof(filename));
549
550 if (!kbd_input(filename, sizeof(filename)))
551 {
552 playlist_save(viewer.playlist, filename);
553 /* reload in case playlist was saved to cwd */
554 reload_directory();
555 }
556
557 return false; 548 return false;
558} 549}
559 550