Package: tvtime
Followup-For: Bug #278220

I write a patch for request, see this feature in action at:
http://www.youtube.com/watch?v=U7mKLXC9fF0.



-- System Information:
Debian Release: wheezy/sid
  APT prefers raring-updates
  APT policy: (500, 'raring-updates'), (500, 'raring-security'), (500, 'raring')
Architecture: amd64 (x86_64)

Kernel: Linux 3.8.0-0-generic (SMP w/2 CPU cores)
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages tvtime depends on:
ii  debconf [debconf-2.0]              1.5.49ubuntu1
ii  fonts-freefont-ttf [ttf-freefont]  20120503-1
ii  libc6                              2.16-0ubuntu8
ii  libfreetype6                       2.4.10-0ubuntu2
ii  libpng12-0                         1.2.49-1ubuntu2
ii  libstdc++6                         4.7.2-19ubuntu1
ii  libx11-6                           2:1.5.0-1
ii  libxext6                           2:1.3.1-2
ii  libxinerama1                       2:1.1.2-1
ii  libxml2                            2.9.0+dfsg1-4ubuntu1
ii  libxtst6                           2:1.2.1-1
ii  libxv1                             2:1.0.7-1
ii  libxxf86vm1                        1:1.1.2-1
ii  perl-modules                       5.14.2-16
ii  ucf                                3.0025+nmu3

Versions of packages tvtime recommends:
pn  xmltv-util  <none>

Versions of packages tvtime suggests:
pn  lirc-x      <none>
pn  oss-compat  <none>

-- debconf information excluded
## Description: Implemented a feature to show a channel menu that show list of stations for comfortable selection.
## Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=278220
## Author: Pojar George <geoubu...@gmail.com>
Index: tvtime-1.0.2/src/commands.c
===================================================================
--- tvtime-1.0.2.orig/src/commands.c	2013-01-19 06:55:05.511430604 +0000
+++ tvtime-1.0.2/src/commands.c	2013-01-19 06:55:05.503430604 +0000
@@ -41,6 +41,7 @@
 #include "tvtimeglyphs.h"
 
 #define NUM_FAVORITES 9
+#define NUM_STATIONS ((num_stations > 15) ? 15 : num_stations)
 #define MAX_USER_MENUS 64
 
 /* Maximum number of steps to increment sleeptimer. */
@@ -49,6 +50,7 @@
 enum menu_type
 {
     MENU_REDIRECT,
+    MENU_CHANNEL_SELECTION,
     MENU_FAVORITES,
     MENU_USER
 };
@@ -63,6 +65,7 @@
     { "root", MENU_REDIRECT, "root-tuner" },
     { "picture", MENU_REDIRECT, "picture-tuner" },
     { "input", MENU_REDIRECT, "input-ntsc" },
+    { "channel-selection", MENU_CHANNEL_SELECTION, 0 },
     { "favorites", MENU_FAVORITES, 0 },
 };
 
@@ -167,6 +170,8 @@
     int numfavorites;
     int favorites[ NUM_FAVORITES ];
 
+    int channel_selection;
+
     int menuactive;
     int curmenu;
     int curmenupos;
@@ -1134,6 +1139,8 @@
     cmd->numfavorites = 0;
     memset( cmd->favorites, 0, sizeof( cmd->favorites ) );
 
+    cmd->channel_selection = 0;
+
     cmd->menuactive = 0;
     cmd->curmenu = MENU_FAVORITES;
     cmd->curmenupos = 0;
@@ -1864,6 +1871,16 @@
             }
         }
         menu_off( cmd );
