rendered paste bodyIndex: libs/libmythtv/previewgeneratorqueue.cpp
===================================================================
--- libs/libmythtv/previewgeneratorqueue.cpp (revision 26449)
+++ libs/libmythtv/previewgeneratorqueue.cpp (working copy)
@@ -273,8 +273,13 @@
bool bookmark_updated = false;
QDateTime bookmark_ts = pginfo.QueryBookmarkTimeStamp();
- QDateTime cmp_ts = bookmark_ts.isValid() ?
- bookmark_ts : pginfo.GetLastModifiedTime();
+ QDateTime cmp_ts;
+ if (bookmark_ts.isValid())
+ cmp_ts = bookmark_ts;
+ else if (QDateTime::currentDateTime() >= pginfo.GetRecordingEndTime())
+ cmp_ts = pginfo.GetLastModifiedTime();
+ else
+ cmp_ts = pginfo.GetRecordingStartTime();
if (streaming)
{
@@ -384,8 +389,9 @@
else if (needs_gen)
{
VERBOSE(VB_PLAYBACK, LOC +
- "Not requesting preview as it "
- "is already being generated");
+ QString("Not requesting preview for %1,"
+ "as it is already being generated")
+ .arg(pginfo.toString(ProgramInfo::kTitleSubtitle)));
IncPreviewGeneratorPriority(key, token);
}
Index: libs/libmythui/mythuibuttonlist.cpp
===================================================================
--- libs/libmythui/mythuibuttonlist.cpp (revision 26449)
+++ libs/libmythui/mythuibuttonlist.cpp (working copy)
@@ -2894,7 +2894,7 @@
newText = text->GetDefaultText();
QRegExp regexp("%(\\|(.))?([^\\|]+)(\\|(.))?%");
regexp.setMinimal(true);
- if (newText.contains(regexp))
+ if (!newText.isEmpty() && newText.contains(regexp))
{
int pos = 0;
QString tempString = newText;
Index: programs/mythfrontend/playbackbox.cpp
===================================================================
--- programs/mythfrontend/playbackbox.cpp (revision 26449)
+++ programs/mythfrontend/playbackbox.cpp (working copy)
@@ -784,9 +784,18 @@
item->DisplayState(rating, "ratingstate");
- QString oldimgfile = item->GetImage("preview");
+ // If there is no preview image, load it.
+ QString oldimgfile = GetLoadedPreview(*pginfo);
if (oldimgfile.isEmpty() || force_preview_reload)
m_preview_tokens.insert(m_helper.GetPreviewImage(*pginfo));
+ // Try to set preview image
+ if (oldimgfile.isEmpty())
+ oldimgfile = GetStalePreview(*pginfo);
+ if (item->GetImage("preview").isEmpty())
+ {
+ if (!oldimgfile.isEmpty())
+ item->SetImage(oldimgfile, "preview", false);
+ }
if ((GetFocusWidget() == m_recordingList) && is_sel)
{
@@ -810,7 +819,7 @@
if (m_previewImage)
{
m_previewImage->SetFilename(oldimgfile);
- m_previewImage->Load(true, true);
+ m_previewImage->Load(false, false);
}
// Handle artwork
@@ -849,33 +858,103 @@
void PlaybackBox::ItemVisible(MythUIButtonListItem *item)
{
ProgramInfo *pginfo = qVariantValue<ProgramInfo*>(item->GetData());
+ if (!pginfo)
+ return;
// Job status (recording, transcoding, flagging)
QString job = extract_job_state(*pginfo);
item->DisplayState(job, "jobstate");
MythUIButtonListItem *sel_item = item->parent()->GetItemCurrent();
- if ((item != sel_item) && pginfo && item->GetImage("preview").isEmpty() &&
- (asAvailable == pginfo->GetAvailableStatus()))
+ if (item == sel_item)
+ return;
+
+ if ((asAvailable == pginfo->GetAvailableStatus()) &&
+ GetLoadedPreview(*pginfo).isEmpty())
{
QString token = m_helper.GetPreviewImage(*pginfo, true);
- if (token.isEmpty())
- return;
-
- m_preview_tokens.insert(token);
- // now make sure selected item is still at the top of the queue
- ProgramInfo *sel_pginfo =
- qVariantValue<ProgramInfo*>(sel_item->GetData());
- if (sel_pginfo && sel_item->GetImage("preview").isEmpty() &&
- (asAvailable == sel_pginfo->GetAvailableStatus()))
+ if (!token.isEmpty())
{
- m_preview_tokens.insert(
- m_helper.GetPreviewImage(*sel_pginfo, false));
+ m_preview_tokens.insert(token);
+ // now make sure selected item is still at the top of the queue
+ ProgramInfo *sel_pginfo =
+ qVariantValue<ProgramInfo*>(sel_item->GetData());
+ if (sel_pginfo && GetLoadedPreview(*sel_pginfo).isEmpty() &&
+ (asAvailable == sel_pginfo->GetAvailableStatus()))
+ {
+ m_preview_tokens.insert(
+ m_helper.GetPreviewImage(*sel_pginfo, false));
+ }
}
}
+
+ if (item->GetImage("preview").isEmpty())
+ {
+ QString cachedPreview = GetStalePreview(*pginfo);
+ if (!cachedPreview.isEmpty())
+ item->SetImage(cachedPreview, "preview", true);
+ }
}
+/** \brief Returns a relatively up to date preview file name if available.
+ * This will only be returned after the preview generator hands us this
+ * preview file as an up to date preview file. This returns an empty string
+ * when not available.
+ * \sa GetStalePreview()
+ */
+QString PlaybackBox::GetLoadedPreview(const ProgramInfo &pginfo) const
+{
+ PreviewCache::const_iterator it =
+ m_previewCache.find(pginfo.MakeUniqueKey());
+ return (it == m_previewCache.end()) ? QString() :
+ ((*it).left(6) == "cache:") ? QString() : *it;
+}
+/** \brief Returns the most up to date preview we have in local storage.
+ * This image may be quite stale, as another frontent may have changed
+ * the file or the bookmarks since the last time it was shown on screen
+ * on this frontend. This is meant as a temporary placeholder image.
+ * \sa GetLoadedPreview()
+ */
+QString PlaybackBox::GetStalePreview(const ProgramInfo &pginfo) const
+{
+ QString key = pginfo.MakeUniqueKey();
+ PreviewCache::const_iterator it = m_previewCache.find(key);
+ QString ret;
+ if (it != m_previewCache.end())
+ ret = ((*it).left(6) == "cache:") ? (*it).mid(6) : *it;
+ if (ret.left(12) == "<NOT_CACHED>")
+ return QString();
+ else if (ret.length())
+ {
+ VERBOSE(VB_IMPORTANT, QString("GetStalePreview() 1 -> '%1'")
+ .arg(ret));
+ return ret;
+ }
+
+ QString preview;
+ QString remotecachedirname = QString("%1/remotecache").arg(GetConfDir());
+ QDir remotecachedir(remotecachedirname);
+ if (remotecachedir.exists())
+ {
+ QString filename = QString("%1/%2")
+ .arg(remotecachedirname)
+ .arg(pginfo.GetBasename() + ".png");
+ if (QFileInfo(filename).isReadable())
+ preview = filename;
+ }
+
+ ret = m_previewCache[key] = QString("cache:") +
+ ((preview.isEmpty()) ? QString("<NOT_CACHED>") : preview);
+ ret = (ret.left(6) == "cache:") ? (ret).mid(6) : ret;
+
+ if (ret.left(12) != "<NOT_CACHED>")
+ VERBOSE(VB_IMPORTANT, QString("GetStalePreview() 2 -> '%1'")
+ .arg(ret));
+
+ return (ret.left(12) == "<NOT_CACHED>") ? QString() : ret;
+}
+
/** \brief Updates the UI properties for a new preview file.
* This first update the image property of the MythUIButtonListItem
* with the new preview file, then if it is selected and there is
@@ -946,6 +1025,8 @@
QString("Loading preview %1,\n\t\t\tmsg %2")
.arg(previewFile).arg(message));
+ m_previewCache[info->MakeUniqueKey()] = previewFile;
+
item->SetImage(previewFile, "preview", true);
if ((GetFocusWidget() == m_recordingList) &&
Index: programs/mythfrontend/playbackboxhelper.cpp
===================================================================
--- programs/mythfrontend/playbackboxhelper.cpp (revision 26449)
+++ programs/mythfrontend/playbackboxhelper.cpp (working copy)
@@ -602,6 +602,9 @@
QString PlaybackBoxHelper::GetPreviewImage(
const ProgramInfo &pginfo, bool check_availability)
{
+ VERBOSE(VB_IMPORTANT, QString("GetPreviewImage(%1)")
+ .arg(pginfo.GetBasename()));
+
if (!check_availability && pginfo.GetAvailableStatus() != asAvailable)
return QString();
Index: programs/mythfrontend/playbackbox.h
===================================================================
--- programs/mythfrontend/playbackbox.h (revision 26449)
+++ programs/mythfrontend/playbackbox.h (working copy)
@@ -45,6 +45,7 @@
class MythDialogBox;
typedef QMap<QString,ProgramList> ProgramMap;
+typedef QMap<QString,QString> PreviewCache;
typedef QMap<QString,QString> Str2StrMap;
enum {
@@ -327,6 +328,9 @@
QString CreateProgramInfoString(const ProgramInfo &program) const;
+ QString GetLoadedPreview(const ProgramInfo &pginfo) const;
+ QString GetStalePreview(const ProgramInfo &pginfo) const;
+
private:
QRegExp m_prefixes; ///< prefixes to be ignored when sorting
QRegExp m_titleChaff; ///< stuff to remove for search rules
@@ -398,6 +402,7 @@
// Main Recording List support
QStringList m_titleList; ///< list of pages
ProgramMap m_progLists; ///< lists of programs by page
+ mutable PreviewCache m_previewCache;
int m_progsInDB; ///< total number of recordings in DB
bool m_isFilling;