[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