Commit a3bd6ef2 authored by Yoann Peronneau's avatar Yoann Peronneau

* added a search function for the playlist with ncurses interface (feature request #1786).

  It doesn't support regexp for now.
* fixed a bug when playlist was empty at start
parent 219bc812
...@@ -49,6 +49,9 @@ ...@@ -49,6 +49,9 @@
#define VCD_MRL "vcdx://" #define VCD_MRL "vcdx://"
#endif #endif
#define SEARCH_CHAIN_SIZE 20
#define OPEN_CHAIN_SIZE 50
/***************************************************************************** /*****************************************************************************
* Local prototypes. * Local prototypes.
*****************************************************************************/ *****************************************************************************/
...@@ -60,7 +63,8 @@ static void PlayPause ( intf_thread_t * ); ...@@ -60,7 +63,8 @@ static void PlayPause ( intf_thread_t * );
static void Eject ( intf_thread_t * ); static void Eject ( intf_thread_t * );
static int HandleKey ( intf_thread_t *, int ); static int HandleKey ( intf_thread_t *, int );
static void Redraw ( intf_thread_t *, time_t * ); static void Redraw ( intf_thread_t *, time_t * );
static void SearchPlaylist ( intf_thread_t *, char * );
static void ManageSlider ( intf_thread_t * ); static void ManageSlider ( intf_thread_t * );
/***************************************************************************** /*****************************************************************************
...@@ -82,7 +86,9 @@ enum ...@@ -82,7 +86,9 @@ enum
BOX_HELP, BOX_HELP,
BOX_INFO, BOX_INFO,
BOX_LOG, BOX_LOG,
BOX_PLAYLIST BOX_PLAYLIST,
BOX_SEARCH,
BOX_OPEN
}; };
struct intf_sys_t struct intf_sys_t
{ {
...@@ -106,6 +112,12 @@ struct intf_sys_t ...@@ -106,6 +112,12 @@ struct intf_sys_t
int b_box_cleared; int b_box_cleared;
msg_subscription_t* p_sub; /* message bank subscription */ msg_subscription_t* p_sub; /* message bank subscription */
char *psz_search_chain; /* for playlist searching */
char *psz_old_search; /* for searching next */
int i_before_search;
char *psz_open_chain;
}; };
static void DrawBox( WINDOW *win, int y, int x, int h, int w, char *title ); static void DrawBox( WINDOW *win, int y, int x, int h, int w, char *title );
...@@ -158,6 +170,14 @@ static int Open( vlc_object_t *p_this ) ...@@ -158,6 +170,14 @@ static int Open( vlc_object_t *p_this )
val.i_int = -1; val.i_int = -1;
var_Set( p_intf->p_vlc, "verbose", val ); var_Set( p_intf->p_vlc, "verbose", val );
/* Initialize search chain */
p_sys->psz_search_chain = (char *)malloc( SEARCH_CHAIN_SIZE + 1 );
p_sys->psz_old_search = NULL;
p_sys->i_before_search = 0;
/* Initialize open chain */
p_sys->psz_open_chain = (char *)malloc( OPEN_CHAIN_SIZE + 1 );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -169,6 +189,10 @@ static void Close( vlc_object_t *p_this ) ...@@ -169,6 +189,10 @@ static void Close( vlc_object_t *p_this )
intf_thread_t *p_intf = (intf_thread_t *)p_this; intf_thread_t *p_intf = (intf_thread_t *)p_this;
intf_sys_t *p_sys = p_intf->p_sys; intf_sys_t *p_sys = p_intf->p_sys;
if( p_sys->psz_search_chain ) free( p_sys->psz_search_chain );
if( p_sys->psz_old_search ) free( p_sys->psz_old_search );
if( p_sys->psz_open_chain ) free( p_sys->psz_open_chain );
if( p_sys->p_input ) if( p_sys->p_input )
{ {
vlc_object_release( p_sys->p_input ); vlc_object_release( p_sys->p_input );
...@@ -235,7 +259,7 @@ static void Run( intf_thread_t *p_intf ) ...@@ -235,7 +259,7 @@ static void Run( intf_thread_t *p_intf )
vlc_mutex_unlock( &p_sys->p_playlist->object_lock ); vlc_mutex_unlock( &p_sys->p_playlist->object_lock );
} }
if( p_sys->b_box_plidx_follow ) if( p_sys->b_box_plidx_follow && p_sys->p_playlist->i_index >= 0 )
{ {
p_sys->i_box_plidx = p_sys->p_playlist->i_index; p_sys->i_box_plidx = p_sys->p_playlist->i_index;
} }
...@@ -407,6 +431,95 @@ static int HandleKey( intf_thread_t *p_intf, int i_key ) ...@@ -407,6 +431,95 @@ static int HandleKey( intf_thread_t *p_intf, int i_key )
break; break;
} }
} }
else if( p_sys->i_box_type == BOX_SEARCH && p_sys->psz_search_chain )
{
int i_chain_len;
i_chain_len = strlen( p_sys->psz_search_chain );
switch( i_key )
{
case 0x0c: /* ^l */
clear();
return 1;
case KEY_ENTER:
case 0x0d:
if( i_chain_len > 0 )
{
p_sys->psz_old_search = strdup( p_sys->psz_search_chain );
}
else if( p_sys->psz_old_search )
{
SearchPlaylist( p_intf, p_sys->psz_old_search );
}
p_sys->i_box_type = BOX_PLAYLIST;
return 1;
case 0x1b: /* Esc. */
p_sys->i_box_plidx = p_sys->i_before_search;
p_sys->i_box_type = BOX_PLAYLIST;
return 1;
case KEY_BACKSPACE:
if( i_chain_len > 0 )
{
p_sys->psz_search_chain[ i_chain_len - 1 ] = '\0';
}
break;
default:
if( i_chain_len < SEARCH_CHAIN_SIZE )
{
p_sys->psz_search_chain[ i_chain_len++ ] = i_key;
p_sys->psz_search_chain[ i_chain_len ] = 0;
}
break;
}
if( p_sys->psz_old_search )
{
free( p_sys->psz_old_search );
p_sys->psz_old_search = NULL;
}
SearchPlaylist( p_intf, p_sys->psz_search_chain );
return 1;
}
else if( p_sys->i_box_type == BOX_OPEN && p_sys->psz_open_chain )
{
int i_chain_len;
i_chain_len = strlen( p_sys->psz_open_chain );
playlist_t *p_playlist = p_sys->p_playlist;
switch( i_key )
{
case 0x0c: /* ^l */
clear();
return 1;
case KEY_ENTER:
case 0x0d:
if( p_playlist )
{
playlist_Add( p_playlist, p_sys->psz_open_chain,
p_sys->psz_open_chain,
PLAYLIST_GO|PLAYLIST_APPEND, PLAYLIST_END );
p_sys->b_box_plidx_follow = VLC_TRUE;
}
p_sys->i_box_type = BOX_PLAYLIST;
return 1;
case 0x1b: /* Esc. */
p_sys->i_box_type = BOX_PLAYLIST;
return 1;
case KEY_BACKSPACE:
if( i_chain_len > 0 )
{
p_sys->psz_open_chain[ i_chain_len - 1 ] = '\0';
}
break;
default:
if( i_chain_len < OPEN_CHAIN_SIZE )
{
p_sys->psz_open_chain[ i_chain_len++ ] = i_key;
p_sys->psz_open_chain[ i_chain_len ] = 0;
}
break;
}
return 1;
}
/* Common keys */ /* Common keys */
switch( i_key ) switch( i_key )
...@@ -445,6 +558,30 @@ static int HandleKey( intf_thread_t *p_intf, int i_key ) ...@@ -445,6 +558,30 @@ static int HandleKey( intf_thread_t *p_intf, int i_key )
p_sys->i_box_type = BOX_HELP; p_sys->i_box_type = BOX_HELP;
p_sys->i_box_lines_total = 0; p_sys->i_box_lines_total = 0;
return 1; return 1;
case '/':
if( p_sys->i_box_type != BOX_SEARCH )
{
if( p_sys->psz_search_chain == NULL )
{
return 1;
}
p_sys->psz_search_chain[0] = '\0';
p_sys->b_box_plidx_follow = VLC_FALSE;
p_sys->i_before_search = p_sys->i_box_plidx;
p_sys->i_box_type = BOX_SEARCH;
}
return 1;
case 0x0f: /* '^o': open */
if( p_sys->i_box_type != BOX_OPEN )
{
if( p_sys->psz_open_chain == NULL )
{
return 1;
}
p_sys->psz_open_chain[0] = '\0';
p_sys->i_box_type = BOX_OPEN;
}
return 1;
/* Navigation */ /* Navigation */
case KEY_RIGHT: case KEY_RIGHT:
...@@ -581,6 +718,59 @@ static void ManageSlider ( intf_thread_t *p_intf ) ...@@ -581,6 +718,59 @@ static void ManageSlider ( intf_thread_t *p_intf )
} }
} }
static void SearchPlaylist( intf_thread_t *p_intf, char *psz_searchstring )
{
bool b_ok = false;
int i_current;
int i_first = 0 ;
int i_item = -1;
intf_sys_t *p_sys = p_intf->p_sys;
playlist_t *p_playlist = p_sys->p_playlist;
if( p_sys->i_before_search >= 0 )
i_first = p_sys->i_before_search;
if( ( ! psz_searchstring ) || strlen( psz_searchstring ) <= 0 )
{
p_sys->i_box_plidx = p_sys->i_before_search;
return;
}
for( i_current = i_first + 1; i_current < p_playlist->i_size;
i_current++ )
{
if( strcasestr( p_playlist->pp_items[i_current]->input.psz_name,
psz_searchstring ) != NULL
|| strcasestr( p_playlist->pp_items[i_current]->input.psz_uri,
psz_searchstring ) != NULL )
{
i_item = i_current;
b_ok = true;
break;
}
}
if( !b_ok )
{
for( i_current = 0; i_current < i_first; i_current++ )
{
if( strcasestr( p_playlist->pp_items[i_current]->input.psz_name,
psz_searchstring ) != NULL
|| strcasestr( p_playlist->pp_items[i_current]->input.psz_uri,
psz_searchstring ) != NULL )
{
i_item = i_current;
b_ok = true;
break;
}
}
}
if( i_item < 0 || i_item >= p_playlist->i_size ) return;
p_sys->i_box_plidx = i_item;
}
static void mvnprintw( int y, int x, int w, const char *p_fmt, ... ) static void mvnprintw( int y, int x, int w, const char *p_fmt, ... )
{ {
va_list vl_args; va_list vl_args;
...@@ -772,6 +962,8 @@ static void Redraw ( intf_thread_t *p_intf, time_t *t_last_refresh ) ...@@ -772,6 +962,8 @@ static void Redraw ( intf_thread_t *p_intf, time_t *t_last_refresh )
MainBoxWrite( p_intf, l++, 1, " r Randomize playlist" ); MainBoxWrite( p_intf, l++, 1, " r Randomize playlist" );
MainBoxWrite( p_intf, l++, 1, " o Order Playlist" ); MainBoxWrite( p_intf, l++, 1, " o Order Playlist" );
MainBoxWrite( p_intf, l++, 1, " O Reverse order Playlist" ); MainBoxWrite( p_intf, l++, 1, " O Reverse order Playlist" );
MainBoxWrite( p_intf, l++, 1, " / Look for an item" );
MainBoxWrite( p_intf, l++, 1, " Ctrl-o Add an entry" );
MainBoxWrite( p_intf, l++, 1, " <del> Delete an entry" ); MainBoxWrite( p_intf, l++, 1, " <del> Delete an entry" );
MainBoxWrite( p_intf, l++, 1, " <backspace> Delete an entry" ); MainBoxWrite( p_intf, l++, 1, " <backspace> Delete an entry" );
MainBoxWrite( p_intf, l++, 1, "" ); MainBoxWrite( p_intf, l++, 1, "" );
...@@ -786,7 +978,7 @@ static void Redraw ( intf_thread_t *p_intf, time_t *t_last_refresh ) ...@@ -786,7 +978,7 @@ static void Redraw ( intf_thread_t *p_intf, time_t *t_last_refresh )
MainBoxWrite( p_intf, l++, 1, "" ); MainBoxWrite( p_intf, l++, 1, "" );
MainBoxWrite( p_intf, l++, 1, "[Miscellaneous]" ); MainBoxWrite( p_intf, l++, 1, "[Miscellaneous]" );
MainBoxWrite( p_intf, l++, 1, " Ctrl-L Refresh the screen" ); MainBoxWrite( p_intf, l++, 1, " Ctrl-l Refresh the screen" );
p_sys->i_box_lines_total = l; p_sys->i_box_lines_total = l;
if( p_sys->i_box_start >= p_sys->i_box_lines_total ) if( p_sys->i_box_start >= p_sys->i_box_lines_total )
...@@ -885,7 +1077,9 @@ static void Redraw ( intf_thread_t *p_intf, time_t *t_last_refresh ) ...@@ -885,7 +1077,9 @@ static void Redraw ( intf_thread_t *p_intf, time_t *t_last_refresh )
vlc_mutex_unlock( p_intf->p_sys->p_sub->p_lock ); vlc_mutex_unlock( p_intf->p_sys->p_sub->p_lock );
y = y_end; y = y_end;
} }
else if( p_sys->i_box_type == BOX_PLAYLIST && p_sys->p_playlist ) else if( ( p_sys->i_box_type == BOX_PLAYLIST ||
p_sys->i_box_type == BOX_SEARCH ||
p_sys->i_box_type == BOX_OPEN ) && p_sys->p_playlist )
{ {
/* Playlist box */ /* Playlist box */
playlist_t *p_playlist = p_sys->p_playlist; playlist_t *p_playlist = p_sys->p_playlist;
...@@ -956,6 +1150,31 @@ static void Redraw ( intf_thread_t *p_intf, time_t *t_last_refresh ) ...@@ -956,6 +1150,31 @@ static void Redraw ( intf_thread_t *p_intf, time_t *t_last_refresh )
{ {
y++; y++;
} }
if( p_sys->i_box_type == BOX_SEARCH )
{
DrawEmptyLine( p_sys->w, 6, 1, COLS-2 );
if( p_sys->psz_search_chain )
{
if( strlen( p_sys->psz_search_chain ) == 0 &&
p_sys->psz_old_search != NULL )
{
/* Searching next entry */
mvnprintw( 6, 1, COLS-2, "Find: %s", p_sys->psz_old_search );
}
else
{
mvnprintw( 6, 1, COLS-2, "Find: %s", p_sys->psz_search_chain );
}
}
}
if( p_sys->i_box_type == BOX_OPEN )
{
DrawEmptyLine( p_sys->w, 6, 1, COLS-2 );
if( p_sys->psz_open_chain )
{
mvnprintw( 6, 1, COLS-2, "Open: %s", p_sys->psz_open_chain );
}
}
while( y < y_end ) while( y < y_end )
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment