MythTV  0.26-pre
gameui.cpp
Go to the documentation of this file.
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 // MythGame headers
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     //  create system filter to only select games where handlers are present
00109     QString systemFilter;
00110 
00111     // The call to GameHandler::count() fills the handler list for us
00112     // to move through.
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     //  create a few top level nodes - this could be moved to a config based
00134     //  approach with multiple roots if/when someone has the time to create
00135     //  the relevant dialog screens
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             // Play button pushed
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     //  this whole section ought to be in rominfo.cpp really, but I've put it
00688     //  in here for now to minimise the number of files changed by this mod
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         // node is being removed
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     // Imagery
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends