00001 #include <QStringList>
00002 #include <QMetaType>
00003 #include <QTimer>
00004
00005 #include <mythcontext.h>
00006 #include <mythuibuttontree.h>
00007 #include <metadata/mythuimetadataresults.h>
00008 #include <mythuiimage.h>
00009 #include <mythuitext.h>
00010 #include <mythuistatetype.h>
00011 #include <mythmainwindow.h>
00012 #include <mythdialogbox.h>
00013 #include <mythgenerictree.h>
00014 #include <mythdirs.h>
00015
00016
00017 #include "gamehandler.h"
00018 #include "rominfo.h"
00019 #include "gamedetails.h"
00020 #include "romedit.h"
00021 #include "gamescan.h"
00022 #include "gameui.h"
00023
00024 class GameTreeInfo
00025 {
00026 public:
00027 GameTreeInfo(const QString& levels, const QString& filter)
00028 : m_levels(levels.split(" "))
00029 , m_filter(filter)
00030 {
00031 }
00032
00033 int getDepth() const { return m_levels.size(); }
00034 const QString& getLevel(unsigned i) const { return m_levels[i]; }
00035 const QString& getFilter() const { return m_filter; }
00036
00037 private:
00038 QStringList m_levels;
00039 QString m_filter;
00040 };
00041
00042 Q_DECLARE_METATYPE(GameTreeInfo *)
00043
00044 GameUI::GameUI(MythScreenStack *parent)
00045 : MythScreenType(parent, "GameUI"),
00046 m_showHashed(false), m_gameShowFileName(0),
00047 m_gameTree(NULL), m_favouriteNode(NULL),
00048 m_busyPopup(0),
00049 m_gameUITree(NULL), m_gameTitleText(NULL),
00050 m_gameSystemText(NULL), m_gameYearText(NULL),
00051 m_gameGenreText(NULL), m_gamePlotText(NULL),
00052 m_gameFavouriteState(NULL), m_gameImage(NULL),
00053 m_fanartImage(NULL), m_boxImage(NULL),
00054 m_scanner(NULL)
00055 {
00056 m_popupStack = GetMythMainWindow()->GetStack("popup stack");
00057
00058 m_query = new MetadataDownload(this);
00059 m_imageDownload = new MetadataImageDownload(this);
00060 }
00061
00062 GameUI::~GameUI()
00063 {
00064 }
00065
00066 bool GameUI::Create()
00067 {
00068 if (!LoadWindowFromXML("game-ui.xml", "gameui", this))
00069 return false;
00070
00071 bool err = false;
00072 UIUtilE::Assign(this, m_gameUITree, "gametreelist", &err);
00073 UIUtilW::Assign(this, m_gameTitleText, "title");
00074 UIUtilW::Assign(this, m_gameSystemText, "system");
00075 UIUtilW::Assign(this, m_gameYearText, "year");
00076 UIUtilW::Assign(this, m_gameGenreText, "genre");
00077 UIUtilW::Assign(this, m_gameFavouriteState, "favorite");
00078 UIUtilW::Assign(this, m_gamePlotText, "description");
00079 UIUtilW::Assign(this, m_gameImage, "screenshot");
00080 UIUtilW::Assign(this, m_fanartImage, "fanart");
00081 UIUtilW::Assign(this, m_boxImage, "coverart");
00082
00083 if (err)
00084 {
00085 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'gameui'");
00086 return false;
00087 }
00088
00089 connect(m_gameUITree, SIGNAL(itemClicked(MythUIButtonListItem*)),
00090 this, SLOT(itemClicked(MythUIButtonListItem*)));
00091
00092 connect(m_gameUITree, SIGNAL(nodeChanged(MythGenericTree*)),
00093 this, SLOT(nodeChanged(MythGenericTree*)));
00094
00095 m_gameShowFileName = gCoreContext->GetSetting("GameShowFileNames").toInt();
00096
00097 Load();
00098
00099 BuildFocusList();
00100
00101 return true;
00102 }
00103
00104 void GameUI::Load()
00105 {
00106 m_gameTree = new MythGenericTree("game root", 0, false);
00107
00108
00109 QString systemFilter;
00110
00111
00112
00113 unsigned handlercount = GameHandler::count();
00114
00115 for (unsigned i = 0; i < handlercount; ++i)
00116 {
00117 QString system = GameHandler::getHandler(i)->SystemName();
00118 if (i == 0)
00119 systemFilter = "system in ('" + system + "'";
00120 else
00121 systemFilter += ",'" + system + "'";
00122 }
00123 if (systemFilter.isEmpty())
00124 {
00125 systemFilter = "1=0";
00126 LOG(VB_GENERAL, LOG_ERR, QString("Couldn't find any game handlers!"));
00127 }
00128 else
00129 systemFilter += ")";
00130
00131 m_showHashed = gCoreContext->GetSetting("GameTreeView").toInt();
00132
00133
00134
00135
00136
00137 QString levels = gCoreContext->GetSetting("GameFavTreeLevels");
00138
00139 MythGenericTree *new_node = new MythGenericTree(tr("Favorites"), 1, true);
00140 new_node->SetData(qVariantFromValue(
00141 new GameTreeInfo(levels, systemFilter + " and favorite=1")));
00142 m_favouriteNode = m_gameTree->addNode(new_node);
00143
00144 levels = gCoreContext->GetSetting("GameAllTreeLevels");
00145
00146 if (m_showHashed)
00147 {
00148 int pos = levels.indexOf("gamename");
00149 if (pos >= 0)
00150 levels.insert(pos, " hash ");
00151 }
00152
00153 new_node = new MythGenericTree(tr("All Games"), 1, true);
00154 new_node->SetData(qVariantFromValue(
00155 new GameTreeInfo(levels, systemFilter)));
00156 m_gameTree->addNode(new_node);
00157
00158 new_node = new MythGenericTree(tr("- By Genre"), 1, true);
00159 new_node->SetData(qVariantFromValue(
00160 new GameTreeInfo("genre gamename", systemFilter)));
00161 m_gameTree->addNode(new_node);
00162
00163 new_node = new MythGenericTree(tr("- By Year"), 1, true);
00164 new_node->SetData(qVariantFromValue(
00165 new GameTreeInfo("year gamename", systemFilter)));
00166 m_gameTree->addNode(new_node);
00167
00168 new_node = new MythGenericTree(tr("- By Name"), 1, true);
00169 new_node->SetData(qVariantFromValue(
00170 new GameTreeInfo("gamename", systemFilter)));
00171 m_gameTree->addNode(new_node);
00172
00173 new_node = new MythGenericTree(tr("- By Publisher"), 1, true);
00174 new_node->SetData(qVariantFromValue(
00175 new GameTreeInfo("publisher gamename", systemFilter)));
00176 m_gameTree->addNode(new_node);
00177
00178 m_gameUITree->AssignTree(m_gameTree);
00179 }
00180
00181 bool GameUI::keyPressEvent(QKeyEvent *event)
00182 {
00183 if (GetFocusWidget()->keyPressEvent(event))
00184 return true;
00185
00186 bool handled = false;
00187 QStringList actions;
00188 handled = GetMythMainWindow()->TranslateKeyPress("Game", event, actions);
00189
00190 for (int i = 0; i < actions.size() && !handled; i++)
00191 {
00192 QString action = actions[i];
00193 handled = true;
00194
00195 if (action == "MENU")
00196 showMenu();
00197 else if (action == "EDIT")
00198 edit();
00199 else if (action == "INFO")
00200 showInfo();
00201 else if (action == "TOGGLEFAV")
00202 toggleFavorite();
00203 else if (action == "INCSEARCH")
00204 searchStart();
00205 else if (action == "INCSEARCHNEXT")
00206 searchStart();
00207 else if (action == "DOWNLOADDATA")
00208 gameSearch();
00209 else
00210 handled = false;
00211 }
00212
00213 if (!handled && MythScreenType::keyPressEvent(event))
00214 handled = true;
00215
00216 return handled;
00217 }
00218
00219 void GameUI::nodeChanged(MythGenericTree* node)
00220 {
00221 if (!node)
00222 return;
00223
00224 if (!isLeaf(node))
00225 {
00226 if (node->childCount() == 0 || node == m_favouriteNode)
00227 {
00228 node->deleteAllChildren();
00229 fillNode(node);
00230 }
00231 clearRomInfo();
00232 }
00233 else
00234 {
00235 RomInfo *romInfo = qVariantValue<RomInfo *>(node->GetData());
00236 if (!romInfo)
00237 return;
00238 if (romInfo->Romname().isEmpty())
00239 romInfo->fillData();
00240 updateRomInfo(romInfo);
00241 if (!romInfo->Screenshot().isEmpty() || !romInfo->Fanart().isEmpty() ||
00242 !romInfo->Boxart().isEmpty())
00243 showImages();
00244 else
00245 {
00246 if (m_gameImage)
00247 m_gameImage->Reset();
00248 if (m_fanartImage)
00249 m_fanartImage->Reset();
00250 if (m_boxImage)
00251 m_boxImage->Reset();
00252 }
00253 }
00254 }
00255
00256 void GameUI::itemClicked(MythUIButtonListItem*)
00257 {
00258 MythGenericTree *node = m_gameUITree->GetCurrentNode();
00259 if (isLeaf(node))
00260 {
00261 RomInfo *romInfo = qVariantValue<RomInfo *>(node->GetData());
00262 if (!romInfo)
00263 return;
00264 if (romInfo->RomCount() == 1)
00265 {
00266 GameHandler::Launchgame(romInfo, NULL);
00267 }
00268 else
00269 {
00270 QString msg = tr("Choose System for") +
00271 ":\n" + node->getString();
00272 MythScreenStack *popupStack = GetMythMainWindow()->
00273 GetStack("popup stack");
00274 MythDialogBox *chooseSystemPopup = new MythDialogBox(
00275 msg, popupStack, "chooseSystemPopup");
00276
00277 if (chooseSystemPopup->Create())
00278 {
00279 chooseSystemPopup->SetReturnEvent(this, "chooseSystemPopup");
00280 QString all_systems = romInfo->AllSystems();
00281 QStringList players = all_systems.split(",");
00282 for (QStringList::Iterator it = players.begin();
00283 it != players.end(); ++it)
00284 {
00285 chooseSystemPopup->AddButton(*it);
00286 }
00287 chooseSystemPopup->AddButton(tr("Cancel"));
00288 popupStack->AddScreen(chooseSystemPopup);
00289 }
00290 else
00291 delete chooseSystemPopup;
00292 }
00293 }
00294 }
00295
00296 void GameUI::showImages(void)
00297 {
00298 if (m_gameImage)
00299 m_gameImage->Load();
00300 if (m_fanartImage)
00301 m_fanartImage->Load();
00302 if (m_boxImage)
00303 m_boxImage->Load();
00304 }
00305
00306 void GameUI::searchComplete(QString string)
00307 {
00308 if (!m_gameUITree->GetCurrentNode())
00309 return;
00310
00311 MythGenericTree *parent = m_gameUITree->GetCurrentNode()->getParent();
00312 if (!parent)
00313 return;
00314
00315 MythGenericTree *new_node = parent->getChildByName(string);
00316 if (new_node)
00317 m_gameUITree->SetCurrentNode(new_node);
00318 }
00319
00320 void GameUI::updateRomInfo(RomInfo *rom)
00321 {
00322 if (m_gameTitleText)
00323 m_gameTitleText->SetText(rom->Gamename());
00324 if (m_gameSystemText)
00325 m_gameSystemText->SetText(rom->System());
00326 if (m_gameYearText)
00327 m_gameYearText->SetText(rom->Year());
00328 if (m_gameGenreText)
00329 m_gameGenreText->SetText(rom->Genre());
00330 if (m_gamePlotText)
00331 m_gamePlotText->SetText(rom->Plot());
00332
00333 if (m_gameFavouriteState)
00334 {
00335 if (rom->Favorite())
00336 m_gameFavouriteState->DisplayState("yes");
00337 else
00338 m_gameFavouriteState->DisplayState("no");
00339 }
00340
00341 if (m_gameImage)
00342 {
00343 m_gameImage->Reset();
00344 m_gameImage->SetFilename(rom->Screenshot());
00345 }
00346 if (m_fanartImage)
00347 {
00348 m_fanartImage->Reset();
00349 m_fanartImage->SetFilename(rom->Fanart());
00350 }
00351 if (m_boxImage)
00352 {
00353 m_boxImage->Reset();
00354 m_boxImage->SetFilename(rom->Boxart());
00355 }
00356 }
00357
00358 void GameUI::clearRomInfo(void)
00359 {
00360 if (m_gameTitleText)
00361 m_gameTitleText->Reset();
00362 if (m_gameSystemText)
00363 m_gameSystemText->Reset();
00364 if (m_gameYearText)
00365 m_gameYearText->Reset();
00366 if (m_gameGenreText)
00367 m_gameGenreText->Reset();
00368 if (m_gamePlotText)
00369 m_gamePlotText->Reset();
00370 if (m_gameFavouriteState)
00371 m_gameFavouriteState->Reset();
00372
00373 if (m_gameImage)
00374 m_gameImage->Reset();
00375
00376 if (m_fanartImage)
00377 m_fanartImage->Reset();
00378
00379 if (m_boxImage)
00380 m_boxImage->Reset();
00381 }
00382
00383 void GameUI::edit(void)
00384 {
00385 MythGenericTree *node = m_gameUITree->GetCurrentNode();
00386 if (isLeaf(node))
00387 {
00388 RomInfo *romInfo = qVariantValue<RomInfo *>(node->GetData());
00389
00390 MythScreenStack *screenStack = GetScreenStack();
00391
00392 EditRomInfoDialog *md_editor = new EditRomInfoDialog(screenStack,
00393 "mythgameeditmetadata", romInfo);
00394
00395 if (md_editor->Create())
00396 {
00397 screenStack->AddScreen(md_editor);
00398 md_editor->SetReturnEvent(this, "editMetadata");
00399 }
00400 else
00401 delete md_editor;
00402 }
00403 }
00404
00405 void GameUI::showInfo()
00406 {
00407 MythGenericTree *node = m_gameUITree->GetCurrentNode();
00408 if (isLeaf(node))
00409 {
00410 RomInfo *romInfo = qVariantValue<RomInfo *>(node->GetData());
00411 if (!romInfo)
00412 return;
00413 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00414 GameDetailsPopup *details_dialog =
00415 new GameDetailsPopup(mainStack, romInfo);
00416
00417 if (details_dialog->Create())
00418 {
00419 mainStack->AddScreen(details_dialog);
00420 details_dialog->SetReturnEvent(this, "detailsPopup");
00421 }
00422 else
00423 delete details_dialog;
00424 }
00425 }
00426
00427 void GameUI::showMenu()
00428 {
00429 MythGenericTree *node = m_gameUITree->GetCurrentNode();
00430
00431 MythScreenStack *popupStack = GetMythMainWindow()->
00432 GetStack("popup stack");
00433 MythDialogBox *showMenuPopup =
00434 new MythDialogBox(node->getString(), popupStack, "showMenuPopup");
00435
00436 if (showMenuPopup->Create())
00437 {
00438 showMenuPopup->SetReturnEvent(this, "showMenuPopup");
00439
00440 showMenuPopup->AddButton(tr("Scan For Changes"));
00441 if (isLeaf(node))
00442 {
00443 RomInfo *romInfo = qVariantValue<RomInfo *>(node->GetData());
00444 if (romInfo)
00445 {
00446 showMenuPopup->AddButton(tr("Show Information"));
00447 if (romInfo->Favorite())
00448 showMenuPopup->AddButton(tr("Remove Favorite"));
00449 else
00450 showMenuPopup->AddButton(tr("Make Favorite"));
00451 showMenuPopup->AddButton(tr("Retrieve Details"));
00452 showMenuPopup->AddButton(tr("Edit Details"));
00453 }
00454 }
00455 popupStack->AddScreen(showMenuPopup);
00456 }
00457 else
00458 delete showMenuPopup;
00459 }
00460
00461 void GameUI::searchStart(void)
00462 {
00463 MythGenericTree *parent = m_gameUITree->GetCurrentNode()->getParent();
00464
00465 if (parent != NULL)
00466 {
00467 QStringList childList;
00468 QList<MythGenericTree*>::iterator it;
00469 QList<MythGenericTree*> *children = parent->getAllChildren();
00470
00471 for (it = children->begin(); it != children->end(); ++it)
00472 {
00473 MythGenericTree *child = *it;
00474 childList << child->getString();
00475 }
00476
00477 MythScreenStack *popupStack =
00478 GetMythMainWindow()->GetStack("popup stack");
00479 MythUISearchDialog *searchDialog = new MythUISearchDialog(popupStack,
00480 tr("Game Search"), childList, true, "");
00481
00482 if (searchDialog->Create())
00483 {
00484 connect(searchDialog, SIGNAL(haveResult(QString)),
00485 SLOT(searchComplete(QString)));
00486
00487 popupStack->AddScreen(searchDialog);
00488 }
00489 else
00490 delete searchDialog;
00491 }
00492 }
00493
00494 void GameUI::toggleFavorite(void)
00495 {
00496 MythGenericTree *node = m_gameUITree->GetCurrentNode();
00497 if (isLeaf(node))
00498 {
00499 RomInfo *romInfo = qVariantValue<RomInfo *>(node->GetData());
00500 romInfo->setFavorite(true);
00501 updateChangedNode(node, romInfo);
00502 }
00503 }
00504
00505 void GameUI::customEvent(QEvent *event)
00506 {
00507 if (event->type() == DialogCompletionEvent::kEventType)
00508 {
00509 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
00510
00511 QString resultid = dce->GetId();
00512 QString resulttext = dce->GetResultText();
00513
00514 if (resultid == "showMenuPopup")
00515 {
00516 if (resulttext == tr("Edit Details"))
00517 {
00518 edit();
00519 }
00520 if (resulttext == tr("Scan For Changes"))
00521 {
00522 doScan();
00523 }
00524 else if (resulttext == tr("Show Information"))
00525 {
00526 showInfo();
00527 }
00528 else if (resulttext == tr("Make Favorite") ||
00529 resulttext == tr("Remove Favorite"))
00530 {
00531 toggleFavorite();
00532 }
00533 else if (resulttext == tr("Retrieve Details"))
00534 {
00535 gameSearch();
00536 }
00537 }
00538 else if (resultid == "chooseSystemPopup")
00539 {
00540 if (!resulttext.isEmpty() && resulttext != tr("Cancel"))
00541 {
00542 MythGenericTree *node = m_gameUITree->GetCurrentNode();
00543 RomInfo *romInfo = qVariantValue<RomInfo *>(node->GetData());
00544 GameHandler::Launchgame(romInfo, resulttext);
00545 }
00546 }
00547 else if (resultid == "editMetadata")
00548 {
00549 MythGenericTree *node = m_gameUITree->GetCurrentNode();
00550 RomInfo *oldRomInfo = qVariantValue<RomInfo *>(node->GetData());
00551 delete oldRomInfo;
00552
00553 RomInfo *romInfo = qVariantValue<RomInfo *>(dce->GetData());
00554 node->SetData(qVariantFromValue(romInfo));
00555 node->setString(romInfo->Gamename());
00556
00557 romInfo->SaveToDatabase();
00558 updateChangedNode(node, romInfo);
00559 }
00560 else if (resultid == "detailsPopup")
00561 {
00562
00563 itemClicked(0);
00564 }
00565 }
00566 if (event->type() == MetadataLookupEvent::kEventType)
00567 {
00568 MetadataLookupEvent *lue = (MetadataLookupEvent *)event;
00569
00570 MetadataLookupList lul = lue->lookupList;
00571
00572 if (m_busyPopup)
00573 {
00574 m_busyPopup->Close();
00575 m_busyPopup = NULL;
00576 }
00577
00578 if (lul.isEmpty())
00579 return;
00580
00581 if (lul.count() == 1)
00582 {
00583 OnGameSearchDone(lul.takeFirst());
00584 }
00585 else
00586 {
00587 MetadataResultsDialog *resultsdialog =
00588 new MetadataResultsDialog(m_popupStack, lul);
00589
00590 connect(resultsdialog, SIGNAL(haveResult(MetadataLookup*)),
00591 SLOT(OnGameSearchListSelection(MetadataLookup*)),
00592 Qt::QueuedConnection);
00593
00594 if (resultsdialog->Create())
00595 m_popupStack->AddScreen(resultsdialog);
00596 }
00597 }
00598 else if (event->type() == MetadataLookupFailure::kEventType)
00599 {
00600 MetadataLookupFailure *luf = (MetadataLookupFailure *)event;
00601
00602 MetadataLookupList lul = luf->lookupList;
00603
00604 if (m_busyPopup)
00605 {
00606 m_busyPopup->Close();
00607 m_busyPopup = NULL;
00608 }
00609
00610 if (lul.size())
00611 {
00612 MetadataLookup *lookup = lul.takeFirst();
00613 MythGenericTree *node = qVariantValue<MythGenericTree *>(lookup->GetData());
00614 if (node)
00615 {
00616 RomInfo *metadata = qVariantValue<RomInfo *>(node->GetData());
00617 if (metadata)
00618 {
00619 }
00620 }
00621 LOG(VB_GENERAL, LOG_ERR,
00622 QString("No results found for %1").arg(lookup->GetTitle()));
00623 }
00624 }
00625 else if (event->type() == ImageDLEvent::kEventType)
00626 {
00627 ImageDLEvent *ide = (ImageDLEvent *)event;
00628
00629 MetadataLookup *lookup = ide->item;
00630
00631 if (!lookup)
00632 return;
00633
00634 handleDownloadedImages(lookup);
00635 }
00636 }
00637
00638 QString GameUI::getFillSql(MythGenericTree *node) const
00639 {
00640 QString layer = node->getString();
00641 int childDepth = node->getInt() + 1;
00642 QString childLevel = getChildLevelString(node);
00643 QString filter = getFilter(node);
00644 bool childIsLeaf = childDepth == getLevelsOnThisBranch(node) + 1;
00645 RomInfo *romInfo = qVariantValue<RomInfo *>(node->GetData());
00646
00647 QString columns;
00648 QString conj = "where ";
00649
00650 if (!filter.isEmpty())
00651 {
00652 filter = conj + filter;
00653 conj = " and ";
00654 }
00655 if ((childLevel == "gamename") && (m_gameShowFileName))
00656 {
00657 columns = childIsLeaf
00658 ? "romname,system,year,genre,gamename"
00659 : "romname";
00660
00661 if (m_showHashed)
00662 filter += " and romname like '" + layer + "%'";
00663
00664 }
00665 else if ((childLevel == "gamename") && (layer.length() == 1))
00666 {
00667 columns = childIsLeaf
00668 ? childLevel + ",system,year,genre,gamename"
00669 : childLevel;
00670
00671 if (m_showHashed)
00672 filter += " and gamename like '" + layer + "%'";
00673
00674 }
00675 else if (childLevel == "hash")
00676 {
00677 columns = "left(gamename,1)";
00678 }
00679 else
00680 {
00681
00682 columns = childIsLeaf
00683 ? childLevel + ",system,year,genre,gamename"
00684 : childLevel;
00685 }
00686
00687
00688
00689 if (romInfo)
00690 {
00691 if (!romInfo->System().isEmpty())
00692 {
00693 filter += conj + "trim(system)=:SYSTEM";
00694 conj = " and ";
00695 }
00696 if (!romInfo->Year().isEmpty())
00697 {
00698 filter += conj + "year=:YEAR";
00699 conj = " and ";
00700 }
00701 if (!romInfo->Genre().isEmpty())
00702 {
00703 filter += conj + "trim(genre)=:GENRE";
00704 conj = " and ";
00705 }
00706 if (!romInfo->Plot().isEmpty())
00707 {
00708 filter += conj + "plot=:PLOT";
00709 conj = " and ";
00710 }
00711 if (!romInfo->Publisher().isEmpty())
00712 {
00713 filter += conj + "publisher=:PUBLISHER";
00714 conj = " and ";
00715 }
00716 if (!romInfo->Gamename().isEmpty())
00717 {
00718 filter += conj + "trim(gamename)=:GAMENAME";
00719 }
00720
00721 }
00722
00723 filter += conj + " display = 1 ";
00724
00725 QString sql;
00726
00727 if ((childLevel == "gamename") && (m_gameShowFileName))
00728 {
00729 sql = "select distinct "
00730 + columns
00731 + " from gamemetadata "
00732 + filter
00733 + " order by romname"
00734 + ";";
00735 }
00736 else if (childLevel == "hash")
00737 {
00738 sql = "select distinct "
00739 + columns
00740 + " from gamemetadata "
00741 + filter
00742 + " order by gamename,romname"
00743 + ";";
00744 }
00745 else
00746 {
00747 sql = "select distinct "
00748 + columns
00749 + " from gamemetadata "
00750 + filter
00751 + " order by "
00752 + childLevel
00753 + ";";
00754 }
00755
00756 return sql;
00757 }
00758
00759 QString GameUI::getChildLevelString(MythGenericTree *node) const
00760 {
00761 unsigned this_level = node->getInt();
00762 while (node->getInt() != 1)
00763 node = node->getParent();
00764
00765 GameTreeInfo *gi = qVariantValue<GameTreeInfo *>(node->GetData());
00766 return gi->getLevel(this_level - 1);
00767 }
00768
00769 QString GameUI::getFilter(MythGenericTree *node) const
00770 {
00771 while (node->getInt() != 1)
00772 node = node->getParent();
00773 GameTreeInfo *gi = qVariantValue<GameTreeInfo *>(node->GetData());
00774 return gi->getFilter();
00775 }
00776
00777 int GameUI::getLevelsOnThisBranch(MythGenericTree *node) const
00778 {
00779 while (node->getInt() != 1)
00780 node = node->getParent();
00781
00782 GameTreeInfo *gi = qVariantValue<GameTreeInfo *>(node->GetData());
00783 return gi->getDepth();
00784 }
00785
00786 bool GameUI::isLeaf(MythGenericTree *node) const
00787 {
00788 return (node->getInt() - 1) == getLevelsOnThisBranch(node);
00789 }
00790
00791 void GameUI::fillNode(MythGenericTree *node)
00792 {
00793 QString layername = node->getString();
00794 RomInfo *romInfo = qVariantValue<RomInfo *>(node->GetData());
00795
00796 MSqlQuery query(MSqlQuery::InitCon());
00797
00798 query.prepare(getFillSql(node));
00799
00800 if (romInfo)
00801 {
00802 if (!romInfo->System().isEmpty())
00803 query.bindValue(":SYSTEM", romInfo->System());
00804 if (!romInfo->Year().isEmpty())
00805 query.bindValue(":YEAR", romInfo->Year());
00806 if (!romInfo->Genre().isEmpty())
00807 query.bindValue(":GENRE", romInfo->Genre());
00808 if (!romInfo->Plot().isEmpty())
00809 query.bindValue(":PLOT", romInfo->Plot());
00810 if (!romInfo->Publisher().isEmpty())
00811 query.bindValue(":PUBLISHER", romInfo->Publisher());
00812 if (!romInfo->Gamename().isEmpty())
00813 query.bindValue(":GAMENAME", romInfo->Gamename());
00814 }
00815
00816 bool IsLeaf = node->getInt() == getLevelsOnThisBranch(node);
00817 if (query.exec() && query.size() > 0)
00818 {
00819 while (query.next())
00820 {
00821 QString current = query.value(0).toString().trimmed();
00822 MythGenericTree *new_node =
00823 new MythGenericTree(current, node->getInt() + 1, false);
00824 if (IsLeaf)
00825 {
00826 RomInfo *temp = new RomInfo();
00827 temp->setSystem(query.value(1).toString().trimmed());
00828 temp->setYear(query.value(2).toString());
00829 temp->setGenre(query.value(3).toString().trimmed());
00830 temp->setGamename(query.value(4).toString().trimmed());
00831 new_node->SetData(qVariantFromValue(temp));
00832 node->addNode(new_node);
00833 }
00834 else
00835 {
00836 RomInfo *newRomInfo;
00837 if (node->getInt() > 1)
00838 {
00839 RomInfo *currentRomInfo;
00840 currentRomInfo = qVariantValue<RomInfo *>(node->GetData());
00841 newRomInfo = new RomInfo(*currentRomInfo);
00842 }
00843 else
00844 {
00845 newRomInfo = new RomInfo();
00846 }
00847 new_node->SetData(qVariantFromValue(newRomInfo));
00848 node->addNode(new_node);
00849 if (getChildLevelString(node) != "hash")
00850 newRomInfo->setField(getChildLevelString(node), current);
00851 }
00852 }
00853 }
00854 }
00855
00856 void GameUI::resetOtherTrees(MythGenericTree *node)
00857 {
00858 MythGenericTree *top_level = node;
00859 while (top_level->getParent() != m_gameTree)
00860 {
00861 top_level = top_level->getParent();
00862 }
00863
00864 QList<MythGenericTree*>::iterator it;
00865 QList<MythGenericTree*> *children = m_gameTree->getAllChildren();
00866
00867 for (it = children->begin(); it != children->end(); ++it)
00868 {
00869 MythGenericTree *child = *it;
00870 if (child != top_level)
00871 {
00872 child->deleteAllChildren();
00873 }
00874 }
00875 }
00876
00877 void GameUI::updateChangedNode(MythGenericTree *node, RomInfo *romInfo)
00878 {
00879 resetOtherTrees(node);
00880
00881 if (node->getParent() == m_favouriteNode && romInfo->Favorite() == 0) {
00882
00883 m_gameUITree->SetCurrentNode(m_favouriteNode);
00884 }
00885 else
00886 nodeChanged(node);
00887 }
00888
00889 void GameUI::gameSearch(MythGenericTree *node,
00890 bool automode)
00891 {
00892 if (!node)
00893 node = m_gameUITree->GetCurrentNode();
00894
00895 if (!node)
00896 return;
00897
00898 RomInfo *metadata = qVariantValue<RomInfo *>(node->GetData());
00899
00900 if (!metadata)
00901 return;
00902
00903 MetadataLookup *lookup = new MetadataLookup();
00904 lookup->SetStep(kLookupSearch);
00905 lookup->SetType(kMetadataGame);
00906 lookup->SetData(qVariantFromValue(node));
00907
00908 if (automode)
00909 {
00910 lookup->SetAutomatic(true);
00911 }
00912
00913 lookup->SetTitle(metadata->Gamename());
00914 lookup->SetInetref(metadata->Inetref());
00915 if (m_query->isRunning())
00916 m_query->prependLookup(lookup);
00917 else
00918 m_query->addLookup(lookup);
00919
00920 if (!automode)
00921 {
00922 QString msg = tr("Fetching details for %1")
00923 .arg(metadata->Gamename());
00924 createBusyDialog(msg);
00925 }
00926 }
00927
00928 void GameUI::createBusyDialog(QString title)
00929 {
00930 if (m_busyPopup)
00931 return;
00932
00933 QString message = title;
00934
00935 m_busyPopup = new MythUIBusyDialog(message, m_popupStack,
00936 "mythgamebusydialog");
00937
00938 if (m_busyPopup->Create())
00939 m_popupStack->AddScreen(m_busyPopup);
00940 }
00941
00942 void GameUI::OnGameSearchListSelection(MetadataLookup *lookup)
00943 {
00944 if (!lookup)
00945 return;
00946
00947 lookup->SetStep(kLookupData);
00948 m_query->prependLookup(lookup);
00949 }
00950
00951 void GameUI::OnGameSearchDone(MetadataLookup *lookup)
00952 {
00953 if (m_busyPopup)
00954 {
00955 m_busyPopup->Close();
00956 m_busyPopup = NULL;
00957 }
00958
00959 if (!lookup)
00960 return;
00961
00962 MythGenericTree *node = qVariantValue<MythGenericTree *>(lookup->GetData());
00963
00964 if (!node)
00965 return;
00966
00967 RomInfo *metadata = qVariantValue<RomInfo *>(node->GetData());
00968
00969 if (!metadata)
00970 return;
00971
00972 metadata->setGamename(lookup->GetTitle());
00973 metadata->setYear(QString::number(lookup->GetYear()));
00974 metadata->setPlot(lookup->GetDescription());
00975 metadata->setSystem(lookup->GetSystem());
00976
00977 QStringList coverart, fanart, screenshot;
00978
00979
00980 ArtworkList coverartlist = lookup->GetArtwork(kArtworkCoverart);
00981 for (ArtworkList::const_iterator p = coverartlist.begin();
00982 p != coverartlist.end(); ++p)
00983 {
00984 coverart.prepend((*p).url);
00985 }
00986 ArtworkList fanartlist = lookup->GetArtwork(kArtworkFanart);
00987 for (ArtworkList::const_iterator p = fanartlist.begin();
00988 p != fanartlist.end(); ++p)
00989 {
00990 fanart.prepend((*p).url);
00991 }
00992 ArtworkList screenshotlist = lookup->GetArtwork(kArtworkScreenshot);
00993 for (ArtworkList::const_iterator p = screenshotlist.begin();
00994 p != screenshotlist.end(); ++p)
00995 {
00996 screenshot.prepend((*p).url);
00997 }
00998
00999 StartGameImageSet(node, coverart, fanart, screenshot);
01000
01001 metadata->SaveToDatabase();
01002 updateChangedNode(node, metadata);
01003 }
01004
01005 void GameUI::StartGameImageSet(MythGenericTree *node, QStringList coverart,
01006 QStringList fanart, QStringList screenshot)
01007 {
01008 if (!node)
01009 return;
01010
01011 RomInfo *metadata = qVariantValue<RomInfo *>(node->GetData());
01012
01013 if (!metadata)
01014 return;
01015
01016 ArtworkMap map;
01017
01018 QString inetref = metadata->Inetref();
01019 QString system = metadata->System();
01020 QString title = metadata->Gamename();
01021
01022 if (metadata->Boxart().isEmpty() && coverart.size())
01023 {
01024 ArtworkInfo info;
01025 info.url = coverart.takeAt(0).trimmed();
01026 map.insert(kArtworkCoverart, info);
01027 }
01028
01029 if (metadata->Fanart().isEmpty() && fanart.size())
01030 {
01031 ArtworkInfo info;
01032 info.url = fanart.takeAt(0).trimmed();
01033 map.insert(kArtworkFanart, info);
01034 }
01035
01036 if (metadata->Screenshot().isEmpty() && screenshot.size())
01037 {
01038 ArtworkInfo info;
01039 info.url = screenshot.takeAt(0).trimmed();
01040 map.insert(kArtworkScreenshot, info);
01041 }
01042
01043 MetadataLookup *lookup = new MetadataLookup();
01044 lookup->SetTitle(metadata->Gamename());
01045 lookup->SetSystem(metadata->System());
01046 lookup->SetInetref(metadata->Inetref());
01047 lookup->SetType(kMetadataGame);
01048 lookup->SetDownloads(map);
01049 lookup->SetData(qVariantFromValue(node));
01050
01051 m_imageDownload->addDownloads(lookup);
01052 }
01053
01054 void GameUI::handleDownloadedImages(MetadataLookup *lookup)
01055 {
01056 if (!lookup)
01057 return;
01058
01059 MythGenericTree *node = qVariantValue<MythGenericTree *>(lookup->GetData());
01060
01061 if (!node)
01062 return;
01063
01064 RomInfo *metadata = qVariantValue<RomInfo *>(node->GetData());
01065
01066 if (!metadata)
01067 return;
01068
01069 DownloadMap downloads = lookup->GetDownloads();
01070
01071 if (downloads.isEmpty())
01072 return;
01073
01074 for (DownloadMap::iterator i = downloads.begin();
01075 i != downloads.end(); ++i)
01076 {
01077 VideoArtworkType type = i.key();
01078 ArtworkInfo info = i.value();
01079 QString filename = info.url;
01080
01081 if (type == kArtworkCoverart)
01082 metadata->setBoxart(filename);
01083 else if (type == kArtworkFanart)
01084 metadata->setFanart(filename);
01085 else if (type == kArtworkScreenshot)
01086 metadata->setScreenshot(filename);
01087 }
01088
01089 metadata->SaveToDatabase();
01090 updateChangedNode(node, metadata);
01091 }
01092
01093 void GameUI::doScan()
01094 {
01095 if (!m_scanner)
01096 m_scanner = new GameScanner();
01097 connect(m_scanner, SIGNAL(finished(bool)), SLOT(reloadAllData(bool)));
01098 m_scanner->doScanAll();
01099 }
01100
01101 void GameUI::reloadAllData(bool dbChanged)
01102 {
01103 delete m_scanner;
01104 m_scanner = NULL;
01105
01106 if (dbChanged)
01107 {
01108 delete m_gameTree;
01109 m_gameTree = NULL;
01110 Load();
01111 }
01112 }
01113