summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a16845a)
raw | patch | inline | side by side (parent: a16845a)
author | Romain Bignon <romain@peerfuse.org> | |
Tue, 10 Feb 2009 14:18:28 +0000 (15:18 +0100) | ||
committer | Max Kellermann <max@duempel.org> | |
Tue, 10 Feb 2009 14:20:48 +0000 (15:20 +0100) |
diff --git a/src/command.c b/src/command.c
index 2f3bafd85a4b53a87b6215d269dda59226ed076e..45584143630b33c8742803c2cd42ecc033e5e1c7 100644 (file)
--- a/src/command.c
+++ b/src/command.c
/* ncmpc (Ncurses MPD Client)
* (c) 2004-2009 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
N_("Page up") },
{ { PGDN, 0, 0 }, 0, CMD_LIST_NEXT_PAGE, "pgdn",
N_("Page down") },
+ { { 'v', 0, 0 }, 0, CMD_LIST_VISUAL_SELECT, "visual-select",
+ N_("Visual selection") },
/* basic screens */
diff --git a/src/command.h b/src/command.h
index 6a295331b4a1c90ef47758d2843952f2e9c98f02..f339910e3a9c5a67345b7701561727148afbc18b 100644 (file)
--- a/src/command.h
+++ b/src/command.h
/* ncmpc (Ncurses MPD Client)
* (c) 2004-2009 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
CMD_LIST_RFIND_NEXT,
CMD_LIST_MOVE_UP,
CMD_LIST_MOVE_DOWN,
+ CMD_LIST_VISUAL_SELECT,
CMD_MOUSE_EVENT,
CMD_SCREEN_UPDATE,
CMD_SCREEN_PREVIOUS,
diff --git a/src/list_window.c b/src/list_window.c
index f7da79ea147973f67db1b44acc86e791bd3076b3..688ae8bd70600ced1c53c0fac83e6144e7143b8d 100644 (file)
--- a/src/list_window.c
+++ b/src/list_window.c
/* ncmpc (Ncurses MPD Client)
* (c) 2004-2009 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
lw->w = w;
lw->cols = width;
lw->rows = height;
+ lw->visual_selection = false;
return lw;
}
list_window_reset(struct list_window *lw)
{
lw->selected = 0;
+ lw->selected_start = 0;
+ lw->selected_end = 0;
+ lw->visual_selection = false;
+ lw->visual_base = 0;
lw->xoffset = 0;
lw->start = 0;
}
lw->selected = 0;
else if (lw->selected >= length)
lw->selected = length - 1;
+
+ if(lw->visual_selection)
+ {
+ if(lw->visual_base > lw->selected_end)
+ lw->selected_end = lw->selected;
+ if(lw->visual_base < lw->selected_start)
+ lw->selected_start = lw->selected;
+ }
+ else
+ {
+ lw->selected_start = lw->selected;
+ lw->selected_end = lw->selected;
+ }
}
void
list_window_set_selected(struct list_window *lw, unsigned n)
{
lw->selected = n;
+ if(lw->visual_selection)
+ {
+ if(n >= lw->visual_base)
+ lw->selected_end = n;
+ if(n <= lw->visual_base)
+ lw->selected_start = n;
+ }
+ else
+ {
+ lw->selected_start = n;
+ lw->selected_end = n;
+ }
}
static void
list_window_next(struct list_window *lw, unsigned length)
{
if (lw->selected + 1 < length)
- lw->selected++;
+ list_window_set_selected(lw, lw->selected + 1);
else if (options.list_wrap)
- lw->selected = 0;
+ list_window_set_selected(lw, 0);
}
static void
list_window_previous(struct list_window *lw, unsigned length)
{
if (lw->selected > 0)
- lw->selected--;
+ list_window_set_selected(lw, lw->selected - 1);
else if (options.list_wrap)
- lw->selected = length - 1;
+ list_window_set_selected(lw, length-1);
}
static void
list_window_first(struct list_window *lw)
{
lw->xoffset = 0;
- lw->selected = 0;
+ list_window_set_selected(lw, 0);
}
static void
{
lw->xoffset = 0;
if (length > 0)
- lw->selected = length - 1;
+ list_window_set_selected(lw, length - 1);
else
- lw->selected = 0;
+ list_window_set_selected(lw, 0);
}
static void
if (lw->rows < 2)
return;
if (lw->selected + lw->rows < length)
- lw->selected += lw->rows - 1;
+ list_window_set_selected(lw, lw->selected + lw->rows - 1);
else
list_window_last(lw, length);
}
if (lw->rows < 2)
return;
if (lw->selected > lw->rows - 1)
- lw->selected -= lw->rows - 1;
+ list_window_set_selected(lw, lw->selected - lw->rows - 1);
else
list_window_first(lw);
}
wmove(lw->w, i, 0);
if (label) {
- bool selected = lw->start + i == lw->selected;
+ bool selected = (lw->start + i >= lw->selected_start && lw->start + i <= lw->selected_end);
unsigned len = utf8_width(label);
if (highlight)
while ((label = callback(i,&h,callback_data))) {
if (str && label && match_line(label, str)) {
lw->selected = i;
+ if(!lw->visual_selection || i > lw->selected_end)
+ lw->selected_end = i;
+ if(!lw->visual_selection || i < lw->selected_start)
+ lw->selected_start = i;
return true;
}
if (wrap && i == lw->selected)
while (i >= 0 && (label = callback(i,&h,callback_data))) {
if( str && label && match_line(label, str) ) {
lw->selected = i;
+ if(!lw->visual_selection || i > (int)lw->selected_end)
+ lw->selected_end = i;
+ if(!lw->visual_selection || i < (int)lw->selected_start)
+ lw->selected_start = i;
return true;
}
if (wrap && i == (int)lw->selected)
case CMD_LIST_PREVIOUS_PAGE:
list_window_previous_page(lw);
break;
+ case CMD_LIST_VISUAL_SELECT:
+ if(lw->visual_selection)
+ {
+ lw->visual_selection = false;
+ list_window_set_selected(lw, lw->selected);
+ }
+ else
+ {
+ lw->visual_base = lw->selected;
+ lw->visual_selection = true;
+ }
+ break;
default:
return false;
}
diff --git a/src/list_window.h b/src/list_window.h
index a103af2608c8c8cce2d8b2eaadd43f94551a97b8..e996039a739f4457356614aa634654888437a78a 100644 (file)
--- a/src/list_window.h
+++ b/src/list_window.h
/* ncmpc (Ncurses MPD Client)
* (c) 2004-2009 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
unsigned start;
unsigned selected;
+ unsigned selected_start; /* for visual selection, first selected item */
+ unsigned selected_end; /* for visual selection, last selected item */
+ unsigned visual_base; /* represents the base item. */
+ bool visual_selection; /* visual selection activated */
unsigned xoffset;
bool hide_cursor;
diff --git a/src/screen_artist.c b/src/screen_artist.c
index 3d03354bdd4d19715f1265a0938f54295aebebe6..3b14e6bd7a90b0db0b45154bed930e25909fba31 100644 (file)
--- a/src/screen_artist.c
+++ b/src/screen_artist.c
/* ncmpc (Ncurses MPD Client)
* (c) 2004-2009 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
case CMD_ADD:
switch(mode) {
case LIST_ARTISTS:
- selected = g_ptr_array_index(artist_list,
- browser.lw->selected);
- add_query(c, MPD_TABLE_ARTIST, selected);
- cmd = CMD_LIST_NEXT; /* continue and select next item... */
+ {
+ unsigned i;
+ for(i = browser.lw->selected_start; i <= browser.lw->selected_end; ++i)
+ {
+ selected = g_ptr_array_index(artist_list, i);
+ add_query(c, MPD_TABLE_ARTIST, selected);
+ cmd = CMD_LIST_NEXT; /* continue and select next item... */
+ }
break;
-
+ }
case LIST_ALBUMS:
- if (browser.lw->selected == album_list->len + 1)
- add_query(c, MPD_TABLE_ARTIST, artist);
- else if (browser.lw->selected > 0) {
- selected = g_ptr_array_index(album_list,
- browser.lw->selected - 1);
- add_query(c, MPD_TABLE_ALBUM, selected);
- cmd = CMD_LIST_NEXT; /* continue and select next item... */
+ {
+ unsigned i;
+ for(i = browser.lw->selected_start; i <= browser.lw->selected_end; ++i)
+ {
+ if(i == album_list->len + 1)
+ add_query(c, MPD_TABLE_ARTIST, artist);
+ else if (i > 0)
+ {
+ selected = g_ptr_array_index(album_list,
+ browser.lw->selected - 1);
+ add_query(c, MPD_TABLE_ALBUM, selected);
+ cmd = CMD_LIST_NEXT; /* continue and select next item... */
+ }
}
break;
+ }
case LIST_SONGS:
/* handled by browser_cmd() */
diff --git a/src/screen_file.c b/src/screen_file.c
index ba751581b9db170f132c9f125a4d616246135567..f9325c092631ac3ffec83ee4b167eb0525ed2d1d 100644 (file)
--- a/src/screen_file.c
+++ b/src/screen_file.c
/* ncmpc (Ncurses MPD Client)
* (c) 2004-2009 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
filelist_entry_t *entry;
char *defaultname = NULL;
int ret;
+ unsigned selected;
if (browser.lw->selected >= filelist_length(browser.filelist))
return -1;
- entry = filelist_get(browser.filelist, browser.lw->selected);
- if( entry && entry->entity ) {
- mpd_InfoEntity *entity = entry->entity;
- if( entity->type==MPD_INFO_ENTITY_TYPE_PLAYLISTFILE ) {
- mpd_PlaylistFile *plf = entity->info.playlistFile;
- defaultname = plf->path;
+ for(selected = browser.lw->selected_start; selected <= browser.lw->selected_end; ++selected)
+ {
+ entry = filelist_get(browser.filelist, selected);
+ if( entry && entry->entity ) {
+ mpd_InfoEntity *entity = entry->entity;
+ if( entity->type==MPD_INFO_ENTITY_TYPE_PLAYLISTFILE ) {
+ mpd_PlaylistFile *plf = entity->info.playlistFile;
+ defaultname = plf->path;
+ }
}
}
mpd_PlaylistFile *plf;
char *str, *buf;
int key;
+ unsigned selected;
+
+ for(selected = browser.lw->selected_start; selected <= browser.lw->selected_end; ++selected)
+ {
+ if (selected >= filelist_length(browser.filelist))
+ return -1;
+
+ entry = filelist_get(browser.filelist, selected);
+ if( entry==NULL || entry->entity==NULL )
+ continue;
+
+ entity = entry->entity;
+
+ if( entity->type!=MPD_INFO_ENTITY_TYPE_PLAYLISTFILE ) {
+ /* translators: the "delete" command is only possible
+ for playlists; the user attempted to delete a song
+ or a directory or something else */
+ screen_status_printf(_("Deleting this item is not possible"));
+ screen_bell();
+ continue;
+ }
- if (browser.lw->selected >= filelist_length(browser.filelist))
- return -1;
-
- entry = filelist_get(browser.filelist, browser.lw->selected);
- if( entry==NULL || entry->entity==NULL )
- return -1;
-
- entity = entry->entity;
+ plf = entity->info.playlistFile;
+ str = utf8_to_locale(g_basename(plf->path));
+ buf = g_strdup_printf(_("Delete playlist %s [%s/%s] ? "), str, YES, NO);
+ g_free(str);
+ key = tolower(screen_getch(screen.status_window.w, buf));
+ g_free(buf);
+ if( key != YES[0] ) {
+ /* translators: a dialog was aborted by the user */
+ screen_status_printf(_("Aborted"));
+ return 0;
+ }
- if( entity->type!=MPD_INFO_ENTITY_TYPE_PLAYLISTFILE ) {
- /* translators: the "delete" command is only possible
- for playlists; the user attempted to delete a song
- or a directory or something else */
- screen_status_printf(_("Deleting this item is not possible"));
- screen_bell();
- return -1;
- }
+ if( mpdclient_cmd_delete_playlist(c, plf->path) )
+ continue;
- plf = entity->info.playlistFile;
- str = utf8_to_locale(g_basename(plf->path));
- buf = g_strdup_printf(_("Delete playlist %s [%s/%s] ? "), str, YES, NO);
- g_free(str);
- key = tolower(screen_getch(screen.status_window.w, buf));
- g_free(buf);
- if( key != YES[0] ) {
- /* translators: a dialog was aborted by the user */
- screen_status_printf(_("Aborted"));
- return 0;
+ /* translators: MPD deleted the playlist, as requested by the
+ user */
+ screen_status_printf(_("Playlist deleted"));
}
-
- if( mpdclient_cmd_delete_playlist(c, plf->path) )
- return -1;
-
- /* translators: MPD deleted the playlist, as requested by the
- user */
- screen_status_printf(_("Playlist deleted"));
return 0;
}
diff --git a/src/screen_help.c b/src/screen_help.c
index 3e99ffa3a50a5a57d3dd52f16713430bdfbf1170..8a33de3ef23d3876511fa23a7878ac70a884fe09 100644 (file)
--- a/src/screen_help.c
+++ b/src/screen_help.c
/* ncmpc (Ncurses MPD Client)
* (c) 2004-2009 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
{ 0, CMD_LIST_NEXT_PAGE, NULL },
{ 0, CMD_LIST_FIRST, NULL },
{ 0, CMD_LIST_LAST, NULL },
+ { 0, CMD_LIST_VISUAL_SELECT, NULL },
{ 0, CMD_NONE, NULL },
{ 0, CMD_SCREEN_PREVIOUS,NULL },
{ 0, CMD_SCREEN_NEXT, NULL },
diff --git a/src/screen_play.c b/src/screen_play.c
index eae3ace8c50098fbc5f2ab1b7bb5ce3bb9df2853..665a986c3080dece6d2715046cd676bccfb10035 100644 (file)
--- a/src/screen_play.c
+++ b/src/screen_play.c
/* ncmpc (Ncurses MPD Client)
* (c) 2004-2009 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
case PLAYLIST_EVENT_DELETE:
break;
case PLAYLIST_EVENT_MOVE:
- lw->selected = *((int *) data);
- if (lw->selected < lw->start)
- lw->start--;
+ if(lw->visual_selection < 0)
+ {
+ lw->selected = *((int *) data);
+ if (lw->selected < lw->start)
+ lw->start--;
+ }
break;
default:
break;
/* make sure the cursor is in the window */
lw->selected = lw->start+offset;
+ lw->selected_start = lw->selected;
+ lw->selected_end = lw->selected;
list_window_check_selected(lw, length);
}
mpdclient_cmd_play(c, lw->selected);
return true;
case CMD_DELETE:
- mpdclient_cmd_delete(c, lw->selected);
+ {
+ int i = lw->selected_end, start = lw->selected_start;
+ for(; i >= start; --i)
+ mpdclient_cmd_delete(c, i);
+
+ i++;
+ if(i >= (int)playlist_length(&c->playlist))
+ i--;
+ lw->selected = i;
+ lw->selected_start = i;
+ lw->selected_end = i;
+ lw->visual_selection = false;
+
return true;
+ }
case CMD_SAVE_PLAYLIST:
playlist_save(c, NULL, NULL);
return true;
center_playing_item(c);
playlist_repaint();
return false;
-
case CMD_LIST_MOVE_UP:
- mpdclient_cmd_move(c, lw->selected, lw->selected-1);
+ if(lw->selected_start == 0)
+ return false;
+ if(lw->visual_selection)
+ {
+ unsigned i = lw->selected_start;
+ unsigned last_selected = lw->selected;
+ for(; i <= lw->selected_end; ++i)
+ mpdclient_cmd_move(c, i, i-1);
+ lw->selected_start--;
+ lw->selected_end--;
+ lw->selected = last_selected - 1;
+ lw->visual_base--;
+ }
+ else
+ mpdclient_cmd_move(c, lw->selected, lw->selected-1);
return true;
case CMD_LIST_MOVE_DOWN:
- mpdclient_cmd_move(c, lw->selected, lw->selected+1);
+ if(lw->selected_end+1 >= playlist_length(&c->playlist))
+ return false;
+ if(lw->visual_selection)
+ {
+ int i = lw->selected_end;
+ unsigned last_selected = lw->selected;
+ for(; i >= (int)lw->selected_start; --i)
+ mpdclient_cmd_move(c, i, i+1);
+ lw->selected_start++;
+ lw->selected_end++;
+ lw->selected = last_selected + 1;
+ lw->visual_base++;
+ }
+ else
+ mpdclient_cmd_move(c, lw->selected, lw->selected+1);
return true;
case CMD_LIST_FIND:
case CMD_LIST_RFIND: