Index: libs/libmythtv/tv_play.h
===================================================================
--- libs/libmythtv/tv_play.h	(revision 11605)
+++ libs/libmythtv/tv_play.h	(working copy)
@@ -38,7 +38,9 @@
 typedef QMap<QString,QString>    InfoMap;
 typedef QMap<QString,InfoMap>    DDValueMap;
 typedef QMap<QString,DDValueMap> DDKeyMap;
+typedef ProgramInfo * (*RUNPLAYBACKBOX)(void *);
 
+
 class VBIMode
 {
   public:
@@ -68,7 +70,8 @@
 enum scheduleEditTypes {
     kScheduleProgramGuide = 0,
     kScheduleProgramFinder,
-    kScheduledRecording
+    kScheduledRecording,
+    kPlaybackBox,
 };
 
 class MPUBLIC TV : public QObject
@@ -112,12 +115,14 @@
     // Recording commands
     int  PlayFromRecorder(int recordernum);
     int  Playback(ProgramInfo *rcinfo);
+
+    // Various commands
     void setLastProgram(ProgramInfo *rcinfo); 
     ProgramInfo *getLastProgram(void) { return lastProgram; }
     void setInPlayList(bool setting) { inPlaylist = setting; }
     void setUnderNetworkControl(bool setting) { underNetworkControl = setting; }
+    bool IsSameProgram(ProgramInfo *p);
 
-    // Various commands
     void ShowNoRecorderDialog(void);
     void FinishRecording(void);
     void AskAllowRecording(const QStringList&, int, bool);
@@ -173,7 +178,7 @@
     static void InitKeys(void);
     static bool StartTV(ProgramInfo *tvrec = NULL, bool startInGuide = false,
                         bool inPlaylist = false, bool initByNetworkCommand = false);
-        
+    static void SetEmbedPbbFunc(RUNPLAYBACKBOX lptr);
 
     void SetIgnoreKeys(bool ignore) { ignoreKeys = ignore; }
 
@@ -194,11 +199,14 @@
     static void *EPGMenuHandler(void *param);
     static void *FinderMenuHandler(void *param);
     static void *ScheduleMenuHandler(void *param);
+    static void *RecordedShowMenuHandler(void *param);
 
     void RunTV(void);
     static void *EventThread(void *param);
 
     bool eventFilter(QObject *o, QEvent *e);
+    static QStringList lastProgramStringList;
+    static RUNPLAYBACKBOX RunPlaybackBoxPtr;
 
   private:
     bool RequestNextRecorder(bool showDialogs);
@@ -297,7 +305,6 @@
     void SetAutoCommercialSkip(enum commSkipMode skipMode = CommSkipOff);
     void SetManualZoom(bool zoomON = false);
 
-    void DoDisplayJumpMenu(void);
     void SetJumpToProgram(QString progKey = "", int progIndex = 0);
  
     bool ClearOSD(void);
@@ -325,7 +332,6 @@
     void ToggleActiveWindow(void);
     void SwapPIP(void);
     void SwapPIPSoon(void) { needToSwapPIP = true; }
-    void DisplayJumpMenuSoon(void) { needToJumpMenu = true; }
 
     void ToggleAutoExpire(void);
 
@@ -426,7 +432,6 @@
 
     bool ignoreKeys;
     bool needToSwapPIP;
-    bool needToJumpMenu;
     QMap<QString,ProgramList> progLists;
 
     mutable QMutex chanEditMapLock; ///< Lock for chanEditMap and ddMap
Index: libs/libmythtv/tv_play.cpp
===================================================================
--- libs/libmythtv/tv_play.cpp	(revision 11605)
+++ libs/libmythtv/tv_play.cpp	(working copy)
@@ -61,9 +61,14 @@
  * \brief stores last program info. maintains info so long as
  * mythfrontend is active
  */
-static QStringList lastProgramStringList = QStringList();
+QStringList TV::lastProgramStringList = QStringList();
 
 /*
+ * \brief function pointer for RunPlaybackBox in playbackbox.cpp
+ */
+RUNPLAYBACKBOX TV::RunPlaybackBoxPtr = NULL;
+
+/*
  \brief returns true if the recording completed when exiting.
  */
 bool TV::StartTV (ProgramInfo *tvrec, bool startInGuide, 
@@ -130,7 +135,11 @@
             ProgramInfo *tmpProgram  = tv->getLastProgram();
             ProgramInfo *nextProgram = new ProgramInfo(*tmpProgram);
 
-            tv->setLastProgram(curProgram);
+            //Temp workaround until Pin support for password protected last show is implemented.
+            if (curProgram->recgroup == nextProgram->recgroup)
+                tv->setLastProgram(curProgram);
+            else
+                tv->setLastProgram(NULL);
 
             if (curProgram)
                 delete curProgram;
@@ -179,7 +188,12 @@
 
     return playCompleted;
 }
-        
+       
+void TV::SetEmbedPbbFunc(RUNPLAYBACKBOX lptr)
+{
+    RunPlaybackBoxPtr = lptr;
+}
+
 void TV::InitKeys(void)
 {
     REG_KEY("TV Frontend", "PAGEUP", "Page Up", "3");
@@ -415,7 +429,7 @@
       queuedTranscode(false), getRecorderPlaybackInfo(false),
       adjustingPicture(kAdjustingPicture_None),
       adjustingPictureAttribute(kPictureAttribute_None),
-      ignoreKeys(false), needToSwapPIP(false), needToJumpMenu(false),
+      ignoreKeys(false), needToSwapPIP(false),
       // Channel Editing
       chanEditMapLock(true), ddMapSourceId(0), ddMapLoaderRunning(false),
       // Sleep Timer
@@ -1935,12 +1949,6 @@
             SwapPIP();
             needToSwapPIP = false;
         }
-
-        if (needToJumpMenu)
-        {
-            DoDisplayJumpMenu();
-            needToJumpMenu = false;
-        }
     }
   
     if (!IsErrored() && (GetState() != kState_None))
