[mythtv] Storage Groups functionality

Chris Pinkham cpinkham at bc2va.org
Thu Mar 9 04:36:23 UTC 2006


* On Wed Mar 08, 2006 at 02:43:34PM -0500, Chris Pinkham wrote:
> I rarely even use MythVideo now so I haven't been keeping the patch up to
> date so it may not apply cleanly to current SVN, but it is attached if
> you want to give it a shot.
> 
> There are 2 files.  The first (p1) is a patch against MythTV that adds
> the ability to display the MythVideo files inside Watch Recordings.  The
> second (p2) is a patch against MythVideo to add settings to enable
> and control this feature as well as setting up MythVideo as a media handler
> so Watch Recordings can tell MythVideo to play the file.

And here's those files I mentioned but neglected to attach. :)

--
Chris
-------------- next part --------------
Index: libs/libmythtv/programinfo.h
===================================================================
--- libs/libmythtv/programinfo.h	(revision 7812)
+++ libs/libmythtv/programinfo.h	(working copy)
@@ -247,6 +247,7 @@
     int chancommfree;
 
     QString pathname;
+    QString previewPath;
     long long filesize;
     QString hostname;
 
Index: libs/libmythtv/programinfo.cpp
===================================================================
--- libs/libmythtv/programinfo.cpp	(revision 7812)
+++ libs/libmythtv/programinfo.cpp	(working copy)
@@ -70,6 +70,7 @@
     timestretch = 1.0;
 
     pathname = "";
+    previewPath = "";
     filesize = 0;
     hostname = "";
     programflags = 0;
@@ -160,6 +161,7 @@
     chanOutputFilters = other.chanOutputFilters;
     
     pathname = other.pathname;
+    previewPath = other.previewPath;
     filesize = other.filesize;
     hostname = other.hostname;
 
@@ -449,7 +451,9 @@
             progMap["starttime"] = startts.toString("yyyy");
             progMap["recstarttime"] = startts.toString("yyyy");
         }
-        
+
+        progMap["timedate"] = "";
+        progMap["shorttimedate"] = "";
     }
     else
     {
@@ -461,6 +465,16 @@
         progMap["recstartdate"] = recstartts.toString(shortDateFormat);
         progMap["recendtime"] = recendts.toString(timeFormat);
         progMap["recenddate"] = recendts.toString(shortDateFormat);
+
+        progMap["timedate"] =
+                recstartts.date().toString(dateFormat) + ", " +
+                recstartts.time().toString(timeFormat) + " - " +
+                recendts.time().toString(timeFormat);
+
+        progMap["shorttimedate"] =
+                recstartts.date().toString(shortDateFormat) + ", " +
+                recstartts.time().toString(timeFormat) + " - " +
+                recendts.time().toString(timeFormat);
     }
     
     progMap["lastmodifiedtime"] = lastmodified.toString(timeFormat);
@@ -530,15 +544,6 @@
     progMap["recgroup"] = recgroup;
     progMap["programflags"] = programflags;
 
-    progMap["timedate"] = recstartts.date().toString(dateFormat) + ", " +
-                          recstartts.time().toString(timeFormat) + " - " +
-                          recendts.time().toString(timeFormat);
-
-    progMap["shorttimedate"] =
-                          recstartts.date().toString(shortDateFormat) + ", " +
-                          recstartts.time().toString(timeFormat) + " - " +
-                          recendts.time().toString(timeFormat);
-
     progMap["time"] = timeNow.time().toString(timeFormat);
 
     MSqlQuery query(MSqlQuery::InitCon());
Index: programs/mythfrontend/playbackbox.cpp
===================================================================
--- programs/mythfrontend/playbackbox.cpp	(revision 7812)
+++ programs/mythfrontend/playbackbox.cpp	(working copy)
@@ -124,6 +124,8 @@
     previewPixmap = NULL;
     previewStartts = QDateTime::currentDateTime();
     previewChanid = "";
+
+    mythVideoCount = 0;
     
     updateFreeSpace = true;
     freeSpaceTotal = 0;
@@ -1158,9 +1160,23 @@
                 }
 
                 ltype->SetItemText(cnt, 1, tempSubTitle);
