X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Fscreen_lyrics.c;h=066fe6edc2ab69baaaf04031dae5f4f574f7596e;hb=9af9cd4bf95871909776499693ca3a3144ba3bb0;hp=a71b932b6544d46b7a5b7b16496aa771b19f9dcb;hpb=e52f36dd83cc444a3b371c8c58507bef07a82361;p=ncmpc.git diff --git a/src/screen_lyrics.c b/src/screen_lyrics.c index a71b932..066fe6e 100644 --- a/src/screen_lyrics.c +++ b/src/screen_lyrics.c @@ -1,25 +1,25 @@ /* ncmpc (Ncurses MPD Client) * (c) 2004-2010 The Music Player Daemon Project * Project homepage: http://musicpd.org - + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. - + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - + * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ + */ #include "screen_lyrics.h" #include "screen_interface.h" -#include "screen_message.h" +#include "screen_status.h" #include "screen_file.h" #include "screen_song.h" #include "i18n.h" @@ -28,9 +28,13 @@ #include "screen.h" #include "lyrics.h" #include "screen_text.h" +#include "screen_utils.h" +#include "ncu.h" #include +#include #include +#include #include #include #include @@ -41,6 +45,8 @@ static struct screen_text text; static struct mpd_song *next_song; static bool follow = false; +/** Set if the cursor position shall be kept during the next lyrics update. */ +static bool reloading = false; static struct { struct mpd_song *song; @@ -168,7 +174,19 @@ delete_lyr_hd(void) static void screen_lyrics_set(const GString *str) { - screen_text_set(&text, str); + if (reloading) { + unsigned saved_start = text.lw->start; + + screen_text_set(&text, str->str); + + /* restore the cursor and ensure that it's still valid */ + text.lw->start = saved_start; + list_window_fetch_cursor(text.lw); + } else { + screen_text_set(&text, str->str); + } + + reloading = false; /* paint new data */ @@ -246,6 +264,18 @@ screen_lyrics_load(const struct mpd_song *song) } } +static void +screen_lyrics_reload(void) +{ + if (current.loader == NULL && current.artist != NULL && + current.title != NULL) { + reloading = true; + current.loader = lyrics_load(current.artist, current.title, + screen_lyrics_callback, NULL); + screen_text_repaint(&text); + } +} + static void lyrics_screen_init(WINDOW *w, int cols, int rows) { @@ -278,9 +308,10 @@ lyrics_open(struct mpdclient *c) mpd_song_get_uri(current.song)) != 0)) screen_lyrics_load(next_song_c); - if (next_song != NULL) + if (next_song != NULL) { mpd_song_free(next_song); - next_song = NULL; + next_song = NULL; + } } static void @@ -312,9 +343,12 @@ lyrics_title(char *str, size_t size) n = snprintf(str, size, "%s: %s - %s", _("Lyrics"), current.artist, current.title); - if (options.lyrics_show_plugin && current.plugin_name != NULL) + + if (options.lyrics_show_plugin && current.plugin_name != NULL && + (unsigned int) n < size - 1) snprintf(str + n, size - n, " (%s)", current.plugin_name); + return str; } else return _("Lyrics"); @@ -326,6 +360,73 @@ lyrics_paint(void) screen_text_paint(&text); } +/* save current lyrics to a file and run editor on it */ +static void +lyrics_edit(void) +{ + char *editor = options.text_editor; + int status; + + if (editor == NULL) { + screen_status_message(_("Editor not configured")); + return; + } + + if (options.text_editor_ask) { + char *buf = g_strdup_printf( + _("Do you really want to start an editor and edit these lyrics [%s/%s]? "), + YES, NO); + bool really = screen_get_yesno(buf, false); + g_free(buf); + if (!really) { + screen_status_message(_("Aborted")); + return; + } + } + + if (store_lyr_hd() < 0) + return; + + ncu_deinit(); + + /* TODO: fork/exec/wait won't work on Windows, but building a command + string for system() is too tricky */ + pid_t pid = fork(); + if (pid == -1) { + screen_status_printf(("%s (%s)"), _("Can't start editor"), g_strerror(errno)); + ncu_init(); + return; + } else if (pid == 0) { + char path[1024]; + path_lyr_file(path, sizeof(path), current.artist, current.title); + execlp(editor, editor, path, NULL); + /* exec failed, do what system does */ + _exit(127); + } else { + int ret; + do { + ret = waitpid(pid, &status, 0); + } while (ret == -1 && errno == EINTR); + } + + ncu_init(); + + /* TODO: hardly portable */ + if (WIFEXITED(status)) { + if (WEXITSTATUS(status) == 0) + /* update to get the changes */ + screen_lyrics_reload(); + else if (WEXITSTATUS(status) == 127) + screen_status_message(_("Can't start editor")); + else + screen_status_printf(_("Editor exited unexpectedly (%d)"), + WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + screen_status_printf(_("Editor exited unexpectedly (signal %d)"), + WTERMSIG(status)); + } +} + static bool lyrics_cmd(struct mpdclient *c, command_t cmd) { @@ -364,13 +465,11 @@ lyrics_cmd(struct mpdclient *c, command_t cmd) screen_text_repaint(&text); } return true; + case CMD_EDIT: + lyrics_edit(); + return true; case CMD_SELECT: - if (current.loader == NULL && current.artist != NULL && - current.title != NULL) { - current.loader = lyrics_load(current.artist, current.title, - screen_lyrics_callback, NULL); - screen_text_repaint(&text); - } + screen_lyrics_reload(); return true; #ifdef ENABLE_SONG_SCREEN