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