Go to the documentation of this file.
7 #include <QApplication>
55 #define LOC_MML QString("Manual Metadata Lookup: ")
61 bool IsValidDialogType(
int num)
64 if (num == i)
return true;
68 class ParentalLevelNotifyContainer :
public QObject
73 void SigLevelChanged();
76 explicit ParentalLevelNotifyContainer(QObject *lparent =
nullptr) :
79 connect(&m_levelCheck,
81 this, &ParentalLevelNotifyContainer::OnResultReady);
88 m_levelCheck.Check(m_level.GetLevel(), level.
GetLevel());
105 if (lastLevel != m_level)
107 emit SigLevelChanged();
132 bool GetLocalVideoImage(
const QString &video_uid,
const QString &
filename,
133 const QStringList &in_dirs, QString &image,
134 QString
title,
int season,
135 const QString &host,
const QString& sgroup,
136 int episode = 0,
bool isScreenshot =
false)
138 QStringList search_dirs(in_dirs);
140 search_dirs += qfi.absolutePath();
141 if (
title.contains(
"/"))
142 title.replace(
"/",
"-");
144 const QString base_name = qfi.completeBaseName();
145 QList<QByteArray> image_types = QImageReader::supportedImageFormats();
147 using image_type_list = std::set<QString>;
148 image_type_list image_exts;
152 if (sgroup ==
"Coverart")
154 if (sgroup ==
"Fanart")
156 if (sgroup ==
"Screenshots")
157 suffix =
"screenshot";
158 if (sgroup ==
"Banners")
161 for (
const auto & itype : qAsConst(image_types))
162 image_exts.insert(QString(itype).toLower());
166 QStringList hostFiles;
169 const QString hntm(
"%2.%3");
171 for (
const auto & ext : image_exts)
174 if (episode > 0 || season > 0)
178 sfn += hntm.arg(QString(
"%1 Season %2x%3_%4")
180 .
arg(QString::number(episode))
186 sfn += hntm.arg(QString(
"%1 Season %2_%3")
195 sfn += hntm.arg(base_name +
"_%1").arg(suffix).arg(ext);
196 sfn += hntm.arg(video_uid +
"_%1").arg(suffix).arg(ext);
199 for (
const auto & str : qAsConst(sfn))
201 if (hostFiles.contains(str))
210 const QString fntm(
"%1/%2.%3");
212 for (
const auto &
dir : qAsConst(search_dirs))
214 if (
dir.isEmpty())
continue;
216 for (
const auto & ext : image_exts)
219 if (season > 0 || episode > 0)
223 sfn += fntm.arg(
dir).arg(QString(
"%1 Season %2x%3_%4")
225 .
arg(QString::number(episode))
231 sfn += fntm.arg(
dir).arg(QString(
"%1 Season %2_%3")
240 .arg(base_name + QString(
"_%1").
arg(suffix))
243 .arg(video_uid + QString(
"_%1").
arg(suffix))
247 for (
const auto &
file : qAsConst(sfn))
249 if (QFile::exists(
file))
261 void PlayVideo(
const QString &
filename,
264 const int WATCHED_WATERMARK = 10000;
272 QElapsedTimer playing_time;
276 playing_time.start();
283 if (item->GetChildID() > 0 && video_list.
byID(item->GetChildID()))
284 item = video_list.
byID(item->GetChildID());
288 while (item && playing_time.hasExpired(WATCHED_WATERMARK));
291 class FanartLoader:
public QObject
296 FanartLoader() =
default;
297 ~FanartLoader()
override
299 m_fanartTimer.stop();
300 m_fanartTimer.disconnect(
this);
307 connect(&m_fanartTimer, &
QTimer::timeout,
this, &FanartLoader::fanartLoad);
311 bool wasActive = m_fanartTimer.isActive();
315 m_fanartTimer.stop();
322 QMutexLocker locker(&m_fanartLock);
324 if (
filename != m_fanart->GetFilename())
327 m_fanartTimer.stop();
333 m_fanartTimer.setSingleShot(
true);
334 m_fanartTimer.start(300ms);
347 void fanartLoad(
void)
349 QMutexLocker locker(&m_fanartLock);
357 QTimer m_fanartTimer;
358 bool m_bConnected {
false};
361 std::unique_ptr<FanartLoader> fanartLoader;
363 struct CopyMetadataDestination
365 virtual void handleText(
const QString &name,
const QString &value) = 0;
366 virtual void handleState(
const QString &name,
const QString &value) = 0;
367 virtual void handleImage(
const QString &name,
371 class ScreenCopyDest :
public CopyMetadataDestination
374 explicit ScreenCopyDest(
MythScreenType *screen) : m_screen(screen) {}
376 void handleText(
const QString &name,
const QString &value)
override
381 void handleState(
const QString &name,
const QString &value)
override
383 handleText(name, value);
386 void handleImage(
const QString &name,
const QString &
filename)
override
392 if (name !=
"fanart")
404 if (fanartLoader ==
nullptr)
405 fanartLoader = std::make_unique<FanartLoader>();
406 fanartLoader->LoadImage(
filename, image);
415 class MythUIButtonListItemCopyDest :
public CopyMetadataDestination
421 void handleText(
const QString &name,
const QString &value)
override
423 m_item->SetText(value, name);
426 void handleState(
const QString &name,
const QString &value)
override
428 m_item->DisplayState(value, name);
431 void handleImage(
const QString &name,
const QString &
filename)
override
442 CopyMetadataDestination &
dest)
444 using valuelist = std::map<QString, QString>;
464 tmp[
"coverart"] = coverfile;
466 tmp[
"coverfile"] = coverfile;
468 QString screenshotfile;
481 tmp[
"screenshot"] = screenshotfile;
483 tmp[
"screenshotfile"] = screenshotfile;
498 tmp[
"banner"] = bannerfile;
500 tmp[
"bannerfile"] = bannerfile;
515 tmp[
"fanart"] = fanartfile;
517 tmp[
"fanartfile"] = fanartfile;
521 tmp[
"userratingstate"] =
530 helper(valuelist &values, CopyMetadataDestination &
d) :
531 m_vallist(values), m_dest(
d) {}
533 void handleImage(
const QString &name)
535 m_dest.handleImage(name, m_vallist[name]);
538 void handleState(
const QString &name)
540 m_dest.handleState(name, m_vallist[name]);
543 valuelist &m_vallist;
544 CopyMetadataDestination &m_dest;
549 h.handleImage(
"coverart");
550 h.handleImage(
"screenshot");
551 h.handleImage(
"banner");
552 h.handleImage(
"fanart");
554 h.handleState(
"trailerstate");
555 h.handleState(
"userratingstate");
556 h.handleState(
"watchedstate");
557 h.handleState(
"videolevel");
603 ScreenCopyDest
dest(
this);
625 bool handled =
false;
626 for (
const auto &
action : qAsConst(actions))
673 public std::binary_function<parental_level_map::value_type,
674 parental_level_map::value_type, bool>
677 const parental_level_map::value_type &rhs)
const
679 return lhs.first.length() < rhs.first.length();
695 QString ratingstring =
697 .
arg(sl.GetLevel()));
698 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
699 QStringList ratings =
700 ratingstring.split(
':', QString::SkipEmptyParts);
702 QStringList ratings =
703 ratingstring.split(
':', Qt::SkipEmptyParts);
705 auto to_pl = [sl](
const auto &
rating)
706 {
return parental_level_map::value_type(
rating, sl.GetLevel()); };
707 std::transform(ratings.cbegin(), ratings.cend(),
749 if (
rating.indexOf(
p->first) != -1)
822 QObject(QCoreApplication::instance())
860 GetNumSetting(
"VideoDefaultParentalLevel",
915 QString windowName =
"videogallery";
916 bool flatlistDefault =
false;
921 windowName =
"browser";
922 flatlistDefault =
true;
925 windowName =
"gallery";
933 windowName =
"manager";
934 flatlistDefault =
true;
1006 LOG(VB_GENERAL, LOG_ERR,
"Cannot load screen '" + windowName +
"'");
1092 QString message = tr(
"The video scan found no files, have you "
1093 "configured a video storage group?");
1152 QStringList lastTreeNodePath =
gCoreContext->
GetSetting(
"mythvideo.VideoTreeLastActive",
"").split(
"\n");
1156 if (!lastTreeNodePath.isEmpty())
1159 for (
int i = 0; i < lastTreeNodePath.size(); i++)
1163 if (node !=
nullptr)
1168 if (node->
GetText().compare(lastTreeNodePath.at(i)) == 0)
1174 i < lastTreeNodePath.size()-1)
1180 if (lastTreeNodePath.at(i) == lastTreeNodePath.last())
1181 selectedNode = node;
1191 using MGTreeChildList = QList<MythGenericTree *>;
1194 for (
auto * child : qAsConst(*lchildren))
1196 if (child !=
nullptr)
1202 item->SetData(QVariant::fromValue(child));
1206 if (child == selectedNode)
1231 metadata->
toMap(metadataMap);
1235 MythUIButtonListItemCopyDest
dest(item);
1236 CopyMetadataToUI(metadata,
dest);
1240 if (parent && metadata && ((QString::compare(parent->
GetText(),
1241 metadata->
GetTitle(), Qt::CaseInsensitive) == 0) ||
1242 parent->
GetText().startsWith(tr(
"Season"), Qt::CaseInsensitive)))
1244 else if (metadata && !metadata->
GetSubtitle().isEmpty())
1254 if (!screenshot.isEmpty() && parent && metadata &&
1255 ((QString::compare(parent->
GetText(),
1256 metadata->
GetTitle(), Qt::CaseInsensitive) == 0) ||
1257 parent->
GetText().startsWith(tr(
"Season"), Qt::CaseInsensitive)))
1263 if (coverimage.isEmpty())
1268 int nodeInt = node->
getInt();
1270 if (coverimage.isEmpty() && nodeInt ==
kSubFolder)
1273 item->
SetImage(coverimage,
"coverart");
1275 if (screenshot.isEmpty() && nodeInt ==
kSubFolder)
1278 item->
SetImage(screenshot,
"screenshot");
1280 if (banner.isEmpty() && nodeInt ==
kSubFolder)
1285 if (fanart.isEmpty() && nodeInt ==
kSubFolder)
1353 QString result =
"";
1355 LOG(VB_GENERAL, LOG_DEBUG, QString(
"RemoteImageCheck(%1)").
arg(
filename));
1360 if (!dirs.isEmpty())
1362 for (
const auto &
dir : qAsConst(dirs))
1365 QString path = sgurl.path();
1367 QString fname = QString(
"%1/%2").arg(path).arg(
filename);
1369 QStringList list( QString(
"QUERY_SG_FILEQUERY") );
1376 if (!ok || list.at(0).startsWith(
"SLAVE UNREACHABLE"))
1378 LOG(VB_GENERAL, LOG_WARNING,
1379 QString(
"Backend : %1 currently Unreachable. Skipping "
1380 "this one.") .
arg(host));
1384 if ((!list.isEmpty()) && (list.at(0) == fname))
1387 if (!result.isEmpty())
1390 LOG(VB_GENERAL, LOG_DEBUG,
1391 QString(
"RemoteImageCheck(%1) res :%2: :%3:")
1410 const QString& host = metadata->
GetHost();
1412 QString
prefix = QDir::cleanPath(fullpath.dir().path());
1416 QStringList test_files;
1417 test_files.append(
filename +
".png");
1418 test_files.append(
filename +
".jpg");
1419 test_files.append(
filename +
".jpeg");
1420 test_files.append(
filename +
".gif");
1422 for (
auto imagePath : qAsConst(test_files))
1424 bool foundCover =
false;
1425 if (!host.isEmpty())
1428 imagePath.replace(
"//",
"/");
1429 prefix.replace(
"//",
"/");
1430 imagePath = imagePath.right(imagePath.length() - (
prefix.length() + 1));
1433 if (!tmpCover.isEmpty())
1436 imagePath = tmpCover;
1440 foundCover = QFile::exists(imagePath);
1444 icon_file = imagePath;
1451 if (icon_file.isEmpty())
1453 QStringList imageTypes;
1454 imageTypes.append(metadata->
GetTitle() +
".png");
1455 imageTypes.append(metadata->
GetTitle() +
".jpg");
1456 imageTypes.append(metadata->
GetTitle() +
".jpeg");
1457 imageTypes.append(metadata->
GetTitle() +
".gif");
1458 imageTypes.append(
"*.png");
1459 imageTypes.append(
"*.jpg");
1460 imageTypes.append(
"*.jpeg");
1461 imageTypes.append(
"*.gif");
1465 if (!host.isEmpty())
1471 if (!dirs.isEmpty())
1473 for (
const auto &
dir : qAsConst(dirs))
1476 QString path = sgurl.path();
1478 const QString& subdir =
prefix;
1480 path = path +
"/" + subdir;
1481 QStringList tmpList;
1486 for (
const auto & pattern : qAsConst(imageTypes))
1488 QRegExp rx(pattern);
1489 rx.setPatternSyntax(QRegExp::Wildcard);
1490 rx.setCaseSensitivity(Qt::CaseInsensitive);
1491 QStringList matches = tmpList.filter(rx);
1492 if (!matches.isEmpty())
1495 fList.append(subdir +
"/" + matches.at(0).split(
"::").at(1));
1508 vidDir.setNameFilters(imageTypes);
1509 fList = vidDir.entryList();
1512 if (!fList.isEmpty())
1516 icon_file = QString(
"%1/%2").arg(
prefix).arg(fList.at(0));
1525 if (!icon_file.isEmpty())
1527 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Found Image : %1 :")
1532 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Could not find cover Image : %1 ")
1548 int nodeInt = node->
getInt();
1559 if (folder_path.startsWith(
"myth://"))
1560 folder_path = folder_path.right(folder_path.length()
1561 - folder_path.lastIndexOf(
"//") - 1);
1563 QString
filename = QString(
"%1/folder").arg(folder_path);
1566 LOG(VB_GENERAL, LOG_DEBUG,
1567 QString(
"GetCoverImage host : %1 prefix : %2 file : %3")
1571 QStringList test_files;
1572 test_files.append(
filename +
".png");
1573 test_files.append(
filename +
".jpg");
1574 test_files.append(
filename +
".jpeg");
1575 test_files.append(
filename +
".gif");
1577 for (
auto imagePath : qAsConst(test_files))
1580 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Cover check :%1 : ").
arg(imagePath));
1583 bool foundCover =
false;
1584 if (!host.isEmpty())
1587 imagePath.replace(
"//",
"/");
1588 prefix.replace(
"//",
"/");
1589 imagePath = imagePath.right(imagePath.length() - (
prefix.length() + 1));
1592 if (!tmpCover.isEmpty())
1595 imagePath = tmpCover;
1599 foundCover = QFile::exists(imagePath);
1603 icon_file = imagePath;
1609 if (icon_file.isEmpty())
1611 QStringList imageTypes;
1612 imageTypes.append(
"*.png");
1613 imageTypes.append(
"*.jpg");
1614 imageTypes.append(
"*.jpeg");
1615 imageTypes.append(
"*.gif");
1619 if (!host.isEmpty())
1625 if (!dirs.isEmpty())
1627 for (
const auto &
dir : qAsConst(dirs))
1630 QString path = sgurl.path();
1632 QString subdir = folder_path.right(folder_path.length() - (
prefix.length() + 1));
1634 path = path +
"/" + subdir;
1636 QStringList tmpList;
1641 for (
const auto & pattern : qAsConst(imageTypes))
1643 QRegExp rx(pattern);
1644 rx.setPatternSyntax(QRegExp::Wildcard);
1645 rx.setCaseSensitivity(Qt::CaseInsensitive);
1646 QStringList matches = tmpList.filter(rx);
1647 if (!matches.isEmpty())
1650 fList.append(subdir +
"/" + matches.at(0).split(
"::").at(1));
1663 QDir vidDir(folder_path);
1664 vidDir.setNameFilters(imageTypes);
1665 fList = vidDir.entryList();
1669 if (icon_file.isEmpty())
1674 for (
int i = 0; i < list_count; i++)
1682 if (!metadata->
GetHost().isEmpty() &&
1687 if (!test_file.endsWith(
"/") && !test_file.isEmpty() &&
1690 icon_file = test_file;
1697 if (!test_file.isEmpty() &&
1700 icon_file = test_file;
1710 if (!fList.isEmpty())
1714 icon_file = QString(
"%1/%2")
1725 if (!icon_file.isEmpty())
1727 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Found Image : %1 :")
1732 LOG(VB_GENERAL, LOG_DEBUG,
1733 QString(
"Could not find folder cover Image : %1 ")
1739 const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1775 const QString& gpnode,
int levels)
1777 if (!node ||
type.isEmpty())
1785 QList<MythGenericTree *> subDirs;
1788 for (
int i = 0; i < list_count; i++)
1800 const QString& host = metadata->
GetHost();
1803 if (
type ==
"Coverart" && !host.isEmpty() &&
1809 else if (
type ==
"Coverart")
1812 if (!test_file.endsWith(
"/") && !test_file.isEmpty() &&
1814 (QString::compare(gpnode,
title, Qt::CaseInsensitive) == 0)))
1816 icon_file = test_file;
1820 if (
type ==
"Fanart" && !host.isEmpty() &&
1826 else if (
type ==
"Fanart")
1829 if (!test_file.endsWith(
"/") && !test_file.isEmpty() &&
1831 (QString::compare(gpnode,
title, Qt::CaseInsensitive) == 0)))
1833 icon_file = test_file;
1837 if (
type ==
"Banners" && !host.isEmpty() &&
1843 else if (
type ==
"Banners")
1846 if (!test_file.endsWith(
"/") && !test_file.isEmpty() &&
1848 (QString::compare(gpnode,
title, Qt::CaseInsensitive) == 0)))
1850 icon_file = test_file;
1854 if (
type ==
"Screenshots" && !host.isEmpty() &&
1860 else if (
type ==
"Screenshots")
1863 if (!test_file.endsWith(
"/") && !test_file.isEmpty() &&
1865 (QString::compare(gpnode,
title, Qt::CaseInsensitive) == 0)))
1867 icon_file = test_file;
1873 if (icon_file.isEmpty() && !subDirs.isEmpty())
1876 int subDirCount = subDirs.count();
1877 for (
int i = 0; i < subDirCount; i ++)
1879 if (levels < maxRecurse)
1883 if (!test_file.isEmpty())
1885 icon_file = test_file;
1901 const int nodeInt = node->
getInt();
1911 const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1941 const int nodeInt = node->
getInt();
1947 const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1952 !metadata->
GetBanner().startsWith(
"/") &&
1976 const int nodeInt = node->
getInt();
1982 const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1987 !metadata->
GetFanart().startsWith(
"/") &&
2014 QStringList actions;
2017 for (
int i = 0; i < actions.size() && !handled; i++)
2019 QString
action = actions[i];
2029 else if (
action ==
"INCPARENT")
2031 else if (
action ==
"DECPARENT")
2036 else if (
action ==
"FILTER")
2038 else if (
action ==
"MENU")
2043 else if (
action ==
"PLAYALT")
2049 else if (
action ==
"DOWNLOADDATA")
2054 else if (
action ==
"INCSEARCH")
2056 else if (
action ==
"ITEMDETAIL")
2058 else if (
action ==
"DELETE")
2065 else if (
action ==
"ESCAPE")
2083 for (
int i = 0; i < actions.size() && !handled; i++)
2085 QString
action = actions[i];
2086 if (
action ==
"PLAYBACK")
2109 const QString& message =
title;
2112 "mythvideobusydialog");
2130 QString msg = tr(
"Fetching details for %1")
2135 desc = tr(
"Season %1, Episode %2")
2155 msg = tr(
"Retrieved details for %1").arg(metadata->
GetTitle());
2159 msg = tr(
"Failed to retrieve details for %1").arg(metadata->
GetTitle());
2164 desc = tr(
"Season %1, Episode %2")
2190 const QString& message =
title;
2194 if (okPopup->Create())
2204 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Jumping to: %1").
arg(
string));
2207 QStringList childList;
2208 QList<MythGenericTree*> *children =
nullptr;
2209 QMap<int, QString> idTitle;
2216 for (
auto * child : qAsConst(*children))
2218 QString
title = child->GetText();
2219 int id = child->getPosition();
2220 idTitle.insert(
id,
title);
2245 QStringList childList;
2246 QList<MythGenericTree*> *children =
nullptr;
2252 for (
auto * child : qAsConst(*children))
2254 childList << child->GetText();
2260 tr(
"Video Search"), childList,
false,
"");
2262 if (searchDialog->Create())
2270 delete searchDialog;
2279 bool handled =
false;
2350 metadata->
toMap(metadataMap);
2360 ScreenCopyDest
dest(
this);
2361 CopyMetadataToUI(metadata,
dest);
2406 label = tr(
"Video Options\n%1\n%2").arg(metadata->
GetTitle())
2411 label = tr(
"Video Options\n%1").arg(metadata->
GetTitle());
2415 label = tr(
"Video Options");
2468 label = tr(
"Playback Options\n%1").arg(metadata->
GetTitle());
2486 QString trailerFile = metadata->
GetTrailer();
2487 if (QFile::exists(trailerFile) ||
2488 (!metadata->
GetHost().isEmpty() && !trailerFile.isEmpty()))
2502 QString label = tr(
"Video Display Menu");
2533 if (which ==
"display")
2544 QString label = tr(
"Change View");
2580 QString label = tr(
"Video Settings");
2639 QString label = tr(
"Browse By");
2682 QString label = tr(
"Video Info");
2694 if (!metadata->
GetCast().empty())
2709 QString label = tr(
"Manage Video Details");
2794 int nodeInt = node->
getInt();
2962 if (mythvideo->Create())
2968 screenStack->
PopScreen(
this,
false,
false);
2973 ShowOkPopup(tr(
"An error occurred when switching views."));
2987 if (plotdialog->Create())
3025 if (castdialog->Create())
3044 if (browser.isEmpty())
3046 ShowOkPopup(tr(
"No browser command set! MythVideo needs MythBrowser "
3047 "installed to display the homepage."));
3051 if (browser.toLower() ==
"internal")
3057 QString cmd = browser;
3058 cmd.replace(
"%ZOOM%", zoom);
3059 cmd.replace(
"%URL%", url);
3060 cmd.replace(
'\'',
"%27");
3061 cmd.replace(
"&",
"\\&");
3062 cmd.replace(
";",
"\\;");
3098 const int WATCHED_WATERMARK = 10000;
3101 QElapsedTimer playing_time;
3107 if (node && !(node->
getInt() >= 0))
3114 bool video_started =
false;
3116 while (i < list_count &&
3117 (!video_started || playing_time.hasExpired(WATCHED_WATERMARK)))
3125 playing_time.start();
3126 video_started =
true;
3140 explicit SimpleCollect(QStringList &fileList) : m_fileList(fileList) {}
3143 const QString &fqDirName)
override
3150 void handleFile(
const QString &fileName,
const QString &fqFileName,
3151 const QString &extension,
const QString &host)
override
3156 m_fileList.push_back(fqFileName);
3160 QStringList &m_fileList;
3163 QStringList GetTrailersInDirectory(
const QString &startDir)
3169 SimpleCollect sc(ret);
3183 if (!metadata)
return;
3191 const int trailersToPlay =
3195 while (!
trailers.isEmpty() && i < trailersToPlay)
3200 LOG(VB_GENERAL, LOG_DEBUG,
3201 QString(
"Random trailer to play will be: %1").
arg(trailer));
3216 if (!metadata)
return;
3262 if (filterdialog->Create())
3281 int nodeInt = node->
getInt();
3284 metadata = GetMetadataPtrFromNode(node);
3302 if (list.count() > 1)
3304 auto *metadata = list[0]->GetData().value<
VideoMetadata *>();
3310 Qt::QueuedConnection);
3312 if (resultsdialog->Create())
3346 metadata->SetProcessed(
true);
3347 metadata->UpdateDatabase();
3349 LOG(VB_GENERAL, LOG_INFO,
3350 QString(
"No results found for %1 %2 %3").
arg(lookup->
GetTitle())
3358 QString
id = dce->
GetId();
3360 if (
id ==
"scanprompt")
3362 int result = dce->GetResult();
3394 if (item !=
nullptr)
3415 QMap<int, int> idPosition;
3419 for (
auto * child : qAsConst(*children))
3421 int nodeInt = child->getInt();
3425 GetMetadataPtrFromNode(child);
3428 int position = child->getPosition();
3429 int id = listmeta->
GetID();
3430 idPosition.insert(
id, position);
3464 using MGTreeChildList = QList<MythGenericTree *>;
3467 LOG(VB_GENERAL, LOG_DEBUG,
3468 QString(
"Fetching details in %1").
arg(node->
GetText()));
3470 for (
auto * child : qAsConst(*lchildren))
3512 QString(
"Selected Item: Type: %1%2 : Subtype: %3%4%5 : InetRef: %6")
3527 QString(
"Selected Item has no InetRef Number!"));
3540 curshowlevel += amount;
3560 "mythvideoeditmetadata", metadata,
3565 if (md_editor->Create())
3576 QString message = tr(
"Are you sure you want to permanently delete:\n%1")
3581 if (confirmdialog->Create())
3613 QString message = tr(
"Failed to delete file");
3618 if (confirmdialog->Create())
3641 QStringList cover_dirs;
3649 QString host = metadata->
GetHost();
3655 if (GetLocalVideoImage(inetref,
filename,
3656 cover_dirs, cover_file,
title,
3657 season, host,
"Coverart", episode))
3664 QStringList fanart_dirs;
3667 QString fanart_file;
3671 if (GetLocalVideoImage(inetref,
filename,
3672 fanart_dirs, fanart_file,
title,
3673 season, host,
"Fanart", episode))
3680 QStringList banner_dirs;
3683 QString banner_file;
3687 if (GetLocalVideoImage(inetref,
filename,
3688 banner_dirs, banner_file,
title,
3689 season, host,
"Banners", episode))
3696 QStringList screenshot_dirs;
3699 QString screenshot_file;
3703 if (GetLocalVideoImage(inetref,
filename,
3704 screenshot_dirs, screenshot_file,
title,
3705 season, host,
"Screenshots", episode,
3725 metadata->SetTitle(lookup->
GetTitle());
3728 if (metadata->GetTagline().isEmpty())
3730 if (metadata->GetYear() == 1895 || metadata->GetYear() == 0)
3731 metadata->SetYear(lookup->
GetYear());
3732 if (metadata->GetReleaseDate() == QDate())
3735 metadata->GetDirector().isEmpty())
3738 if (director.count() > 0)
3739 metadata->SetDirector(director.takeFirst().name);
3741 if (metadata->GetStudio().isEmpty())
3744 if (studios.count() > 0)
3745 metadata->SetStudio(studios.takeFirst());
3748 metadata->GetPlot().isEmpty())
3750 if (metadata->GetUserRating() == 0)
3754 if (metadata->GetLength() == 0min)
3756 if (metadata->GetSeason() == 0)
3757 metadata->SetSeason(lookup->
GetSeason());
3758 if (metadata->GetEpisode() == 0)
3760 if (metadata->GetHomepage().isEmpty())
3771 for (
const auto & name : qAsConst(gueststars))
3772 actors.append(name);
3777 for (
const auto & person : qAsConst(actors))
3778 cl.append(person.name);
3780 for (
const auto & name : qAsConst(cl))
3782 QString cn = name.trimmed();
3786 value_type(-1, cn));
3790 metadata->SetCast(cast);
3796 for (
const auto & name : qAsConst(
genres))
3798 QString genre_name = name.trimmed();
3799 if (!genre_name.isEmpty())
3801 video_genres.push_back(
3802 VideoMetadata::genre_list::value_type(-1, genre_name));
3806 metadata->SetGenres(video_genres);
3812 for (
const auto & name : qAsConst(
countries))
3814 QString country_name = name.trimmed();
3815 if (!country_name.isEmpty())
3817 video_countries.push_back(
3818 VideoMetadata::country_list::value_type(-1,
3823 metadata->SetCountries(video_countries);
3824 metadata->SetProcessed(
true);
3826 metadata->UpdateDatabase();
3829 if (item !=
nullptr)
3845 QString message = tr(
"There are no videos in the database, would you like "
3846 "to scan your video directories now?");
3848 dialog->SetReturnEvent(
this,
"scanprompt");
3849 if (dialog->Create())
3855 #include "videodlg.moc"
simple_ref_ptr< class VideoList > VideoListPtr
static QString GetBanner(MythGenericTree *node)
Find the Banner for a given node.
MythScreenStack * GetMainStack()
QString generate_file_url(const QString &storage_group, const QString &host, const QString &path)
Provide a dialog to quickly find an entry in a list.
class VideoDialogPrivate * m_d
MythMenu * CreateMetadataBrowseMenu()
Create a MythMenu for MythVideo Metadata Browse modes.
void OnVideoImageSetDone(VideoMetadata *metadata)
std::list< std::pair< QString, ParentalLevel::Level > > parental_level_map
static QString GetImageFromFolder(VideoMetadata *metadata)
Attempt to find/fallback a cover image for a given metadata item.
void playVideoAlt()
Play the selected item in an alternate player.
QString WatchedToState(bool watched)
void AutomaticParentalAdjustment(VideoMetadata *metadata)
Image widget, displays a single image or multiple images in sequence.
MythMenu * CreateSettingsMenu()
Create a MythMenu for MythVideo Settings.
void StartVideoImageSet(VideoMetadata *metadata)
void getExtensionIgnoreList(ext_ignore_list &ext_ignore) const
void playTrailer()
Play the trailer associated with the selected item.
QString GetText(const QString &name="") const
void ShowMetadataSettings()
Pop up a MythUI Menu for MythVideo Metadata Settings.
VideoDialog::DialogType m_type
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
MythDialogBox * m_menuPopup
void doScan(const QStringList &dirs)
void SwitchManager()
Switch to Video Manager View.
int Register(void *from)
An application can register in which case it will be assigned a reusable screen, which can be modifie...
uint visibleChildCount() const
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
void refreshData()
Reloads the tree without invalidating the data.
bool Create(void) override
static void DelayVideoListDestruction(const VideoListPtr &videoList)
void SwitchVideoGenreGroup()
Switch to Genre browse mode.
arg(title).arg(filename).arg(doDelete))
~VideoListDeathDelay() override
QVariant GetData(void) const
void dismissFetchDialog(VideoMetadata *metadata, bool ok)
void SwitchVideoInsertDateGroup()
Switch to Insert Date browse mode.
void handleSelect(MythUIButtonListItem *item)
Handle SELECT action for a given MythUIButtonListItem.
MythGenericTree * getChildByName(const QString &a_name) const
void CheckedSet(MythUIStateType *uiItem, const QString &value)
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
void Closed(QString, int)
MythMenu * CreateManageMenu()
Create a MythMenu for metadata management.
Screen in which all other widgets are contained and rendered.
void Load() override
Called after the screen is created by MythScreenStack.
static VideoListDeathDelayPtr & GetSavedVideoList()
void Reset(void) override
Reset the image back to the default defined in the theme.
VideoListDeathDelay(const VideoDialog::VideoListPtr &toSave)
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
MythMenu * CreateViewMenu()
Create a MythMenu for MythVideo Views.
void SwitchVideoUserRatingGroup()
Switch to User Rating browse mode.
static MythThemedMenu * menu
static void ClearGroupToUseCache(void)
MythUIStateType * m_studioState
VideoDialog::BrowseType m_browse
bool HandleMedia(const QString &Handler, const QString &Mrl, const QString &Plot="", const QString &Title="", const QString &Subtitle="", const QString &Director="", int Season=0, int Episode=0, const QString &Inetref="", std::chrono::minutes LenMins=2h, const QString &Year="1895", const QString &Id="", bool UseBookmarks=false)
void shiftParental(int amount)
Shift the parental level for the library by an integer amount.
MythUIText * m_positionText
MythUIBusyDialog * m_busyPopup
MythUIButtonTree * m_videoButtonTree
static VideoDialog::VideoListDeathDelayPtr m_savedPtr
MythUIType * GetFocusWidget(void) const
MythUIStateType * m_trailerState
QHash< QString, QString > InfoMap
MythGenericTree * getChildAt(uint reference) const
QString GetFirstImage(MythGenericTree *node, const QString &type, const QString &gpnode=QString(), int levels=0)
Find the first image of "type" within a folder structure.
virtual MythUIButtonListItem * GetItemByMetadata(VideoMetadata *metadata)
void searchComplete(const QString &string)
After using incremental search, move to the selected item.
MythGenericTree * getSelectedChild(bool onlyVisible=false) const
VideoDialog::VideoListPtr GetSaved()
void SwitchVideoTVMovieGroup()
Switch to Television/Movie browse mode.
static QString GetScreenshot(MythGenericTree *node)
Find the Screenshot for a given node.
void playVideoWithTrailers()
Play the selected item w/ a User selectable # of trailers.
static QString GetFanart(MythGenericTree *node)
Find the Fanart for a given node.
void scanFinished(bool dbChanged)
void SwitchBrowse()
Switch to Browser View.
void OnVideoSearchListSelection(RefCountHandler< MetadataLookup > lookup)
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
MetadataFactory * m_metadataFactory
QStringList GetVideoDirs()
bool goBack()
Move one level up in the tree.
MythScreenStack * m_popupStack
static QString RemoteImageCheck(const QString &host, const QString &filename)
Search for a given (image) filename in the Video SG.
ParentalLevelNotifyContainer m_parentalLevel
QPointer< class VideoListDeathDelay > VideoListDeathDelayPtr
bool SetFocusWidget(MythUIType *widget=nullptr)
QStringList getRouteByString(void)
std::vector< std::pair< QString, bool > > ext_ignore_list
Basic menu dialog, message and a list of options.
void SwitchVideoYearGroup()
Switch to Year browse mode.
void SwitchTree()
Switch to Tree (List) View.
void ShowCastDialog()
Display the Cast if the selected item.
bool Create(void) override
void SetParent(void *Parent)
Contains the parent address. Required if id is set Id provided must match the parent address as provi...
class VideoListDeathDelayPrivate * m_d
virtual MythUIButtonListItem * GetItemCurrent()
void BuildFocusList(void)
def rating(profile, smoonURL, gate)
MythScreenStack * m_mainStack
VideoDialog::VideoListPtr m_savedList
void searchStart()
Create an incremental search dialog for the current tree level.
int childCount(void) const
const QString VIDEO_PLOT_DEFAULT
virtual void SetTextFromMap(const InfoMap &infoMap)
void SwitchVideoDirectorGroup()
Switch to Director browse mode.
void SetCurrentNode(MythGenericTree *node)
Switch to a given MythGenericTree node.
bool IsDefaultBanner(const QString &banner)
MythGenericTree * getVisibleChildAt(uint reference) const
void SwitchVideoFolderGroup()
Switch to Folder (filesystem) browse mode.
void SwitchLayout(DialogType type, BrowseType browse)
Handle a layout or browse mode switch.
void SwitchVideoCastGroup()
Switch to Cast browse mode.
void setParentalLevel(ParentalLevel::Level level)
Set the parental level for the library.
void handleDynamicDirSelect(MythGenericTree *node)
Request the latest metadata for a folder.
MythMenu * CreateInfoMenu()
Create a MythMenu for Info pertaining to the selected item.
MythUIStateType * m_parentalLevelState
void createOkDialog(const QString &title)
Create a MythUI "OK" Dialog.
void ShowExtensionSettings()
Pop up a MythUI Menu for MythVideo filte Type Settings.
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
void SigResultReady(bool passwordValid, ParentalLevel::Level newLevel)
bool IsDefaultFanart(const QString &fanart)
int GetNumSetting(const QString &key, int defaultval=0)
MythScreenStack * GetScreenStack() const
MythMenu * CreatePlayMenu()
Create a "Play Menu" for MythVideo. Appears if multiple play options exist.
QList< MythGenericTree * > * getAllChildren() const
const QString VIDEO_FANART_DEFAULT
MythUIStateType * m_watchedState
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
virtual void loadData()
load the data used to build the ButtonTree/List for MythVideo.
VideoListDeathDelayPrivate(const VideoDialog::VideoListPtr &toSave)
void SwitchVideoCategoryGroup()
Switch to Category browse mode.
QString ParentalLevelToState(const ParentalLevel &level)
bool IsDefaultCoverFile(const QString &coverfile)
bool IsDefaultScreenshot(const QString &screenshot)
void customEvent(QEvent *levent) override
bool GetBoolSetting(const QString &key, bool defaultval=false)
void popupClosed(const QString &which, int result)
static FileAssociations & getFileAssociation()
void UpdatePosition()
Called after the screen is created by MythScreenStack.
void createBusyDialog(const QString &title)
Create a busy dialog, used during metadata search, etc.
MBASE_PUBLIC uint32_t MythRandom()
static VideoPlayerCommand AltPlayerFor(const VideoMetadata *item)
VideoDialog(MythScreenStack *lparent, const QString &lname, const VideoListPtr &video_list, DialogType type, BrowseType browse)
void handleDirSelect(MythGenericTree *node)
Descend into a selected folder.
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
void deleteNode(MythGenericTree *child)
MythGenericTree * m_currentNode
void reloadData()
Reloads the tree after having invalidated the data.
Dialog asking for user confirmation. Ok and optional Cancel button.
bool ScanVideoDirectory(const QString &start_path, DirectoryHandler *handler, const FileAssociations::ext_ignore_list &ext_disposition, bool list_unknown_extensions)
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
void ShowPlayerSettings()
Pop up a MythUI Menu for MythVideo Player Settings.
MythGenericTree * getParent(void) const
QStringList GetVideoDirsByHost(const QString &host)
const QString VIDEO_RATING_DEFAULT
void ChangeFilter()
Change the filtering of the library.
void OnVideoSearchDone(MetadataLookup *lookup)
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
void UpdateText(MythUIButtonListItem *item)
Update the visible text values for a given ButtonListItem.
static VideoMetadata * GetMetadata(MythUIButtonListItem *item)
Retrieve the Database Metadata for a given MythUIButtonListItem.
void OnParentalChange(int amount)
virtual void SetVisible(bool visible)
VideoDialog::VideoListPtr GetSaved()
MythNotificationCenter * GetNotificationCenter(void)
void UnRegister(void *from, int id, bool closeimemdiately=false)
Unregister the client.
void createFetchDialog(VideoMetadata *metadata)
Create a fetch notification, used during metadata search.
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
MythUIImage * m_coverImage
parental_level_map m_ratingToPl
MythMainWindow * GetMythMainWindow(void)
void SetId(int Id)
Contains the application registration id.
void fetchVideos()
Build the buttonlist/tree.
MythGenericTree * m_rootNode
void SwitchGallery()
Switch to Gallery View.
MythScreenStack * GetStack(const QString &Stackname)
static constexpr std::chrono::milliseconds kDelayTimeMS
void playVideo()
Play the selected item.
bool operator()(const parental_level_map::value_type &lhs, const parental_level_map::value_type &rhs) const
void playFolder()
Play all the items in the selected folder.
static VideoPlayerCommand PlayerFor(const VideoMetadata *item)
MythUIImage * m_screenshot
virtual DirectoryHandler * newDir(const QString &dir_name, const QString &fq_dir_name)=0
QString TrailerToState(const QString &trailerFile)
const QString VIDEO_BANNER_DEFAULT
static const iso6937table * d
void SwitchVideoStudioGroup()
Switch to Studio browse mode.
void OnRemoveVideo(bool dodelete)
@ kMSDontDisableDrawing
avoid disabling UI drawing
void SaveSetting(const QString &key, int newValue)
void ToggleFlatView()
Toggle Flat View.
void AllowInput(bool Allow)
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
void UpdateItem(MythUIButtonListItem *item)
Update the visible representation of a MythUIButtonListItem.
VideoDialogPrivate(const VideoListPtr &videoList, VideoDialog::DialogType type, VideoDialog::BrowseType browse)
MythUIText * m_novideoText
QMap< QString, int > m_notifications
void DisplayMenu()
Pop up a MythUI Menu for MythVideo Global Functions. Bound to MENU.
virtual int IncrRef(void)
Increments reference count.
void VideoMenu()
Pop up a MythUI "Playback Menu" for MythVideo. Bound to INFO.
void ToggleBrowseMode()
Toggle the browseable status for the selected item.
MythUIButtonList * m_videoButtonList
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
void becomeSelectedChild(void)
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
void ViewPlot()
Display a MythUI Popup with the selected item's plot.
static QString GetCoverImage(MythGenericTree *node)
A "hunt" for cover art to apply for a folder item.
QString m_lastTreeNodePath
t<< doc.toString(4);f.close();LOG(VB_JOBQUEUE, LOG_INFO, "Copying video file");bool res=copyFile(filename, saveDirectory+title+"/"+baseName);if(!res) return 0;if(QFile::exists(filename+".png")) { LOG(VB_JOBQUEUE, LOG_INFO, "Copying preview image");res=copyFile(filename+".png", saveDirectory+title+"/"+baseName+".png");if(!res) return 0;} LOG(VB_JOBQUEUE, LOG_INFO, "Item Archived OK");return 1;}int NativeArchive::exportVideo(QDomElement &itemNode, const QString &saveDirectory){ QString dbVersion=gCoreContext-> GetSetting("DBSchemaVer", "")
virtual void handleFile(const QString &file_name, const QString &fq_file_name, const QString &extension, const QString &host)=0
bool keyPressEvent(QKeyEvent *levent) override
Handle keypresses and keybindings.
bool DoItemDetailShow()
Display the Item Detail Popup.
const QString VIDEO_SCREENSHOT_DEFAULT
QString GetSetting(const QString &key, const QString &defaultval="")
static const QString sLocation
bool Queue(const MythNotification ¬ification)
Queue a notification Queue() is thread-safe and can be called from anywhere.
bool RemoteGetFileList(const QString &host, const QString &path, QStringList *list, QString sgroup, bool fileNamesOnly)
const QString VIDEO_DIRECTOR_UNKNOWN