@@ -2685,7 +2693,10 @@
             jumpToProgram = true;
         }
         else if (action == "JUMPREC")
-            DisplayJumpMenuSoon();
+        {
+            if (RunPlaybackBoxPtr)
+                EditSchedule(kPlaybackBox);
+        }
         else if (action == "SIGNALMON")
         {
             if ((GetState() == kState_WatchingLiveTV) && activerecorder)
@@ -4940,6 +4951,7 @@
     pbinfoLock.unlock();
 
     bool changeChannel = false;
+    ProgramInfo *nextProgram = NULL;
 
     if (StateIsLiveTV(GetState()))
     {
@@ -4969,12 +4981,26 @@
                     RunProgramFind(true, false);
                     break;
             case kScheduledRecording:
+            {
                     pbinfoLock.lock();
                     ScheduledRecording record;
                     record.loadByProgram(playbackinfo);
                     record.exec();
                     pbinfoLock.unlock();
                     break;
+            }
+            case kPlaybackBox:
+            {
+                    nextProgram = RunPlaybackBoxPtr((void *)this);
+                    if (nextProgram)
+                    {
+                        setLastProgram(nextProgram);
+                        jumpToProgram = true;
+                        exitPlayer = true;
+                        delete nextProgram;
+                    }
+                    break;
+            }
         }
 
         if (!stayPaused)
@@ -5020,6 +5046,14 @@
     return NULL;
 }
 
+void *TV::RecordedShowMenuHandler(void *param)
+{
+    TV *obj = (TV *)param;
+    obj->doEditSchedule(kPlaybackBox);
+
+    return NULL;
+}
+
 void TV::EditSchedule(int editType)
 {
     if (menurunning == true)
@@ -5042,6 +5076,9 @@
         case kScheduledRecording:
                 pthread_create(&tid, &attr, TV::ScheduleMenuHandler, this);
                 break;
+        case kPlaybackBox:
+                pthread_create(&tid, &attr, TV::RecordedShowMenuHandler, this);
+                break;
     }
 }
 
@@ -6337,7 +6374,10 @@
             jumpToProgram = true;
         }
         else if (action == "JUMPREC")
-            DisplayJumpMenuSoon();
+        {
+            if (RunPlaybackBoxPtr)
+                EditSchedule(kPlaybackBox);
+        }
         else if (action.left(8) == "JUMPPROG")
         {
             SetJumpToProgram(action.section(" ",1,-2),
@@ -6368,78 +6408,6 @@
     }
 }
 
