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
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
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