Go to the documentation of this file.
9 #include <QApplication>
57 #define LOC_MML QString("Manual Metadata Lookup: ")
63 bool IsValidDialogType(
int num)
66 if (num == i)
return true;
70 class ParentalLevelNotifyContainer :
public QObject
75 void SigLevelChanged();
78 explicit ParentalLevelNotifyContainer(QObject *lparent =
nullptr) :
81 connect(&m_levelCheck,
83 this, &ParentalLevelNotifyContainer::OnResultReady);
90 m_levelCheck.Check(m_level.GetLevel(), level.
GetLevel());
107 if (lastLevel != m_level)
109 emit SigLevelChanged();
134 bool GetLocalVideoImage(
const QString &video_uid,
const QString &
filename,
135 const QStringList &in_dirs, QString &image,
136 QString title,
int season,
137 const QString &host,
const QString& sgroup,
138 int episode = 0,
bool isScreenshot =
false)
140 QStringList search_dirs(in_dirs);
142 search_dirs += qfi.absolutePath();
143 if (title.contains(
"/"))
144 title.replace(
"/",
"-");
146 const QString base_name = qfi.completeBaseName();
147 QList<QByteArray> image_types = QImageReader::supportedImageFormats();
149 using image_type_list = std::set<QString>;
150 image_type_list image_exts;
154 if (sgroup ==
"Coverart")
156 if (sgroup ==
"Fanart")
158 if (sgroup ==
"Screenshots")
159 suffix =
"screenshot";
160 if (sgroup ==
"Banners")
163 for (
const auto & itype : qAsConst(image_types))
164 image_exts.insert(QString(itype).toLower());
168 QStringList hostFiles;
171 const QString hntm(
"%2.%3");
173 for (
const auto & ext : image_exts)
176 if (episode > 0 || season > 0)
180 sfn += hntm.arg(QString(
"%1 Season %2x%3_%4")
181 .arg(title, QString::number(season),
182 QString::number(episode), suffix),
187 sfn += hntm.arg(QString(
"%1 Season %2_%3")
188 .arg(title, QString::number(season),
196 sfn += hntm.arg(base_name + QString(
"_%1").arg(suffix),
198 sfn += hntm.arg(video_uid + QString(
"_%1").arg(suffix),
202 for (
const auto & str : qAsConst(sfn))
204 if (hostFiles.contains(str))
213 const QString fntm(
"%1/%2.%3");
215 for (
const auto & dir : qAsConst(search_dirs))
217 if (dir.isEmpty())
continue;
219 for (
const auto & ext : image_exts)
222 if (season > 0 || episode > 0)
227 QString(
"%1 Season %2x%3_%4")
228 .arg(title, QString::number(season),
229 QString::number(episode),
236 QString(
"%1 Season %2_%3")
237 .arg(title, QString::number(season),
245 base_name + QString(
"_%1").arg(suffix),
248 video_uid + QString(
"_%1").arg(suffix),
252 for (
const auto &
file : qAsConst(sfn))
254 if (QFile::exists(
file))
266 void PlayVideo(
const QString &
filename,
269 const int WATCHED_WATERMARK = 10000;
277 QElapsedTimer playing_time;
281 playing_time.start();
288 if (item->GetChildID() > 0 && video_list.
byID(item->GetChildID()))
289 item = video_list.
byID(item->GetChildID());
293 while (item && playing_time.hasExpired(WATCHED_WATERMARK));
296 class FanartLoader:
public QObject
301 FanartLoader() =
default;
302 ~FanartLoader()
override
304 m_fanartTimer.stop();
305 m_fanartTimer.disconnect(
this);
312 connect(&m_fanartTimer, &
QTimer::timeout,
this, &FanartLoader::fanartLoad);
316 bool wasActive = m_fanartTimer.isActive();
320 m_fanartTimer.stop();
327 QMutexLocker locker(&m_fanartLock);
329 if (
filename != m_fanart->GetFilename())
332 m_fanartTimer.stop();
338 m_fanartTimer.setSingleShot(
true);
339 m_fanartTimer.start(300ms);
352 void fanartLoad(
void)
354 QMutexLocker locker(&m_fanartLock);
362 QTimer m_fanartTimer;
363 bool m_bConnected {
false};
366 std::unique_ptr<FanartLoader> fanartLoader;
368 struct CopyMetadataDestination
370 virtual void handleText(
const QString &name,
const QString &value) = 0;
371 virtual void handleState(
const QString &name,
const QString &value) = 0;
372 virtual void handleImage(
const QString &name,
376 class ScreenCopyDest :
public CopyMetadataDestination
379 explicit ScreenCopyDest(
MythScreenType *screen) : m_screen(screen) {}
381 void handleText(
const QString &name,
const QString &value)
override
386 void handleState(
const QString &name,
const QString &value)
override
388 handleText(name, value);
391 void handleImage(
const QString &name,
const QString &
filename)
override
397 if (name !=
"fanart")
409 if (fanartLoader ==
nullptr)
410 fanartLoader = std::make_unique<FanartLoader>();
411 fanartLoader->LoadImage(
filename, image);
420 class MythUIButtonListItemCopyDest :
public CopyMetadataDestination
426 void handleText(
const QString &name,
const QString &value)
override
428 m_item->SetText(value, name);
431 void handleState(
const QString &name,
const QString &value)
override
433 m_item->DisplayState(value, name);
436 void handleImage([[maybe_unused]]
const QString &name,
437 [[maybe_unused]]
const QString &
filename)
override
446 CopyMetadataDestination &
dest)
448 using valuelist = std::map<QString, QString>;
468 tmp[
"coverart"] = coverfile;
470 tmp[
"coverfile"] = coverfile;
472 QString screenshotfile;
485 tmp[
"screenshot"] = screenshotfile;
487 tmp[
"screenshotfile"] = screenshotfile;
502 tmp[
"banner"] = bannerfile;
504 tmp[
"bannerfile"] = bannerfile;
519 tmp[
"fanart"] = fanartfile;
521 tmp[
"fanartfile"] = fanartfile;
525 tmp[
"userratingstate"] =
534 helper(valuelist &values, CopyMetadataDestination &
d) :
535 m_vallist(values), m_dest(
d) {}
537 void handleImage(
const QString &name)
539 m_dest.handleImage(name, m_vallist[name]);
542 void handleState(
const QString &name)
544 m_dest.handleState(name, m_vallist[name]);
547 valuelist &m_vallist;
548 CopyMetadataDestination &m_dest;
553 h.handleImage(
"coverart");
554 h.handleImage(
"screenshot");
555 h.handleImage(
"banner");
556 h.handleImage(
"fanart");
558 h.handleState(
"trailerstate");
559 h.handleState(
"userratingstate");
560 h.handleState(
"watchedstate");
561 h.handleState(
"videolevel");
607 ScreenCopyDest
dest(
this);
629 bool handled =
false;
630 for (
const auto &
action : qAsConst(actions))
677 const parental_level_map::value_type &rhs)
679 return lhs.first.length() >= rhs.first.length();
694 QString ratingstring =
696 .arg(sl.GetLevel()));
697 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
698 QStringList ratings =
699 ratingstring.split(
':', QString::SkipEmptyParts);
701 QStringList ratings =
702 ratingstring.split(
':', Qt::SkipEmptyParts);
704 auto to_pl = [sl](
const auto &
rating)
705 {
return parental_level_map::value_type(
rating, sl.GetLevel()); };
706 std::transform(ratings.cbegin(), ratings.cend(),
748 if (
rating.indexOf(
p->first) != -1)
821 QObject(QCoreApplication::instance())
859 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,
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:")
1392 .arg(fname).arg(result).arg(dir));
1412 int nodeInt = node->
getInt();
1427 if (folder_path.startsWith(
"myth://"))
1428 folder_path = folder_path.right(folder_path.length()
1429 - folder_path.lastIndexOf(
"//") - 1);
1431 QString
filename = QString(
"%1/folder").arg(folder_path);
1434 LOG(VB_GENERAL, LOG_DEBUG,
1435 QString(
"GetCoverImage host : %1 prefix : %2 file : %3")
1439 QStringList test_files;
1440 test_files.append(
filename +
".png");
1441 test_files.append(
filename +
".jpg");
1442 test_files.append(
filename +
".jpeg");
1443 test_files.append(
filename +
".gif");
1446 for (
auto imagePath : qAsConst(test_files))
1449 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Cover check :%1 : ").arg(imagePath));
1452 bool foundCover =
false;
1453 if (!host.isEmpty())
1456 imagePath.replace(
"//",
"/");
1457 prefix.replace(
"//",
"/");
1458 imagePath = imagePath.right(imagePath.length() - (
prefix.length() + 1));
1461 if (!tmpCover.isEmpty())
1464 imagePath = tmpCover;
1468 foundCover = QFile::exists(imagePath);
1472 icon_file = imagePath;
1478 if (icon_file.isEmpty())
1480 QStringList imageTypes {
"*.png",
"*.jpg",
"*.jpeg",
"*.gif" };
1483 if (!host.isEmpty())
1489 if (!dirs.isEmpty())
1491 for (
const auto & dir : qAsConst(dirs))
1494 QString path = sgurl.path();
1496 QString subdir = folder_path.right(folder_path.length() - (
prefix.length() + 1));
1498 path = path +
"/" + subdir;
1500 QStringList tmpList;
1505 for (
const auto & pattern : qAsConst(imageTypes))
1507 auto rePattern = QRegularExpression::wildcardToRegularExpression(pattern);
1508 QRegularExpression rx {
1509 rePattern.mid(2,rePattern.size()-4),
1510 QRegularExpression::CaseInsensitiveOption };
1511 QStringList matches = tmpList.filter(rx);
1512 if (!matches.isEmpty())
1515 fList.append(subdir +
"/" + matches.at(0).split(
"::").at(1));
1528 QDir vidDir(folder_path);
1529 vidDir.setNameFilters(imageTypes);
1530 fList = vidDir.entryList();
1534 if (icon_file.isEmpty())
1539 for (
int i = 0; i < list_count; i++)
1547 if (!metadata->
GetHost().isEmpty() &&
1552 if (!test_file.endsWith(
"/") && !test_file.isEmpty() &&
1555 icon_file = test_file;
1562 if (!test_file.isEmpty() &&
1565 icon_file = test_file;
1575 if (!fList.isEmpty())
1579 icon_file = QString(
"%1/%2").arg(folder_path, fList.at(0));
1588 if (!icon_file.isEmpty())
1590 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Found Image : %1 :")
1595 LOG(VB_GENERAL, LOG_DEBUG,
1596 QString(
"Could not find folder cover Image : %1 ")
1602 const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1638 const QString& gpnode,
int levels)
1640 if (!node ||
type.isEmpty())
1648 QList<MythGenericTree *> subDirs;
1649 static constexpr
int maxRecurse { 1 };
1651 for (
int i = 0; i < list_count; i++)
1663 const QString& host = metadata->
GetHost();
1664 const QString& title = metadata->
GetTitle();
1666 if (
type ==
"Coverart" && !host.isEmpty() &&
1672 else if (
type ==
"Coverart")
1675 if (!test_file.endsWith(
"/") && !test_file.isEmpty() &&
1677 (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1679 icon_file = test_file;
1683 if (
type ==
"Fanart" && !host.isEmpty() &&
1689 else if (
type ==
"Fanart")
1692 if (!test_file.endsWith(
"/") && !test_file.isEmpty() &&
1694 (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1696 icon_file = test_file;
1700 if (
type ==
"Banners" && !host.isEmpty() &&
1706 else if (
type ==
"Banners")
1709 if (!test_file.endsWith(
"/") && !test_file.isEmpty() &&
1711 (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1713 icon_file = test_file;
1717 if (
type ==
"Screenshots" && !host.isEmpty() &&
1723 else if (
type ==
"Screenshots")
1726 if (!test_file.endsWith(
"/") && !test_file.isEmpty() &&
1728 (QString::compare(gpnode, title, Qt::CaseInsensitive) == 0)))
1730 icon_file = test_file;
1736 if (icon_file.isEmpty() && !subDirs.isEmpty())
1739 int subDirCount = subDirs.count();
1740 for (
int i = 0; i < subDirCount; i ++)
1742 if (levels < maxRecurse)
1746 if (!test_file.isEmpty())
1748 icon_file = test_file;
1764 const int nodeInt = node->
getInt();
1774 const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1804 const int nodeInt = node->
getInt();
1810 const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1815 !metadata->
GetBanner().startsWith(
"/") &&
1839 const int nodeInt = node->
getInt();
1845 const VideoMetadata *metadata = GetMetadataPtrFromNode(node);
1850 !metadata->
GetFanart().startsWith(
"/") &&
1877 QStringList actions;
1880 for (
int i = 0; i < actions.size() && !handled; i++)
1882 QString
action = actions[i];
1892 else if (
action ==
"INCPARENT")
1894 else if (
action ==
"DECPARENT")
1899 else if (
action ==
"FILTER")
1901 else if (
action ==
"MENU")
1906 else if (
action ==
"PLAYALT")
1912 else if (
action ==
"DOWNLOADDATA")
1917 else if (
action ==
"INCSEARCH")
1919 else if (
action ==
"ITEMDETAIL")
1921 else if (
action ==
"DELETE")
1928 else if (
action ==
"ESCAPE")
1946 for (
int i = 0; i < actions.size() && !handled; i++)
1948 QString
action = actions[i];
1949 if (
action ==
"PLAYBACK")
1972 const QString& message = title;
1975 "mythvideobusydialog");
1993 QString msg = tr(
"Fetching details for %1")
1998 desc = tr(
"Season %1, Episode %2")
2018 msg = tr(
"Retrieved details for %1").arg(metadata->
GetTitle());
2022 msg = tr(
"Failed to retrieve details for %1").arg(metadata->
GetTitle());
2027 desc = tr(
"Season %1, Episode %2")
2053 const QString& message = title;
2057 if (okPopup->Create())
2067 LOG(VB_GENERAL, LOG_DEBUG, QString(
"Jumping to: %1").arg(
string));
2070 QList<MythGenericTree*> *children =
nullptr;
2071 QMap<int, QString> idTitle;
2078 for (
auto * child : qAsConst(*children))
2080 QString title = child->GetText();
2081 int id = child->getPosition();
2082 idTitle.insert(
id, title);
2107 QStringList childList;
2108 QList<MythGenericTree*> *children =
nullptr;
2114 for (
auto * child : qAsConst(*children))
2116 childList << child->GetText();
2122 tr(
"Video Search"), childList,
false,
"");
2124 if (searchDialog->Create())
2132 delete searchDialog;
2141 bool handled =
false;
2212 metadata->
toMap(metadataMap);
2222 ScreenCopyDest
dest(
this);
2223 CopyMetadataToUI(metadata,
dest);
2268 label = tr(
"Video Options\n%1\n%2").arg(metadata->
GetTitle(),
2273 label = tr(
"Video Options\n%1").arg(metadata->
GetTitle());
2277 label = tr(
"Video Options");
2330 label = tr(
"Playback Options\n%1").arg(metadata->
GetTitle());
2348 QString trailerFile = metadata->
GetTrailer();
2349 if (QFile::exists(trailerFile) ||
2350 (!metadata->
GetHost().isEmpty() && !trailerFile.isEmpty()))
2364 QString label = tr(
"Video Display Menu");
2395 if (which ==
"display")
2406 QString label = tr(
"Change View");
2442 QString label = tr(
"Video Settings");
2501 QString label = tr(
"Browse By");
2544 QString label = tr(
"Video Info");
2556 if (!metadata->
GetCast().empty())
2571 QString label = tr(
"Manage Video Details");
2656 int nodeInt = node->
getInt();
2824 if (mythvideo->Create())
2830 screenStack->
PopScreen(
this,
false,
false);
2835 ShowOkPopup(tr(
"An error occurred when switching views."));
2849 if (plotdialog->Create())
2887 if (castdialog->Create())
2906 if (browser.isEmpty())
2908 ShowOkPopup(tr(
"No browser command set! MythVideo needs MythBrowser "
2909 "installed to display the homepage."));
2913 if (browser.toLower() ==
"internal")
2919 QString cmd = browser;
2920 cmd.replace(
"%ZOOM%", zoom);
2921 cmd.replace(
"%URL%", url);
2922 cmd.replace(
'\'',
"%27");
2923 cmd.replace(
"&",
"\\&");
2924 cmd.replace(
";",
"\\;");
2960 const int WATCHED_WATERMARK = 10000;
2963 QElapsedTimer playing_time;
2969 if (node && !(node->
getInt() >= 0))
2976 bool video_started =
false;
2978 while (i < list_count &&
2979 (!video_started || playing_time.hasExpired(WATCHED_WATERMARK)))
2987 playing_time.start();
2988 video_started =
true;
3002 explicit SimpleCollect(QStringList &fileList) : m_fileList(fileList) {}
3005 [[maybe_unused]]
const QString &fqDirName)
override
3010 void handleFile([[maybe_unused]]
const QString &fileName,
3011 const QString &fqFileName,
3012 [[maybe_unused]]
const QString &extension,
3013 [[maybe_unused]]
const QString &host)
override
3015 m_fileList.push_back(fqFileName);
3019 QStringList &m_fileList;
3022 QStringList GetTrailersInDirectory(
const QString &startDir)
3028 SimpleCollect sc(ret);
3042 if (!metadata)
return;
3045 GetSetting(
"mythvideo.TrailersDir"));
3050 const int trailersToPlay =
3054 while (!
trailers.isEmpty() && i < trailersToPlay)
3059 LOG(VB_GENERAL, LOG_DEBUG,
3060 QString(
"Random trailer to play will be: %1").arg(trailer));
3075 if (!metadata)
return;
3121 if (filterdialog->Create())
3140 int nodeInt = node->
getInt();
3143 metadata = GetMetadataPtrFromNode(node);
3161 if (list.count() > 1)
3163 auto *metadata = list[0]->GetData().value<
VideoMetadata *>();
3169 Qt::QueuedConnection);
3171 if (resultsdialog->Create())
3205 metadata->SetProcessed(
true);
3206 metadata->UpdateDatabase();
3208 LOG(VB_GENERAL, LOG_INFO,
3209 QString(
"No results found for %1 %2 %3").arg(lookup->
GetTitle())
3217 QString
id = dce->
GetId();
3219 if (
id ==
"scanprompt")
3221 int result = dce->GetResult();
3253 if (item !=
nullptr)
3274 QMap<int, int> idPosition;
3278 for (
auto * child : qAsConst(*children))
3280 int nodeInt = child->getInt();
3284 GetMetadataPtrFromNode(child);
3287 int position = child->getPosition();
3288 int id = listmeta->
GetID();
3289 idPosition.insert(
id, position);
3323 using MGTreeChildList = QList<MythGenericTree *>;
3326 LOG(VB_GENERAL, LOG_DEBUG,
3327 QString(
"Fetching details in %1").arg(node->
GetText()));
3329 for (
auto * child : qAsConst(*lchildren))
3371 QString(
"Selected Item: Type: %1%2 : Subtype: %3%4%5 : InetRef: %6")
3386 QString(
"Selected Item has no InetRef Number!"));
3399 curshowlevel += amount;
3419 "mythvideoeditmetadata", metadata,
3424 if (md_editor->Create())
3435 QString message = tr(
"Are you sure you want to permanently delete:\n%1")
3440 if (confirmdialog->Create())
3472 QString message = tr(
"Failed to delete file");
3477 if (confirmdialog->Create())
3500 QStringList cover_dirs;
3506 QString title = metadata->
GetTitle();
3508 QString host = metadata->
GetHost();
3514 if (GetLocalVideoImage(inetref,
filename,
3515 cover_dirs, cover_file, title,
3516 season, host,
"Coverart", episode))
3523 QStringList fanart_dirs;
3526 QString fanart_file;
3530 if (GetLocalVideoImage(inetref,
filename,
3531 fanart_dirs, fanart_file, title,
3532 season, host,
"Fanart", episode))
3539 QStringList banner_dirs;
3542 QString banner_file;
3546 if (GetLocalVideoImage(inetref,
filename,
3547 banner_dirs, banner_file, title,
3548 season, host,
"Banners", episode))
3555 QStringList screenshot_dirs;
3558 QString screenshot_file;
3562 if (GetLocalVideoImage(inetref,
filename,
3563 screenshot_dirs, screenshot_file, title,
3564 season, host,
"Screenshots", episode,
3584 metadata->SetTitle(lookup->
GetTitle());
3587 if (metadata->GetTagline().isEmpty())
3589 if (metadata->GetYear() == 1895 || metadata->GetYear() == 0)
3590 metadata->SetYear(lookup->
GetYear());
3591 if (metadata->GetReleaseDate() == QDate())
3594 metadata->GetDirector().isEmpty())
3597 if (director.count() > 0)
3598 metadata->SetDirector(director.takeFirst().name);
3600 if (metadata->GetStudio().isEmpty())
3603 if (studios.count() > 0)
3604 metadata->SetStudio(studios.takeFirst());
3607 metadata->GetPlot().isEmpty())
3609 if (metadata->GetUserRating() == 0)
3613 if (metadata->GetLength() == 0min)
3615 if (metadata->GetSeason() == 0)
3616 metadata->SetSeason(lookup->
GetSeason());
3617 if (metadata->GetEpisode() == 0)
3619 if (metadata->GetHomepage().isEmpty())
3630 for (
const auto & name : qAsConst(gueststars))
3631 actors.append(name);
3636 for (
const auto & person : qAsConst(actors))
3637 cl.append(person.name);
3639 for (
const auto & name : qAsConst(cl))
3641 QString cn = name.trimmed();
3644 cast.emplace_back(-1, cn);
3648 metadata->SetCast(cast);
3654 for (
const auto & name : qAsConst(genres))
3656 QString genre_name = name.trimmed();
3657 if (!genre_name.isEmpty())
3659 video_genres.emplace_back(-1, genre_name);
3663 metadata->SetGenres(video_genres);
3669 for (
const auto & name : qAsConst(countries))
3671 QString country_name = name.trimmed();
3672 if (!country_name.isEmpty())
3674 video_countries.emplace_back(-1, country_name);
3678 metadata->SetCountries(video_countries);
3679 metadata->SetProcessed(
true);
3681 metadata->UpdateDatabase();
3684 if (item !=
nullptr)
3700 QString message = tr(
"There are no videos in the database, would you like "
3701 "to scan your video directories now?");
3703 dialog->SetReturnEvent(
this,
"scanprompt");
3704 if (dialog->Create())
3710 #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
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.
~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 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.
static const Type kEventType
static MythThemedMenu * menu
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.
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)
static bool rating_to_pl_greater(const parental_level_map::value_type &lhs, const parental_level_map::value_type &rhs)
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.
static void ClearBackendServerPortCache()
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)
static const Type kEventType
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.
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.
uint32_t MythRandom()
generate 32 random bits
QString m_lastTreeNodePath
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