-                ltype->SetItemText(cnt, 2, tempDate);
-                ltype->SetItemText(cnt, 3, tempTime);
-                ltype->SetItemText(cnt, 4, tempSize);
+
+                if (tempInfo->isVideo)
+                {
+                    if ((tempInfo->endts).date().year() > 1950)
+                    {
+                        QString tempYear = (tempInfo->endts).toString("yyyy");
+                        ltype->SetItemText(cnt, 2, tempYear);
+                    }
+                    ltype->SetItemText(cnt, 3, tr("MythVideo"));
+                }
+                else
+                {
+                    ltype->SetItemText(cnt, 2, tempDate);
+                    ltype->SetItemText(cnt, 3, tempTime);
+                    ltype->SetItemText(cnt, 4, tempSize);
+                }
+
                 if (tempInfo->recstatus == rsRecording)
                     ltype->EnableForcedFont(cnt, "recording");
 
@@ -1323,6 +1339,103 @@
     }
 }
 
+int PlaybackBox::GetMythVideoCount()
+{
+    MSqlQuery query(MSqlQuery::InitCon());
+    query.prepare("SELECT count(title) "
+                  "FROM videometadata "
+                  "WHERE childid = -1 AND showlevel = 1 AND browse = 1;");
+
+    if (query.exec() && query.isActive() && query.size() > 0 && query.next())
+        return query.value(0).toInt();
+    else
+        return 0;
+}
+
+int PlaybackBox::AddMythVideoList(QMap<QString, QString> &sortedList,
+                                   bool asRecGroup)
+{
+    MSqlQuery query(MSqlQuery::InitCon());
+    query.prepare("SELECT intid, title, plot, year, filename, coverfile, "
+                      "length, category "
+                  "FROM videometadata "
+                  "WHERE childid = -1 AND showlevel = 1 AND browse = 1 "
+                  "ORDER BY title DESC;");
+
+    int recordings = 0;
+    bool parentDirIsTitle =
+         gContext->GetNumSetting("MythVideoParentIsTitle", 0);
+
+    if (query.exec() && query.isActive() && query.size() > 0)
+    {
+        QDateTime baseTime = QDateTime(QDate(1970,1,1), QTime(00,00));
+        while (query.next())
+        {
+            ProgramInfo *pginfo = new ProgramInfo();
+            pginfo->sourceid = query.value(0).toInt();
+            pginfo->chanid = query.value(0).toInt();
+
+            if (query.value(2).toString() != "None")
+                pginfo->description = query.value(2).toString();
+            else
+                pginfo->description = "";
+
+            // startts contains fudged dates to allow us to order videos
+            pginfo->startts = baseTime.addSecs(recordings);
+            // endts contains the year of the video for display
+            pginfo->endts = QDateTime(QDate(query.value(3).toInt(),1,1),
+                                      QTime(00,00));
+            pginfo->pathname = query.value(4).toString();
+            pginfo->previewPath = query.value(5).toString();
+            pginfo->lenMins = query.value(6).toInt();
+            pginfo->category = query.value(7).toString();
+
+            QStringList tokens = QStringList::split("/", pginfo->pathname);
+            if (titleView && parentDirIsTitle && tokens.size() > 2)
+            {
+                pginfo->title = tokens[tokens.size() - 2];
+                pginfo->subtitle = query.value(1).toString();
+            }
+            else
+            {
+                pginfo->title = query.value(1).toString();
+            }
+
+            if (asRecGroup)
+                pginfo->recgroup = tr("MythVideo");
+            else
+                pginfo->recgroup = tr("Default");
+
+            pginfo->isVideo = true;
+            pginfo->recstartts = pginfo->startts;
+            pginfo->recendts = pginfo->startts;
+            pginfo->lastmodified = pginfo->startts;
+
+            progLists[""].prepend(pginfo);
+            progLists[pginfo->title].prepend(pginfo);
+            sortedList[pginfo->title] = pginfo->title;
+
+            if (useRecGroups) // Show recording groups                 
+            { 
+                progLists[pginfo->recgroup].prepend(pginfo);
+                progLists[pginfo->recgroup].setAutoDelete(false);
+                sortedList[pginfo->recgroup] = pginfo->recgroup;
+            }
+
+            if (useCategories) // Show categories
+            {
+                progLists[pginfo->category].prepend(pginfo);
+                progLists[pginfo->category].setAutoDelete(false);
+                sortedList[pginfo->category] = pginfo->category;
+            }
+
+            recordings++;
+        }
+    }
+
+    return recordings;
+}
+
 bool PlaybackBox::FillList()
 {
     ProgramInfo *p;
@@ -1359,10 +1472,21 @@
 
     fillRecGroupPasswordCache();
 
+    int includeMythVideo =
+        gContext->GetNumSetting("MythVideoInMythTV", 0);
+
     QMap<QString, QString> sortedList;
     QRegExp prefixes = tr("^(The |A |An )");
     QString sTitle = "";
 
+    if ((includeMythVideo == 1) &&
+        ((recGroup == "All Programs") || (recGroup == "MythVideo")))
+        mythVideoCount = AddMythVideoList(sortedList, true);
+    else if ((includeMythVideo == 2) && (recGroup == "Default"))
+        mythVideoCount = AddMythVideoList(sortedList, false);
+    else if (includeMythVideo)
+        mythVideoCount = GetMythVideoCount();
+
     vector<ProgramInfo *> *infoList;
     infoList = RemoteGetRecordedList(listOrder == 0 || type == Delete);
     if (infoList)
@@ -1546,7 +1670,7 @@
 
     lastUpdateTime = QDateTime::currentDateTime();
 
-    return (infoList != NULL);
+    return (titleList.size() != 0);
 }
 
 static void *SpawnDecoder(void *param)
