summaryrefslogtreecommitdiff
path: root/apps/playlist_viewer.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/playlist_viewer.c')
-rw-r--r--apps/playlist_viewer.c122
1 files changed, 87 insertions, 35 deletions
diff --git a/apps/playlist_viewer.c b/apps/playlist_viewer.c
index 579eba5a61..d06a3f3df6 100644
--- a/apps/playlist_viewer.c
+++ b/apps/playlist_viewer.c
@@ -51,6 +51,10 @@
51#include "menus/exported_menus.h" 51#include "menus/exported_menus.h"
52#include "yesno.h" 52#include "yesno.h"
53 53
54#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
55#include "tagcache.h"
56#endif
57
54/* Maximum number of tracks we can have loaded at one time */ 58/* Maximum number of tracks we can have loaded at one time */
55#define MAX_PLAYLIST_ENTRIES 200 59#define MAX_PLAYLIST_ENTRIES 200
56 60
@@ -60,11 +64,11 @@
60 64
61/* Information about a specific track */ 65/* Information about a specific track */
62struct playlist_entry { 66struct playlist_entry {
63 char *name; /* Formatted track name */ 67 char *name; /* track path */
68 char *title; /* Formatted track name */
64 int index; /* Playlist index */ 69 int index; /* Playlist index */
65 int display_index; /* Display index */ 70 int display_index; /* Display index */
66 bool queued; /* Is track queued? */ 71 int attr; /* Is track queued?; Is track marked as bad?*/
67 bool skipped; /* Is track marked as bad? */
68}; 72};
69 73
70enum direction 74enum direction
@@ -86,6 +90,8 @@ enum pv_onplay_result {
86 90
87struct playlist_buffer 91struct playlist_buffer
88{ 92{
93 struct playlist_entry tracks[MAX_PLAYLIST_ENTRIES];
94
89 char *name_buffer; /* Buffer used to store track names */ 95 char *name_buffer; /* Buffer used to store track names */
90 int buffer_size; /* Size of name buffer */ 96 int buffer_size; /* Size of name buffer */
91 97
@@ -97,7 +103,6 @@ struct playlist_buffer
97 the buffer has a real index < to the 103 the buffer has a real index < to the
98 real index of the the first track)*/ 104 real index of the the first track)*/
99 105
100 struct playlist_entry tracks[MAX_PLAYLIST_ENTRIES];
101 int num_loaded; /* Number of track entries loaded in buffer */ 106 int num_loaded; /* Number of track entries loaded in buffer */
102}; 107};
103 108
@@ -136,7 +141,6 @@ static bool playlist_viewer_init(struct playlist_viewer * viewer,
136 const char* filename, bool reload, 141 const char* filename, bool reload,
137 int *most_recent_selection); 142 int *most_recent_selection);
138 143
139static void format_name(char* dest, const char* src);
140static void format_line(const struct playlist_entry* track, char* str, 144static void format_line(const struct playlist_entry* track, char* str,
141 int len); 145 int len);
142 146
@@ -221,6 +225,40 @@ static void playlist_buffer_load_entries_screen(struct playlist_buffer * pb,
221 } 225 }
222} 226}
223 227
228static bool retrieve_track_metadata(struct mp3entry *id3, const char *filename, int flags)
229{
230 bool success = true;
231#if defined(HAVE_TC_RAMCACHE) && defined(HAVE_DIRCACHE)
232 /* try to get the id3 data from the database */
233 /* the database, doesn't store frequency, file size or codec (g4470) ChrisS*/
234 if ((flags & METADATA_EXCLUDE_ID3_PATH) || !tagcache_fill_tags(id3, filename))
235#endif
236 /* fall back to reading the file from disk */
237 {
238 success = get_metadata_ex(id3, -1, filename, flags);
239 }
240 return success;
241}
242
243static int load_track_title(char* buffer, size_t bufsz, char *filename)
244{
245 struct mp3entry id3;
246 if (retrieve_track_metadata(&id3, filename, METADATA_EXCLUDE_ID3_PATH)
247 && id3.title && id3.title[0] != '\0')
248 {
249 const char *artist = id3.artist;
250 if (!artist)
251 artist = id3.albumartist;
252 if(!artist)
253 artist = str(LANG_TAGNAVI_UNTAGGED);
254
255 size_t len = snprintf(buffer, bufsz, "%s - %s", artist, id3.title) + 1;
256 if (len < bufsz)
257 return len;
258 }
259 return 0; /*Failure*/
260}
261
224static int playlist_entry_load(struct playlist_entry *entry, int index, 262static int playlist_entry_load(struct playlist_entry *entry, int index,
225 char* name_buffer, int remaining_size) 263 char* name_buffer, int remaining_size)
226{ 264{
@@ -234,17 +272,29 @@ static int playlist_entry_load(struct playlist_entry *entry, int index,
234 if (playlist_get_track_info(viewer.playlist, index, &info) < 0) 272 if (playlist_get_track_info(viewer.playlist, index, &info) < 0)
235 return -1; 273 return -1;
236 274
237 len = strlen(info.filename) + 1; 275 len = strlcpy(name_buffer, info.filename, remaining_size) + 1;
238 276
239 if (len <= remaining_size) 277 if (len <= remaining_size)
240 { 278 {
241 strcpy(name_buffer, info.filename);
242
243 entry->name = name_buffer; 279 entry->name = name_buffer;
280 entry->title = name_buffer;
244 entry->index = info.index; 281 entry->index = info.index;
245 entry->display_index = info.display_index; 282 entry->display_index = info.display_index;
246 entry->queued = info.attr & PLAYLIST_ATTR_QUEUED; 283 entry->attr = info.attr & (PLAYLIST_ATTR_SKIPPED | PLAYLIST_ATTR_QUEUED);
247 entry->skipped = info.attr & PLAYLIST_ATTR_SKIPPED; 284
285 if (global_settings.playlist_viewer_track_display == 2) /* title */
286 {
287 /* advance buffer position past filename, adjust length remaining */
288 name_buffer += len;
289 remaining_size -= len;
290 int tlen = load_track_title(name_buffer, remaining_size, info.filename);
291 if (tlen > 0)
292 {
293 entry->title = name_buffer;
294 len += tlen;
295 }
296 }
297
248 return len; 298 return len;
249 } 299 }
250 return -1; 300 return -1;
@@ -433,7 +483,7 @@ static bool playlist_viewer_init(struct playlist_viewer * viewer,
433} 483}
434 484
435/* Format trackname for display purposes */ 485/* Format trackname for display purposes */
436static void format_name(char* dest, const char* src) 486static void format_name(char* dest, const char* src, size_t bufsz)
437{ 487{
438 switch (global_settings.playlist_viewer_track_display) 488 switch (global_settings.playlist_viewer_track_display)
439 { 489 {
@@ -442,17 +492,16 @@ static void format_name(char* dest, const char* src)
442 { 492 {
443 /* Only display the filename */ 493 /* Only display the filename */
444 char* p = strrchr(src, '/'); 494 char* p = strrchr(src, '/');
445 495 strlcpy(dest, p+1, bufsz);
446 strcpy(dest, p+1);
447
448 /* Remove the extension */ 496 /* Remove the extension */
449 strrsplt(dest, '.'); 497 strrsplt(dest, '.');
450
451 break; 498 break;
452 } 499 }
500 case 2: /* Artist - Title */
501 /*fall-through*/
453 case 1: 502 case 1:
454 /* Full path */ 503 /* Full path */
455 strcpy(dest, src); 504 strlcpy(dest, src, bufsz);
456 break; 505 break;
457 } 506 }
458} 507}
@@ -463,10 +512,9 @@ static void format_line(const struct playlist_entry* track, char* str,
463{ 512{
464 char name[MAX_PATH]; 513 char name[MAX_PATH];
465 char *skipped = ""; 514 char *skipped = "";
515 format_name(name, track->title, sizeof(name));
466 516
467 format_name(name, track->name); 517 if (track->attr & PLAYLIST_ATTR_SKIPPED)
468
469 if (track->skipped)
470 skipped = "(ERR) "; 518 skipped = "(ERR) ";
471 519
472 if (global_settings.playlist_viewer_indices) 520 if (global_settings.playlist_viewer_indices)
@@ -524,13 +572,7 @@ static enum pv_onplay_result show_track_info(const struct playlist_entry *curren
524 } 572 }
525 else 573 else
526 { 574 {
527 int fd = open(current_track->name, O_RDONLY); 575 id3_retrieval_successful = retrieve_track_metadata(&id3, current_track->name, 0);
528 if (fd >= 0)
529 {
530 if (get_metadata(&id3, fd, current_track->name))
531 id3_retrieval_successful = true;
532 close(fd);
533 }
534 } 576 }
535 577
536 return id3_retrieval_successful && 578 return id3_retrieval_successful &&
@@ -755,7 +797,7 @@ static enum themable_icons playlist_callback_icons(int selected_item,
755 /* Track we are moving */ 797 /* Track we are moving */
756 return Icon_Moving; 798 return Icon_Moving;
757 } 799 }
758 else if (track->queued) 800 else if (track->attr & PLAYLIST_ATTR_QUEUED)
759 { 801 {
760 /* Queued track */ 802 /* Queued track */
761 return Icon_Queued; 803 return Icon_Queued;
@@ -776,17 +818,27 @@ static int playlist_callback_voice(int selected_item, void *data)
776 talk_id(LANG_NOW_PLAYING, true); 818 talk_id(LANG_NOW_PLAYING, true);
777 if (track->index == local_viewer->moving_track) 819 if (track->index == local_viewer->moving_track)
778 talk_id(VOICE_TRACK_TO_MOVE, true); 820 talk_id(VOICE_TRACK_TO_MOVE, true);
779 if (track->queued) 821 if (track->attr & PLAYLIST_ATTR_QUEUED)
780 talk_id(VOICE_QUEUED, true); 822 talk_id(VOICE_QUEUED, true);
781 } 823 }
782 if (track->skipped) 824 if (track->attr & PLAYLIST_ATTR_SKIPPED)
783 talk_id(VOICE_BAD_TRACK, true); 825 talk_id(VOICE_BAD_TRACK, true);
784 if (global_settings.playlist_viewer_indices) 826 if (global_settings.playlist_viewer_indices)
785 talk_number(track->display_index, true); 827 talk_number(track->display_index, true);
786 828
787 if(global_settings.playlist_viewer_track_display) 829 switch(global_settings.playlist_viewer_track_display)
788 talk_fullpath(track->name, true); 830 {
789 else talk_file_or_spell(NULL, track->name, NULL, true); 831 case 1: /*full path*/
832 talk_fullpath(track->name, true);
833 break;
834 case 2: /*title*/
835 talk_spell(track->title, true);
836 break;
837 default:
838 case 0: /*filename only*/
839 talk_file_or_spell(NULL, track->name, NULL, true);
840 break;
841 }
790 if (viewer.moving_track != -1) 842 if (viewer.moving_track != -1)
791 talk_ids(true,VOICE_PAUSE, VOICE_MOVING_TRACK); 843 talk_ids(true,VOICE_PAUSE, VOICE_MOVING_TRACK);
792 844
@@ -1132,11 +1184,11 @@ static void close_playlist_viewer(void)
1132static const char* playlist_search_callback_name(int selected_item, void * data, 1184static const char* playlist_search_callback_name(int selected_item, void * data,
1133 char *buffer, size_t buffer_len) 1185 char *buffer, size_t buffer_len)
1134{ 1186{
1135 (void)buffer_len; /* this should probably be used */
1136 int *found_indicies = (int*)data; 1187 int *found_indicies = (int*)data;
1137 static struct playlist_track_info track; 1188 static struct playlist_track_info track;
1138 playlist_get_track_info(viewer.playlist, found_indicies[selected_item], &track); 1189 playlist_get_track_info(viewer.playlist, found_indicies[selected_item], &track);
1139 format_name(buffer, track.filename); 1190
1191 format_name(buffer, track.filename, buffer_len);
1140 return buffer; 1192 return buffer;
1141} 1193}
1142 1194
@@ -1145,7 +1197,7 @@ static int say_search_item(int selected_item, void *data)
1145 int *found_indicies = (int*)data; 1197 int *found_indicies = (int*)data;
1146 static struct playlist_track_info track; 1198 static struct playlist_track_info track;
1147 playlist_get_track_info(viewer.playlist,found_indicies[selected_item],&track); 1199 playlist_get_track_info(viewer.playlist,found_indicies[selected_item],&track);
1148 if(global_settings.playlist_viewer_track_display) 1200 if(global_settings.playlist_viewer_track_display == 1)
1149 talk_fullpath(track.filename, false); 1201 talk_fullpath(track.filename, false);
1150 else talk_file_or_spell(NULL, track.filename, NULL, false); 1202 else talk_file_or_spell(NULL, track.filename, NULL, false);
1151 return 0; 1203 return 0;