Remove trailing whitespace throughout the source tree.
[herrie-working.git] / herrie / src / gui_playq.c
blobb4ccb4a42034bafb68a7e50353f26b14dd73e730
1 /*
2 * Copyright (c) 2006-2011 Ed Schouten <ed@80386.nl>
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
26 /**
27 * @file gui_playq.c
28 * @brief Playlist management for textual user interface.
31 #include "stdinc.h"
33 #include "audio_file.h"
34 #include "audio_output.h"
35 #include "gui.h"
36 #include "gui_internal.h"
37 #include "gui_vfslist.h"
38 #include "playq.h"
39 #include "vfs.h"
41 /**
42 * @brief Buffer containing a string representation of the playback time
43 * of the current song in the form of " [x:xx/y:yy]".
45 static GString *str_time;
46 /**
47 * @brief Pointer to string containing playback status.
49 static const char *str_status = NULL;
50 /**
51 * @brief Buffer containing a string representation of the artist and
52 * title of the current song.
54 static GString *str_song;
55 /**
56 * @brief Window object of the status bar at the top of the screen.
58 static WINDOW *win_statbar;
59 /**
60 * @brief Reference to the window used to display the playlist.
62 static struct gui_vfslist *win_playq;
64 /**
65 * @brief Fills the str_song with the artist and song value of the audio
66 * file.
68 static void
69 gui_playq_statbar_song(struct audio_file *fd)
71 char *artist, *title;
73 if (fd == NULL) {
74 g_string_assign(str_song, "");
75 } else {
76 /* Smash strings down to the correct charset */
77 g_assert(fd->title != NULL);
78 title = g_convert_with_fallback(fd->title,
79 -1, "", "UTF-8", "?", NULL, NULL, NULL);
80 if (title == NULL)
81 /* Conversion error - don't convert charset */
82 title = g_strdup(fd->title);
84 if (fd->artist == NULL) {
85 /* Only show the title */
86 g_string_assign(str_song, title);
87 } else {
88 /* Print artist and title */
89 artist = g_convert_with_fallback(fd->artist,
90 -1, "", "UTF-8", "?", NULL, NULL, NULL);
91 if (artist == NULL)
92 /* Conversion error */
93 artist = g_strdup(fd->artist);
94 g_string_printf(str_song, "%s - %s",
95 artist, title);
96 g_free(artist);
98 g_free(title);
103 * @brief Set str_status to the current playback status.
105 static void
106 gui_playq_statbar_status(struct audio_file *fd, int paused)
108 if (fd == NULL) {
109 str_status = _("Idle");
110 } else {
111 if (paused)
112 str_status = _("Paused");
113 else
114 str_status = _("Playing");
119 * @brief Append a formatted string representation of a timestamp to a
120 * string.
122 static void
123 gui_playq_statbar_time_calc(GString *str, unsigned int time)
125 if (time < 3600)
126 /* Only show minutes and seconds */
127 g_string_append_printf(str, "%u:%02u",
128 time / 60, time % 60);
129 else
130 /* Show hours as well */
131 g_string_append_printf(str, "%u:%02u:%02u",
132 time / 3600, (time / 60) % 60, time % 60);
136 * @brief Fills the str_time with the time value of the audio file.
137 * audio file. It also checks if the times are the same as
138 * before, useful to discard useless refreshes.
140 static void
141 gui_playq_statbar_time(struct audio_file *fd)
143 if (fd == NULL) {
144 g_string_assign(str_time, "");
145 } else {
146 g_string_assign(str_time, " [");
147 gui_playq_statbar_time_calc(str_time, fd->time_cur);
148 if (!fd->stream) {
149 g_string_append_c(str_time, '/');
150 gui_playq_statbar_time_calc(str_time, fd->time_len);
152 g_string_append_c(str_time, ']');
157 * @brief Set the name of the song and time showed in the status bar.
159 static void
160 gui_playq_song_set(struct audio_file *fd, int paused, int timeonly)
162 gui_lock();
163 if (!timeonly)
164 gui_playq_statbar_song(fd);
165 gui_playq_statbar_time(fd);
166 gui_playq_statbar_status(fd, paused);
167 gui_unlock();
171 * @brief Refresh the bar above the playlist to show the correct title
172 * and time of the current track and the percentage of the
173 * playlist.
175 static void
176 gui_playq_statbar_refresh(void)
178 const char *percent;
179 int plen;
181 gui_lock();
182 /* Blank it */
183 werase(win_statbar);
185 /* Put the content back */
186 mvwaddstr(win_statbar, 0, 1, str_status);
187 waddstr(win_statbar, " | ");
188 waddstr(win_statbar, str_song->str);
190 percent = gui_vfslist_getpercentage(win_playq);
191 plen = strlen(percent);
192 mvwaddstr(win_statbar, 0, COLS - str_time->len - plen, str_time->str);
193 waddstr(win_statbar, percent);
195 /* And draw it */
196 wnoutrefresh(win_statbar);
197 gui_unlock();
200 void
201 gui_playq_init(void)
203 win_statbar = newwin(1, 0, 0, 0);
204 clearok(win_statbar, TRUE);
205 if (gui_draw_colors)
206 wbkgdset(win_statbar, COLOR_PAIR(GUI_COLOR_BAR));
207 else
208 wbkgdset(win_statbar, A_REVERSE);
210 str_time = g_string_sized_new(24);
211 str_song = g_string_sized_new(128);
213 gui_playq_song_set(NULL, 0, 0);
215 win_playq = gui_vfslist_new(1);
216 gui_vfslist_setcallback(win_playq, gui_playq_statbar_refresh);
217 gui_vfslist_setlist(win_playq, &playq_list);
218 gui_vfslist_move(win_playq, 0, 1, COLS, GUI_SIZE_PLAYQ_HEIGHT);
221 void
222 gui_playq_destroy(void)
224 delwin(win_statbar);
225 gui_vfslist_destroy(win_playq);
227 g_string_free(str_time, TRUE);
228 g_string_free(str_song, TRUE);
231 void
232 gui_playq_song_update(struct audio_file *fd, int paused, int timeonly)
234 gui_playq_song_set(fd, paused, timeonly);
236 #ifdef BUILD_SETPROCTITLE
237 /* Print same message in ps(1) */
238 setproctitle("%s %s%s", str_status, str_song->str, str_time->str);
239 #endif /* BUILD_SETPROCTITLE */
241 gui_playq_statbar_refresh();
242 gui_draw_done();
245 void
246 gui_playq_resize(void)
248 gui_lock();
249 wresize(win_statbar, 1, COLS);
250 clearok(win_statbar, TRUE);
251 gui_unlock();
253 playq_lock();
254 gui_vfslist_move(win_playq, 0, 1, COLS, GUI_SIZE_PLAYQ_HEIGHT);
255 playq_unlock();
258 void
259 gui_playq_notify_pre_removal(unsigned int index)
261 gui_vfslist_notify_pre_removal(win_playq, index);
264 void
265 gui_playq_notify_post_insertion(unsigned int index)
267 gui_vfslist_notify_post_insertion(win_playq, index);
270 void
271 gui_playq_notify_post_randomization(void)
273 gui_vfslist_notify_post_randomization(win_playq);
276 void
277 gui_playq_notify_done(void)
279 gui_vfslist_notify_done(win_playq);
280 gui_draw_done();
283 void
284 gui_playq_cursor_up(void)
286 playq_lock();
287 gui_vfslist_cursor_up(win_playq);
288 playq_unlock();
291 void
292 gui_playq_cursor_down(void)
294 playq_lock();
295 gui_vfslist_cursor_down(win_playq, 0);
296 playq_unlock();
299 void
300 gui_playq_cursor_pageup(void)
302 playq_lock();
303 gui_vfslist_cursor_pageup(win_playq);
304 playq_unlock();
307 void
308 gui_playq_cursor_pagedown(void)
310 playq_lock();
311 gui_vfslist_cursor_pagedown(win_playq);
312 playq_unlock();
315 void
316 gui_playq_cursor_head(void)
318 playq_lock();
319 gui_vfslist_cursor_head(win_playq);
320 playq_unlock();
323 void
324 gui_playq_cursor_tail(void)
326 playq_lock();
327 gui_vfslist_cursor_tail(win_playq);
328 playq_unlock();
331 void
332 gui_playq_song_remove(void)
334 struct vfsref *vr;
336 playq_lock();
337 if (!gui_vfslist_warn_isempty(win_playq)) {
338 vr = gui_vfslist_getselected(win_playq);
339 playq_song_fast_remove(vr,
340 gui_vfslist_getselectedidx(win_playq));
342 playq_unlock();
345 void
346 gui_playq_song_remove_all(void)
348 /* Don't care about locking here */
349 if (gui_vfslist_warn_isempty(win_playq))
350 return;
352 if (gui_input_askyesno(_("Remove all songs from the playlist?")) == 0)
353 playq_song_remove_all();
356 void
357 gui_playq_song_randomize(void)
359 /* Don't care about locking here */
360 if (gui_vfslist_warn_isempty(win_playq))
361 return;
363 if (gui_input_askyesno(_("Randomize the playlist?")) == 0)
364 playq_song_randomize();
367 void
368 gui_playq_song_add_before(struct vfsref *vr)
370 struct vfsref *vr_selected;
372 playq_lock();
373 vr_selected = gui_vfslist_getselected(win_playq);
374 if (vr_selected == vfs_list_first(&playq_list)) {
375 playq_unlock();
376 /* List is empty or adding before the first node */
377 playq_song_add_head(vr);
378 } else {
379 playq_song_fast_add_before(vr, vr_selected,
380 gui_vfslist_getselectedidx(win_playq));
381 playq_unlock();
385 void
386 gui_playq_song_add_after(struct vfsref *vr)
388 struct vfsref *vr_selected;
390 playq_lock();
391 vr_selected = gui_vfslist_getselected(win_playq);
392 if (vr_selected == vfs_list_last(&playq_list)) {
393 playq_unlock();
394 /* List is empty or appending after the last node */
395 playq_song_add_tail(vr);
396 } else {
397 playq_song_fast_add_after(vr, vr_selected,
398 gui_vfslist_getselectedidx(win_playq));
399 playq_unlock();
403 void
404 gui_playq_song_move_up(void)
406 struct vfsref *vr_selected;
408 playq_lock();
409 if (!gui_vfslist_warn_isempty(win_playq)) {
410 vr_selected = gui_vfslist_getselected(win_playq);
411 if (vr_selected == vfs_list_first(&playq_list)) {
412 gui_msgbar_warn(_("The song is already at the "
413 "top of the playlist."));
414 } else {
415 playq_song_fast_move_up(vr_selected,
416 gui_vfslist_getselectedidx(win_playq));
419 playq_unlock();
422 void
423 gui_playq_song_move_down(void)
425 struct vfsref *vr_selected;
427 playq_lock();
428 if (!gui_vfslist_warn_isempty(win_playq)) {
429 vr_selected = gui_vfslist_getselected(win_playq);
430 if (vr_selected == vfs_list_last(&playq_list)) {
431 gui_msgbar_warn(_("The song is already at the "
432 "bottom of the playlist."));
433 } else {
434 playq_song_fast_move_down(vr_selected,
435 gui_vfslist_getselectedidx(win_playq));
438 playq_unlock();
441 void
442 gui_playq_song_move_head(void)
444 struct vfsref *vr_selected;
446 playq_lock();
447 if (!gui_vfslist_warn_isempty(win_playq)) {
448 vr_selected = gui_vfslist_getselected(win_playq);
449 if (vr_selected == vfs_list_first(&playq_list)) {
450 gui_msgbar_warn(_("The song is already at the "
451 "top of the playlist."));
452 } else {
453 playq_song_fast_move_head(vr_selected,
454 gui_vfslist_getselectedidx(win_playq));
457 playq_unlock();
460 void
461 gui_playq_song_move_tail(void)
463 struct vfsref *vr_selected;
465 playq_lock();
466 if (!gui_vfslist_warn_isempty(win_playq)) {
467 vr_selected = gui_vfslist_getselected(win_playq);
468 if (vr_selected == vfs_list_last(&playq_list)) {
469 gui_msgbar_warn(_("The song is already at the "
470 "bottom of the playlist."));
471 } else {
472 playq_song_fast_move_tail(vr_selected,
473 gui_vfslist_getselectedidx(win_playq));
476 playq_unlock();
479 void
480 gui_playq_song_select(void)
482 playq_lock();
483 if (!gui_vfslist_warn_isempty(win_playq))
484 playq_song_fast_select(gui_vfslist_getselected(win_playq));
485 playq_unlock();
489 gui_playq_searchnext(const struct vfsmatch *vm)
491 int ret;
493 playq_lock();
494 ret = gui_vfslist_searchnext(win_playq, vm);
495 playq_unlock();
497 return (ret);
500 void
501 gui_playq_setfocus(int focus)
503 playq_lock();
504 gui_vfslist_setfocus(win_playq, focus);
505 playq_unlock();
508 void
509 gui_playq_fullpath(void)
511 playq_lock();
512 gui_vfslist_fullpath(win_playq);
513 playq_unlock();
516 #ifdef BUILD_VOLUME
518 * @brief Show the result of the volume setting routines.
520 static void
521 gui_playq_volume_show(int nval)
523 char *str;
525 if (nval < 0) {
526 gui_msgbar_warn(_("Failed to adjust the volume."));
527 } else {
528 str = g_strdup_printf(_("Volume: %d%%"), nval);
529 gui_msgbar_warn(str);
530 g_free(str);
534 void
535 gui_playq_volume_up(void)
537 int nval;
539 nval = audio_output_volume_up();
540 gui_playq_volume_show(nval);
543 void
544 gui_playq_volume_down(void)
546 int nval;
548 nval = audio_output_volume_down();
549 gui_playq_volume_show(nval);
551 #endif /* BUILD_VOLUME */
553 void
554 gui_playq_gotofolder(void)
556 struct vfsref *vr;
558 playq_lock();
559 if (gui_vfslist_warn_isempty(win_playq)) {
560 playq_unlock();
561 } else {
562 vr = gui_vfslist_getselected(win_playq);
563 playq_unlock();
565 gui_browser_gotofile(vr);