MythTV  master
gameui.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QMetaType>
3 #include <QStringList>
4 #include <QTimer>
5 
6 // MythTV
7 #include <libmyth/mythcontext.h>
8 #include <libmythbase/mythdirs.h>
14 #include <libmythui/mythuiimage.h>
16 #include <libmythui/mythuitext.h>
17 
18 // MythGame headers
19 #include "gamehandler.h"
20 #include "rominfo.h"
21 #include "gamedetails.h"
22 #include "romedit.h"
23 #include "gamescan.h"
24 #include "gameui.h"
25 
26 static const QString sLocation = "MythGame";
27 
29 {
30  public:
31  GameTreeInfo(const QString& levels, QString filter)
32  : m_levels(levels.split(" "))
33  , m_filter(std::move(filter))
34  {
35  }
36 
37  int getDepth() const { return m_levels.size(); }
38  const QString& getLevel(unsigned i) const { return m_levels[i]; }
39  const QString& getFilter() const { return m_filter; }
40 
41  private:
42  QStringList m_levels;
43  QString m_filter;
44 };
45 
47 
49  : MythScreenType(parent, "GameUI"),
50  m_query(new MetadataDownload(this)),
51  m_imageDownload(new MetadataImageDownload(this))
52 {
53  m_popupStack = GetMythMainWindow()->GetStack("popup stack");
54 }
55 
57 {
58  if (!LoadWindowFromXML("game-ui.xml", "gameui", this))
59  return false;
60 
61  bool err = false;
62  UIUtilE::Assign(this, m_gameUITree, "gametreelist", &err);
63  UIUtilW::Assign(this, m_gameTitleText, "title");
64  UIUtilW::Assign(this, m_gameSystemText, "system");
65  UIUtilW::Assign(this, m_gameYearText, "year");
66  UIUtilW::Assign(this, m_gameGenreText, "genre");
67  UIUtilW::Assign(this, m_gameFavouriteState, "favorite");
68  UIUtilW::Assign(this, m_gamePlotText, "description");
69  UIUtilW::Assign(this, m_gameImage, "screenshot");
70  UIUtilW::Assign(this, m_fanartImage, "fanart");
71  UIUtilW::Assign(this, m_boxImage, "coverart");
72 
73  if (err)
74  {
75  LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'gameui'");
76  return false;
77  }
78 
80  this, &GameUI::itemClicked);
81 
83  this, &GameUI::nodeChanged);
84 
85  m_gameShowFileName = gCoreContext->GetBoolSetting("GameShowFileNames");
86 
87  BuildTree();
88 
90 
91  return true;
92 }
93 
95 {
96  if (m_gameTree)
97  {
99  delete m_gameTree;
100  m_gameTree = nullptr;
101  }
102 
103  m_gameTree = new MythGenericTree("game root", 0, false);
104 
105  // create system filter to only select games where handlers are present
106  QString systemFilter;
107 
108  // The call to GameHandler::count() fills the handler list for us
109  // to move through.
110  unsigned handlercount = GameHandler::count();
111 
112  for (unsigned i = 0; i < handlercount; ++i)
113  {
114  QString system = GameHandler::getHandler(i)->SystemName();
115  if (i == 0)
116  systemFilter = "`system` in ('" + system + "'";
117  else
118  systemFilter += ",'" + system + "'";
119  }
120  if (systemFilter.isEmpty())
121  {
122  systemFilter = "1=0";
123  LOG(VB_GENERAL, LOG_ERR, QString("Couldn't find any game handlers!"));
124  }
125  else
126  {
127  systemFilter += ")";
128  }
129 
130  m_showHashed = gCoreContext->GetBoolSetting("GameTreeView");
131 
132  // create a few top level nodes - this could be moved to a config based
133  // approach with multiple roots if/when someone has the time to create
134  // the relevant dialog screens
135 
136  QString levels = gCoreContext->GetSetting("GameFavTreeLevels", "gamename");
137 
138  auto *new_node = new MythGenericTree(tr("Favorites"), 1, true);
139  new_node->SetData(QVariant::fromValue(
140  new GameTreeInfo(levels, systemFilter + " and favorite=1")));
141  m_favouriteNode = m_gameTree->addNode(new_node);
142 
143  levels = gCoreContext->GetSetting("GameAllTreeLevels", "system gamename");
144 
145  if (m_showHashed)
146  {
147  int pos = levels.indexOf("gamename");
148  if (pos >= 0)
149  levels.insert(pos, " hash ");
150  }
151 
152  new_node = new MythGenericTree(tr("All Games"), 1, true);
153  new_node->SetData(QVariant::fromValue(
154  new GameTreeInfo(levels, systemFilter)));
155  m_gameTree->addNode(new_node);
156 
157  new_node = new MythGenericTree(tr("- By Genre"), 1, true);
158  new_node->SetData(QVariant::fromValue(
159  new GameTreeInfo("genre gamename", systemFilter)));
160  m_gameTree->addNode(new_node);
161 
162  new_node = new MythGenericTree(tr("- By Year"), 1, true);
163  new_node->SetData(QVariant::fromValue(
164  new GameTreeInfo("year gamename", systemFilter)));
165  m_gameTree->addNode(new_node);
166 
167  new_node = new MythGenericTree(tr("- By Name"), 1, true);
168  new_node->SetData(QVariant::fromValue(
169  new GameTreeInfo("gamename", systemFilter)));
170  m_gameTree->addNode(new_node);
171 
172  new_node = new MythGenericTree(tr("- By Publisher"), 1, true);
173  new_node->SetData(QVariant::fromValue(
174  new GameTreeInfo("publisher gamename", systemFilter)));
175  m_gameTree->addNode(new_node);
176 
179 }
180 
181 bool GameUI::keyPressEvent(QKeyEvent *event)
182 {
183  if (GetFocusWidget()->keyPressEvent(event))
184  return true;
185 
186  QStringList actions;
187  bool handled = GetMythMainWindow()->TranslateKeyPress("Game", event, actions);
188 
189  for (int i = 0; i < actions.size() && !handled; i++)
190  {
191  const QString& action = actions[i];
192  handled = true;
193 
194  if (action == "MENU")
195  ShowMenu();
196  else if (action == "EDIT")
197  edit();
198  else if (action == "INFO")
199  showInfo();
200  else if (action == "TOGGLEFAV")
201  toggleFavorite();
202  else if ((action == "INCSEARCH") || (action == "INCSEARCHNEXT"))
203  searchStart();
204  else if (action == "DOWNLOADDATA")
205  gameSearch();
206  else
207  handled = false;
208  }
209 
210  if (!handled && MythScreenType::keyPressEvent(event))
211  handled = true;
212 
213  return handled;
214 }
215 
217 {
218  if (!node)
219  return;
220 
221  if (!isLeaf(node))
222  {
223  if (node->childCount() == 0 || node == m_favouriteNode)
224  {
225  node->deleteAllChildren();
226  fillNode(node);
227  }
228  clearRomInfo();
229  }
230  else
231  {
232  auto *romInfo = node->GetData().value<RomInfo *>();
233  if (!romInfo)
234  return;
235  if (romInfo->Romname().isEmpty())
236  romInfo->fillData();
237  updateRomInfo(romInfo);
238  if (!romInfo->Screenshot().isEmpty() || !romInfo->Fanart().isEmpty() ||
239  !romInfo->Boxart().isEmpty())
240  showImages();
241  else
242  {
243  if (m_gameImage)
244  m_gameImage->Reset();
245  if (m_fanartImage)
246  m_fanartImage->Reset();
247  if (m_boxImage)
248  m_boxImage->Reset();
249  }
250  }
251 }
252 
254 {
256  if (isLeaf(node))
257  {
258  auto *romInfo = node->GetData().value<RomInfo *>();
259  if (!romInfo)
260  return;
261  if (romInfo->RomCount() == 1)
262  {
263  GameHandler::Launchgame(romInfo, nullptr);
264  }
265  else
266  {
267  //: %1 is the game name
268  QString msg = tr("Choose System for:\n%1").arg(node->GetText());
269  MythScreenStack *popupStack = GetMythMainWindow()->
270  GetStack("popup stack");
271  auto *chooseSystemPopup = new MythDialogBox(
272  msg, popupStack, "chooseSystemPopup");
273 
274  if (chooseSystemPopup->Create())
275  {
276  chooseSystemPopup->SetReturnEvent(this, "chooseSystemPopup");
277  QString all_systems = romInfo->AllSystems();
278  QStringList players = all_systems.split(',');
279  for (const auto & player : std::as_const(players))
280  chooseSystemPopup->AddButton(player);
281  popupStack->AddScreen(chooseSystemPopup);
282  }
283  else
284  {
285  delete chooseSystemPopup;
286  }
287  }
288  }
289 }
290 
292 {
293  if (m_gameImage)
294  m_gameImage->Load();
295  if (m_fanartImage)
296  m_fanartImage->Load();
297  if (m_boxImage)
298  m_boxImage->Load();
299 }
300 
301 void GameUI::searchComplete(const QString& string)
302 {
304  return;
305 
307  if (!parent)
308  return;
309 
310  MythGenericTree *new_node = parent->getChildByName(string);
311  if (new_node)
312  m_gameUITree->SetCurrentNode(new_node);
313 }
314 
316 {
317  if (m_gameTitleText)
319  if (m_gameSystemText)
321  if (m_gameYearText)
322  m_gameYearText->SetText(rom->Year());
323  if (m_gameGenreText)
324  m_gameGenreText->SetText(rom->Genre());
325  if (m_gamePlotText)
326  m_gamePlotText->SetText(rom->Plot());
327 
329  {
330  if (rom->Favorite())
332  else
334  }
335 
336  if (m_gameImage)
337  {
338  m_gameImage->Reset();
340  }
341  if (m_fanartImage)
342  {
343  m_fanartImage->Reset();
345  }
346  if (m_boxImage)
347  {
348  m_boxImage->Reset();
349  m_boxImage->SetFilename(rom->Boxart());
350  }
351 }
352 
354 {
355  if (m_gameTitleText)
357  if (m_gameSystemText)
359  if (m_gameYearText)
361  if (m_gameGenreText)
363  if (m_gamePlotText)
367 
368  if (m_gameImage)
369  m_gameImage->Reset();
370 
371  if (m_fanartImage)
372  m_fanartImage->Reset();
373 
374  if (m_boxImage)
375  m_boxImage->Reset();
376 }
377 
378 void GameUI::edit(void)
379 {
381  if (isLeaf(node))
382  {
383  auto *romInfo = node->GetData().value<RomInfo *>();
384 
385  MythScreenStack *screenStack = GetScreenStack();
386 
387  auto *md_editor = new EditRomInfoDialog(screenStack,
388  "mythgameeditmetadata", romInfo);
389 
390  if (md_editor->Create())
391  {
392  screenStack->AddScreen(md_editor);
393  md_editor->SetReturnEvent(this, "editMetadata");
394  }
395  else
396  {
397  delete md_editor;
398  }
399  }
400 }
401 
403 {
405  if (isLeaf(node))
406  {
407  auto *romInfo = node->GetData().value<RomInfo *>();
408  if (!romInfo)
409  return;
411  auto *details_dialog = new GameDetailsPopup(mainStack, romInfo);
412 
413  if (details_dialog->Create())
414  {
415  mainStack->AddScreen(details_dialog);
416  details_dialog->SetReturnEvent(this, "detailsPopup");
417  }
418  else
419  {
420  delete details_dialog;
421  }
422  }
423 }
424 
426 {
428 
429  MythScreenStack *popupStack = GetMythMainWindow()->
430  GetStack("popup stack");
431  auto *showMenuPopup =
432  new MythDialogBox(node->GetText(), popupStack, "showMenuPopup");
433 
434  if (showMenuPopup->Create())
435  {
436  showMenuPopup->SetReturnEvent(this, "showMenuPopup");
437 
438  showMenuPopup->AddButton(tr("Scan For Changes"));
439  if (isLeaf(node))
440  {
441  auto *romInfo = node->GetData().value<RomInfo *>();
442  if (romInfo)
443  {
444  showMenuPopup->AddButton(tr("Show Information"));
445  if (romInfo->Favorite())
446  showMenuPopup->AddButton(tr("Remove Favorite"));
447  else
448  showMenuPopup->AddButton(tr("Make Favorite"));
449  showMenuPopup->AddButton(tr("Retrieve Details"));
450  showMenuPopup->AddButton(tr("Edit Details"));
451  }
452  }
453  popupStack->AddScreen(showMenuPopup);
454  }
455  else
456  {
457  delete showMenuPopup;
458  }
459 }
460 
462 {
464 
465  if (parent != nullptr)
466  {
467  QStringList childList;
468  QList<MythGenericTree*>::iterator it;
469  QList<MythGenericTree*> *children = parent->getAllChildren();
470 
471  for (it = children->begin(); it != children->end(); ++it)
472  {
473  MythGenericTree *child = *it;
474  childList << child->GetText();
475  }
476 
477  MythScreenStack *popupStack =
478  GetMythMainWindow()->GetStack("popup stack");
479  auto *searchDialog = new MythUISearchDialog(popupStack,
480  tr("Game Search"), childList, true, "");
481 
482  if (searchDialog->Create())
483  {
484  connect(searchDialog, &MythUISearchDialog::haveResult,
485  this, &GameUI::searchComplete);
486 
487  popupStack->AddScreen(searchDialog);
488  }
489  else
490  {
491  delete searchDialog;
492  }
493  }
494 }
495 
497 {
499  if (isLeaf(node))
500  {
501  auto *romInfo = node->GetData().value<RomInfo *>();
502  romInfo->setFavorite(true);
503  updateChangedNode(node, romInfo);
504  }
505 }
506 
507 void GameUI::customEvent(QEvent *event)
508 {
509  if (event->type() == DialogCompletionEvent::kEventType)
510  {
511  auto *dce = dynamic_cast<DialogCompletionEvent*>(event);
512  if (dce == nullptr)
513  return;
514  QString resultid = dce->GetId();
515  QString resulttext = dce->GetResultText();
516 
517  if (resultid == "showMenuPopup")
518  {
519  if (resulttext == tr("Edit Details"))
520  {
521  edit();
522  }
523  if (resulttext == tr("Scan For Changes"))
524  {
525  doScan();
526  }
527  else if (resulttext == tr("Show Information"))
528  {
529  showInfo();
530  }
531  else if (resulttext == tr("Make Favorite") ||
532  resulttext == tr("Remove Favorite"))
533  {
534  toggleFavorite();
535  }
536  else if (resulttext == tr("Retrieve Details"))
537  {
538  gameSearch();
539  }
540  }
541  else if (resultid == "chooseSystemPopup")
542  {
543  if (!resulttext.isEmpty() && resulttext != tr("Cancel"))
544  {
546  auto *romInfo = node->GetData().value<RomInfo *>();
547  GameHandler::Launchgame(romInfo, resulttext);
548  }
549  }
550  else if (resultid == "editMetadata")
551  {
553  auto *oldRomInfo = node->GetData().value<RomInfo *>();
554  delete oldRomInfo;
555 
556  auto *romInfo = dce->GetData().value<RomInfo *>();
557  node->SetData(QVariant::fromValue(romInfo));
558  node->SetText(romInfo->Gamename());
559 
560  romInfo->SaveToDatabase();
561  updateChangedNode(node, romInfo);
562  }
563  else if (resultid == "detailsPopup")
564  {
565  // Play button pushed
566  itemClicked(nullptr);
567  }
568  }
569  if (event->type() == MetadataLookupEvent::kEventType)
570  {
571  auto *lue = dynamic_cast<MetadataLookupEvent *>(event);
572  if (lue == nullptr)
573  return;
574  MetadataLookupList lul = lue->m_lookupList;
575 
576  if (m_busyPopup)
577  {
578  m_busyPopup->Close();
579  m_busyPopup = nullptr;
580  }
581 
582  if (lul.isEmpty())
583  return;
584 
585  if (lul.count() == 1)
586  {
587  OnGameSearchDone(lul[0]);
588  }
589  else
590  {
591  auto *resultsdialog =
593 
594  connect(resultsdialog, &MetadataResultsDialog::haveResult,
596  Qt::QueuedConnection);
597 
598  if (resultsdialog->Create())
599  m_popupStack->AddScreen(resultsdialog);
600  }
601  }
602  else if (event->type() == MetadataLookupFailure::kEventType)
603  {
604  auto *luf = dynamic_cast<MetadataLookupFailure *>(event);
605  if (luf == nullptr)
606  return;
607  MetadataLookupList lul = luf->m_lookupList;
608 
609  if (m_busyPopup)
610  {
611  m_busyPopup->Close();
612  m_busyPopup = nullptr;
613  }
614 
615  if (!lul.empty())
616  {
617  MetadataLookup *lookup = lul[0];
618  auto *node = lookup->GetData().value<MythGenericTree *>();
619  if (node)
620  {
621  auto *metadata = node->GetData().value<RomInfo *>();
622  if (metadata)
623  {
624  }
625  }
626  LOG(VB_GENERAL, LOG_ERR,
627  QString("No results found for %1").arg(lookup->GetTitle()));
628  }
629  }
630  else if (event->type() == ImageDLEvent::kEventType)
631  {
632  auto *ide = dynamic_cast<ImageDLEvent *>(event);
633  if (ide == nullptr)
634  return;
635  MetadataLookup *lookup = ide->m_item;
636 
637  if (!lookup)
638  return;
639 
640  handleDownloadedImages(lookup);
641  }
642  else if (event->type() == ImageDLFailureEvent::kEventType)
643  {
644  MythErrorNotification n(tr("Failed to retrieve image(s)"),
645  sLocation,
646  tr("Check logs"));
648  }
649 }
650 
652 {
653  QString layer = node->GetText();
654  int childDepth = node->getInt() + 1;
655  QString childLevel = getChildLevelString(node);
656  QString filter = getFilter(node);
657  bool childIsLeaf = childDepth == getLevelsOnThisBranch(node) + 1;
658  auto *romInfo = node->GetData().value<RomInfo *>();
659 
660  if (childLevel.isEmpty())
661  childLevel = "gamename";
662 
663  QString columns;
664  QString conj = "where ";
665 
666  if (!filter.isEmpty())
667  {
668  filter = conj + filter;
669  conj = " and ";
670  }
671  if ((childLevel == "gamename") && (m_gameShowFileName))
672  {
673  columns = childIsLeaf
674  ? "romname,`system`,year,genre,gamename"
675  : "romname";
676 
677  if (m_showHashed)
678  filter += " and romname like '" + layer + "%'";
679 
680  }
681  else if ((childLevel == "gamename") && (layer.length() == 1))
682  {
683  columns = childIsLeaf
684  ? childLevel + ",`system`,year,genre,gamename"
685  : childLevel;
686 
687  if (m_showHashed)
688  filter += " and gamename like '" + layer + "%'";
689 
690  }
691  else if (childLevel == "hash")
692  {
693  columns = "left(gamename,1)";
694  }
695  else
696  {
697 
698  columns = childIsLeaf
699  ? childLevel + ",`system`,year,genre,gamename"
700  : childLevel;
701  }
702 
703  // this whole section ought to be in rominfo.cpp really, but I've put it
704  // in here for now to minimise the number of files changed by this mod
705  if (romInfo)
706  {
707  if (!romInfo->System().isEmpty())
708  {
709  filter += conj + "trim(system)=:SYSTEM";
710  conj = " and ";
711  }
712  if (!romInfo->Year().isEmpty())
713  {
714  filter += conj + "year=:YEAR";
715  conj = " and ";
716  }
717  if (!romInfo->Genre().isEmpty())
718  {
719  filter += conj + "trim(genre)=:GENRE";
720  conj = " and ";
721  }
722  if (!romInfo->Plot().isEmpty())
723  {
724  filter += conj + "plot=:PLOT";
725  conj = " and ";
726  }
727  if (!romInfo->Publisher().isEmpty())
728  {
729  filter += conj + "publisher=:PUBLISHER";
730  conj = " and ";
731  }
732  if (!romInfo->Gamename().isEmpty())
733  {
734  filter += conj + "trim(gamename)=:GAMENAME";
735  }
736 
737  }
738 
739  filter += conj + " display = 1 ";
740 
741  QString sql;
742 
743  if ((childLevel == "gamename") && (m_gameShowFileName))
744  {
745  sql = "select distinct "
746  + columns
747  + " from gamemetadata "
748  + filter
749  + " order by romname"
750  + ";";
751  }
752  else if (childLevel == "hash")
753  {
754  sql = "select distinct "
755  + columns
756  + " from gamemetadata "
757  + filter
758  + " order by gamename,romname"
759  + ";";
760  }
761  else
762  {
763  sql = "select distinct "
764  + columns
765  + " from gamemetadata "
766  + filter
767  + " order by "
768  + childLevel
769  + ";";
770  }
771 
772  return sql;
773 }
774 
776 {
777  unsigned this_level = node->getInt();
778  while (node->getInt() != 1)
779  node = node->getParent();
780 
781  auto *gi = node->GetData().value<GameTreeInfo *>();
782  return gi ? gi->getLevel(this_level - 1) : "<invalid>";
783 }
784 
786 {
787  while (node->getInt() != 1)
788  node = node->getParent();
789  auto *gi = node->GetData().value<GameTreeInfo *>();
790  return gi ? gi->getFilter() : "<invalid>";
791 }
792 
794 {
795  while (node->getInt() != 1)
796  node = node->getParent();
797 
798  auto *gi = node->GetData().value<GameTreeInfo *>();
799  return gi ? gi->getDepth() : 0;
800 }
801 
803 {
804  return (node->getInt() - 1) == getLevelsOnThisBranch(node);
805 }
806 
808 {
809 // QString layername = node->GetText();
810  auto *romInfo = node->GetData().value<RomInfo *>();
811 
812  MSqlQuery query(MSqlQuery::InitCon());
813 
814  query.prepare(getFillSql(node));
815 
816  if (romInfo)
817  {
818  if (!romInfo->System().isEmpty())
819  query.bindValue(":SYSTEM", romInfo->System());
820  if (!romInfo->Year().isEmpty())
821  query.bindValue(":YEAR", romInfo->Year());
822  if (!romInfo->Genre().isEmpty())
823  query.bindValue(":GENRE", romInfo->Genre());
824  if (!romInfo->Plot().isEmpty())
825  query.bindValue(":PLOT", romInfo->Plot());
826  if (!romInfo->Publisher().isEmpty())
827  query.bindValue(":PUBLISHER", romInfo->Publisher());
828  if (!romInfo->Gamename().isEmpty())
829  query.bindValue(":GAMENAME", romInfo->Gamename());
830  }
831 
832  bool IsLeaf = node->getInt() == getLevelsOnThisBranch(node);
833  if (query.exec() && query.size() > 0)
834  {
835  while (query.next())
836  {
837  QString current = query.value(0).toString().trimmed();
838  auto *new_node =
839  new MythGenericTree(current, node->getInt() + 1, false);
840  if (IsLeaf)
841  {
842  auto *temp = new RomInfo();
843  temp->setSystem(query.value(1).toString().trimmed());
844  temp->setYear(query.value(2).toString());
845  temp->setGenre(query.value(3).toString().trimmed());
846  temp->setGamename(query.value(4).toString().trimmed());
847  new_node->SetData(QVariant::fromValue(temp));
848  node->addNode(new_node);
849  }
850  else
851  {
852  RomInfo *newRomInfo = nullptr;
853  if (node->getInt() > 1)
854  {
855  auto *currentRomInfo = node->GetData().value<RomInfo *>();
856  newRomInfo = new RomInfo(*currentRomInfo);
857  }
858  else
859  {
860  newRomInfo = new RomInfo();
861  }
862  new_node->SetData(QVariant::fromValue(newRomInfo));
863  node->addNode(new_node);
864  if (getChildLevelString(node) != "hash")
865  newRomInfo->setField(getChildLevelString(node), current);
866  }
867  }
868  }
869 }
870 
872 {
873  MythGenericTree *top_level = node;
874  while (top_level->getParent() != m_gameTree)
875  {
876  top_level = top_level->getParent();
877  }
878 
879  QList<MythGenericTree*>::iterator it;
880  QList<MythGenericTree*> *children = m_gameTree->getAllChildren();
881 
882  for (it = children->begin(); it != children->end(); ++it)
883  {
884  MythGenericTree *child = *it;
885  if (child != top_level)
886  {
887  child->deleteAllChildren();
888  }
889  }
890 }
891 
893 {
894  resetOtherTrees(node);
895 
896  if (node->getParent() == m_favouriteNode && !romInfo->Favorite())
897  {
898  // node is being removed
900  }
901  else
902  {
903  nodeChanged(node);
904  }
905 }
906 
908  bool automode)
909 {
910  if (!node)
911  node = m_gameUITree->GetCurrentNode();
912 
913  if (!node)
914  return;
915 
916  auto *metadata = node->GetData().value<RomInfo *>();
917  if (!metadata)
918  return;
919 
920  auto *lookup = new MetadataLookup();
921  lookup->SetStep(kLookupSearch);
922  lookup->SetType(kMetadataGame);
923  lookup->SetData(QVariant::fromValue(node));
924 
925  if (automode)
926  {
927  lookup->SetAutomatic(true);
928  }
929 
930  lookup->SetTitle(metadata->Gamename());
931  lookup->SetInetref(metadata->Inetref());
932  if (m_query->isRunning())
933  m_query->prependLookup(lookup);
934  else
935  m_query->addLookup(lookup);
936 
937  if (!automode)
938  {
939  //: %1 is the game name
940  QString msg = tr("Fetching details for %1")
941  .arg(metadata->Gamename());
942  createBusyDialog(msg);
943  }
944 }
945 
946 void GameUI::createBusyDialog(const QString& title)
947 {
948  if (m_busyPopup)
949  return;
950 
951  const QString& message = title;
952 
954  "mythgamebusydialog");
955 
956  if (m_busyPopup->Create())
958 }
959 
961 {
962  if (!lookup)
963  return;
964 
965  lookup->SetStep(kLookupData);
966  lookup->IncrRef();
967  m_query->prependLookup(lookup);
968 }
969 
971 {
972  if (m_busyPopup)
973  {
974  m_busyPopup->Close();
975  m_busyPopup = nullptr;
976  }
977 
978  if (!lookup)
979  return;
980 
981  auto *node = lookup->GetData().value<MythGenericTree *>();
982  if (!node)
983  return;
984 
985  auto *metadata = node->GetData().value<RomInfo *>();
986  if (!metadata)
987  return;
988 
989  metadata->setGamename(lookup->GetTitle());
990  metadata->setYear(QString::number(lookup->GetYear()));
991  metadata->setPlot(lookup->GetDescription());
992  metadata->setSystem(lookup->GetSystem());
993 
994  QStringList coverart;
995  QStringList fanart;
996  QStringList screenshot;
997 
998  // Imagery
999  ArtworkList coverartlist = lookup->GetArtwork(kArtworkCoverart);
1000  for (const auto & art : std::as_const(coverartlist))
1001  coverart.prepend(art.url);
1002  ArtworkList fanartlist = lookup->GetArtwork(kArtworkFanart);
1003  for (const auto & art : std::as_const(fanartlist))
1004  fanart.prepend(art.url);
1005  ArtworkList screenshotlist = lookup->GetArtwork(kArtworkScreenshot);
1006  for (const auto & art : std::as_const(screenshotlist))
1007  screenshot.prepend(art.url);
1008 
1009  StartGameImageSet(node, coverart, fanart, screenshot);
1010 
1011  metadata->SaveToDatabase();
1012  updateChangedNode(node, metadata);
1013 }
1014 
1015 void GameUI::StartGameImageSet(MythGenericTree *node, QStringList coverart,
1016  QStringList fanart, QStringList screenshot)
1017 {
1018  if (!node)
1019  return;
1020 
1021  auto *metadata = node->GetData().value<RomInfo *>();
1022  if (!metadata)
1023  return;
1024 
1025  DownloadMap map;
1026 
1027  if (metadata->Boxart().isEmpty() && !coverart.empty())
1028  {
1029  ArtworkInfo info;
1030  info.url = coverart.takeAt(0).trimmed();
1031  map.insert(kArtworkCoverart, info);
1032  }
1033 
1034  if (metadata->Fanart().isEmpty() && !fanart.empty())
1035  {
1036  ArtworkInfo info;
1037  info.url = fanart.takeAt(0).trimmed();
1038  map.insert(kArtworkFanart, info);
1039  }
1040 
1041  if (metadata->Screenshot().isEmpty() && !screenshot.empty())
1042  {
1043  ArtworkInfo info;
1044  info.url = screenshot.takeAt(0).trimmed();
1045  map.insert(kArtworkScreenshot, info);
1046  }
1047 
1048  auto *lookup = new MetadataLookup();
1049  lookup->SetTitle(metadata->Gamename());
1050  lookup->SetSystem(metadata->System());
1051  lookup->SetInetref(metadata->Inetref());
1052  lookup->SetType(kMetadataGame);
1053  lookup->SetDownloads(map);
1054  lookup->SetData(QVariant::fromValue(node));
1055 
1056  m_imageDownload->addDownloads(lookup);
1057 }
1058 
1060 {
1061  if (!lookup)
1062  return;
1063 
1064  auto *node = lookup->GetData().value<MythGenericTree *>();
1065  if (!node)
1066  return;
1067 
1068  auto *metadata = node->GetData().value<RomInfo *>();
1069  if (!metadata)
1070  return;
1071 
1072  DownloadMap downloads = lookup->GetDownloads();
1073 
1074  if (downloads.isEmpty())
1075  return;
1076 
1077  for (DownloadMap::iterator i = downloads.begin();
1078  i != downloads.end(); ++i)
1079  {
1080  VideoArtworkType type = i.key();
1081  const ArtworkInfo& info = i.value();
1082  QString filename = info.url;
1083 
1084  if (type == kArtworkCoverart)
1085  metadata->setBoxart(filename);
1086  else if (type == kArtworkFanart)
1087  metadata->setFanart(filename);
1088  else if (type == kArtworkScreenshot)
1089  metadata->setScreenshot(filename);
1090  }
1091 
1092  metadata->SaveToDatabase();
1093  updateChangedNode(node, metadata);
1094 }
1095 
1097 {
1098  if (!m_scanner)
1099  m_scanner = new GameScanner();
1101  m_scanner->doScanAll();
1102 }
1103 
1104 void GameUI::reloadAllData(bool dbChanged)
1105 {
1106  delete m_scanner;
1107  m_scanner = nullptr;
1108 
1109  if (dbChanged)
1110  BuildTree();
1111 }
1112 
GameScanner::doScanAll
void doScanAll(void)
Definition: gamescan.cpp:232
RomInfo::Boxart
QString Boxart() const
Definition: rominfo.h:69
GameUI::getFillSql
QString getFillSql(MythGenericTree *node) const
Definition: gameui.cpp:651
GameUI::m_popupStack
MythScreenStack * m_popupStack
Definition: gameui.h:80
GameUI::isLeaf
static bool isLeaf(MythGenericTree *node)
Definition: gameui.cpp:802
mythuibuttontree.h
mythuimetadataresults.h
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:317
GameTreeInfo::m_filter
QString m_filter
Definition: gameui.cpp:43
MythUISearchDialog
Provide a dialog to quickly find an entry in a list.
Definition: mythdialogbox.h:399
GameUI::customEvent
void customEvent(QEvent *event) override
Definition: gameui.cpp:507
RefCountHandler
Definition: referencecounterlist.h:17
GameUI::getChildLevelString
static QString getChildLevelString(MythGenericTree *node)
Definition: gameui.cpp:775
mythuitext.h
MythGenericTree::SetData
void SetData(QVariant data)
Definition: mythgenerictree.h:97
GameTreeInfo::GameTreeInfo
GameTreeInfo(const QString &levels, QString filter)
Definition: gameui.cpp:31
DialogCompletionEvent::GetId
QString GetId()
Definition: mythdialogbox.h:52
MythUIText::Reset
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuitext.cpp:65
MetadataImageDownload
Definition: metadataimagedownload.h:87
MythGenericTree::GetText
QString GetText(const QString &name="") const
Definition: mythgenerictree.cpp:555
GameUI::createBusyDialog
void createBusyDialog(const QString &title)
Definition: gameui.cpp:946
RomInfo::Plot
QString Plot() const
Definition: rominfo.h:102
GameUI::ShowMenu
void ShowMenu(void) override
Definition: gameui.cpp:425
GameUI::nodeChanged
void nodeChanged(MythGenericTree *node)
Definition: gameui.cpp:216
MetadataLookup::GetTitle
QString GetTitle() const
Definition: metadatacommon.h:299
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:383
RomInfo::Gamename
QString Gamename() const
Definition: rominfo.h:78
MetadataResultsDialog
Definition: mythuimetadataresults.h:10
GameUI::m_gameYearText
MythUIText * m_gameYearText
Definition: gameui.h:85
GameUI::edit
void edit(void)
Definition: gameui.cpp:378
GameUI
Definition: gameui.h:25
RomInfo::Favorite
bool Favorite() const
Definition: rominfo.h:117
ArtworkList
QList< ArtworkInfo > ArtworkList
Definition: metadataimagehelper.h:30
EditRomInfoDialog
Definition: romedit.h:9
kLookupData
@ kLookupData
Definition: metadatacommon.h:29
GameTreeInfo::m_levels
QStringList m_levels
Definition: gameui.cpp:42
GameTreeInfo::getDepth
int getDepth() const
Definition: gameui.cpp:37
GameUI::StartGameImageSet
void StartGameImageSet(MythGenericTree *node, QStringList coverart, QStringList fanart, QStringList screenshot)
Definition: gameui.cpp:1015
GameTreeInfo::getLevel
const QString & getLevel(unsigned i) const
Definition: gameui.cpp:38
MythUIImage::Load
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
Definition: mythuiimage.cpp:971
MetadataDownload::prependLookup
void prependLookup(MetadataLookup *lookup)
prependLookup: Add lookup to top of the queue MetadataDownload::m_lookupList takes ownership of the g...
Definition: metadatadownload.cpp:55
GameUI::m_gameUITree
MythUIButtonTree * m_gameUITree
Definition: gameui.h:82
MythGenericTree::getInt
int getInt() const
Definition: mythgenerictree.h:73
MythUISearchDialog::haveResult
void haveResult(QString)
MythUIBusyDialog::Create
bool Create(void) override
Definition: mythprogressdialog.cpp:32
romedit.h
GameUI::m_scanner
GameScanner * m_scanner
Definition: gameui.h:96
mythdialogbox.h
MythScreenStack
Definition: mythscreenstack.h:16
GameScanner
Definition: gamescan.h:71
MythGenericTree::GetData
QVariant GetData(void) const
Definition: mythgenerictree.h:98
RomInfo::Genre
QString Genre() const
Definition: rominfo.h:81
MythUIButtonTree::SetCurrentNode
bool SetCurrentNode(MythGenericTree *node)
Set the currently selected node.
Definition: mythuibuttontree.cpp:348
MythGenericTree::getChildByName
MythGenericTree * getChildByName(const QString &a_name) const
Definition: mythgenerictree.cpp:377
ImageDLEvent
Definition: metadataimagedownload.h:18
MetadataDownload
Definition: metadatadownload.h:35
MetadataLookup::GetArtwork
ArtworkList GetArtwork(VideoArtworkType type) const
Definition: metadatacommon.cpp:331
GameUI::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: gameui.cpp:181
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
mythuistatetype.h
GameUI::itemClicked
void itemClicked(MythUIButtonListItem *item)
Definition: gameui.cpp:253
MythUIStateType::Reset
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuistatetype.cpp:197
GameUI::doScan
void doScan(void)
Definition: gameui.cpp:1096
mythdirs.h
MythUIImage::Reset
void Reset(void) override
Reset the image back to the default defined in the theme.
Definition: mythuiimage.cpp:644
RomInfo::System
QString System() const
Definition: rominfo.h:75
MythUIButtonTree::AssignTree
bool AssignTree(MythGenericTree *tree)
Assign the root node of the tree to be displayed.
Definition: mythuibuttontree.cpp:213
GameTreeInfo
Definition: gameui.cpp:28
GameUI::searchComplete
void searchComplete(const QString &string)
Definition: gameui.cpp:301
GameUI::m_gameTree
MythGenericTree * m_gameTree
Definition: gameui.h:76
mythuiimage.h
gamescan.h
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:15
VideoArtworkType
VideoArtworkType
Definition: metadataimagehelper.h:10
sLocation
static const QString sLocation
Definition: gameui.cpp:26
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:110
GameUI::m_gamePlotText
MythUIText * m_gamePlotText
Definition: gameui.h:87
MetadataLookup
Definition: metadatacommon.h:87
kArtworkScreenshot
@ kArtworkScreenshot
Definition: metadataimagehelper.h:14
MythGenericTree::addNode
MythGenericTree * addNode(const QString &a_string, int an_int=0, bool selectable_flag=false, bool visible=true)
Definition: mythgenerictree.cpp:85
MythUIButtonListItem
Definition: mythuibuttonlist.h:41
MythUIButtonTree::itemClicked
void itemClicked(MythUIButtonListItem *item)
MetadataLookup::GetDownloads
DownloadMap GetDownloads() const
Definition: metadatacommon.h:372
GameUI::updateChangedNode
void updateChangedNode(MythGenericTree *node, RomInfo *romInfo)
Definition: gameui.cpp:892
kArtworkCoverart
@ kArtworkCoverart
Definition: metadataimagehelper.h:11
RomInfo::Screenshot
QString Screenshot() const
Definition: rominfo.h:63
kLookupSearch
@ kLookupSearch
Definition: metadatacommon.h:28
GameUI::m_gameImage
MythUIImage * m_gameImage
Definition: gameui.h:89
RomInfo::fillData
void fillData()
Definition: rominfo.cpp:247
GameUI::gameSearch
void gameSearch(MythGenericTree *node=nullptr, bool automode=false)
Definition: gameui.cpp:907
kArtworkFanart
@ kArtworkFanart
Definition: metadataimagehelper.h:12
GameUI::reloadAllData
void reloadAllData(bool dbchanged)
Definition: gameui.cpp:1104
MetadataLookup::GetDescription
QString GetDescription() const
Definition: metadatacommon.h:312
Q_DECLARE_METATYPE
Q_DECLARE_METATYPE(std::chrono::seconds)
MythMainWindow::TranslateKeyPress
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
Definition: mythmainwindow.cpp:1111
MetadataLookupFailure
Definition: metadatadownload.h:23
ArtworkInfo
Definition: metadataimagehelper.h:21
RomInfo::setGamename
void setGamename(const QString &lgamename)
Definition: rominfo.h:79
RefCountedList< MetadataLookup >
MythDialogBox
Basic menu dialog, message and a list of options.
Definition: mythdialogbox.h:166
MetadataLookup::GetData
QVariant GetData() const
Definition: metadatacommon.h:288
ImageDLFailureEvent::kEventType
static const Type kEventType
Definition: metadataimagedownload.h:67
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:550
GameUI::OnGameSearchDone
void OnGameSearchDone(MetadataLookup *lookup)
Definition: gameui.cpp:970
GameHandler::getHandler
static GameHandler * getHandler(uint i)
Definition: gamehandler.cpp:54
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:203
GameScanner::finished
void finished(bool)
MythGenericTree::childCount
int childCount(void) const
Definition: mythgenerictree.cpp:254
MythErrorNotification
Definition: mythnotification.h:198
GameUI::m_gameGenreText
MythUIText * m_gameGenreText
Definition: gameui.h:86
GameUI::OnGameSearchListSelection
void OnGameSearchListSelection(RefCountHandler< MetadataLookup > lookup)
Definition: gameui.cpp:960
ImageDLEvent::kEventType
static const Type kEventType
Definition: metadataimagedownload.h:41
RomInfo::setFavorite
void setFavorite(bool updateDatabase=false)
Definition: rominfo.cpp:213
rominfo.h
mythgenerictree.h
MythUIBusyDialog
Definition: mythprogressdialog.h:36
MetadataDownload::addLookup
void addLookup(MetadataLookup *lookup)
addLookup: Add lookup to bottom of the queue MetadataDownload::m_lookupList takes ownership of the gi...
Definition: metadatadownload.cpp:40
MetadataLookup::GetYear
uint GetYear() const
Definition: metadatacommon.h:349
MythGenericTree::deleteAllChildren
void deleteAllChildren()
Definition: mythgenerictree.cpp:453
GameUI::handleDownloadedImages
void handleDownloadedImages(MetadataLookup *lookup)
Definition: gameui.cpp:1059
MythUIButtonTree::GetCurrentNode
MythGenericTree * GetCurrentNode(void) const
Definition: mythuibuttontree.h:32
GameUI::showInfo
void showInfo(void)
Definition: gameui.cpp:402
GameUI::m_busyPopup
MythUIBusyDialog * m_busyPopup
Definition: gameui.h:79
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
MythScreenType::GetScreenStack
MythScreenStack * GetScreenStack() const
Definition: mythscreentype.cpp:214
MythGenericTree::getAllChildren
QList< MythGenericTree * > * getAllChildren() const
Definition: mythgenerictree.cpp:276
UIUtilDisp::Assign
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
MetadataLookupFailure::kEventType
static const Type kEventType
Definition: metadatadownload.h:32
GameDetailsPopup
Definition: gamedetails.h:13
GameUI::m_gameShowFileName
bool m_gameShowFileName
Definition: gameui.h:74
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:910
RomInfo
Definition: rominfo.h:14
MetadataLookup::GetSystem
QString GetSystem() const
Definition: metadatacommon.h:346
MetadataResultsDialog::haveResult
void haveResult(RefCountHandler< MetadataLookup >)
GameUI::m_gameSystemText
MythUIText * m_gameSystemText
Definition: gameui.h:84
kMetadataGame
@ kMetadataGame
Definition: metadatacommon.h:46
GameUI::m_gameTitleText
MythUIText * m_gameTitleText
Definition: gameui.h:83
MythUIButtonTree::Reset
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuibuttontree.cpp:236
MythScreenType::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythscreentype.cpp:401
RomInfo::Fanart
QString Fanart() const
Definition: rominfo.h:66
GameHandler::SystemName
QString SystemName() const
Definition: gamehandler.h:105
GameUI::m_fanartImage
MythUIImage * m_fanartImage
Definition: gameui.h:90
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:701
MythGenericTree::getParent
MythGenericTree * getParent(void) const
Definition: mythgenerictree.cpp:370
GameUI::m_query
MetadataDownload * m_query
Definition: gameui.h:93
DialogCompletionEvent
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:41
GameUI::Create
bool Create() override
Definition: gameui.cpp:56
MythGenericTree
Definition: mythgenerictree.h:27
GameUI::showImages
void showImages(void)
Definition: gameui.cpp:291
GameUI::m_imageDownload
MetadataImageDownload * m_imageDownload
Definition: gameui.h:94
GameUI::m_gameFavouriteState
MythUIStateType * m_gameFavouriteState
Definition: gameui.h:88
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:115
GetNotificationCenter
MythNotificationCenter * GetNotificationCenter(void)
Definition: mythmainwindow.cpp:124
mythcontext.h
DialogCompletionEvent::kEventType
static const Type kEventType
Definition: mythdialogbox.h:57
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
MThread::isRunning
bool isRunning(void) const
Definition: mthread.cpp:263
GameHandler::Launchgame
static void Launchgame(RomInfo *romdata, const QString &systemname)
Definition: gamehandler.cpp:824
GameUI::resetOtherTrees
void resetOtherTrees(MythGenericTree *node)
Definition: gameui.cpp:871
GameUI::clearRomInfo
void clearRomInfo(void)
Definition: gameui.cpp:353
build_compdb.action
action
Definition: build_compdb.py:9
GameUI::m_favouriteNode
MythGenericTree * m_favouriteNode
Definition: gameui.h:77
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:322
DownloadMap
QMap< VideoArtworkType, ArtworkInfo > DownloadMap
Definition: metadatacommon.h:84
GameUI::getFilter
static QString getFilter(MythGenericTree *node)
Definition: gameui.cpp:785
GameUI::getLevelsOnThisBranch
static int getLevelsOnThisBranch(MythGenericTree *node)
Definition: gameui.cpp:793
MetadataLookupEvent::kEventType
static const Type kEventType
Definition: metadatadownload.h:20
azlyrics.info
dictionary info
Definition: azlyrics.py:7
MythGenericTree::SetText
void SetText(const QString &text, const QString &name="", const QString &state="")
Definition: mythgenerictree.cpp:517
gameui.h
RomInfo::setField
void setField(const QString &field, const QString &data)
Definition: rominfo.cpp:172
GameUI::BuildTree
void BuildTree()
Definition: gameui.cpp:94
GameUI::m_showHashed
bool m_showHashed
Definition: gameui.h:73
GameTreeInfo::getFilter
const QString & getFilter() const
Definition: gameui.cpp:39
MythUIImage::SetFilename
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
Definition: mythuiimage.cpp:677
GameUI::searchStart
void searchStart(void)
Definition: gameui.cpp:461
ReferenceCounter::IncrRef
virtual int IncrRef(void)
Increments reference count.
Definition: referencecounter.cpp:101
build_compdb.filename
filename
Definition: build_compdb.py:21
mythmainwindow.h
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
GameUI::toggleFavorite
void toggleFavorite(void)
Definition: gameui.cpp:496
MetadataLookupEvent
Definition: metadatadownload.h:11
gamehandler.h
MetadataLookup::SetStep
void SetStep(LookupStep step)
Definition: metadatacommon.h:244
RomInfo::Year
QString Year() const
Definition: rominfo.h:111
GameUI::fillNode
void fillNode(MythGenericTree *node)
Definition: gameui.cpp:807
gamedetails.h
MythUIStateType::DisplayState
bool DisplayState(const QString &name)
Definition: mythuistatetype.cpp:84
MythUIButtonTree::nodeChanged
void nodeChanged(MythGenericTree *node)
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:902
GameHandler::count
static uint count(void)
Definition: gamehandler.cpp:96
GameUI::m_boxImage
MythUIImage * m_boxImage
Definition: gameui.h:91
MetadataImageDownload::addDownloads
void addDownloads(MetadataLookup *lookup)
addLookup: Add lookup to bottom of the queue MetadataDownload::m_downloadList takes ownership of the ...
Definition: metadataimagedownload.cpp:54
GameUI::updateRomInfo
void updateRomInfo(RomInfo *rom)
Definition: gameui.cpp:315
MythNotificationCenter::Queue
bool Queue(const MythNotification &notification)
Queue a notification Queue() is thread-safe and can be called from anywhere.
Definition: mythnotificationcenter.cpp:1349