-void TV::DoDisplayJumpMenu(void)
-{
-    if (treeMenu)
-        delete treeMenu;
-
-    treeMenu = new OSDGenericTree(NULL, "treeMenu");
-    OSDGenericTree *item, *subitem;
-
-    // Build jumpMenu of recorded program titles
-    ProgramInfo *p;
-    progLists.clear();
-    vector<ProgramInfo *> *infoList;
-    infoList = RemoteGetRecordedList(false);
-
-    bool LiveTVInAllPrograms = gContext->GetNumSetting("LiveTVInAllPrograms",0);
-
-    if (infoList)
-    {
-        pbinfoLock.lock();
-        vector<ProgramInfo *>::iterator i = infoList->begin();
-        for ( ; i != infoList->end(); i++)
-        {
-            p = *i;
-            //if (p->recgroup != "LiveTV" || LiveTVInAllPrograms)
-            if (p->recgroup == playbackinfo->recgroup)
-                progLists[p->title].prepend(p);
-        }
-        pbinfoLock.unlock();
-
-        QMap<QString,ProgramList>::Iterator Iprog;
-        for (Iprog = progLists.begin(); Iprog != progLists.end(); Iprog++)
-        {
-            ProgramList plist = Iprog.data();
-            int progIndex = plist.count();
-            if (progIndex == 1)
-            {
-                item = new OSDGenericTree(treeMenu, tr(Iprog.key()),
-                    QString("JUMPPROG %1 0").arg(Iprog.key()));
-            } 
-            else 
-            {
-                item = new OSDGenericTree(treeMenu, tr(Iprog.key()));
-                for (int i = 0; i < progIndex; i++)
-                {
-                    p = plist.at(i);
-                    if (p->subtitle != "")
-                        subitem = new OSDGenericTree(item, tr(p->subtitle), 
-                            QString("JUMPPROG %1 %2").arg(Iprog.key()).arg(i));
-                    else 
-                        subitem = new OSDGenericTree(item, tr(p->title), 
-                            QString("JUMPPROG %1 %2").arg(Iprog.key()).arg(i));
-                }
-            }
-        }
-    } 
-
-    if (GetOSD())
-    {
-        ClearOSD();
-
-        OSDListTreeType *tree = GetOSD()->ShowTreeMenu("menu", treeMenu);
-        if (tree)
-        {
-            connect(tree, SIGNAL(itemSelected(OSDListTreeType *,OSDGenericTree *)), 
-                    this, SLOT(TreeMenuSelected(OSDListTreeType *, OSDGenericTree *)));
-
-            connect(tree, SIGNAL(itemEntered(OSDListTreeType *, OSDGenericTree *)),
-                    this, SLOT(TreeMenuEntered(OSDListTreeType *, OSDGenericTree *)));
-        }
-    } 
-}
-
 void TV::ShowOSDTreeMenu(void)
 {
     BuildOSDTreeMenu();
@@ -7409,4 +7377,12 @@
         lastProgram = NULL;
 }
 
+bool TV::IsSameProgram(ProgramInfo *rcinfo)
+{
+    if (rcinfo && playbackinfo)
+        return playbackinfo->IsSameProgram(*rcinfo);
+
+    return false;
+}
+
 /* vim: set expandtab tabstop=4 shiftwidth=4: */
Index: programs/mythfrontend/playbackbox.cpp
===================================================================
--- programs/mythfrontend/playbackbox.cpp	(revision 11605)
+++ programs/mythfrontend/playbackbox.cpp	(working copy)
@@ -16,6 +16,7 @@
 #include <qfileinfo.h>
 #include <qsqldatabase.h>
 #include <qmap.h>
+#include <qwaitcondition.h>
 
 #include <cmath>
 #include <unistd.h>
@@ -50,6 +51,8 @@
 
 #define USE_PREV_GEN_THREAD
 
+QWaitCondition pbbIsVisibleCond;
+
 static int comp_programid(ProgramInfo *a, ProgramInfo *b)
 {
     if (a->programid == b->programid)
@@ -185,8 +188,29 @@
         return (a->startts.date() > b->startts.date() ? 1 : -1);
 }
 
