MythTV  0.26-pre
gamescan.cpp
Go to the documentation of this file.
00001 #include <QImageReader>
00002 #include <QApplication>
00003 #include <QThread>
00004 #include <QStringList>
00005 #include <QUrl>
00006 
00007 #include <mythcontext.h>
00008 #include <mythscreenstack.h>
00009 #include <mythprogressdialog.h>
00010 #include <mythdialogbox.h>
00011 #include <mythevent.h>
00012 #include <remoteutil.h>
00013 #include <mythlogging.h>
00014 
00015 #include "gamescan.h"
00016 #include "gamehandler.h"
00017 #include "rominfo.h"
00018 
00019 class MythUIProgressDialog;
00020 
00021 GameScannerThread::GameScannerThread(QObject *parent) :
00022     MThread("GameScanner"), m_parent(parent),
00023     m_HasGUI(gCoreContext->HasGUI()),
00024     m_dialog(NULL), m_DBDataChanged(false)
00025 {
00026 }
00027 
00028 GameScannerThread::~GameScannerThread()
00029 {
00030 }
00031 
00032 void GameScannerThread::run(void)
00033 {
00034     RunProlog();
00035 
00036     LOG(VB_GENERAL, LOG_INFO, QString("Beginning Game Scan."));
00037 
00038     m_files.clear();
00039     m_remove.clear();
00040     m_dbgames = RomInfo::GetAllRomInfo();
00041 
00042     buildFileList();
00043     verifyFiles();
00044     updateDB();
00045 
00046     RunEpilog();
00047 }
00048 
00049 
00050 void GameScannerThread::removeOrphan(const int id)
00051 {
00052     RomInfo *info = RomInfo::GetRomInfoById(id);
00053     if (info)
00054     {
00055         info->DeleteFromDatabase();
00056         delete info;
00057         info = NULL;
00058     }
00059 }
00060 
00061 void GameScannerThread::verifyFiles()
00062 {
00063     int counter = 0;
00064 
00065     if (m_HasGUI)
00066         SendProgressEvent(counter, (uint)m_dbgames.count(),
00067                           GameScanner::tr("Verifying game files..."));
00068 
00069     // For every file we know about, check to see if it still exists.
00070     for (QList<RomInfo*>::iterator p = m_dbgames.begin();
00071              p != m_dbgames.end(); ++p)
00072     {
00073         RomInfo *info = *p;
00074         QString romfile = info->Romname();
00075         QString system = info->System();
00076         QString gametype = info->GameType();
00077         if (!romfile.isEmpty())
00078         {
00079             bool found = false;
00080             for (QList<RomFileInfo>::iterator p = m_files.begin();
00081                                      p != m_files.end(); ++p)
00082             {
00083                 if ((*p).romfile == romfile &&
00084                     (*p).gametype == gametype)
00085                 {
00086                     // We're done here, this file matches one in the DB
00087                     (*p).indb = true;
00088                     found = true;
00089                     continue;
00090                 }
00091             }
00092             if (!found)
00093             {
00094                 m_remove.append(info->Id());
00095             }
00096         }
00097         if (m_HasGUI)
00098             SendProgressEvent(++counter);
00099 
00100         delete info;
00101         info = NULL;
00102     }
00103 }
00104 
00105 void GameScannerThread::updateDB()
00106 {
00107     uint counter = 0;
00108     if (m_HasGUI)
00109         SendProgressEvent(counter, (uint)(m_files.size() + m_remove.size()),
00110                           GameScanner::tr("Updating game database..."));
00111 
00112     for (QList<RomFileInfo>::iterator p = m_files.begin();
00113                                  p != m_files.end(); ++p)
00114     {
00115         if (!(*p).indb)
00116         {
00117             RomInfo *add = new RomInfo(0, (*p).romfile, (*p).system,
00118                                (*p).romname, "", "", "", (*p).rompath,
00119                                "", "", 0, (*p).gametype, 0, "", "", "",
00120                                "", "", "", "", "");
00121             add->SaveToDatabase();
00122             m_DBDataChanged = true;
00123         }
00124         if (m_HasGUI)
00125             SendProgressEvent(++counter);
00126     }
00127 
00128     for (QList<uint>::iterator p = m_remove.begin();
00129                                  p != m_remove.end(); ++p)
00130     {
00131         removeOrphan(*p);
00132         m_DBDataChanged = true;
00133     }
00134 }
00135 
00136 bool GameScannerThread::buildFileList()
00137 {
00138     if (m_handlers.size() == 0)
00139         return false;
00140 
00141     int counter = 0;
00142 
00143     if (m_HasGUI)
00144         SendProgressEvent(counter, (uint)m_handlers.size(),
00145                           GameScanner::tr("Searching for games..."));
00146 
00147     for (QList<GameHandler*>::const_iterator iter = m_handlers.begin();
00148          iter != m_handlers.end(); ++iter)
00149     {
00150         QDir dir((*iter)->SystemRomPath());
00151         QStringList extensions = (*iter)->ValidExtensions();
00152         QStringList filters;
00153         for (QStringList::iterator i = extensions.begin();
00154              i != extensions.end(); ++i)
00155         {
00156             filters.append(QString("*.%1").arg(*i));
00157         }
00158 
00159         dir.setNameFilters(filters);
00160         dir.setFilter(QDir::Files | QDir::Readable | QDir::NoDotAndDotDot);
00161 
00162         QStringList files = dir.entryList();
00163         for (QStringList::iterator i = files.begin();
00164              i != files.end(); ++i)
00165         {
00166             RomFileInfo info;
00167             info.system = (*iter)->SystemName();
00168             info.gametype = (*iter)->GameType();
00169             info.romfile = *i;
00170             info.rompath = (*iter)->SystemRomPath();
00171             info.romname = QFileInfo(*i).baseName();
00172             info.indb = false;
00173             m_files.append(info);
00174         }
00175 
00176         if (m_HasGUI)
00177             SendProgressEvent(++counter);
00178     }
00179 
00180     return true;
00181 }
00182 
00183 void GameScannerThread::SendProgressEvent(uint progress, uint total,
00184                                            QString messsage)
00185 {
00186     if (!m_dialog)
00187         return;
00188 
00189     ProgressUpdateEvent *pue = new ProgressUpdateEvent(progress, total,
00190                                                        messsage);
00191     QApplication::postEvent(m_dialog, pue);
00192 }
00193 
00194 GameScanner::GameScanner()
00195 {
00196     m_scanThread = new GameScannerThread(this);
00197 }
00198 
00199 GameScanner::~GameScanner()
00200 {
00201     if (m_scanThread && m_scanThread->wait())
00202         delete m_scanThread;
00203 }
00204 
00205 void GameScanner::doScan(QList<GameHandler*> handlers)
00206 {
00207     if (m_scanThread->isRunning())
00208         return;
00209 
00210     if (gCoreContext->HasGUI())
00211     {
00212         MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00213 
00214         MythUIProgressDialog *progressDlg = new MythUIProgressDialog("",
00215                 popupStack, "gamescanprogressdialog");
00216 
00217         if (progressDlg->Create())
00218         {
00219             popupStack->AddScreen(progressDlg, false);
00220             connect(m_scanThread->qthread(), SIGNAL(finished()),
00221                     progressDlg, SLOT(Close()));
00222             connect(m_scanThread->qthread(), SIGNAL(finished()),
00223                     SLOT(finishedScan()));
00224         }
00225         else
00226         {
00227             delete progressDlg;
00228             progressDlg = NULL;
00229         }
00230         m_scanThread->SetProgressDialog(progressDlg);
00231     }
00232 
00233     m_scanThread->SetHandlers(handlers);
00234     m_scanThread->start();
00235 }
00236 
00237 void GameScanner::doScanAll()
00238 {
00239     QList<GameHandler*> hlist;
00240 
00241     MSqlQuery query(MSqlQuery::InitCon());
00242     query.prepare("SELECT DISTINCT playername FROM gameplayers "
00243                     "WHERE playername <> '';");
00244 
00245     if (!query.exec())
00246         MythDB::DBError("doScanAll - selecting playername", query);
00247 
00248     while (query.next())
00249     {
00250         QString name = query.value(0).toString();
00251         GameHandler *hnd = GameHandler::GetHandlerByName(name);
00252         if (hnd)
00253             hlist.append(hnd);
00254     }
00255 
00256     doScan(hlist);
00257 }
00258 
00259 void GameScanner::finishedScan()
00260 {
00261     emit finished(m_scanThread->getDataChanged());
00262 }
00263 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends