Code

command: added CMD_LOCATE to locate song in database
[ncmpc.git] / src / screen_lyrics.c
index 3c0393488fde736866ae6a669f20a8fbab42f23d..30a89a163973ddaf8f29143bf2bd5c88fdea20f1 100644 (file)
@@ -18,7 +18,7 @@
  */
 
 #include <sys/stat.h>
-#include "ncmpc.h"
+#include "i18n.h"
 #include "options.h"
 #include "mpdclient.h"
 #include "command.h"
 #include "screen_utils.h"
 #include "strfsong.h"
 #include "lyrics.h"
+#include "charset.h"
 #include "gcc.h"
 
 #define _GNU_SOURCE
 #include <stdlib.h>
 #include <string.h>
 #include <glib.h>
-#include <ncurses.h>
 #include <unistd.h>
 #include <stdio.h>
 
 static list_window_t *lw = NULL;
 
+static const struct mpd_song *next_song;
+
 static struct {
-       const struct mpd_song *song;
+       struct mpd_song *song;
 
        char *artist, *title;
 
@@ -66,7 +68,10 @@ screen_lyrics_abort(void)
                current.artist = NULL;
        }
 
-       current.song = NULL;
+       if (current.song != NULL) {
+               mpd_freeSong(current.song);
+               current.song = NULL;
+       }
 }
 
 static void
@@ -81,7 +86,7 @@ screen_lyrics_clear(void)
 }
 
 static void
-lyrics_paint(mpdclient_t *c);
+lyrics_paint(void);
 
 /**
  * Repaint and update the screen.
@@ -89,7 +94,7 @@ lyrics_paint(mpdclient_t *c);
 static void
 lyrics_repaint(void)
 {
-       lyrics_paint(NULL);
+       lyrics_paint();
        wrefresh(lw->w);
 }
 
@@ -99,7 +104,7 @@ lyrics_repaint(void)
 static void
 lyrics_repaint_if_active(void)
 {
-       if (get_cur_mode_id() == 104) { /* XXX don't use the literal number */
+       if (screen_is_visible(&screen_lyrics)) {
                lyrics_repaint();
 
                /* XXX repaint the screen title */
@@ -164,7 +169,7 @@ screen_lyrics_callback(const GString *result, mpd_unused void *data)
 }
 
 static void
-screen_lyrics_load(struct mpd_song *song)
+screen_lyrics_load(const struct mpd_song *song)
 {
        char buffer[MAX_SONGNAME_LENGTH];
 
@@ -173,7 +178,7 @@ screen_lyrics_load(struct mpd_song *song)
        screen_lyrics_abort();
        screen_lyrics_clear();
 
-       current.song = song;
+       current.song = mpd_songDup(song);
 
        strfsong(buffer, sizeof(buffer), "%artist%", song);
        current.artist = g_strdup(buffer);
@@ -219,10 +224,17 @@ static int store_lyr_hd(void)
 static const char *
 list_callback(unsigned idx, mpd_unused int *highlight, mpd_unused void *data)
 {
+       static char buffer[256];
+       char *value;
+
        if (idx >= current.lines->len)
                return NULL;
 
-       return g_ptr_array_index(current.lines, idx);
+       value = utf8_to_locale(g_ptr_array_index(current.lines, idx));
+       g_strlcpy(buffer, value, sizeof(buffer));
+       free(value);
+
+       return buffer;
 }
 
 
@@ -254,35 +266,45 @@ lyrics_exit(void)
 }
 
 static void
-lyrics_open(mpd_unused screen_t *screen, mpdclient_t *c)
+lyrics_open(mpdclient_t *c)
 {
-       if (c->song != NULL && c->song != current.song)
-               screen_lyrics_load(c->song);
+       if (next_song == NULL)
+               next_song = c->song;
+
+       if (next_song != NULL &&
+           (current.song == NULL ||
+            strcmp(next_song->file, current.song->file) != 0))
+               screen_lyrics_load(next_song);
+
+       next_song = NULL;
 }
 
 
 static const char *
 lyrics_title(char *str, size_t size)
 {
-       if (current.loader != NULL)
-               return "Lyrics (loading)";
-       else if (current.artist != NULL && current.title != NULL &&
-                current.lines->len > 0) {
-               snprintf(str, size, "Lyrics: %s - %s",
+       if (current.loader != NULL) {
+               snprintf(str, size, "%s (%s)",
+                        _("Lyrics"), _("loading..."));
+               return str;
+       } else if (current.artist != NULL && current.title != NULL &&
+                  current.lines->len > 0) {
+               snprintf(str, size, "%s: %s - %s",
+                        _("Lyrics"),
                         current.artist, current.title);
                return str;
        } else
-               return "Lyrics";
+               return _("Lyrics");
 }
 
 static void
-lyrics_paint(mpd_unused mpdclient_t *c)
+lyrics_paint(void)
 {
        list_window_paint(lw, list_callback, NULL);
 }
 
 static int
-lyrics_cmd(screen_t *screen, mpdclient_t *c, command_t cmd)
+lyrics_cmd(mpdclient_t *c, command_t cmd)
 {
        if (list_window_scroll_cmd(lw, current.lines->len, cmd)) {
                lyrics_repaint();
@@ -307,13 +329,21 @@ lyrics_cmd(screen_t *screen, mpdclient_t *c, command_t cmd)
                        lyrics_repaint();
                }
                return 1;
+
+       case CMD_LOCATE:
+               if (current.song != NULL) {
+                       screen_file_goto_song(c, current.song);
+                       return true;
+               }
+
+               return false;
+
        default:
                break;
        }
 
        lw->selected = lw->start+lw->rows;
-       if (screen_find(screen,
-                       lw, current.lines->len,
+       if (screen_find(lw, current.lines->len,
                        cmd, list_callback, NULL)) {
                /* center the row */
                list_window_center(lw, current.lines->len, lw->selected);
@@ -334,3 +364,12 @@ const struct screen_functions screen_lyrics = {
        .cmd = lyrics_cmd,
        .get_title = lyrics_title,
 };
+
+void
+screen_lyrics_switch(struct mpdclient *c, const struct mpd_song *song)
+{
+       assert(song != NULL);
+
+       next_song = song;
+       screen_switch(&screen_lyrics, c);
+}