+
+ProgramInfo *PlaybackBox::RunPlaybackBox(void * player)
+{
+    ProgramInfo *nextProgram = NULL;
+    qApp->lock();
+
+    PlaybackBox *pbb = new PlaybackBox(PlaybackBox::Play,
+            gContext->GetMainWindow(), "tvplayselect", (TV *)player);
+    pbb->Show();
+
+    qApp->unlock();
+    pbbIsVisibleCond.wait();
+
+    if (pbb->getSelected())
+        nextProgram = new ProgramInfo(*pbb->getSelected());
+   
+    delete pbb;
+    
+    return nextProgram;
+}
+
 PlaybackBox::PlaybackBox(BoxType ltype, MythMainWindow *parent, 
-                         const char *name)
+                         const char *name, TV *player)
     : MythDialog(parent, name),
       // Settings
       type(ltype),
@@ -248,7 +272,8 @@
       previewPixmapEnabled(false),      previewPixmap(NULL),
       previewSuspend(false),            previewChanid(""),
       // Network Control Variables
-      underNetworkControl(false)
+      underNetworkControl(false),
+      m_player(NULL)
 {
     formatShortDate    = gContext->GetSetting("ShortDateFormat", "M/d");
     formatLongDate     = gContext->GetSetting("DateFormat", "ddd MMMM d");
@@ -263,7 +288,8 @@
     groupnameAsAllProg = gContext->GetNumSetting("DispRecGroupAsAllProg", 0);
     arrowAccel         = gContext->GetNumSetting("UseArrowAccels", 1);
     inTitle            = gContext->GetNumSetting("PlaybackBoxStartInTitle", 0);
-    previewVideoEnabled =gContext->GetNumSetting("PlaybackPreview");
+    if (!player)
+        previewVideoEnabled =gContext->GetNumSetting("PlaybackPreview");
     previewPixmapEnabled=gContext->GetNumSetting("GeneratePreviewPixmaps");
     previewFromBookmark= gContext->GetNumSetting("PreviewFromBookmark");
     drawTransPixmap    = gContext->LoadScalePixmap("trans-backup.png");
@@ -283,6 +309,9 @@
     titleList << "";
     playList.clear();
 
+    if (player)
+        m_player = player;
+
     // recording group stuff
     recGroupType.clear();
     recGroupType[recGroup] = (displayCat) ? "category" : "recgroup";
@@ -369,7 +398,8 @@
     gContext->removeListener(this);
     gContext->removeCurrentLocation();
 
-    killPlayerSafe();
+    if (!m_player)
+        killPlayerSafe();
 
     if (previewVideoRefreshTimer)
     {
@@ -566,7 +596,16 @@
 
 void PlaybackBox::exitWin()
 {
-    killPlayerSafe();
+    if (m_player)
+    {
+        if (curitem)
+            delete curitem;
+        curitem = NULL;
+        pbbIsVisibleCond.wakeAll();
+    }
+    else
+        killPlayerSafe();
+
     accept();
 }
 
@@ -1247,7 +1286,8 @@
                 if (playList.grep(tempInfo->MakeUniqueKey()).count())
                     ltype->EnableForcedFont(cnt, "tagged");
 
-                if (tempInfo->availableStatus != asAvailable)
+                if (tempInfo->availableStatus != asAvailable || 
+                        (m_player && m_player->IsSameProgram(tempInfo)) && tempInfo->recstatus != rsRecording)
                     ltype->EnableForcedFont(cnt, "inactive");
             }
         } 
@@ -2080,10 +2120,19 @@
     if (!curitem)
         return;
 
+    if (m_player && m_player->IsSameProgram(curitem))
+        exitWin();
+
     if (curitem && curitem->availableStatus != asAvailable)
         showAvailablePopup(curitem);
     else
         play(curitem);
+
+    if (m_player)
+    {
+        pbbIsVisibleCond.wakeAll();
+        accept();
+    }
 }
 
 void PlaybackBox::stopSelected()
@@ -2212,7 +2261,7 @@
         popup->addButton(tr("Playlist options"), this,
                          SLOT(showPlaylistPopup()));
     }
-    else
+    else if (!m_player)
     {
         if (inTitle)
         {
@@ -2255,6 +2304,9 @@
     if (!rec)
         return false;
 
+    if (m_player)
+        return true;
+            
     if (fileExists(rec) == false)
     {
         QString msg = 
@@ -2913,20 +2965,26 @@
 
     initPopup(popup, program, "", "");
 
-    QButton *playButton;
+    QButton *playButton = new QButton();
 
-    if (curitem->programflags & FL_BOOKMARK)
-        playButton = popup->addButton(tr("Play from..."), this,
-                                      SLOT(showPlayFromPopup()));
-    else
-        playButton = popup->addButton(tr("Play"), this, SLOT(doPlay()));
+    if (!(m_player && m_player->IsSameProgram(curitem)))
+    {
+        if (curitem->programflags & FL_BOOKMARK)
+            popup->addButton(tr("Play from..."), this,
+                                        SLOT(showPlayFromPopup()));
+        else
+            popup->addButton(tr("Play"), this, SLOT(doPlay()));
+    }
 
-    if (playList.grep(curitem->MakeUniqueKey()).count())
-        popup->addButton(tr("Remove from Playlist"), this,
-                         SLOT(togglePlayListItem()));
-    else
-        popup->addButton(tr("Add to Playlist"), this,
-                         SLOT(togglePlayListItem()));
+    if (!m_player)
+    {
+        if (playList.grep(curitem->MakeUniqueKey()).count())
+            popup->addButton(tr("Remove from Playlist"), this,
+                            SLOT(togglePlayListItem()));
+        else
+            popup->addButton(tr("Add to Playlist"), this,
+                            SLOT(togglePlayListItem()));
+    }
 
     if (program->recstatus == rsRecording)
         popup->addButton(tr("Stop Recording"), this, SLOT(askStop()));
@@ -2942,7 +3000,8 @@
     popup->addButton(tr("Recording Options"), this, SLOT(showRecordingPopup()));
     popup->addButton(tr("Job Options"), this, SLOT(showJobPopup()));
 
-    popup->addButton(tr("Delete"), this, SLOT(askDelete()));
+    if (!(m_player && m_player->IsSameProgram(curitem)))
+        popup->addButton(tr("Delete"), this, SLOT(askDelete()));
 
     popup->ShowPopup(this, SLOT(doCancel()));
 
Index: programs/mythfrontend/main.cpp
===================================================================
--- programs/mythfrontend/main.cpp	(revision 11605)
+++ programs/mythfrontend/main.cpp	(working copy)
@@ -614,6 +614,8 @@
     REG_JUMP("Previously Recorded", "", "", startPrevious);
 
     TV::InitKeys();
+
+    TV::SetEmbedPbbFunc(PlaybackBox::RunPlaybackBox);
 }
 
 int internal_media_init() 
Index: programs/mythfrontend/playbackbox.h
===================================================================
--- programs/mythfrontend/playbackbox.h	(revision 11605)
+++ programs/mythfrontend/playbackbox.h	(working copy)
@@ -13,6 +13,7 @@
 #include "xmlparse.h"
 #include "programinfo.h"
 #include "jobqueue.h"
+#include "tv_play.h"
 
 #include <qvaluelist.h>
 #include <pthread.h>
@@ -98,11 +99,13 @@
     } killStateType;
      
 
-    PlaybackBox(BoxType ltype, MythMainWindow *parent, const char *name = 0);
+    PlaybackBox(BoxType ltype, MythMainWindow *parent, const char *name = 0, TV *player = NULL);
    ~PlaybackBox(void);
    
     void customEvent(QCustomEvent *e);
-  
+    static ProgramInfo *RunPlaybackBox(void *player);
+    
+    
   protected slots:
     void timeout(void);
 
@@ -246,6 +249,8 @@
     void stop(ProgramInfo *);
     void remove(ProgramInfo *);
     void showActions(ProgramInfo *);
+    ProgramInfo *getSelected(void){ return curitem; }
+        
 
     void togglePlayListItem(ProgramInfo *pginfo);
     void randomizePlayList(void);
@@ -451,6 +456,8 @@
     mutable QMutex      ncLock;
     QValueList<QString> networkControlCommands;
     bool                underNetworkControl;
+    
+    TV                  *m_player;
 };
 
 #endif

