diff options
Diffstat (limited to 'apps/playlist_catalog.c')
-rw-r--r-- | apps/playlist_catalog.c | 161 |
1 files changed, 85 insertions, 76 deletions
diff --git a/apps/playlist_catalog.c b/apps/playlist_catalog.c index 619293377c..b160d6c3f4 100644 --- a/apps/playlist_catalog.c +++ b/apps/playlist_catalog.c | |||
@@ -54,73 +54,73 @@ struct add_track_context { | |||
54 | int count; | 54 | int count; |
55 | }; | 55 | }; |
56 | 56 | ||
57 | enum catbrowse_status_flags{ | ||
58 | CATBROWSE_NOTHING = 0, | ||
59 | CATBROWSE_CATVIEW, | ||
60 | CATBROWSE_PLAYLIST | ||
61 | }; | ||
62 | |||
57 | /* keep track of most recently used playlist */ | 63 | /* keep track of most recently used playlist */ |
58 | static char most_recent_playlist[MAX_PATH]; | 64 | static char most_recent_playlist[MAX_PATH]; |
65 | /* we need playlist_dir_length for easy removal of playlist dir prefix */ | ||
66 | static size_t playlist_dir_length; | ||
67 | /* keep track of what browser(s) are current to prevent reentry */ | ||
68 | static int browser_status = CATBROWSE_NOTHING; | ||
59 | 69 | ||
60 | /* directory where our playlists our stored */ | 70 | static size_t get_directory(char* dirbuf, size_t dirbuf_sz) |
61 | static char playlist_dir[MAX_PATH]; | ||
62 | static int playlist_dir_length; | ||
63 | static bool playlist_dir_exists = false; | ||
64 | |||
65 | /* Retrieve playlist directory from config file and verify it exists */ | ||
66 | static bool initialized = false; | ||
67 | static int initialize_catalog(void) | ||
68 | { | 71 | { |
72 | char *pl_dir = PLAYLIST_CATALOG_DEFAULT_DIR; | ||
69 | 73 | ||
70 | if (!initialized) | 74 | /* directory config is of the format: "dir: /path/to/dir" */ |
75 | if (global_settings.playlist_catalog_dir[0] != '\0') | ||
71 | { | 76 | { |
72 | bool default_dir = true; | 77 | pl_dir = global_settings.playlist_catalog_dir; |
73 | 78 | } | |
74 | /* directory config is of the format: "dir: /path/to/dir" */ | ||
75 | if (global_settings.playlist_catalog_dir[0] && | ||
76 | strcmp(global_settings.playlist_catalog_dir, | ||
77 | PLAYLIST_CATALOG_DEFAULT_DIR)) | ||
78 | { | ||
79 | strcpy(playlist_dir, global_settings.playlist_catalog_dir); | ||
80 | default_dir = false; | ||
81 | } | ||
82 | |||
83 | /* fall back to default directory if no or invalid config */ | ||
84 | if (default_dir) | ||
85 | { | ||
86 | strcpy(playlist_dir, PLAYLIST_CATALOG_DEFAULT_DIR); | ||
87 | if (!dir_exists(playlist_dir)) | ||
88 | mkdir(playlist_dir); | ||
89 | } | ||
90 | 79 | ||
91 | playlist_dir_length = strlen(playlist_dir); | 80 | /* remove duplicate leading '/' */ |
81 | if (pl_dir[0] == '/' && pl_dir[1] == '/') | ||
82 | { | ||
83 | pl_dir++; | ||
84 | } | ||
92 | 85 | ||
93 | /* remove duplicate leading '/' */ | 86 | return strlcpy(dirbuf, pl_dir, dirbuf_sz); |
94 | if (playlist_dir[0] == '/' && playlist_dir[1] == '/') | 87 | } |
95 | { | ||
96 | memmove(&playlist_dir[0], &playlist_dir[1], playlist_dir_length); /* gets the \0 too */ | ||
97 | playlist_dir_length--; | ||
98 | } | ||
99 | 88 | ||
100 | if (dir_exists(playlist_dir)) | 89 | /* Retrieve playlist directory from config file and verify it exists |
101 | { | 90 | * attempts to create directory |
102 | playlist_dir_exists = true; | 91 | * catalog dir is returned in dirbuf */ |
103 | memset(most_recent_playlist, 0, sizeof(most_recent_playlist)); | 92 | static int initialize_catalog_buf(char* dirbuf, size_t dirbuf_sz) |
104 | initialized = true; | 93 | { |
105 | } | 94 | playlist_dir_length = get_directory(dirbuf, dirbuf_sz); |
95 | if (playlist_dir_length >= dirbuf_sz) | ||
96 | { | ||
97 | return -2; | ||
106 | } | 98 | } |
107 | 99 | ||
108 | if (!playlist_dir_exists) | 100 | if (!dir_exists(dirbuf)) |
109 | { | 101 | { |
110 | if (mkdir(playlist_dir) < 0) { | 102 | if (mkdir(dirbuf) < 0) { |
111 | splashf(HZ*2, ID2P(LANG_CATALOG_NO_DIRECTORY), playlist_dir); | 103 | splashf(HZ*2, ID2P(LANG_CATALOG_NO_DIRECTORY), dirbuf); |
112 | return -1; | 104 | return -1; |
113 | } | 105 | } |
114 | else { | 106 | else { |
115 | playlist_dir_exists = true; | ||
116 | memset(most_recent_playlist, 0, sizeof(most_recent_playlist)); | 107 | memset(most_recent_playlist, 0, sizeof(most_recent_playlist)); |
117 | initialized = true; | ||
118 | } | 108 | } |
119 | } | 109 | } |
120 | 110 | ||
121 | return 0; | 111 | return 0; |
122 | } | 112 | } |
123 | 113 | ||
114 | /* Retrieve playlist directory from config file and verify it exists | ||
115 | * attempts to create directory | ||
116 | * Don't inline as we want the stack to be freed ASAP */ | ||
117 | static NO_INLINE int initialize_catalog(void) | ||
118 | { | ||
119 | char playlist_dir[MAX_PATH]; | ||
120 | |||
121 | return initialize_catalog_buf(playlist_dir, sizeof(playlist_dir)); | ||
122 | } | ||
123 | |||
124 | void catalog_set_directory(const char* directory) | 124 | void catalog_set_directory(const char* directory) |
125 | { | 125 | { |
126 | if (directory == NULL) | 126 | if (directory == NULL) |
@@ -132,36 +132,44 @@ void catalog_set_directory(const char* directory) | |||
132 | strmemccpy(global_settings.playlist_catalog_dir, | 132 | strmemccpy(global_settings.playlist_catalog_dir, |
133 | directory, sizeof(global_settings.playlist_catalog_dir)); | 133 | directory, sizeof(global_settings.playlist_catalog_dir)); |
134 | } | 134 | } |
135 | initialized = false; | ||
136 | initialize_catalog(); | 135 | initialize_catalog(); |
137 | } | 136 | } |
138 | 137 | ||
139 | const char* catalog_get_directory(void) | 138 | void catalog_get_directory(char* dirbuf, size_t dirbuf_sz) |
140 | { | 139 | { |
141 | if (initialize_catalog() == -1) | 140 | if (initialize_catalog_buf(dirbuf, dirbuf_sz) < 0) |
142 | return ""; | 141 | { |
143 | return playlist_dir; | 142 | dirbuf[0] = '\0'; |
143 | return; | ||
144 | } | ||
144 | } | 145 | } |
145 | 146 | ||
146 | /* Display all playlists in catalog. Selected "playlist" is returned. | 147 | /* Display all playlists in catalog. Selected "playlist" is returned. |
147 | If "view" mode is set then we're not adding anything into playlist. */ | 148 | * If status is CATBROWSE_CATVIEW then we're not adding anything into playlist */ |
148 | static int display_playlists(char* playlist, bool view) | 149 | static int display_playlists(char* playlist, enum catbrowse_status_flags status) |
149 | { | 150 | { |
150 | static bool reopen_last_playlist = false; | 151 | static bool reopen_last_playlist = false; |
151 | static int most_recent_selection = 0; | 152 | static int most_recent_selection = 0; |
152 | struct browse_context browse; | 153 | struct browse_context browse; |
153 | char selected_playlist[MAX_PATH]; | ||
154 | int result = -1; | 154 | int result = -1; |
155 | char selected_playlist[MAX_PATH]; | ||
156 | selected_playlist[0] = '\0'; | ||
157 | |||
158 | browser_status |= status; | ||
159 | bool view = (status == CATBROWSE_CATVIEW); | ||
155 | 160 | ||
156 | browse_context_init(&browse, SHOW_M3U, | 161 | browse_context_init(&browse, SHOW_M3U, |
157 | BROWSE_SELECTONLY|(view? 0: BROWSE_NO_CONTEXT_MENU), | 162 | BROWSE_SELECTONLY|(view? 0: BROWSE_NO_CONTEXT_MENU), |
158 | str(LANG_CATALOG), NOICON, | 163 | str(LANG_CATALOG), NOICON, |
159 | playlist_dir, playlist_dir_length + 1 + most_recent_playlist); | 164 | selected_playlist, |
165 | playlist_dir_length + 1 + most_recent_playlist); | ||
160 | 166 | ||
161 | browse.buf = selected_playlist; | 167 | browse.buf = selected_playlist; |
162 | browse.bufsize = sizeof(selected_playlist); | 168 | browse.bufsize = sizeof(selected_playlist); |
163 | 169 | ||
164 | restart: | 170 | restart: |
171 | /* set / restore the root directory for the browser */ | ||
172 | catalog_get_directory(selected_playlist, sizeof(selected_playlist)); | ||
165 | browse.flags &= ~BROWSE_SELECTED; | 173 | browse.flags &= ~BROWSE_SELECTED; |
166 | 174 | ||
167 | if (view && reopen_last_playlist) | 175 | if (view && reopen_last_playlist) |
@@ -169,13 +177,18 @@ restart: | |||
169 | switch (playlist_viewer_ex(most_recent_playlist, &most_recent_selection)) | 177 | switch (playlist_viewer_ex(most_recent_playlist, &most_recent_selection)) |
170 | { | 178 | { |
171 | case PLAYLIST_VIEWER_OK: | 179 | case PLAYLIST_VIEWER_OK: |
180 | { | ||
172 | result = 0; | 181 | result = 0; |
173 | break; | 182 | break; |
183 | } | ||
174 | case PLAYLIST_VIEWER_CANCEL: | 184 | case PLAYLIST_VIEWER_CANCEL: |
185 | { | ||
175 | reopen_last_playlist = false; | 186 | reopen_last_playlist = false; |
176 | goto restart; | 187 | goto restart; |
188 | } | ||
177 | case PLAYLIST_VIEWER_USB: | 189 | case PLAYLIST_VIEWER_USB: |
178 | case PLAYLIST_VIEWER_MAINMENU: | 190 | case PLAYLIST_VIEWER_MAINMENU: |
191 | /* Fall through */ | ||
179 | default: | 192 | default: |
180 | break; | 193 | break; |
181 | } | 194 | } |
@@ -208,13 +221,18 @@ restart: | |||
208 | { | 221 | { |
209 | switch (playlist_viewer_ex(selected_playlist, &most_recent_selection)) { | 222 | switch (playlist_viewer_ex(selected_playlist, &most_recent_selection)) { |
210 | case PLAYLIST_VIEWER_OK: | 223 | case PLAYLIST_VIEWER_OK: |
224 | { | ||
211 | reopen_last_playlist = true; | 225 | reopen_last_playlist = true; |
212 | result = 0; | 226 | result = 0; |
213 | break; | 227 | break; |
228 | } | ||
214 | case PLAYLIST_VIEWER_CANCEL: | 229 | case PLAYLIST_VIEWER_CANCEL: |
230 | { | ||
215 | goto restart; | 231 | goto restart; |
232 | } | ||
216 | case PLAYLIST_VIEWER_USB: | 233 | case PLAYLIST_VIEWER_USB: |
217 | case PLAYLIST_VIEWER_MAINMENU: | 234 | case PLAYLIST_VIEWER_MAINMENU: |
235 | /* Fall through */ | ||
218 | default: | 236 | default: |
219 | reopen_last_playlist = true; | 237 | reopen_last_playlist = true; |
220 | break; | 238 | break; |
@@ -227,7 +245,7 @@ restart: | |||
227 | strmemccpy(playlist, selected_playlist, MAX_PATH); | 245 | strmemccpy(playlist, selected_playlist, MAX_PATH); |
228 | } | 246 | } |
229 | } | 247 | } |
230 | 248 | browser_status &= ~status; | |
231 | return result; | 249 | return result; |
232 | } | 250 | } |
233 | 251 | ||
@@ -356,32 +374,26 @@ exit: | |||
356 | close(fd); | 374 | close(fd); |
357 | return result; | 375 | return result; |
358 | } | 376 | } |
359 | static bool in_cat_viewer = false; | 377 | |
360 | bool catalog_view_playlists(void) | 378 | bool catalog_view_playlists(void) |
361 | { | 379 | { |
362 | bool retval = true; | 380 | if ((browser_status & CATBROWSE_CATVIEW) == CATBROWSE_CATVIEW) |
363 | if (in_cat_viewer) | ||
364 | return false; | 381 | return false; |
365 | 382 | ||
366 | if (initialize_catalog() == -1) | 383 | if (initialize_catalog() < 0) |
367 | return false; | 384 | return false; |
368 | 385 | ||
369 | in_cat_viewer = true; | 386 | return (display_playlists(NULL, CATBROWSE_CATVIEW) >= 0); |
370 | retval = (display_playlists(NULL, true) != -1); | ||
371 | in_cat_viewer = false; | ||
372 | return retval; | ||
373 | } | 387 | } |
374 | 388 | ||
375 | static bool in_add_to_playlist = false; | ||
376 | bool catalog_add_to_a_playlist(const char* sel, int sel_attr, | 389 | bool catalog_add_to_a_playlist(const char* sel, int sel_attr, |
377 | bool new_playlist, char *m3u8name) | 390 | bool new_playlist, char *m3u8name) |
378 | { | 391 | { |
379 | int result; | ||
380 | char playlist[MAX_PATH + 7]; /* room for /.m3u8\0*/ | 392 | char playlist[MAX_PATH + 7]; /* room for /.m3u8\0*/ |
381 | if (in_add_to_playlist) | 393 | if ((browser_status & CATBROWSE_PLAYLIST) == CATBROWSE_PLAYLIST) |
382 | return false; | 394 | return false; |
383 | 395 | ||
384 | if (initialize_catalog() == -1) | 396 | if (initialize_catalog_buf(playlist, sizeof(playlist)) < 0) |
385 | return false; | 397 | return false; |
386 | 398 | ||
387 | if (new_playlist) | 399 | if (new_playlist) |
@@ -391,7 +403,7 @@ bool catalog_add_to_a_playlist(const char* sel, int sel_attr, | |||
391 | { | 403 | { |
392 | const char *name; | 404 | const char *name; |
393 | /* If sel is empty, root, or playlist directory we use 'all' */ | 405 | /* If sel is empty, root, or playlist directory we use 'all' */ |
394 | if (!sel || !strcmp(sel, "/") || !strcmp(sel, playlist_dir)) | 406 | if (!sel || !strcmp(sel, "/") || !strcmp(sel, playlist)) |
395 | { | 407 | { |
396 | sel = "/"; | 408 | sel = "/"; |
397 | name = "/all"; | 409 | name = "/all"; |
@@ -399,9 +411,10 @@ bool catalog_add_to_a_playlist(const char* sel, int sel_attr, | |||
399 | else /*If sel is a folder, we prefill the text field with its name*/ | 411 | else /*If sel is a folder, we prefill the text field with its name*/ |
400 | name = strrchr(sel, '/'); | 412 | name = strrchr(sel, '/'); |
401 | 413 | ||
402 | snprintf(playlist, MAX_PATH + 1, "%s/%s", | 414 | if (name == NULL || ((sel_attr & ATTR_DIRECTORY) != ATTR_DIRECTORY)) |
403 | playlist_dir, | 415 | name = "/"; |
404 | (name!=NULL && (sel_attr & ATTR_DIRECTORY))?name+1:""); | 416 | |
417 | strlcat(playlist, name, sizeof(playlist)); | ||
405 | } | 418 | } |
406 | else | 419 | else |
407 | strmemccpy(playlist, m3u8name, MAX_PATH); | 420 | strmemccpy(playlist, m3u8name, MAX_PATH); |
@@ -417,11 +430,7 @@ bool catalog_add_to_a_playlist(const char* sel, int sel_attr, | |||
417 | } | 430 | } |
418 | else | 431 | else |
419 | { | 432 | { |
420 | in_add_to_playlist = true; | 433 | if (display_playlists(playlist, CATBROWSE_PLAYLIST) < 0) |
421 | result = display_playlists(playlist, false); | ||
422 | in_add_to_playlist = false; | ||
423 | |||
424 | if (result == -1) | ||
425 | return false; | 434 | return false; |
426 | } | 435 | } |
427 | 436 | ||