PageRenderTime 56ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/mamepgui/mainwindow.cpp

https://github.com/ef1105/mameplus
C++ | 1621 lines | 1264 code | 273 blank | 84 comment | 181 complexity | be59b73a1cb982e378fbfe86a4e01faa MD5 | raw file
  1. #include <QtPlugin>
  2. #include "7zVersion.h"
  3. #include "mainwindow.h"
  4. #include "prototype.h"
  5. #include "utils.h"
  6. #include "processmanager.h"
  7. #include "gamelist.h"
  8. #include "screenshot.h"
  9. #include "audit.h"
  10. #include "mameopt.h"
  11. #include "dialogs.h"
  12. #include "ips.h"
  13. #include "m1.h"
  14. #ifdef USE_SDL
  15. #undef main
  16. #include "SDL.h"
  17. #undef main
  18. #endif /* USE_SDL */
  19. //static Qt plugins
  20. #ifdef USE_STATIC
  21. Q_IMPORT_PLUGIN(qico)
  22. Q_IMPORT_PLUGIN(qjpeg)
  23. //Q_IMPORT_PLUGIN(qmng)
  24. #endif /* USE_STATIC */
  25. /* global */
  26. QString CFG_PREFIX =
  27. #ifndef Q_WS_WIN
  28. QDir::homePath() + "/" +
  29. #endif
  30. ".mamepgui/";
  31. MainWindow *win;
  32. QSettings *pGuiSettings;
  33. QSettings defaultGuiSettings(":/res/mamepgui" INI_EXT, QSettings::IniFormat);
  34. QString currentAppDir;
  35. QString mame_binary;
  36. QString language;
  37. bool local_game_list;
  38. bool isDarkBg = false;
  39. bool sdlInited = false;
  40. bool isMESS = false;
  41. bool isUME = false;
  42. QStringList validGuiSettings;
  43. #define MPGUI_VER "1.6.0"
  44. void MainWindow::log(QString message)
  45. {
  46. emit logUpdated(message);
  47. }
  48. void MainWindow::updateLog(QString message)
  49. {
  50. QString timeString = QTime::currentTime().toString("hh:mm:ss.zzz");
  51. QString msg = timeString + ": " + message;
  52. tbGUILog->append(msg);
  53. tbGUILog->horizontalScrollBar()->setValue(0);
  54. }
  55. void MainWindow::poplog(QString message)
  56. {
  57. //explicitly declare the dialog so that it can be closed by joystick
  58. pop->setText(message);
  59. pop->exec();
  60. }
  61. void MainWindow::logStatus(QString message)
  62. {
  63. if (currentAppDir != QDir::currentPath())
  64. return;
  65. labelProgress->setText(message);
  66. }
  67. void MainWindow::logStatus(GameInfo *gameInfo)
  68. {
  69. //if everything is ok, only show 1 icon
  70. //show all 6 icons otherwise
  71. static const QString prefix = ":/res/16x16/";
  72. static const QString suffix = ".png";
  73. QString statusBuffer = "";
  74. if (gameInfo->isExtRom)
  75. gameInfo = pMameDat->games[gameInfo->romof];
  76. QString statusText = utils->getStatusString (gameInfo->status);
  77. QString statusName = QT_TR_NOOP("status");
  78. labelStatus->setPixmap(QPixmap(prefix + statusName + "_" + statusText + suffix));
  79. statusBuffer += tr(qPrintable(statusName)) + ": " + Utils::tr(qPrintable(statusText)) + "\n";
  80. statusText = utils->getStatusString (gameInfo->emulation);
  81. statusName = QT_TR_NOOP("emulation");
  82. labelEmulation->setPixmap(QPixmap(prefix + statusName + "_" + statusText + suffix));
  83. statusBuffer += tr(qPrintable(statusName)) + ": " + Utils::tr(qPrintable(statusText)) + "\n";
  84. statusText = utils->getStatusString (gameInfo->color);
  85. statusName = QT_TR_NOOP("color");
  86. labelColor->setPixmap(QPixmap(prefix + statusName + "_" + statusText + suffix));
  87. statusBuffer += tr(qPrintable(statusName)) + ": " + Utils::tr(qPrintable(statusText)) + "\n";
  88. statusText = utils->getStatusString (gameInfo->sound);
  89. statusName = QT_TR_NOOP("sound");
  90. labelSound->setPixmap(QPixmap(prefix + statusName + "_" + statusText + suffix));
  91. statusBuffer += tr(qPrintable(statusName)) + ": " + Utils::tr(qPrintable(statusText)) + "\n";
  92. statusText = utils->getStatusString (gameInfo->graphic);
  93. statusName = QT_TR_NOOP("graphic");
  94. labelGraphic->setPixmap(QPixmap(prefix + statusName + "_" + statusText + suffix));
  95. statusBuffer += tr(qPrintable(statusName)) + ": " + Utils::tr(qPrintable(statusText)) + "\n";
  96. statusText = utils->getStatusString (gameInfo->savestate, true);
  97. statusName = QT_TR_NOOP("savestate");
  98. labelSavestate->setPixmap(QPixmap(prefix + statusName + "_" + statusText + suffix));
  99. statusBuffer += tr(qPrintable(statusName)) + ": " + Utils::tr(qPrintable(statusText)) + "\n";
  100. //show 2 more icons if applicable, hide otherwise
  101. labelCocktail->hide();
  102. wStatus->layout()->removeWidget(labelCocktail);
  103. if (gameInfo->cocktail != 64)
  104. {
  105. wStatus->layout()->addWidget(labelCocktail);
  106. labelCocktail->show();
  107. statusText = utils->getStatusString (gameInfo->cocktail);
  108. statusName = QT_TR_NOOP("cocktail");
  109. labelCocktail->setPixmap(QPixmap(prefix + statusName + "_" + statusText + suffix));
  110. statusBuffer += tr(qPrintable(statusName)) + ": " + Utils::tr(qPrintable(statusText)) + "\n";
  111. }
  112. labelProtection->hide();
  113. wStatus->layout()->removeWidget(labelProtection);
  114. if (gameInfo->protection != 64)
  115. {
  116. wStatus->layout()->addWidget(labelProtection);
  117. labelProtection->show();
  118. statusText = utils->getStatusString (gameInfo->protection);
  119. statusName = QT_TR_NOOP("protection");
  120. labelProtection->setPixmap(QPixmap(prefix + statusName + "_" + statusText + suffix));
  121. statusBuffer += tr(qPrintable(statusName)) + ": " + Utils::tr(qPrintable(statusText)) + "\n";
  122. }
  123. statusBuffer.chop(1);
  124. wStatus->setToolTip(statusBuffer);
  125. // setText(QString("E: %1").arg(status));
  126. }
  127. MainWindow::MainWindow(QWidget *parent) :
  128. QMainWindow(parent),
  129. dwHistory(NULL)
  130. {
  131. setupUi(this);
  132. currentAppDir = QDir::currentPath();
  133. dockCtrlNames = (QStringList()
  134. << QT_TR_NOOP("Snapshot")
  135. << QT_TR_NOOP("Flyer")
  136. << QT_TR_NOOP("Cabinet")
  137. << QT_TR_NOOP("Marquee")
  138. << QT_TR_NOOP("Title")
  139. << QT_TR_NOOP("Control Panel")
  140. << QT_TR_NOOP("PCB")
  141. << QT_TR_NOOP("History")
  142. << QT_TR_NOOP("MAMEInfo")
  143. << QT_TR_NOOP("DriverInfo")
  144. << QT_TR_NOOP("Story")
  145. << QT_TR_NOOP("Command"));
  146. #ifdef Q_OS_MAC
  147. actionDefaultOptions->setText(tr("Preferences..."));
  148. //macx font hack
  149. QFont font = QApplication::font();
  150. font.setPixelSize(13);
  151. qApp->setFont(font);
  152. #endif
  153. //setExclusive(true) for some actions
  154. QActionGroup *viewActions = new QActionGroup(this);
  155. viewActions->addAction(actionDetails);
  156. viewActions->addAction(actionGrouped);
  157. viewActions->addAction(actionLargeIcons);
  158. QActionGroup *langActions = new QActionGroup(this);
  159. langActions->addAction(actionEnglish);
  160. langActions->addAction(actionChinese_PRC);
  161. langActions->addAction(actionChinese_Taiwan);
  162. langActions->addAction(actionJapanese);
  163. langActions->addAction(actionHungarian);
  164. langActions->addAction(actionKorean);
  165. langActions->addAction(actionBrazilian);
  166. langActions->addAction(actionRussian);
  167. langActions->addAction(actionItalian);
  168. QActionGroup *bgStretchActions = new QActionGroup(this);
  169. bgStretchActions->addAction(actionBgStretch);
  170. bgStretchActions->addAction(actionBgTile);
  171. // init controls
  172. tvGameList = new GameListTreeView(centralwidget);
  173. tvGameList->setRootIsDecorated(false);
  174. tvGameList->setItemsExpandable(false);
  175. tvGameList->setFrameShape(QFrame::NoFrame);
  176. tvGameList->hide();
  177. lvGameList = new QListView(centralwidget);
  178. lvGameList->setMovement(QListView::Static);
  179. //lvGameList->setResizeMode(QListView::Adjust);
  180. lvGameList->setViewMode(QListView::IconMode);
  181. lvGameList->setIconSize(QSize(48, 48));
  182. lvGameList->setGridSize(QSize(72, 80));
  183. lvGameList->setUniformItemSizes(true);
  184. lvGameList->setWordWrap(true);
  185. // lvGameList->setTextElideMode(Qt::TextDontClip | Qt::TextWordWrap);
  186. lvGameList->setFrameShape(QFrame::NoFrame);
  187. lvGameList->hide();
  188. lineEditSearch = new QLineEdit(centralwidget);
  189. QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
  190. sizePolicy.setHorizontalStretch(0);
  191. sizePolicy.setVerticalStretch(0);
  192. sizePolicy.setHeightForWidth(lineEditSearch->sizePolicy().hasHeightForWidth());
  193. lineEditSearch->setSizePolicy(sizePolicy);
  194. lineEditSearch->setMinimumWidth(240);
  195. toolBarSearch->addWidget(lineEditSearch);
  196. btnSearch = new QToolButton(centralwidget);
  197. btnSearch->setIcon(QIcon(":/res/16x16/system-search.png"));
  198. btnSearch->setFixedWidth(24);
  199. btnSearch->setToolTip(tr("Search"));
  200. toolBarSearch->addWidget(btnSearch);
  201. btnClearSearch = new QToolButton(centralwidget);
  202. btnClearSearch->setIcon(QIcon(":/res/16x16/status_cross.png"));
  203. btnClearSearch->setFixedWidth(24);
  204. btnClearSearch->setToolTip(tr("Clear"));
  205. toolBarSearch->addWidget(btnClearSearch);
  206. labelProgress = new QLabel(statusbar);
  207. statusbar->addWidget(labelProgress);
  208. wStatus = new QWidget(statusbar);
  209. wStatus->setMaximumHeight(18);
  210. QHBoxLayout *layout = new QHBoxLayout(wStatus);
  211. layout->setMargin(0);
  212. layout->setSpacing(1);
  213. wStatus->setLayout(layout);
  214. statusbar->addPermanentWidget(wStatus);
  215. labelStatus = new QLabel(statusbar);
  216. layout->addWidget(labelStatus);
  217. labelEmulation = new QLabel(statusbar);
  218. layout->addWidget(labelEmulation);
  219. labelColor = new QLabel(statusbar);
  220. layout->addWidget(labelColor);
  221. labelSound = new QLabel(statusbar);
  222. layout->addWidget(labelSound);
  223. labelGraphic = new QLabel(statusbar);
  224. layout->addWidget(labelGraphic);
  225. labelSavestate = new QLabel(statusbar);
  226. layout->addWidget(labelSavestate);
  227. labelCocktail = new QLabel(statusbar);
  228. layout->addWidget(labelCocktail);
  229. labelProtection = new QLabel(statusbar);
  230. layout->addWidget(labelProtection);
  231. labelGameCount = new QLabel(statusbar);
  232. statusbar->addPermanentWidget(labelGameCount);
  233. progressBarGamelist = new QProgressBar(centralwidget);
  234. progressBarGamelist->setMaximumHeight(16);
  235. progressBarGamelist->hide();
  236. pop = new QMessageBox(this);
  237. pop->setObjectName("msgWarning");
  238. QAction *actionFolderList = dwFolderList->toggleViewAction();
  239. actionFolderList->setIcon(QIcon(":/res/mame32-show-tree.png"));
  240. menuShowFolders->addAction(actionFolderList);
  241. menuShowFolders->addSeparator();
  242. toolBar->insertAction(actionLargeIcons, actionFolderList);
  243. romAuditor = new RomAuditor(this);
  244. mameAuditor = new MameExeRomAuditor(this);
  245. pMameDat = new MameDat(0, 0);
  246. gameList = new Gamelist(0);
  247. optUtils = new OptionUtils(0);
  248. dirsUI = new DirsUI(this);
  249. playOptionsUI = new PlayOptionsUI(this);
  250. optionsUI = new OptionsUI(this);
  251. csvCfgUI = new CsvCfgUI(this);
  252. aboutUI = new AboutUI(this);
  253. ipsUI = new IpsUI(this);
  254. cmdUI = new CmdUI(this);
  255. #ifdef Q_OS_WIN
  256. m1Core = new M1Core(0);
  257. m1UI = new M1UI(this);
  258. #endif /* Q_OS_WIN */
  259. #ifdef USE_SDL
  260. if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE) >= 0)
  261. sdlInited = true;
  262. #endif /* USE_SDL */
  263. QTimer::singleShot(0, this, SLOT(init()));
  264. }
  265. MainWindow::~MainWindow()
  266. {
  267. #ifdef USE_SDL
  268. // if (joystick == NULL)
  269. // ;
  270. // else
  271. // SDL_JoystickClose(joystick);
  272. SDL_Quit();
  273. #endif /* USE_SDL */
  274. }
  275. void MainWindow::initHistory(int snapType)
  276. {
  277. QString title = dockCtrlNames[snapType];
  278. QDockWidget *dockWidget = new QDockWidget(this);
  279. dockWidget->setObjectName("dockWidget_" + title);
  280. dockWidget->setFeatures(QDockWidget::DockWidgetClosable|QDockWidget::DockWidgetMovable|QDockWidget::NoDockWidgetFeatures);
  281. QWidget *dockWidgetContents = new QWidget(dockWidget);
  282. dockWidgetContents->setObjectName("dockWidgetContents_" + title);
  283. QGridLayout *gridLayout = new QGridLayout(dockWidgetContents);
  284. gridLayout->setObjectName("gridLayout_" + title);
  285. gridLayout->setContentsMargins(0, 0, 0, 0);
  286. QTextBrowser * tb;
  287. if (snapType == DOCK_HISTORY)
  288. {
  289. tb = tbHistory = new QTextBrowser(dockWidgetContents);
  290. tbHistory->setOpenExternalLinks(true);
  291. }
  292. else if (snapType == DOCK_MAMEINFO)
  293. tb = tbMameinfo = new QTextBrowser(dockWidgetContents);
  294. else if (snapType == DOCK_DRIVERINFO)
  295. tb = tbDriverinfo = new QTextBrowser(dockWidgetContents);
  296. else if (snapType == DOCK_STORY)
  297. tb = tbStory = new QTextBrowser(dockWidgetContents);
  298. else
  299. tb = tbCommand = new QTextBrowser(dockWidgetContents);
  300. tb->setObjectName("textBrowser_" + title);
  301. tb->setFrameShape(QFrame::NoFrame);
  302. gridLayout->addWidget(tb);
  303. dockWidget->setWidget(dockWidgetContents);
  304. dockWidget->setWindowTitle(tr(qPrintable(title)));
  305. addDockWidget(static_cast<Qt::DockWidgetArea>(Qt::RightDockWidgetArea), dockWidget);
  306. // create tabbed history widgets
  307. if (dwHistory)
  308. tabifyDockWidget(dwHistory, dockWidget);
  309. else
  310. dwHistory = dockWidget;
  311. menuDocuments->addAction(dockWidget->toggleViewAction());
  312. dockCtrls[snapType] = dockWidget;
  313. }
  314. void MainWindow::initSnap(int snapType)
  315. {
  316. static Screenshot *dockWidget0 = NULL;
  317. Screenshot *dockWidget = new Screenshot(dockCtrlNames[snapType], this);
  318. addDockWidget(static_cast<Qt::DockWidgetArea>(Qt::RightDockWidgetArea), dockWidget);
  319. // create tabbed history widgets
  320. if (dockWidget0)
  321. tabifyDockWidget(dockWidget0, dockWidget);
  322. else
  323. dockWidget0 = dockWidget;
  324. menuPictures->addAction(dockWidget->toggleViewAction());
  325. dockCtrls[snapType] = dockWidget;
  326. }
  327. void MainWindow::init()
  328. {
  329. // Log
  330. connect(this, SIGNAL(logUpdated(QString)), this, SLOT(updateLog(QString)));
  331. enableCtrls(false);
  332. for (int i = DOCK_SNAP; i <= DOCK_PCB; i ++)
  333. initSnap(i);
  334. for (int i = DOCK_HISTORY; i <= DOCK_COMMAND; i ++)
  335. initHistory(i);
  336. ipsUI->init();
  337. // must call optUtils->init() after win, before show()
  338. optUtils->init();
  339. #ifdef Q_OS_WIN
  340. //fixme: win font hack
  341. if (language.startsWith("zh_") || language.startsWith("ja_"))
  342. {
  343. QFont font;
  344. font.setFamily("MS Gothic");
  345. font.setFixedPitch(true);
  346. tbCommand->setFont(font);
  347. // tbCommand->setLineWrapMode(QTextEdit::NoWrap);
  348. }
  349. //rearrange docks
  350. addDockWidget(static_cast<Qt::DockWidgetArea>(Qt::LeftDockWidgetArea), m1UI);
  351. tabifyDockWidget(dwFolderList, m1UI);
  352. #endif /* Q_OS_WIN */
  353. tabifyDockWidget(dwHistory, dwGUILog);
  354. //hide non popular docks by default
  355. dwGUILog->hide();
  356. for (int i = DOCK_SNAP; i < DOCK_LAST; i ++)
  357. {
  358. if (i != DOCK_SNAP
  359. && i != DOCK_TITLE
  360. && i != DOCK_HISTORY
  361. && i != DOCK_MAMEINFO)
  362. dockCtrls[i]->hide();
  363. }
  364. dwFolderList->raise();
  365. dockCtrls[DOCK_SNAP]->raise();
  366. dockCtrls[DOCK_HISTORY]->raise();
  367. /* test ini readable/writable */
  368. // mkdir for individual game settings
  369. QDir().mkpath(CFG_PREFIX);
  370. QString warnings = "";
  371. QFile iniFile(CFG_PREFIX + "mamepgui" INI_EXT);
  372. if (!iniFile.open(QIODevice::ReadWrite | QFile::Text))
  373. warnings.append(QFileInfo(iniFile).absoluteFilePath());
  374. iniFile.close();
  375. if (warnings.size() > 0)
  376. {
  377. poplog("Current user has no sufficient privilege to read/write:\n" + warnings + "\n\ncouldn't save GUI settings.");
  378. //quit the program
  379. close();
  380. return;
  381. }
  382. loadGuiSettings();
  383. if (!validateMameBinary())
  384. {
  385. //quit the program
  386. close();
  387. return;
  388. }
  389. QIcon mamepIcon(":/res/mamep_256.png");
  390. qApp->setWindowIcon(mamepIcon);
  391. trayIcon = new QSystemTrayIcon(this);
  392. trayIcon->setIcon(mamepIcon);
  393. // must init app style before background
  394. if (gui_style.isEmpty())
  395. gui_style = pGuiSettings->value("gui_style").toString();
  396. QStringList styles = QStyleFactory::keys();
  397. QActionGroup *styleActions = new QActionGroup(this);
  398. foreach (QString style, styles)
  399. {
  400. QAction* act = menuGUIStyle->addAction(style);
  401. act->setCheckable(true);
  402. if (gui_style == style)
  403. act->setChecked(true);
  404. styleActions->addAction(act);
  405. connect(act, SIGNAL(triggered()), this, SLOT(setGuiStyle()));
  406. }
  407. if (!gui_style.isEmpty())
  408. setGuiStyle(gui_style);
  409. // init background menu
  410. QString _dirpath = utils->getPath(pGuiSettings->value("background_directory", "bkground").toString());
  411. QDir dir(_dirpath);
  412. if (background_file.isEmpty())
  413. background_file = pGuiSettings->value("background_file", "bkground.png").toString();
  414. QActionGroup *bgActions = new QActionGroup(this);
  415. if (dir.exists())
  416. {
  417. QString dirpath = utils->getPath(_dirpath);
  418. QStringList nameFilter;
  419. nameFilter << "*" PNG_EXT;
  420. nameFilter << "*.jpg";
  421. // iterate all files in the path
  422. QStringList files = dir.entryList(nameFilter, QDir::Files | QDir::Readable);
  423. foreach (QString fileName, files)
  424. {
  425. QAction* act = menuBackground->addAction(fileName);
  426. act->setCheckable(true);
  427. if (background_file == fileName)
  428. act->setChecked(true);
  429. bgActions->addAction(act);
  430. connect(act, SIGNAL(triggered()), this, SLOT(setBgPixmap()));
  431. }
  432. }
  433. //show UI
  434. loadLayout();
  435. setDockOptions();
  436. //after loadLayout(), so we can check background stretch option
  437. if (!background_file.isEmpty())
  438. setBgPixmap(background_file);
  439. int des11n_status = pMameDat->load();
  440. if (des11n_status == QDataStream::Ok)
  441. {
  442. gameList->init(true, GAMELIST_INIT_FULL);
  443. setVersion();
  444. }
  445. else
  446. //des11n() failed, construct a new pMameDat
  447. {
  448. show();
  449. pTempDat = pMameDat;
  450. pMameDat = new MameDat(0, 1);
  451. }
  452. // connect misc signals and slots
  453. // Docked snapshots
  454. QList<QTabBar *> tabBars = getSSTabBars();
  455. foreach (QTabBar *tabBar, tabBars)
  456. {
  457. connect(tabBar, SIGNAL(currentChanged(int)), gameList, SLOT(updateSelection()));
  458. tabBar->setMovable(true);
  459. }
  460. connect(actionBgStretch, SIGNAL(triggered()), this, SLOT(setBgTile()));
  461. connect(actionBgTile, SIGNAL(triggered()), this, SLOT(setBgTile()));
  462. // Actions
  463. connect(actionVerticalTabs, SIGNAL(toggled(bool)), this, SLOT(setDockOptions()));
  464. connect(actionLargeIcons, SIGNAL(toggled(bool)), gameList, SLOT(init(bool)));
  465. connect(actionDetails, SIGNAL(toggled(bool)), gameList, SLOT(init(bool)));
  466. connect(actionGrouped, SIGNAL(toggled(bool)), gameList, SLOT(init(bool)));
  467. connect(actionStretchSshot, SIGNAL(toggled(bool)), gameList, SLOT(updateSelection()));
  468. connect(actionEnforceAspect, SIGNAL(toggled(bool)), gameList, SLOT(updateSelection()));
  469. connect(actionFilterClones, SIGNAL(toggled(bool)), gameList, SLOT(filterFlagsChanged(bool)));
  470. connect(actionFilterNonWorking, SIGNAL(toggled(bool)), gameList, SLOT(filterFlagsChanged(bool)));
  471. connect(actionFilterUnavailable, SIGNAL(toggled(bool)), gameList, SLOT(filterFlagsChanged(bool)));
  472. connect(actionFilterMechanical, SIGNAL(toggled(bool)), gameList, SLOT(filterFlagsChanged(bool)));
  473. // Auditor
  474. connect(romAuditor, SIGNAL(progressSwitched(int, QString)), gameList, SLOT(switchProgress(int, QString)));
  475. connect(romAuditor, SIGNAL(progressUpdated(int)), gameList, SLOT(updateProgress(int)));
  476. connect(romAuditor, SIGNAL(finished()), gameList, SLOT(init()));
  477. // Game List
  478. connect(lineEditSearch, SIGNAL(returnPressed()), gameList, SLOT(filterSearchChanged()));
  479. connect(btnSearch, SIGNAL(clicked()), gameList, SLOT(filterSearchChanged()));
  480. connect(btnClearSearch, SIGNAL(clicked()), gameList, SLOT(filterSearchCleared()));
  481. // Tray Icon
  482. connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
  483. this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
  484. // gameList->restoreGameSelection();
  485. // gameList->updateSelection();
  486. }
  487. bool MainWindow::validateMameBinary()
  488. {
  489. // validate mame_binary
  490. mame_binary = pGuiSettings->value("mame_binary", "mamep.exe").toString();
  491. pMameDat->mameVersion = utils->getMameVersion();
  492. QFileInfo mamebin(mame_binary);
  493. // if no valid exec was found
  494. if (mame_binary.isEmpty() ||
  495. mamebin.absoluteFilePath() == QCoreApplication::applicationFilePath() ||
  496. pMameDat->mameVersion.isEmpty())
  497. {
  498. mame_binary = selectMameBinary();
  499. mamebin.setFile(mame_binary);
  500. pMameDat->mameVersion = utils->getMameVersion();
  501. if (mame_binary.isEmpty() ||
  502. mamebin.absoluteFilePath() == QCoreApplication::applicationFilePath() ||
  503. pMameDat->mameVersion.isEmpty())
  504. {
  505. poplog(QString("Could not find valid MAME/MESS."));
  506. mame_binary = "";
  507. return false;
  508. }
  509. }
  510. //save the new mame_binary value now, it will be accessed later in option module
  511. pGuiSettings->setValue("mame_binary", mame_binary);
  512. if (QFileInfo(mame_binary).baseName().contains("mess", Qt::CaseInsensitive))
  513. isMESS = true;
  514. else if (QFileInfo(mame_binary).baseName().contains("ume", Qt::CaseInsensitive))
  515. isUME = true;
  516. return true;
  517. }
  518. QString MainWindow::selectMameBinary()
  519. {
  520. QString filter = "";
  521. #ifdef Q_WS_WIN
  522. filter.append(tr("Executable files") + " (*" EXEC_EXT ")");
  523. filter.append(";;");
  524. #endif
  525. filter.append(tr("All Files (*)"));
  526. return QFileDialog::getOpenFileName(this,
  527. tr("MAME/MESS executable:"),
  528. QCoreApplication::applicationDirPath(),
  529. filter);
  530. }
  531. void MainWindow::setVersion()
  532. {
  533. //set version info
  534. QString mameString;
  535. QString m1Ver = "";
  536. QString m1VerString = "";
  537. QString sdlVerString = "";
  538. if (!isMESS)
  539. mameString.append(QString("<a href=\"http://mamedev.org\">M.A.M.E.</a> %1 - Multiple Arcade Machine Emulator &copy; Nicola Salmoria and the MAME Team<br>").arg(pMameDat->mameVersion));
  540. if (hasDevices)
  541. mameString.append(QString("<a href=\"http://www.mess.org\">M.E.S.S.</a> %1 - Multi Emulator Super System &copy; the MESS Team<br>").arg(pMameDat->mameVersion));
  542. #ifdef Q_OS_WIN
  543. if (m1Core != NULL && m1Core->available)
  544. {
  545. m1Ver = m1Core->version;
  546. m1VerString = QString("<a href=\"http://rbelmont.mameworld.info/?page_id=223\">M1</a> %1 multi-platform arcade music emulator &copy; R. Belmont<br>")
  547. .arg(m1Ver);
  548. }
  549. #endif /* Q_OS_WIN */
  550. #ifdef USE_SDL
  551. sdlVerString = QString("<a href=\"http://www.libsdl.org\">SDL</a> %1.%2.%3-%4 - Simple DirectMedia Layer<br>")
  552. .arg(SDL_MAJOR_VERSION)
  553. .arg(SDL_MINOR_VERSION)
  554. .arg(SDL_PATCHLEVEL)
  555. .arg(SDL_REVISION)
  556. ;
  557. #endif /* USE_SDL */
  558. QString strVersion = QString(
  559. "<html>"
  560. "<head>"
  561. "<style type=\"text/css\">"
  562. "a {color: #006d9f;text-decoration: underline;}"
  563. "</style>"
  564. "</head>"
  565. "<body>"
  566. "<strong>M+GUI</strong> %1 &copy; 2008-2011 <a href=\"http://mameicons.free.fr/mame32p/\">MAME Plus!</a> Team<br>"
  567. "A Qt implementation of <a href=\"http://mameui.classicgaming.gamespy.com\">MameUI</a><br>"
  568. "Source code released under <a href=\"http://sam.zoy.org/wtfpl/COPYING\">WTFPL</a>"
  569. "<hr>"
  570. "%2%3%4%5%6"
  571. "</body>"
  572. "</html>")
  573. .arg(MPGUI_VER)
  574. .arg(mameString)
  575. .arg(m1VerString)
  576. .arg("<a href=\"http://qt.nokia.com\">Qt</a> " QT_VERSION_STR " &copy; Nokia Corporation<br>")
  577. .arg(sdlVerString)
  578. .arg("<a href=\"http://www.7-zip.org\">LZMA SDK</a> " MY_VERSION_COPYRIGHT_DATE)
  579. ;
  580. aboutUI->tbVersion->setHtml(strVersion);
  581. #ifdef Q_OS_WIN
  582. if (!m1Ver.isEmpty())
  583. m1UI->setWindowTitle("M1 - " + m1Ver);
  584. #endif /* Q_OS_WIN */
  585. QFileInfo fi(mame_binary);
  586. setWindowTitle(QString("%1 - %2 %3")
  587. .arg("M+GUI " MPGUI_VER)
  588. .arg(fi.baseName().toUpper())
  589. .arg(pMameDat->mameVersion));
  590. }
  591. void MainWindow::enableCtrls(bool isEnabled)
  592. {
  593. treeFolders->setEnabled(isEnabled);
  594. actionLargeIcons->setEnabled(false);
  595. actionDetails->setEnabled(isEnabled);
  596. actionGrouped->setEnabled(isEnabled);
  597. actionRefresh->setEnabled(isEnabled);
  598. actionDirectories->setEnabled(isEnabled);
  599. actionProperties->setEnabled(isEnabled);
  600. actionSrcProperties->setEnabled(isEnabled);
  601. actionDefaultOptions->setEnabled(isEnabled);
  602. actionPlay->setEnabled(isEnabled);
  603. menuPlayWith->setEnabled(isEnabled);
  604. menuAudit->setEnabled(isEnabled);
  605. menuArrangeIcons->setEnabled(isEnabled);
  606. menuCustomizeFields->setEnabled(isEnabled);
  607. menuCustomFilters->setEnabled(isEnabled);
  608. lineEditSearch->setEnabled(isEnabled);
  609. btnSearch->setEnabled(isEnabled);
  610. btnClearSearch->setEnabled(isEnabled);
  611. }
  612. void MainWindow::on_actionPlay_triggered()
  613. {
  614. gameList->runMame();
  615. }
  616. void MainWindow::on_actionCommandLine_triggered()
  617. {
  618. gameList->runMame(RUNMAME_CMD);
  619. }
  620. void MainWindow::on_actionSavestate_triggered()
  621. {
  622. playOptionsUI->initSavestate();
  623. playOptionsUI->exec();
  624. }
  625. void MainWindow::on_actionPlayback_triggered()
  626. {
  627. playOptionsUI->initPlayback();
  628. playOptionsUI->exec();
  629. }
  630. void MainWindow::on_actionRecord_triggered()
  631. {
  632. playOptionsUI->initRecord();
  633. playOptionsUI->exec();
  634. }
  635. void MainWindow::on_actionMNG_triggered()
  636. {
  637. playOptionsUI->initMNG();
  638. playOptionsUI->exec();
  639. }
  640. void MainWindow::on_actionAVI_triggered()
  641. {
  642. playOptionsUI->initAVI();
  643. playOptionsUI->exec();
  644. }
  645. void MainWindow::on_actionWave_triggered()
  646. {
  647. playOptionsUI->initWave();
  648. playOptionsUI->exec();
  649. }
  650. void MainWindow::on_actionConfigIPS_triggered()
  651. {
  652. ipsUI->updateList();
  653. ipsUI->exec();
  654. }
  655. void MainWindow::on_actionRefresh_triggered()
  656. {
  657. romAuditor->audit();
  658. }
  659. void MainWindow::on_actionFixDatComplete_triggered()
  660. {
  661. exportFixDat(AUDIT_EXPORT_COMPLETE);
  662. }
  663. void MainWindow::on_actionFixDatAll_triggered()
  664. {
  665. exportFixDat(AUDIT_EXPORT_ALL);
  666. }
  667. void MainWindow::on_actionFixDatIncomplete_triggered()
  668. {
  669. exportFixDat(AUDIT_EXPORT_INCOMPLETE);
  670. }
  671. void MainWindow::on_actionFixDatMissing_triggered()
  672. {
  673. exportFixDat(AUDIT_EXPORT_MISSING);
  674. }
  675. void MainWindow::exportFixDat(int method)
  676. {
  677. QString filter = "";
  678. filter.append(tr("Dat files") + " (*.dat)");
  679. filter.append(";;");
  680. filter.append(tr("All Files (*)"));
  681. QFileInfo mamebin(mame_binary);
  682. QString fileName = QFileDialog::getSaveFileName
  683. (0, tr("File name:"), mamebin.absolutePath(), filter);
  684. if (!fileName.isEmpty())
  685. romAuditor->audit(false, method, fileName);
  686. }
  687. void MainWindow::on_actionAudit_triggered()
  688. {
  689. mameAuditor->audit(VERIFY_CURRENT_ROMS);
  690. }
  691. void MainWindow::on_actionAuditAll_triggered()
  692. {
  693. mameAuditor->audit(VERIFY_ALL_ROMS);
  694. }
  695. void MainWindow::on_actionAuditAllSamples_triggered()
  696. {
  697. mameAuditor->audit(VERIFY_ALL_SAMPLES);
  698. }
  699. void MainWindow::on_actionSrcProperties_triggered()
  700. {
  701. if (!pMameDat->games.contains(currentGame))
  702. return;
  703. optionsUI->init(OPTLEVEL_SRC, 0);
  704. optionsUI->exec();
  705. }
  706. void MainWindow::on_actionProperties_triggered()
  707. {
  708. if (!pMameDat->games.contains(currentGame))
  709. return;
  710. optionsUI->init(OPTLEVEL_CURR, 0);
  711. optionsUI->exec();
  712. }
  713. void MainWindow::on_actionDefaultOptions_triggered()
  714. {
  715. if (!pMameDat->games.contains(currentGame))
  716. return;
  717. optionsUI->init(OPTLEVEL_GLOBAL, 0);
  718. optionsUI->exec();
  719. }
  720. void MainWindow::on_actionDirectories_triggered()
  721. {
  722. if (!pMameDat->games.contains(currentGame))
  723. return;
  724. optionsUI->init(OPTLEVEL_GUI, 0);
  725. optionsUI->exec();
  726. }
  727. void MainWindow::on_actionExitStop_triggered()
  728. {
  729. close();
  730. }
  731. void MainWindow::on_actionReadme_triggered()
  732. {
  733. QDesktopServices::openUrl(QUrl("http://www.mameworld.info/ubbthreads/showflat.php?Cat=&Number=158710&view=collapsed"));
  734. }
  735. void MainWindow::on_actionFAQ_triggered()
  736. {
  737. if (language.startsWith("zh_"))
  738. QDesktopServices::openUrl(QUrl("http://bbs.wisestudio.org/viewthread.php?tid=504"));
  739. else
  740. QDesktopServices::openUrl(QUrl("http://www.mameworld.info/ubbthreads/showflat.php?Cat=&Number=164054&view=collapsed"));
  741. }
  742. void MainWindow::on_actionBoard_triggered()
  743. {
  744. if (language.startsWith("zh_"))
  745. QDesktopServices::openUrl(QUrl("http://bbs.wisestudio.org/forum-16-1.html"));
  746. else
  747. QDesktopServices::openUrl(QUrl("http://www.mameworld.info/ubbthreads/postlist.php?Cat=&Board=mameplus&view=collapsed"));
  748. }
  749. void MainWindow::on_actionAbout_triggered()
  750. {
  751. aboutUI->exec();
  752. }
  753. void MainWindow::on_actionHaveList_triggered()
  754. {
  755. exportGameList(true);
  756. }
  757. void MainWindow::on_actionMissList_triggered()
  758. {
  759. exportGameList(false);
  760. }
  761. void MainWindow::exportGameList(bool have)
  762. {
  763. QString filter = "";
  764. filter.append(tr("Txt files") + " (*.txt)");
  765. filter.append(";;");
  766. filter.append(tr("All Files (*)"));
  767. QFileInfo mamebin(mame_binary);
  768. QString fileName = QFileDialog::getSaveFileName
  769. (0, tr("File name:"), mamebin.absolutePath(), filter);
  770. if (fileName.isEmpty())
  771. return;
  772. QFile fileinfo(fileName);
  773. fileinfo.open(QIODevice::WriteOnly | QFile::Text);
  774. QTextStream outinfo(&fileinfo);
  775. outinfo.setCodec("UTF-8");
  776. QStringList Available;
  777. foreach (QString gameName, pMameDat->games.keys())
  778. {
  779. GameInfo *gameInfo = pMameDat->games[gameName];
  780. if (!gameInfo->isDevice && gameInfo->devices.isEmpty() && (have ? gameInfo->available : !gameInfo->available))
  781. Available.append(gameName);
  782. }
  783. Available.sort();
  784. outinfo << Available.join("\n");
  785. fileinfo.close();
  786. win->poplog("Finished.");
  787. }
  788. void MainWindow::toggleGameListColumn()
  789. {
  790. int col = colToggleActions.indexOf((QAction *)sender());
  791. if (col == -1)
  792. return;
  793. if (tvGameList->header()->isSectionHidden(col))
  794. tvGameList->header()->setSectionHidden (col, false);
  795. else
  796. tvGameList->header()->setSectionHidden (col, true);
  797. }
  798. void MainWindow::on_actionColSortAscending_triggered()
  799. {
  800. int col = colSortActionGroup->actions().indexOf((QAction *)sender());
  801. if (col == -1)
  802. col = tvGameList->header()->sortIndicatorSection();
  803. tvGameList->sortByColumn(col, Qt::AscendingOrder);
  804. }
  805. void MainWindow::on_actionColSortDescending_triggered()
  806. {
  807. tvGameList->sortByColumn(tvGameList->header()->sortIndicatorSection(), Qt::DescendingOrder);
  808. }
  809. void MainWindow::on_actionEnglish_triggered()
  810. {
  811. language = "en_US";
  812. showRestartDialog();
  813. }
  814. void MainWindow::on_actionChinese_PRC_triggered()
  815. {
  816. language = "zh_CN";
  817. showRestartDialog();
  818. }
  819. void MainWindow::on_actionChinese_Taiwan_triggered()
  820. {
  821. language = "zh_TW";
  822. showRestartDialog();
  823. }
  824. void MainWindow::on_actionJapanese_triggered()
  825. {
  826. language = "ja_JP";
  827. showRestartDialog();
  828. }
  829. void MainWindow::on_actionSpanish_triggered()
  830. {
  831. language = "es_ES";
  832. showRestartDialog();
  833. }
  834. void MainWindow::on_actionFrench_triggered()
  835. {
  836. language = "fr_FR";
  837. showRestartDialog();
  838. }
  839. void MainWindow::on_actionHungarian_triggered()
  840. {
  841. language = "hu_HU";
  842. showRestartDialog();
  843. }
  844. void MainWindow::on_actionKorean_triggered()
  845. {
  846. language = "ko_KR";
  847. showRestartDialog();
  848. }
  849. void MainWindow::on_actionBrazilian_triggered()
  850. {
  851. language = "pt_BR";
  852. showRestartDialog();
  853. }
  854. void MainWindow::on_actionRussian_triggered()
  855. {
  856. language = "ru_RU";
  857. showRestartDialog();
  858. }
  859. void MainWindow::on_actionItalian_triggered()
  860. {
  861. language = "it_IT";
  862. showRestartDialog();
  863. }
  864. void MainWindow::on_actionLocalGameList_triggered()
  865. {
  866. local_game_list = actionLocalGameList->isChecked();
  867. }
  868. void MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason)
  869. {
  870. switch (reason)
  871. {
  872. case QSystemTrayIcon::Trigger:
  873. case QSystemTrayIcon::DoubleClick:
  874. if (isVisible())
  875. hide();
  876. else
  877. show();
  878. break;
  879. default:
  880. ;
  881. }
  882. }
  883. void MainWindow::showRestartDialog()
  884. {
  885. if (QMessageBox::Yes == QMessageBox::question(this,
  886. tr("Restart"),
  887. tr("Changing this option requires a restart to take effect.\nDo you wish to continue?"),
  888. QMessageBox::Yes | QMessageBox::No))
  889. close();
  890. }
  891. void MainWindow::loadGuiSettings()
  892. {
  893. pGuiSettings->setFallbacksEnabled(false);
  894. validGuiSettings = (QStringList()
  895. << "snapshot_directory" //fixme: core
  896. << "flyer_directory"
  897. << "cabinet_directory"
  898. << "marquee_directory"
  899. << "title_directory"
  900. << "cpanel_directory"
  901. << "pcb_directory"
  902. << "history_file"
  903. << "mameinfo_file"
  904. << "story_file"
  905. << "command_file" //fixme: core
  906. << "icons_directory"
  907. << "background_directory"
  908. << "folder_directory"
  909. //m1
  910. << "m1_directory"
  911. << "m1_language"
  912. //ips
  913. << "ips_language"
  914. << "ips_relationship"
  915. //ui path
  916. << "mame_binary"
  917. //ui mainwindow
  918. << "background_file"
  919. << "background_stretch"
  920. << "gui_style"
  921. //ui gamelist
  922. << "zoom_icon"
  923. << "list_mode"
  924. << "local_game_list"
  925. << "sort_column"
  926. << "sort_reverse"
  927. << "default_game"
  928. //ui folder
  929. << "default_folder"
  930. << "hide_folders"
  931. << "folder_flag"
  932. //ui snapshot
  933. << "stretch_screenshot_larger"
  934. << "enforce_aspect"
  935. << "vertical_tabs"
  936. << "window_geometry"
  937. << "window_state"
  938. << "column_state"
  939. << "option_geometry"
  940. << "option_column_state"
  941. << "language");
  942. //remove invalid settings
  943. QStringList keys = pGuiSettings->allKeys();
  944. foreach(QString key, keys)
  945. {
  946. //fixme: ignore mess for now
  947. if (key.endsWith("_extra_software") || validGuiSettings.contains(key))
  948. continue;
  949. pGuiSettings->remove(key);
  950. }
  951. //assign settings to local variables
  952. //fixme: move loadLayout and other similar methods
  953. currentGame = pGuiSettings->value("default_game").toString();
  954. //fixme: remove default by setting it programatically
  955. if (pGuiSettings->value("option_column_state").isValid())
  956. option_column_state = pGuiSettings->value("option_column_state").toByteArray();
  957. else
  958. option_column_state = defaultGuiSettings.value("option_column_state").toByteArray();
  959. }
  960. void MainWindow::loadLayout()
  961. {
  962. if (pGuiSettings->value("window_geometry").isValid())
  963. restoreGeometry(pGuiSettings->value("window_geometry").toByteArray());
  964. if (pGuiSettings->value("window_state").isValid())
  965. restoreState(pGuiSettings->value("window_state").toByteArray());
  966. option_geometry = pGuiSettings->value("option_geometry").toByteArray();
  967. actionVerticalTabs->setChecked(pGuiSettings->value("vertical_tabs", "1").toInt() == 1);
  968. actionRowDelegate->setChecked(pGuiSettings->value("zoom_icon", "1").toInt() == 1);
  969. gameList->listMode = pGuiSettings->value("list_mode").toString();
  970. if (gameList->listMode == actionDetails->objectName().remove("action"))
  971. actionDetails->setChecked(true);
  972. else if (gameList->listMode == actionLargeIcons->objectName().remove("action"))
  973. actionLargeIcons->setChecked(true);
  974. else
  975. actionGrouped->setChecked(true);
  976. //fixme: use built-in locale name string?
  977. if (language == "zh_CN")
  978. actionChinese_PRC->setChecked(true);
  979. else if (language == "zh_TW")
  980. actionChinese_Taiwan->setChecked(true);
  981. else if (language == "ja_JP")
  982. actionJapanese->setChecked(true);
  983. else if (language == "es_ES")
  984. actionSpanish->setChecked(true);
  985. else if (language == "fr_FR")
  986. actionFrench->setChecked(true);
  987. else if (language == "hu_HU")
  988. actionHungarian->setChecked(true);
  989. else if (language == "ko_KR")
  990. actionKorean->setChecked(true);
  991. else if (language == "pt_BR")
  992. actionBrazilian->setChecked(true);
  993. else if (language == "ru_RU")
  994. actionRussian->setChecked(true);
  995. else if (language == "it_IT")
  996. actionItalian->setChecked(true);
  997. else
  998. actionEnglish->setChecked(true);
  999. actionStretchSshot->setChecked(pGuiSettings->value("stretch_screenshot_larger", "0").toInt() == 1);
  1000. actionEnforceAspect->setChecked(pGuiSettings->value("enforce_aspect", "1").toInt() == 1);
  1001. local_game_list = pGuiSettings->value("local_game_list", "1").toInt() == 1;
  1002. actionLocalGameList->setChecked(local_game_list);
  1003. if (pGuiSettings->value("background_stretch", "1").toInt() == 0)
  1004. actionBgTile->setChecked(true);
  1005. else
  1006. actionBgStretch->setChecked(true);
  1007. }
  1008. void MainWindow::saveSettings()
  1009. {
  1010. //some guiSettings uses mameOpts mapping for dialog view
  1011. pGuiSettings->setValue("cabinet_directory", mameOpts["cabinet_directory"]->globalvalue);
  1012. pGuiSettings->setValue("cpanel_directory", mameOpts["cpanel_directory"]->globalvalue);
  1013. pGuiSettings->setValue("flyer_directory", mameOpts["flyer_directory"]->globalvalue);
  1014. pGuiSettings->setValue("marquee_directory", mameOpts["marquee_directory"]->globalvalue);
  1015. pGuiSettings->setValue("pcb_directory", mameOpts["pcb_directory"]->globalvalue);
  1016. pGuiSettings->setValue("title_directory", mameOpts["title_directory"]->globalvalue);
  1017. pGuiSettings->setValue("icons_directory", mameOpts["icons_directory"]->globalvalue);
  1018. pGuiSettings->setValue("background_directory", mameOpts["background_directory"]->globalvalue);
  1019. pGuiSettings->setValue("folder_directory", mameOpts["folder_directory"]->globalvalue);
  1020. pGuiSettings->setValue("background_file", background_file);
  1021. pGuiSettings->setValue("m1_directory", mameOpts["m1_directory"]->globalvalue);
  1022. #ifdef Q_OS_WIN
  1023. pGuiSettings->setValue("m1_language", m1UI->cmbLang->currentText());
  1024. #endif /* Q_OS_WIN */
  1025. pGuiSettings->setValue("ips_language", ipsUI->cmbLang->currentText());
  1026. pGuiSettings->setValue("ips_relationship", ipsUI->chkRelation->isChecked() ? 1 : 0);
  1027. pGuiSettings->setValue("gui_style", gui_style);
  1028. pGuiSettings->setValue("language", language);
  1029. pGuiSettings->setValue("history_file", mameOpts["history_file"]->globalvalue);
  1030. pGuiSettings->setValue("story_file", mameOpts["story_file"]->globalvalue);
  1031. pGuiSettings->setValue("mameinfo_file", mameOpts["mameinfo_file"]->globalvalue);
  1032. if (mameOpts["mame_binary"]->globalvalue != mameOpts["mame_binary"]->defvalue)
  1033. pGuiSettings->setValue("mame_binary", mameOpts["mame_binary"]->globalvalue);
  1034. else
  1035. pGuiSettings->setValue("mame_binary", mame_binary);
  1036. QList<QTreeWidgetItem *> softwaresItems = treeFolders->findItems(gameList->intFolderNames[FOLDER_CONSOLE], Qt::MatchFixedString);
  1037. QTreeWidgetItem *softwaresItem = NULL;
  1038. if (!softwaresItems.isEmpty())
  1039. softwaresItem = softwaresItems.first();
  1040. //save console dirs
  1041. foreach (QString optName, mameOpts.keys())
  1042. {
  1043. MameOption *pMameOpt = mameOpts[optName];
  1044. if (pMameOpt->guivisible && optName.endsWith("_extra_software"))
  1045. {
  1046. QString sysName = optName;
  1047. sysName.remove("_extra_software");
  1048. QString v = mameOpts[optName]->globalvalue;
  1049. if (!v.trimmed().isEmpty())
  1050. {
  1051. pGuiSettings->setValue(optName, mameOpts[optName]->globalvalue);
  1052. if (softwaresItem != NULL)
  1053. for (int i = 0; i < softwaresItem->childCount(); i++)
  1054. {
  1055. const QString sysDesc = softwaresItem->child(i)->text(0);
  1056. if (consoleMap.contains(sysDesc) &&
  1057. consoleMap[sysDesc] == sysName)
  1058. {
  1059. softwaresItem->child(i)->setHidden(false);
  1060. break;
  1061. }
  1062. }
  1063. }
  1064. else
  1065. {
  1066. pGuiSettings->remove(optName);
  1067. if (softwaresItem != NULL)
  1068. {
  1069. for (int i = 0; i < softwaresItem->childCount(); i++)
  1070. {
  1071. const QString sysDesc = softwaresItem->child(i)->text(0);
  1072. if (consoleMap.contains(sysDesc) &&
  1073. consoleMap[sysDesc] == sysName)
  1074. {
  1075. softwaresItem->child(i)->setHidden(true);
  1076. break;
  1077. }
  1078. }
  1079. }
  1080. }
  1081. }
  1082. }
  1083. //prepare default_folder
  1084. QString folderName, subFolderName, defalutFolder;
  1085. QStringList strlist = utils->split2Str(currentFolder, "/");
  1086. folderName = strlist.first();
  1087. subFolderName = strlist.last();
  1088. if (folderName.isEmpty())
  1089. {
  1090. folderName = strlist.last();
  1091. subFolderName.clear();
  1092. }
  1093. int p = gameList->intFolderNames.indexOf(folderName);
  1094. if (p >= 0)
  1095. folderName = gameList->intFolderNames0[p];
  1096. if (subFolderName.isEmpty())
  1097. defalutFolder = "/" + folderName;
  1098. else
  1099. defalutFolder = folderName + "/" + subFolderName;
  1100. //save layout
  1101. pGuiSettings->setValue("window_geometry", saveGeometry());
  1102. pGuiSettings->setValue("window_state", saveState());
  1103. pGuiSettings->setValue("option_geometry", option_geometry);
  1104. pGuiSettings->setValue("option_column_state", option_column_state);
  1105. pGuiSettings->setValue("column_state", tvGameList->header()->saveState());
  1106. pGuiSettings->setValue("sort_column", tvGameList->header()->sortIndicatorSection());
  1107. pGuiSettings->setValue("sort_reverse", (tvGameList->header()->sortIndicatorOrder() == Qt::AscendingOrder) ? 0 : 1);
  1108. pGuiSettings->setValue("vertical_tabs", actionVerticalTabs->isChecked() ? 1 : 0);
  1109. pGuiSettings->setValue("stretch_screenshot_larger", actionStretchSshot->isChecked() ? 1 : 0);
  1110. pGuiSettings->setValue("enforce_aspect", actionEnforceAspect->isChecked() ? 1 : 0);
  1111. pGuiSettings->setValue("zoom_icon", actionRowDelegate->isChecked() ? 1 : 0);
  1112. pGuiSettings->setValue("local_game_list", actionLocalGameList->isChecked() ? 1 : 0);
  1113. pGuiSettings->setValue("background_stretch", actionBgTile->isChecked() ? 0 : 1);
  1114. pGuiSettings->setValue("default_game", currentGame);
  1115. pGuiSettings->setValue("default_folder", defalutFolder);
  1116. pGuiSettings->setValue("list_mode", gameList->listMode);
  1117. pGuiSettings->setValue("hide_folders", hiddenFolders);
  1118. pGuiSettings->setValue("folder_flag", gameList->filterFlags);
  1119. }
  1120. void MainWindow::closeEvent(QCloseEvent *event)
  1121. {
  1122. hide();
  1123. if (!mame_binary.isEmpty())
  1124. {
  1125. saveSettings();
  1126. pMameDat->save();
  1127. }
  1128. event->accept();
  1129. }
  1130. void MainWindow::setDockOptions()
  1131. {
  1132. DockOptions opts = dockOptions();
  1133. if (actionVerticalTabs->isChecked())
  1134. opts |= VerticalTabs;
  1135. else
  1136. opts &= ~VerticalTabs;
  1137. QMainWindow::setDockOptions(opts);
  1138. }
  1139. void MainWindow::setTransparentBg(QWidget * w)
  1140. {
  1141. QPalette palette;
  1142. QBrush brush, bgBrush;
  1143. brush.setStyle(Qt::SolidPattern);
  1144. bgBrush.setStyle(Qt::SolidPattern);
  1145. if (isDarkBg)
  1146. {
  1147. bgBrush.setColor(QColor(0, 0, 0, 128));
  1148. brush.setColor(QColor(Qt::white));
  1149. }
  1150. else
  1151. {
  1152. bgBrush.setColor(QColor(255, 255, 255, 128));
  1153. brush.setColor(QColor(Qt::black));
  1154. }
  1155. palette.setBrush(QPalette::Active, QPalette::Base, bgBrush);
  1156. palette.setBrush(QPalette::Inactive, QPalette::Base, bgBrush);
  1157. palette.setBrush(QPalette::Disabled, QPalette::Base, bgBrush);
  1158. palette.setBrush(QPalette::Active, QPalette::Text, brush);
  1159. palette.setBrush(QPalette::Inactive, QPalette::Text, brush);
  1160. palette.setBrush(QPalette::Disabled, QPalette::Text, brush);
  1161. w->setPalette(palette);
  1162. }
  1163. void MainWindow::setTransparentStyle(QWidget * w)
  1164. {
  1165. QString style;
  1166. if (isDarkBg)
  1167. style =
  1168. "color: rgba(255, 255, 255, 196);"
  1169. "background-color: rgba(0, 0, 0, 128);"
  1170. ;
  1171. else
  1172. style =
  1173. "color: rgba(0, 0, 0, 196);"
  1174. "background-color: rgba(255, 255, 255, 128);"
  1175. ;
  1176. w->setStyleSheet(style);
  1177. }
  1178. void MainWindow::resizeEvent(QResizeEvent * /* event */)
  1179. {
  1180. // setBgPixmap(background_file);
  1181. }
  1182. void MainWindow::setGuiStyle(QString style)
  1183. {
  1184. if (style.isEmpty())
  1185. style = ((QAction *)sender())->text();
  1186. gui_style = style;
  1187. QApplication::setStyle(QStyleFactory::create(gui_style));
  1188. //have to chain setBgPixmap() otherwise bgcolor isn't set properly
  1189. if (!background_file.isEmpty())
  1190. setBgPixmap(background_file);
  1191. }
  1192. void MainWindow::setBgTile()
  1193. {
  1194. setBgPixmap(background_file);
  1195. }
  1196. void MainWindow::setBgPixmap(QString fileName)
  1197. {
  1198. if (fileName.isEmpty())
  1199. fileName = ((QAction *)sender())->text();
  1200. background_file = fileName;
  1201. QString _dirpath = utils->getPath(pGuiSettings->value("background_directory", "bkground").toString());
  1202. QImage bkgroundImg(_dirpath + fileName);
  1203. // setup mainwindow background
  1204. if (!bkgroundImg.isNull())
  1205. {
  1206. if (actionBgStretch->isChecked())
  1207. bkgroundImg = bkgroundImg.scaled(size(), Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
  1208. //fixme: must init before stylesheet applied
  1209. QPalette palette = this->palette();
  1210. palette.setBrush(backgroundRole(), QBrush(bkgroundImg));
  1211. // setPalette(palette);
  1212. //get the color tone of bg image
  1213. bkgroundImg = bkgroundImg.scaled(1, 1, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
  1214. int grayVal = qGray(bkgroundImg.pixel(0, 0));
  1215. if (grayVal < 128)
  1216. isDarkBg = true;
  1217. else
  1218. isDarkBg = false;
  1219. QString TEXT_COLOR = QString("color:") + (isDarkBg ? "white" : "black") + "; ";
  1220. QString TEXT_BGCOLOR = isDarkBg ? "background-color: rgba(0, 0, 0, 128)" : "background-color: rgba(255, 255, 255, 128)";
  1221. static const QString STATIC_STYLE =
  1222. " QToolBar{background-color:palette(window);}"
  1223. " QStatusBar::item, QDockWidget::title {border-width:1px; border-style:solid; border-color:palette(dark);}"
  1224. " QStatusBar QLabel {padding:0 1px;}"
  1225. " QDockWidget::title {padding:1px 2px; margin:2px 0;}"
  1226. ;
  1227. // setup background alpha
  1228. setTransparentBg(treeFolders);
  1229. setTransparentBg(tvGameList);
  1230. setTransparentBg(lvGameList);
  1231. setTransparentBg(tbHistory);
  1232. setTransparentBg(tbMameinfo);
  1233. setTransparentBg(tbDriverinfo);
  1234. setTransparentBg(tbStory);
  1235. setTransparentBg(tbCommand);
  1236. #ifdef Q_OS_WIN
  1237. setTransparentBg(m1UI->twSongList);
  1238. setTransparentStyle(m1UI->groupBox);
  1239. setTransparentStyle(m1UI->lcdNumber);
  1240. #endif /* Q_OS_WIN */
  1241. ///*
  1242. qApp->setStyleSheet( STATIC_STYLE
  1243. + " QDockWidget, QStatusBar QLabel {" + TEXT_COLOR + "}"
  1244. + " QStatusBar::item, QDockWidget::title {" + TEXT_BGCOLOR + "}"
  1245. );
  1246. //*/
  1247. setPalette(palette);
  1248. }
  1249. }
  1250. void MainWindow::toggleTrayIcon(int, QProcess::ExitStatus, bool isTrayIconVisible)
  1251. {
  1252. trayIcon->setVisible(isTrayIconVisible);
  1253. if (isTrayIconVisible)
  1254. trayIcon->setToolTip(windowTitle());
  1255. setVisible(!isTrayIconVisible);
  1256. }
  1257. QList<QTabBar *> MainWindow::getSSTabBars()
  1258. {
  1259. //there's no API in Qt to access docked widget tabbar, we have to do it on our own
  1260. QList<QTabBar *> tabBars = findChildren<QTabBar *>();
  1261. QList<QTabBar *> tabBars2;
  1262. //iterate all tab ctrls
  1263. foreach (QTabBar *tabBar, tabBars)
  1264. {
  1265. bool isSSDocked = false;
  1266. //iterate known screenshot/history dock names
  1267. for (int i = 0; i < dockCtrlNames.size(); i++)
  1268. {
  1269. //iterate tabs in a tab bar
  1270. for (int t = 0; t < tabBar->count(); t ++)
  1271. {
  1272. //if the tab contains any known screenshot/history dock names
  1273. QString tabName = tabBar->tabText(t);
  1274. if (tr(qPrintable(dockCtrlNames[i])) == tabName
  1275. #ifdef Q_OS_WIN
  1276. || tabName == "M1"
  1277. #endif /* Q_OS_WIN */
  1278. )
  1279. {
  1280. isSSDocked = true;
  1281. break;
  1282. }
  1283. }
  1284. if (isSSDocked)
  1285. break;
  1286. }
  1287. if (isSSDocked)
  1288. tabBars2.append(tabBar);
  1289. }
  1290. return tabBars2;
  1291. }
  1292. //fixme: dockCtrls[snapType]->isVisible() && isDockTabVisible(dockCtrlNames[snapType])
  1293. bool MainWindow::isDockTabVisible(QString objName)
  1294. {
  1295. bool isSSTabbed = false;
  1296. QList<QTabBar *> tabBars = getSSTabBars();
  1297. objName = tr(qPrintable(objName));
  1298. //iterate all tab ctrls
  1299. foreach (QTabBar *tabBar, tabBars)
  1300. {
  1301. //tab bar's current index matches $objName
  1302. if (objName == tabBar->tabText(tabBar->currentIndex()))
  1303. return true;
  1304. //iterate tabs in a tab bar
  1305. for (int t = 0; t < tabBar->count(); t ++)
  1306. {
  1307. //if $objName is tabified in any of the tab ctrls
  1308. if (objName == tabBar->tabText(t))
  1309. {
  1310. isSSTabbed = true;
  1311. break;
  1312. }
  1313. }
  1314. }
  1315. // if the dock area contains only one SS widget
  1316. if (!isSSTabbed)
  1317. return true;
  1318. return false;
  1319. }
  1320. int main(int argc, char *argv[])
  1321. {
  1322. for (int i = 1; i < argc; i++)
  1323. {
  1324. if (QString(argv[i]) == "-configpath" && i + 1 < argc)
  1325. {
  1326. CFG_PREFIX = utils->getPath(argv[i + 1]);
  1327. break;
  1328. }
  1329. }
  1330. pGuiSettings = new QSettings(CFG_PREFIX + "mamepgui" INI_EXT, QSettings::IniFormat);
  1331. QApplication myApp(argc, argv);
  1332. QTranslator appTranslator;
  1333. language = pGuiSettings->value("language").toString();
  1334. if (language.isEmpty())
  1335. language = QLocale::system().name();
  1336. appTranslator.load(":/lang/mamepgui_" + language);
  1337. myApp.installTranslator(&appTranslator);
  1338. if (language.startsWith("zh_") || language.startsWith("ja_"))
  1339. {
  1340. QFont font;
  1341. font.setPointSize(9);
  1342. myApp.setFont(font);
  1343. }
  1344. procMan = new ProcessManager(0);
  1345. utils = new Utils(0);
  1346. win = new MainWindow(0);
  1347. return myApp.exec();
  1348. }