[mythtv] [PATCH] MythTV Previous Channel functionality

Dan M dan at milkcarton.com
Thu Apr 17 20:06:41 EDT 2003


Attached is a patch for MythTV to provide channel history.  To use it 
press the "H" key.  That will go to the previous channel.  If you press 
"H" twice, it will go to the channel you were on two channel changes 
ago.  etc etc.   Pressing "H" once will make it perform just like the 
'Previous Channel' functionality we're all used to on a standard TV.

Patch is made against CVS current

Isaac, this one should be good for commit.

-dan

Additional Credits:  Chris Palmer, Andy Davidoff, John Danner, and Isaac 
for help in the debugging process
-------------- next part --------------
Index: libs/libmythtv/tv_play.cpp
===================================================================
RCS file: /var/lib/cvs/MC/libs/libmythtv/tv_play.cpp,v
retrieving revision 1.44
diff -u -d -r1.44 tv_play.cpp
--- libs/libmythtv/tv_play.cpp	17 Apr 2003 15:16:38 -0000	1.44
+++ libs/libmythtv/tv_play.cpp	18 Apr 2003 02:53:33 -0000
@@ -7,6 +7,7 @@
 #include <qapplication.h>
 #include <qregexp.h>
 #include <qfile.h>
+#include <qtimer.h>

 #include <iostream>
 using namespace std;
@@ -122,6 +123,13 @@

     deinterlace_mode = DEINTERLACE_NONE;
     gContext->addListener(this);
+
+    //The channel name vector will hold 30 items
+    PrevChannelVector channame_vector( 30 );
+
+    //Create and connect our timer
+    prevChannelTimer = new QTimer(this);
+    connect( prevChannelTimer, SIGNAL(timeout()), SLOT(SetPreviousChannel()) );
 }

 void TV::Init(void)
@@ -998,6 +1006,8 @@

             case 'x': ChangeDeinterlacer(); break;

+            case 'H': case 'h': PreviousChannel(); break;
+
             default: break;
         }
     }
@@ -1380,10 +1390,17 @@
     while (!activenvp->GetPause())
         usleep(5);

+    //Save the current channel if this is the first time
+    if ( channame_vector.size() == 0 )
+        AddPreviousChannel();
+
     activerecorder->Pause();
     activerbuffer->Reset();
     activerecorder->ChangeChannel(direction);

+    //Save the new channel
+    AddPreviousChannel();
+
     activenvp->ResetPlaying();
     while (!activenvp->ResetYet())
         usleep(5);
@@ -1467,10 +1484,17 @@
     while (!activenvp->GetPause())
         usleep(5);

+    //Save the current channel if this is the first time
+    if ( channame_vector.size() == 0 )
+        AddPreviousChannel();
+
     activerecorder->Pause();
     activerbuffer->Reset();
     activerecorder->SetChannel(name);

+    //Save the new channel
+    AddPreviousChannel();
+
     activenvp->ResetPlaying();
     while (!activenvp->ResetYet())
         usleep(5);
@@ -1483,12 +1507,89 @@
     activenvp->Unpause();
 }

+void TV::AddPreviousChannel(void)
+{
+    //Don't store more than thirty channels.  Remove the first item
+    if ( channame_vector.size() > 29 )
+    {
+        PrevChannelVector::iterator it;
+        it = channame_vector.begin();
+        channame_vector.erase( it );
+    }
+
+    //Get the current channel and add it to the vector
+    QString dummy     = "";
+    QString chan_name = "";
+    activerecorder->GetChannelInfo( dummy, dummy, dummy, dummy,     dummy,
+                                    dummy, dummy, dummy, chan_name, dummy);
+
+    //This method builds the stack of previous channels
+    channame_vector.push_back(chan_name);
+}
+
+void TV::PreviousChannel(void)
+{
+    //Save the channel if this is the first time, and return so we don't
+    // change chan to the current chan
+    if ( channame_vector.size() == 0 )
+        return;
+
+    //Increment the times_pressed counter so we know how far to jump
+    times_pressed++;
+
+    //Figure out the vector the desired channel is in
+    int vector = (channame_vector.size() - times_pressed - 1) % channame_vector.size();
+
+    //Display channel name in the OSD for up to 1 second.
+    if (activenvp == nvp && osd)
+    {
+        osd->HideSet("program_info");
+        osd->SetChannumText(channame_vector[vector], 1);
+    }
+
+    //Reset the timer
+    prevChannelTimer->stop();
+    prevChannelTimer->start(750);
+}
+
+void TV::SetPreviousChannel()
+{
+    //Stop the timer
+    prevChannelTimer->stop();
+
+    //Figure out the vector the desired channel is in
+    int vector = (channame_vector.size() - times_pressed - 1) % channame_vector.size();
+
+    //Reset the times_pressed counter
+    times_pressed = 0;
+
+    //Only change channel if channame_vector[vector] != current channel
+    QString dummy     = "";
+    QString chan_name = "";
+    activerecorder->GetChannelInfo( dummy, dummy, dummy, dummy,     dummy,
+                                    dummy, dummy, dummy, chan_name, dummy);
+    if ( chan_name != channame_vector[vector].latin1() )
+    {
+        //Populate the array with the channel
+        for(uint i = 0; i < channame_vector[vector].length(); i++)
+        {
+            channelKeys[i] = (int ) *channame_vector[vector].mid(i, 1).latin1();
+        }
+
+        channelqueued = true;
+    }
+
+    //Turn off the OSD Channel Num so the channel changes right away
+    if (activenvp == nvp && osd)
+        osd->HideSet("channel_number");
+}
+
 void TV::UpdateOSD(void)
 {
     QString title, subtitle, desc, category, starttime, endtime;
     QString callsign, iconpath, channelname, chanid;

-    GetChannelInfo(activerecorder, title, subtitle, desc, category,
+    GetChannelInfo(activerecorder, title, subtitle, desc, category,
                    starttime, endtime, callsign, iconpath, channelname, chanid);

     osd->SetInfoText(title, subtitle, desc, category, starttime, endtime,
Index: libs/libmythtv/tv_play.h
===================================================================
RCS file: /var/lib/cvs/MC/libs/libmythtv/tv_play.h,v
retrieving revision 1.25
diff -u -d -r1.25 tv_play.h
--- libs/libmythtv/tv_play.h	8 Apr 2003 00:59:13 -0000	1.25
+++ libs/libmythtv/tv_play.h	18 Apr 2003 02:53:33 -0000
@@ -3,7 +3,9 @@

 #include <qstring.h>
 #include <pthread.h>
+#include <qvaluevector.h>

+#include "tv.h"
 #include <qobject.h>

 class QSqlDatabase;
@@ -17,7 +19,8 @@

 class TV : public QObject
 {
- public:
+Q_OBJECT
+public:
     TV(QSqlDatabase *db);
    ~TV(void);

@@ -56,6 +59,9 @@
     void ProcessKeypress(int keypressed);
     void customEvent(QCustomEvent *e);

+    void AddPreviousChannel(void);
+    void PreviousChannel(void);
+
  protected:
     void doLoadMenu(void);
     static void *MenuHandler(void *param);
@@ -175,6 +181,15 @@

     unsigned int embedid;
     int embx, emby, embw, embh;
+
+    typedef QValueVector<QString> PrevChannelVector;
+    PrevChannelVector channame_vector;
+    unsigned int times_pressed;
+    QTimer *prevChannelTimer;
+    QString last_channel;
+
+protected slots:
+    void SetPreviousChannel();
 };

 #endif


More information about the mythtv-dev mailing list