@@ -1845,7 +1969,7 @@
 
 void PlaybackBox::showActionsSelected()
 {
-    if (!curitem)
+    if (!curitem || curitem->isVideo)
         return;
 
     if (inTitle && haveGroupInfoSet)
@@ -1883,51 +2007,61 @@
 
     ProgramInfo *tvrec = new ProgramInfo(*rec);
 
-    TV *tv = new TV();
-    if (!tv->Init())
-    {
-        VERBOSE(VB_IMPORTANT, "PlaybackBox::play(): "
-                "Error, initializing TV class.");
-        delete tv;
-        delete tvrec;
-        return false;
-    }
-
     setEnabled(false);
     state = kKilling; // stop preview playback and don't restart it
     playingSomething = true;
+    TV *tv = NULL;
 
-    tv->setLastProgram(lastProgram);
-
-    if (tv->Playback(tvrec))
+    if (rec->isVideo)
     {
-        while (tv->GetState() != kState_None)
+        QString handler = "MythVideo";
+        const QString videopath = rec->pathname;
+        gContext->GetMainWindow()->HandleMedia(handler, videopath);
+    }
+    else
+    {
+        tv = new TV();
+        if (!tv->Init())
         {
-            qApp->unlock();
-            qApp->processEvents();
-            usleep(100000);
-            qApp->lock();
+            VERBOSE(VB_IMPORTANT, "PlaybackBox::play(): "
+                    "Error, initializing TV class.");
+            delete tv;
+            delete tvrec;
+            return false;
         }
-        while (tv->getJumpToProgram())
+
+        tv->setLastProgram(lastProgram);
+
+        if (tv->Playback(tvrec))
         {
-            ProgramInfo *tmpProgram = new ProgramInfo(*lastProgram);
+            while (tv->GetState() != kState_None)
+            {
+                qApp->unlock();
+                qApp->processEvents();
+                usleep(100000);
+                qApp->lock();
+            }
+            while (tv->getJumpToProgram())
+            {
+                ProgramInfo *tmpProgram = new ProgramInfo(*lastProgram);
 
-            if (lastProgram)
-                delete lastProgram;
-            lastProgram = new ProgramInfo(*tvrec);
+                if (lastProgram)
+                    delete lastProgram;
+                lastProgram = new ProgramInfo(*tvrec);
 
-            if (tvrec)
-                delete tvrec;
-            tvrec = tmpProgram;
+                if (tvrec)
+                    delete tvrec;
+                tvrec = tmpProgram;
 
-            if (tv->Playback(tvrec))
-            {
-                while (tv->GetState() != kState_None)
+                if (tv->Playback(tvrec))
                 {
-                    qApp->unlock();
-                    qApp->processEvents();
-                    usleep(100000);
-                    qApp->lock();
+                    while (tv->GetState() != kState_None)
+                    {
+                        qApp->unlock();
+                        qApp->processEvents();
+                        usleep(100000);
+                        qApp->lock();
+                    }
                 }
             }
         }
@@ -1945,30 +2079,33 @@
     bool doremove = false;
     bool doprompt = false;
 
-    if (tv->getEndOfRecording())
+    if (tvrec->isVideo)
+    {
         playCompleted = true;
-
-    if (tv->getRequestDelete())
-    {
-        doremove = true;
     }
-    else if (tv->getEndOfRecording() &&
-             !inPlaylist &&
-             gContext->GetNumSetting("EndOfRecordingExitPrompt"))
+    else
     {
-        doprompt = true;
-    }
+        if (tv->getEndOfRecording())
+            playCompleted = true;
 
-    delete tv;
+        if (tv->getRequestDelete())
+        {
+            doremove = true;
+        }
+        else if (tv->getEndOfRecording() &&
+                 !inPlaylist &&
+                 gContext->GetNumSetting("EndOfRecordingExitPrompt"))
+        {
+            doprompt = true;
+        }
 
-    if (doremove)
-    {
-        remove(tvrec);
+        delete tv;
+
+        if (doremove)
+            remove(tvrec);
+        else if (doprompt) 
+            promptEndOfRecording(tvrec);
     }
-    else if (doprompt) 
-    {
-        promptEndOfRecording(tvrec);
-    }
 
     delete tvrec;
 
@@ -3392,6 +3529,28 @@
     if (!generatePreviewPixmap || !pginfo)
         return retpixmap;
         
+    if (pginfo->isVideo)
+    {
+        previewPixmap = gContext->LoadScalePixmap(pginfo->previewPath);
+        QImage image;
+
+        image = previewPixmap->convertToImage();
+        int w = image.width();
+        int h = image.height();
+        float smult = 1.0;
+
+        if (h > w)
+            smult = h / 120;
+        else
+            smult = w / 160;
+
+        QImage tmp2 = image.smoothScale((int)(w / smult), (int)(h / smult));
+        previewPixmap->convertFromImage(tmp2);
+
+        retpixmap = *previewPixmap;
+        return retpixmap;
+    }
+
     QString filename = pginfo->pathname + ".png";
 
     previewLastModified = getPreviewLastModified(pginfo);
@@ -3769,6 +3928,7 @@
     QString dispGroup;
     int items;
     int totalItems = 0;
+    int includeMythVideo = gContext->GetNumSetting("MythVideoInMythTV", 0);
 
     recGroupType.clear();
 
@@ -3787,7 +3947,11 @@
                 itemStr = tr("items");
 
             if (dispGroup == "Default")
+            {
                 dispGroup = tr("Default");
+                if (includeMythVideo == 2)
+                    items += mythVideoCount;
+            }
 
             groups += QString::fromUtf8(QString("%1 [%2 %3]").arg(dispGroup)
                                                 .arg(items).arg(itemStr));
@@ -3797,6 +3961,9 @@
         }
     }
 
+    if (includeMythVideo)
+        totalItems += mythVideoCount;
+
     if (totalItems == 1)
         itemStr = tr("item");
     else
@@ -3806,6 +3973,19 @@
                                         .arg(totalItems).arg(itemStr));
     recGroupType["All Programs"] = "recgroup";
 
+    if (includeMythVideo == 1)
+    {
+        if (mythVideoCount == 1)
+            itemStr = tr("item");
+        else
+            itemStr = tr("items");
+
+        recGroupListBox->insertItem(QString("%1 [%2 %3]")
+                                            .arg(tr("MythVideo"))
+                                            .arg(mythVideoCount).arg(itemStr));
+        recGroupType[("MythVideo")] = "recgroup";
+    }
+
     recGroupListBox->insertItem(QString("------- %1 -------")
                                         .arg(tr("Groups")));
     groups.sort();
Index: programs/mythfrontend/playbackbox.h
===================================================================
--- programs/mythfrontend/playbackbox.h	(revision 7812)
+++ programs/mythfrontend/playbackbox.h	(working copy)
@@ -152,6 +152,9 @@
     bool IsGeneratingPreview(const QString &fn) const;
 
   private:
+    int GetMythVideoCount(void);
+    int AddMythVideoList(QMap<QString, QString> &sortedList,
+                         bool asRecGroup = false);
     bool FillList(void);
     void UpdateProgressBar(void);
 
@@ -194,6 +197,8 @@
     QStringList playList;
     QMap<QString, ProgramList> progLists;
 
+    int mythVideoCount;
+
     ProgramInfo *findMatchingProg(ProgramInfo *);
     ProgramInfo *findMatchingProg(QString key);
     ProgramInfo *findMatchingProg(QString chanid, QString startts);
-------------- next part --------------
Index: mythvideo/mythvideo/globalsettings.cpp
===================================================================
--- mythvideo/mythvideo/globalsettings.cpp	(revision 7812)
+++ mythvideo/mythvideo/globalsettings.cpp	(working copy)
@@ -62,6 +62,31 @@
     return gc;
 };
 