+    } else if( cmd->curmenu == MENU_CHANNEL_SELECTION ) {
+        int command = tvtime_osd_list_get_enter_command( cmd->osd, cmd->curmenupos + 1 );
+        const char *argument = tvtime_osd_list_get_enter_argument( cmd->osd, cmd->curmenupos + 1 );
+        const char *current = station_get_current_channel_name( cmd->stationmgr );
+        if( !strcmp( argument, current ) ) return;
+
+        /* I check for MENU_ENTER just to avoid a malicious infinite loop. */
+        if( command != TVTIME_MENU_ENTER ) {
+            commands_handle( cmd, command, argument );
+        }
     } else if( cmd->curmenu == MENU_USER ) {
         int command = menu_get_enter_command( cmd->curusermenu, cmd->curmenupos + 1 );
         const char *argument = menu_get_enter_argument( cmd->curusermenu, cmd->curmenupos + 1 );
@@ -1877,7 +1894,7 @@
 
 static void menu_back( commands_t *cmd )
 {
-    if( cmd->curmenu == MENU_FAVORITES ) {
+    if( ( cmd->curmenu == MENU_FAVORITES ) || ( cmd->curmenu == MENU_CHANNEL_SELECTION ) ) {
         commands_handle( cmd, TVTIME_SHOW_MENU, "stations" );
     } else if( cmd->curmenu == MENU_USER ) {
         int command = menu_get_back_command( cmd->curusermenu );
@@ -1890,6 +1907,40 @@
     }
 }
 
+static int show_channel_selection( commands_t *cmd, tvtime_osd_t* osd, int channel )
+{
+    const int num_stations = station_get_num_stations( cmd->stationmgr );
+    const int num = NUM_STATIONS;
+    int i;
+
+    tvtime_osd_list_set_lines( cmd->osd, num + 1 );
+    tvtime_osd_list_set_text( cmd->osd, 0, _("Channel Selection") );
+
+    for( i = 0; i < num; i++ ) {
+        const char *name = station_get_name( cmd->stationmgr, i + channel - 1 );
+        char string[ 128 ];
+
+        if ( channel > num_stations ) {
+            channel = 1;
+        } else if ( channel < 1 ) {
+            channel = num_stations;
+        }
+
+        snprintf(string, sizeof( string ), "[%s] %s",
+                  station_get_channel( cmd->stationmgr, i + channel - 1 ),
+                  station_get_name( cmd->stationmgr, i + channel - 1 ) );
+        tvtime_osd_list_set_text( cmd->osd, i + 1, string );
+        tvtime_osd_list_set_enter_command( cmd->osd, i + 1, TVTIME_SET_STATION, name );
+    }
+    cmd->curmenusize = num;
+
+    tvtime_osd_list_set_hilight( cmd->osd, cmd->curmenupos + 1 );
+    tvtime_osd_show_list( cmd->osd, 1, 0 );
+    tvtime_osd_list_hold( cmd->osd, 1 );
+
+    return channel;
+}
+
 static void display_current_menu( commands_t *cmd )
 {
     int i;
@@ -1897,10 +1948,11 @@
     if( cmd->curmenu == MENU_FAVORITES ) {
         char string[ 128 ];
         tvtime_osd_list_set_lines( cmd->osd, cmd->numfavorites + 3 );
-        tvtime_osd_list_set_text( cmd->osd, 0, _("Favorites") );
+        tvtime_osd_list_set_text( cmd->osd, 0, _("Favorite Selection") );
         for( i = 0; i < cmd->numfavorites; i++ ) {
             char text[ 32 ];
-            snprintf( text, sizeof (text), "%d", cmd->favorites[ i ] );
+            snprintf( text, sizeof (text), "[%d] %s", cmd->favorites[ i ],
+                  station_get_name( cmd->stationmgr, ( cmd->favorites[ i ] - 1 ) ) );
             tvtime_osd_list_set_text( cmd->osd, i + 1, text );
         }
         snprintf( string, sizeof( string ), TVTIME_ICON_PLUSBUTTON "  %s",
@@ -1951,6 +2003,8 @@
 
 static int set_menu( commands_t *cmd, const char *menuname )
 {
+    const int num_stations = station_get_num_stations( cmd->stationmgr );
+    const int num = NUM_STATIONS;
     int i;
 
     if( !menuname || !*menuname ) {
@@ -1966,7 +2020,15 @@
                 return set_menu( cmd, menu_table[ i ].dest );
             } else {
                 cmd->curmenu = menu_table[ i ].menutype;
-                cmd->curmenupos = 0;
+                if( cmd->curmenu == MENU_CHANNEL_SELECTION ) {
+                    if( station_get_current_pos( cmd->stationmgr ) < num ) {
+                        cmd->curmenupos = station_get_current_pos( cmd->stationmgr );
+                    } else {
+                        cmd->curmenupos = num - 1;
+                    }
+                } else {
+                    cmd->curmenupos = 0;
+                }
                 return 1;
             }
         }
@@ -2089,20 +2151,43 @@
     if( tvtime_cmd == TVTIME_NOCOMMAND ) return;
 
     if( cmd->menuactive && tvtime_is_menu_command( tvtime_cmd ) ) {
+        const int num_stations = station_get_num_stations( cmd->stationmgr );
+        const int num = NUM_STATIONS;
+        const char *first = station_get_name( cmd->stationmgr, 0 );
+        const char *last = station_get_name( cmd->stationmgr, num_stations - 1 );
+        const char *argument = tvtime_osd_list_get_enter_argument( cmd->osd, cmd->curmenupos + 1 );
         int x, y, line;
         switch( tvtime_cmd ) {
         case TVTIME_MENU_EXIT:
             menu_off( cmd );
             break;
         case TVTIME_MENU_UP:
-            cmd->curmenupos = (cmd->curmenupos + cmd->curmenusize - 1) % (cmd->curmenusize);
-            if( cmd->curusermenu ) menu_set_cursor( cmd->curusermenu, cmd->curmenupos );
-            display_current_menu( cmd );
+            if( ( cmd->curmenu == MENU_CHANNEL_SELECTION ) && ( cmd->curmenupos == 0 ) ) {
+                if( !strcmp( argument, first ) ) {
+                    cmd->curmenupos = num - 1;
+                    cmd->channel_selection = show_channel_selection( cmd, cmd->osd, num_stations - num + 1 );
+                } else {
+                    cmd->channel_selection = show_channel_selection( cmd, cmd->osd, cmd->channel_selection - 1 );
+                }
+            } else {
+                cmd->curmenupos = (cmd->curmenupos + cmd->curmenusize - 1) % (cmd->curmenusize);
+                if( cmd->curusermenu ) menu_set_cursor( cmd->curusermenu, cmd->curmenupos );
+                display_current_menu( cmd );
+            }
             break;
         case TVTIME_MENU_DOWN:
-            cmd->curmenupos = (cmd->curmenupos + 1) % (cmd->curmenusize);
-            if( cmd->curusermenu ) menu_set_cursor( cmd->curusermenu, cmd->curmenupos );
-            display_current_menu( cmd );
+            if( ( cmd->curmenu == MENU_CHANNEL_SELECTION ) && ( cmd->curmenupos == num - 1 ) ) {
+                if( !strcmp( argument, last ) ) {
+                    cmd->curmenupos = 0;
+                    cmd->channel_selection = show_channel_selection( cmd, cmd->osd, 1 );
+                } else {
+                    cmd->channel_selection = show_channel_selection( cmd, cmd->osd, cmd->channel_selection + 1 );
+                }
+            } else {
+                cmd->curmenupos = (cmd->curmenupos + 1) % (cmd->curmenusize);
+                if( cmd->curusermenu ) menu_set_cursor( cmd->curusermenu, cmd->curmenupos );
+                display_current_menu( cmd );
+            }
             break;
         case TVTIME_MENU_BACK: menu_back( cmd ); break;
         case TVTIME_MENU_ENTER: menu_enter( cmd ); break;
@@ -2144,6 +2229,22 @@
         }
         break;
 
+    case TVTIME_CHANNEL_SELECTION:
+        if( cmd->osd ) {
+            commands_clear_menu_positions( cmd );
+            if( set_menu( cmd, arg ) || set_menu( cmd, "channel-selection" ) ) {
+                const int num_stations = station_get_num_stations( cmd->stationmgr );
+                const int num = NUM_STATIONS;
+                if( station_get_current_pos( cmd->stationmgr ) < num ) {
+                    cmd->channel_selection = show_channel_selection( cmd, cmd->osd,
+                                                                     atoi( station_get_channel( cmd->stationmgr, 0 ) ) );
+                } else {
+                    cmd->channel_selection = show_channel_selection( cmd, cmd->osd,
+                                                                     station_get_current_pos( cmd->stationmgr ) - num + 2 );
+                }
+            }
+        }
+        break;
     case TVTIME_KEY_EVENT:
         key = input_string_to_special_key( arg );
         if( !key ) key = arg[ 0 ];
Index: tvtime-1.0.2/src/tvtimeconf.c
===================================================================
--- tvtime-1.0.2.orig/src/tvtimeconf.c	2013-01-19 06:55:05.511430604 +0000
+++ tvtime-1.0.2/src/tvtimeconf.c	2013-01-19 06:55:05.507430604 +0000
@@ -835,6 +835,7 @@
     ct->keymap[ ',' ] = TVTIME_MIXER_TOGGLE_MUTE;
     ct->keymap[ 'e' ] = TVTIME_TOGGLE_AUDIO_MODE;
     ct->keymap[ '/' ] = TVTIME_AUTO_ADJUST_WINDOW;
+    ct->keymap[ 'u' ] = TVTIME_CHANNEL_SELECTION;
     ct->keymap[ 'v' ] = TVTIME_TOGGLE_ALWAYSONTOP;
     ct->keymap[ '0' ] = TVTIME_CHANNEL_0;
     ct->keymap[ '1' ] = TVTIME_CHANNEL_1;
Index: tvtime-1.0.2/src/tvtimeosd.c
===================================================================
--- tvtime-1.0.2.orig/src/tvtimeosd.c	2013-01-19 06:55:05.511430604 +0000
+++ tvtime-1.0.2/src/tvtimeosd.c	2013-01-19 06:55:05.507430604 +0000
@@ -34,6 +34,8 @@
 #include "tvtimeosd.h"
 #include "pulldown.h"
 
+#define OSD_MAX 16
+
 typedef struct string_object_s
 {
     osd_string_t *string;
@@ -116,6 +118,9 @@
     char hold_message[ 255 ];
     char hold_message2[ 255 ];
 
+    char arguments[ OSD_MAX ][ 128 ];
+    int commands[ OSD_MAX ];
+
     int film_mode;
     int info_available;
     int pulldown_mode;
@@ -859,6 +864,24 @@
     osd_list_set_text( osd->list, line, text );
 }
 
+void tvtime_osd_list_set_enter_command( tvtime_osd_t *osd, int line, int command,
+                             const char *argument )
+{
+    osd->commands[ line ] = command;
+    snprintf( osd->arguments[ line ], sizeof( osd->arguments[ 0 ] ),
+              "%s", argument );
+}
+
+int tvtime_osd_list_get_enter_command( tvtime_osd_t *osd, int line )
+{
+    return osd->commands[ line ];
+}
+
+const char *tvtime_osd_list_get_enter_argument( tvtime_osd_t *osd, int line )
+{
+    return osd->arguments[ line ];
+}
+
 void tvtime_osd_list_set_lines( tvtime_osd_t *osd, int numlines )
 {
     osd_list_set_lines( osd->list, numlines );
Index: tvtime-1.0.2/src/tvtimeosd.h
===================================================================
--- tvtime-1.0.2.orig/src/tvtimeosd.h	2013-01-19 06:55:05.511430604 +0000
+++ tvtime-1.0.2/src/tvtimeosd.h	2013-01-19 06:55:05.507430604 +0000
@@ -92,6 +92,10 @@
 int tvtime_osd_list_get_line_pos( tvtime_osd_t *osd, int y );
 void tvtime_osd_list_set_hilight( tvtime_osd_t *osd, int pos );
 void tvtime_osd_list_set_text( tvtime_osd_t *osd, int line, const char *text );
+void tvtime_osd_list_set_enter_command( tvtime_osd_t *osd, int line, int command,
+                             const char *argument );
+int tvtime_osd_list_get_enter_command( tvtime_osd_t *osd, int line );
+const char *tvtime_osd_list_get_enter_argument( tvtime_osd_t *osd, int line );
 void tvtime_osd_list_set_lines( tvtime_osd_t *osd, int numlines );
 void tvtime_osd_list_get_bounding_box( tvtime_osd_t *osd, int *x, int *y,
                                        int *width, int *height );
Index: tvtime-1.0.2/src/utils.c
===================================================================
--- tvtime-1.0.2.orig/src/utils.c	2013-01-19 06:55:05.511430604 +0000
+++ tvtime-1.0.2/src/utils.c	2013-01-19 06:55:05.507430604 +0000
@@ -447,6 +447,7 @@
     { "CHANNEL_RENUMBER", TVTIME_CHANNEL_RENUMBER },
     { "CHANNEL_SAVE_TUNING", TVTIME_CHANNEL_SAVE_TUNING },
     { "CHANNEL_SCAN", TVTIME_CHANNEL_SCAN },
+    { "CHANNEL_SELECTION", TVTIME_CHANNEL_SELECTION },
     { "CHANNEL_SKIP", TVTIME_CHANNEL_SKIP },
     { "CHANNEL_UP", TVTIME_CHANNEL_INC },
 
Index: tvtime-1.0.2/src/station.c
===================================================================
--- tvtime-1.0.2.orig/src/station.c	2013-01-19 06:55:05.511430604 +0000
+++ tvtime-1.0.2/src/station.c	2013-01-19 06:55:05.507430604 +0000
@@ -754,6 +754,47 @@
     }
 }
 
+const station_info_t *station_get_station( station_mgr_t *mgr, int pos)
+{
+    const station_info_t *tmp = mgr->first;
+    int i;
+    for (i = 0; tmp && i < pos; i++)
+         tmp = tmp->next;
+    return tmp;
+}
+
+const char *station_get_xmltv_id( station_mgr_t *mgr, int pos )
+{
+    const station_info_t *station = station_get_station(mgr, pos);
+    if( (station) && (*station->xmltvid) ) {
+        return station->xmltvid;
+    } else {
+        return 0;
+    }
+}
+
+const char *station_get_channel( station_mgr_t *mgr, int pos )
+{
+    const station_info_t *station = station_get_station(mgr, pos);
+    if( (station) && (station->network_name) ) {
+           static char buf[10];
+           snprintf(buf, 10 ,"%d", station->pos);
+        return buf;
+    } else {
+        return 0;
+    }
+}
+
+const char *station_get_name( station_mgr_t *mgr, int pos )
+{
+    const station_info_t *station = station_get_station(mgr, pos);
+    if( (station) && (*station->name) ) {
+        return station->name;
+    } else {
+        return 0;
+    }
+}
+
 void station_set_current_xmltv_id( station_mgr_t *mgr, const char *xmltvid )
 {
     if( mgr->current ) {
Index: tvtime-1.0.2/src/station.h
===================================================================
--- tvtime-1.0.2.orig/src/station.h	2013-01-19 06:55:05.511430604 +0000
+++ tvtime-1.0.2/src/station.h	2013-01-19 06:55:05.507430604 +0000
@@ -160,6 +160,21 @@
 const char *station_get_current_xmltv_id( station_mgr_t *mgr );
 
 /**
+ * Returns the XMLTV identifier for the channel in pos.
+ */
+const char *station_get_xmltv_id( station_mgr_t *mgr, int pos );
+
+/**
+ * Returns the name of the channel in pos.
+ */
+const char *station_get_name( station_mgr_t *mgr, int pos );
+
+/**
+ * Returns the channel nr of the channel in pos.
+ */
+const char *station_get_channel( station_mgr_t *mgr, int pos );
+
+/**
  * Returns the norm set for this channel.
  */
 const char *station_get_current_norm( station_mgr_t *mgr );
Index: tvtime-1.0.2/src/utils.h
===================================================================
--- tvtime-1.0.2.orig/src/utils.h	2013-01-19 06:14:49.146845000 +0000
+++ tvtime-1.0.2/src/utils.h	2013-01-19 06:57:19.659426616 +0000
@@ -194,6 +194,7 @@
     TVTIME_CHANNEL_SCAN,
     TVTIME_CHANNEL_RENUMBER,
     TVTIME_CHANNEL_SAVE_TUNING,
+    TVTIME_CHANNEL_SELECTION,
     TVTIME_OVERSCAN_UP,
     TVTIME_OVERSCAN_DOWN,
     TVTIME_CHANNEL_1,

Reply via email to