+static GlobalComboBox *MythVideoInMythTV()
+{
+    GlobalComboBox *bc = new GlobalComboBox("MythVideoInMythTV");
+    bc->setLabel(QObject::tr("Browse MythVideo files inside MythTV"));
+    bc->addSelection(QObject::tr("Off"), "0");
+    bc->addSelection(QObject::tr("In 'MythVideo' Group"), "1");
+    bc->addSelection(QObject::tr("In 'Default' Group"), "2"); 
+    bc->setHelpText(QObject::tr("If set, all videos with a Parental level of 1 "
+                    "will be viewable from within MythTV's 'Watch "
+                    "Recordings' screen."));
+    return bc;
+}
+
+static GlobalCheckBox *MythVideoParentIsTitle()
+{
+    GlobalCheckBox *gc = new GlobalCheckBox("MythVideoParentIsTitle");
+    gc->setLabel(QObject::tr("Parent Directories are Titles"));
+    gc->setValue(false);
+    gc->setHelpText(QObject::tr("If this and 'Browse MythVideo files inside "
+                    "MythTV' are set, then the parent directory of a video "
+                    "will be listed as the title and the MythVideo title "
+                    "listed as the subtitle."));
+    return gc;
+};
+
 static HostCheckBox *VideoListUnknownFiletypes()
 {
     HostCheckBox *gc = new HostCheckBox("VideoListUnknownFiletypes");
@@ -248,6 +273,8 @@
     general2->addChild(VideoTreeNoDB());
     general2->addChild(VideoNewBrowsable());
     general2->addChild(VideoDefaultView());
+    general2->addChild(MythVideoInMythTV());
+    general2->addChild(MythVideoParentIsTitle());
     addChild(general2);
 
     VerticalConfigurationGroup* vman = new VerticalConfigurationGroup(false);
Index: mythvideo/mythvideo/main.cpp
===================================================================
--- mythvideo/mythvideo/main.cpp	(revision 7812)
+++ mythvideo/mythvideo/main.cpp	(working copy)
@@ -17,6 +17,7 @@
 
 #include "metadata.h"
 #include "videomanager.h"
+#include "videodlg.h"
 #include "videobrowser.h"
 #include "videotree.h"
 #include "videogallery.h"
@@ -29,6 +30,7 @@
 #include <mythtv/themedmenu.h>
 #include <mythtv/mythcontext.h>
 #include <mythtv/mythplugin.h>
+#include <mythtv/dialogbox.h>
 #include <mythtv/lcddevice.h>
 #include <mythtv/mythdbcon.h>
 
@@ -51,6 +53,8 @@
 void runVideoGallery(void);
 void runDefaultView(void);
 
+int MythVideoHandler(const char *mrl, const char *plot, const char *title,
+                     const char *director, int lenMins, const char *year);
 
 void setupKeys(void)
 {
@@ -96,6 +100,8 @@
 
     setupKeys();
 
+    REG_MEDIAPLAYER( "MythVideo", "MythVideo", MythVideoHandler);
+
     return 0;
 }
 
@@ -324,8 +330,25 @@
     }
 }
 
+int MythVideoHandler(const char *mrl, const char *plot, const char *title,
+                     const char *director, int lenMins, const char *year)
+{
+    VideoTree *tree = new VideoTree(gContext->GetMainWindow(),
+                                   "videotree", "video-", "video tree"); 
 
+    cerr << "In MythVideoHandler" << endl;
+    Metadata *myData = new Metadata;
+    QString filename(mrl);
+    myData->setFilename(filename);
+    if (!myData->fillDataFromFilename())
+        return 1;
 
+    tree->playVideo(myData);
 
+    delete myData;
+    delete tree;
 
+    return 0;
+}
 
+/* vim: set expandtab tabstop=4 shiftwidth=4: */


More information about the mythtv-dev mailing list