2020-09-21 17:17:34 +00:00
|
|
|
// SPDX-License-Identifier: MIT
|
2020-06-06 11:10:33 +00:00
|
|
|
//
|
2020-09-21 17:17:34 +00:00
|
|
|
// EmulationStation Desktop Edition
|
2020-06-21 12:25:28 +00:00
|
|
|
// GuiScraperMenu.cpp
|
2020-06-06 11:10:33 +00:00
|
|
|
//
|
2020-06-21 12:25:28 +00:00
|
|
|
// Game media scraper, including settings as well as the scraping start button.
|
|
|
|
// Submenu to the GuiMenu main menu.
|
|
|
|
// Will call GuiScraperMulti to perform the actual scraping.
|
2020-06-06 11:10:33 +00:00
|
|
|
//
|
|
|
|
|
|
|
|
#include "guis/GuiScraperMenu.h"
|
|
|
|
|
2021-07-07 18:03:42 +00:00
|
|
|
#include "FileData.h"
|
|
|
|
#include "FileSorts.h"
|
|
|
|
#include "SystemData.h"
|
2020-06-06 11:10:33 +00:00
|
|
|
#include "components/OptionListComponent.h"
|
|
|
|
#include "components/SwitchComponent.h"
|
|
|
|
#include "guis/GuiMsgBox.h"
|
2021-06-09 18:56:41 +00:00
|
|
|
#include "guis/GuiOfflineGenerator.h"
|
2020-06-06 11:10:33 +00:00
|
|
|
#include "guis/GuiScraperMulti.h"
|
|
|
|
|
2022-01-19 17:01:54 +00:00
|
|
|
GuiScraperMenu::GuiScraperMenu(std::string title)
|
|
|
|
: mMenu {title}
|
2020-06-06 11:10:33 +00:00
|
|
|
{
|
2020-11-05 17:18:11 +00:00
|
|
|
// Scraper service.
|
2022-01-19 17:01:54 +00:00
|
|
|
mScraper =
|
|
|
|
std::make_shared<OptionListComponent<std::string>>(getHelpStyle(), "SCRAPE FROM", false);
|
2020-06-21 12:25:28 +00:00
|
|
|
std::vector<std::string> scrapers = getScraperList();
|
|
|
|
// Select either the first entry or the one read from the settings,
|
|
|
|
// just in case the scraper from settings has vanished.
|
2021-11-17 16:35:34 +00:00
|
|
|
for (auto it = scrapers.cbegin(); it != scrapers.cend(); ++it)
|
2020-11-05 17:18:11 +00:00
|
|
|
mScraper->add(*it, *it, *it == Settings::getInstance()->getString("Scraper"));
|
2021-11-06 20:12:13 +00:00
|
|
|
// If there are no objects returned, then there must be a manually modified entry in the
|
|
|
|
// configuration file. Simply set the scraper to "screenscraper" in this case.
|
|
|
|
if (mScraper->getSelectedObjects().size() == 0)
|
|
|
|
mScraper->selectEntry(0);
|
|
|
|
|
2020-11-05 17:18:11 +00:00
|
|
|
mMenu.addWithLabel("SCRAPE FROM", mScraper);
|
2020-06-21 12:25:28 +00:00
|
|
|
|
|
|
|
// Search filters, getSearches() will generate a queue of games to scrape
|
|
|
|
// based on the outcome of the checks below.
|
2022-01-19 17:01:54 +00:00
|
|
|
mFilters = std::make_shared<OptionListComponent<GameFilterFunc>>(getHelpStyle(),
|
2021-07-07 18:03:42 +00:00
|
|
|
"SCRAPE THESE GAMES", false);
|
|
|
|
mFilters->add(
|
|
|
|
"ALL GAMES",
|
|
|
|
[](SystemData*, FileData*) -> bool {
|
|
|
|
// All games.
|
|
|
|
return true;
|
|
|
|
},
|
|
|
|
false);
|
|
|
|
mFilters->add(
|
|
|
|
"FAVORITE GAMES",
|
|
|
|
[](SystemData*, FileData* g) -> bool {
|
|
|
|
// Favorite games.
|
|
|
|
return g->getFavorite();
|
|
|
|
},
|
|
|
|
false);
|
|
|
|
mFilters->add(
|
|
|
|
"NO METADATA",
|
|
|
|
[](SystemData*, FileData* g) -> bool {
|
|
|
|
// No metadata.
|
|
|
|
return g->metadata.get("desc").empty();
|
|
|
|
},
|
|
|
|
false);
|
|
|
|
mFilters->add(
|
|
|
|
"NO GAME IMAGE",
|
|
|
|
[](SystemData*, FileData* g) -> bool {
|
|
|
|
// No game image.
|
|
|
|
return g->getImagePath().empty();
|
|
|
|
},
|
|
|
|
false);
|
|
|
|
mFilters->add(
|
|
|
|
"NO GAME VIDEO",
|
|
|
|
[](SystemData*, FileData* g) -> bool {
|
|
|
|
// No game video.
|
|
|
|
return g->getVideoPath().empty();
|
|
|
|
},
|
|
|
|
false);
|
|
|
|
mFilters->add(
|
|
|
|
"FOLDERS ONLY",
|
|
|
|
[](SystemData*, FileData* g) -> bool {
|
|
|
|
// Folders only.
|
|
|
|
return g->getType() == FOLDER;
|
|
|
|
},
|
|
|
|
false);
|
2020-12-16 16:35:23 +00:00
|
|
|
|
|
|
|
mFilters->selectEntry(Settings::getInstance()->getInt("ScraperFilter"));
|
2021-01-26 20:36:25 +00:00
|
|
|
mMenu.addWithLabel("SCRAPE THESE GAMES", mFilters);
|
2020-06-21 12:25:28 +00:00
|
|
|
|
2020-12-16 16:35:23 +00:00
|
|
|
mMenu.addSaveFunc([this] {
|
|
|
|
if (mScraper->getSelected() != Settings::getInstance()->getString("Scraper")) {
|
|
|
|
Settings::getInstance()->setString("Scraper", mScraper->getSelected());
|
|
|
|
mMenu.setNeedsSaving();
|
|
|
|
}
|
|
|
|
// The filter setting is only retained during the program session i.e. it's not saved
|
2021-06-16 17:05:24 +00:00
|
|
|
// to es_settings.xml.
|
2021-09-19 12:37:10 +00:00
|
|
|
if (mFilters->getSelectedId() !=
|
|
|
|
static_cast<unsigned int>(Settings::getInstance()->getInt("ScraperFilter")))
|
2020-12-16 16:35:23 +00:00
|
|
|
Settings::getInstance()->setInt("ScraperFilter", mFilters->getSelectedId());
|
|
|
|
});
|
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
// Add systems (all systems with an existing platform ID are listed).
|
2022-01-19 17:01:54 +00:00
|
|
|
mSystems = std::make_shared<OptionListComponent<SystemData*>>(getHelpStyle(),
|
2021-07-07 18:03:42 +00:00
|
|
|
"SCRAPE THESE SYSTEMS", true);
|
2021-11-17 16:35:34 +00:00
|
|
|
for (unsigned int i = 0; i < SystemData::sSystemVector.size(); ++i) {
|
2020-06-21 12:25:28 +00:00
|
|
|
if (!SystemData::sSystemVector[i]->hasPlatformId(PlatformIds::PLATFORM_IGNORE)) {
|
2021-07-07 18:03:42 +00:00
|
|
|
mSystems->add(SystemData::sSystemVector[i]->getFullName(), SystemData::sSystemVector[i],
|
|
|
|
!SystemData::sSystemVector[i]->getPlatformIds().empty());
|
|
|
|
SystemData::sSystemVector[i]->getScrapeFlag() ? mSystems->selectEntry(i) :
|
|
|
|
mSystems->unselectEntry(i);
|
2020-06-21 12:25:28 +00:00
|
|
|
}
|
|
|
|
}
|
2021-01-26 20:36:25 +00:00
|
|
|
mMenu.addWithLabel("SCRAPE THESE SYSTEMS", mSystems);
|
2020-06-21 12:25:28 +00:00
|
|
|
|
2020-11-07 14:34:15 +00:00
|
|
|
addEntry("ACCOUNT SETTINGS", 0x777777FF, true, [this] {
|
2021-07-07 18:03:42 +00:00
|
|
|
// Open the account options menu.
|
2021-06-07 21:02:42 +00:00
|
|
|
openAccountOptions();
|
2020-11-07 14:34:15 +00:00
|
|
|
});
|
2020-08-05 17:31:59 +00:00
|
|
|
addEntry("CONTENT SETTINGS", 0x777777FF, true, [this] {
|
2020-11-05 17:18:11 +00:00
|
|
|
// If the scraper service has been changed before entering this menu, then save the
|
|
|
|
// settings so that the specific options supported by the respective scrapers
|
|
|
|
// can be enabled or disabled.
|
|
|
|
if (mScraper->getSelected() != Settings::getInstance()->getString("Scraper"))
|
|
|
|
mMenu.save();
|
2021-06-07 21:02:42 +00:00
|
|
|
openContentOptions();
|
|
|
|
});
|
|
|
|
addEntry("MIXIMAGE SETTINGS", 0x777777FF, true, [this] {
|
2021-07-07 18:03:42 +00:00
|
|
|
// Open the miximage options menu.
|
2021-06-07 21:02:42 +00:00
|
|
|
openMiximageOptions();
|
2020-08-05 17:31:59 +00:00
|
|
|
});
|
|
|
|
addEntry("OTHER SETTINGS", 0x777777FF, true, [this] {
|
2020-11-05 17:18:11 +00:00
|
|
|
// If the scraper service has been changed before entering this menu, then save the
|
|
|
|
// settings so that the specific options supported by the respective scrapers
|
|
|
|
// can be enabled or disabled.
|
|
|
|
if (mScraper->getSelected() != Settings::getInstance()->getString("Scraper"))
|
|
|
|
mMenu.save();
|
2021-06-07 21:02:42 +00:00
|
|
|
openOtherOptions();
|
2020-08-05 17:31:59 +00:00
|
|
|
});
|
2020-06-21 12:25:28 +00:00
|
|
|
|
|
|
|
addChild(&mMenu);
|
|
|
|
|
2022-12-05 20:40:33 +00:00
|
|
|
mMenu.addButton("START", "start scraper", std::bind(&GuiScraperMenu::pressedStart, this));
|
2020-06-21 12:25:28 +00:00
|
|
|
mMenu.addButton("BACK", "back", [&] { delete this; });
|
|
|
|
|
|
|
|
setSize(mMenu.getSize());
|
|
|
|
|
2021-08-16 16:25:01 +00:00
|
|
|
setPosition((Renderer::getScreenWidth() - mSize.x) / 2.0f, Renderer::getScreenHeight() * 0.13f);
|
2020-06-06 11:10:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
GuiScraperMenu::~GuiScraperMenu()
|
|
|
|
{
|
2020-06-21 12:25:28 +00:00
|
|
|
// Save the scrape flags to the system settings so that they are
|
|
|
|
// remembered throughout the program session.
|
2022-09-03 10:44:49 +00:00
|
|
|
std::vector<SystemData*> sys {mSystems->getSelectedObjects()};
|
2021-07-07 18:03:42 +00:00
|
|
|
for (auto it = SystemData::sSystemVector.cbegin(); // Line break.
|
2021-11-17 16:35:34 +00:00
|
|
|
it != SystemData::sSystemVector.cend(); ++it) {
|
2021-07-07 18:03:42 +00:00
|
|
|
(*it)->setScrapeFlag(false);
|
2021-11-17 16:35:34 +00:00
|
|
|
for (auto it_sys = sys.cbegin(); it_sys != sys.cend(); ++it_sys) {
|
2020-06-21 12:25:28 +00:00
|
|
|
if ((*it)->getFullName() == (*it_sys)->getFullName())
|
|
|
|
(*it)->setScrapeFlag(true);
|
|
|
|
}
|
|
|
|
}
|
2020-06-06 11:10:33 +00:00
|
|
|
}
|
|
|
|
|
2021-06-07 21:02:42 +00:00
|
|
|
void GuiScraperMenu::openAccountOptions()
|
2020-11-07 14:34:15 +00:00
|
|
|
{
|
2022-01-19 17:01:54 +00:00
|
|
|
auto s = new GuiSettings("ACCOUNT SETTINGS");
|
2020-11-07 14:34:15 +00:00
|
|
|
|
|
|
|
// ScreenScraper username.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperUsernameScreenScraper =
|
2022-01-19 17:01:54 +00:00
|
|
|
std::make_shared<TextComponent>("", Font::get(FONT_SIZE_MEDIUM), 0x777777FF, ALIGN_RIGHT);
|
2022-09-03 10:44:49 +00:00
|
|
|
s->addEditableTextComponent("SCREENSCRAPER USERNAME", scraperUsernameScreenScraper,
|
2021-07-07 18:03:42 +00:00
|
|
|
Settings::getInstance()->getString("ScraperUsernameScreenScraper"));
|
2022-09-03 10:44:49 +00:00
|
|
|
s->addSaveFunc([scraperUsernameScreenScraper, s] {
|
|
|
|
if (scraperUsernameScreenScraper->getValue() !=
|
2021-07-07 18:03:42 +00:00
|
|
|
Settings::getInstance()->getString("ScraperUsernameScreenScraper")) {
|
2020-11-07 14:34:15 +00:00
|
|
|
Settings::getInstance()->setString("ScraperUsernameScreenScraper",
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperUsernameScreenScraper->getValue());
|
2020-11-07 14:34:15 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// ScreenScraper password.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperPasswordScreenScraper =
|
2022-01-19 17:01:54 +00:00
|
|
|
std::make_shared<TextComponent>("", Font::get(FONT_SIZE_MEDIUM), 0x777777FF, ALIGN_RIGHT);
|
2020-11-07 14:34:15 +00:00
|
|
|
std::string passwordMasked;
|
|
|
|
if (Settings::getInstance()->getString("ScraperPasswordScreenScraper") != "") {
|
|
|
|
passwordMasked = "********";
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperPasswordScreenScraper->setHiddenValue(
|
2021-07-07 18:03:42 +00:00
|
|
|
Settings::getInstance()->getString("ScraperPasswordScreenScraper"));
|
2020-11-07 14:34:15 +00:00
|
|
|
}
|
2022-09-03 10:44:49 +00:00
|
|
|
s->addEditableTextComponent("SCREENSCRAPER PASSWORD", scraperPasswordScreenScraper,
|
2021-07-07 18:03:42 +00:00
|
|
|
passwordMasked, "", true);
|
2022-09-03 10:44:49 +00:00
|
|
|
s->addSaveFunc([scraperPasswordScreenScraper, s] {
|
|
|
|
if (scraperPasswordScreenScraper->getHiddenValue() !=
|
2021-07-07 18:03:42 +00:00
|
|
|
Settings::getInstance()->getString("ScraperPasswordScreenScraper")) {
|
2020-11-07 14:34:15 +00:00
|
|
|
Settings::getInstance()->setString("ScraperPasswordScreenScraper",
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperPasswordScreenScraper->getHiddenValue());
|
2020-11-07 14:34:15 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-12-06 19:21:32 +00:00
|
|
|
// Whether to use the ScreenScraper account when scraping.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperUseAccountScreenScraper = std::make_shared<SwitchComponent>();
|
|
|
|
scraperUseAccountScreenScraper->setState(
|
2021-12-06 19:21:32 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperUseAccountScreenScraper"));
|
2022-09-03 10:44:49 +00:00
|
|
|
s->addWithLabel("USE THIS ACCOUNT FOR SCREENSCRAPER", scraperUseAccountScreenScraper);
|
|
|
|
s->addSaveFunc([scraperUseAccountScreenScraper, s] {
|
|
|
|
if (scraperUseAccountScreenScraper->getState() !=
|
2021-12-06 19:21:32 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperUseAccountScreenScraper")) {
|
|
|
|
Settings::getInstance()->setBool("ScraperUseAccountScreenScraper",
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperUseAccountScreenScraper->getState());
|
2021-12-06 19:21:32 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-11-07 14:34:15 +00:00
|
|
|
mWindow->pushGui(s);
|
|
|
|
}
|
|
|
|
|
2021-06-07 21:02:42 +00:00
|
|
|
void GuiScraperMenu::openContentOptions()
|
2020-06-06 11:10:33 +00:00
|
|
|
{
|
2022-01-19 17:01:54 +00:00
|
|
|
auto s = new GuiSettings("CONTENT SETTINGS");
|
2020-06-21 12:25:28 +00:00
|
|
|
|
|
|
|
// Scrape game names.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scrapeGameNames = std::make_shared<SwitchComponent>();
|
|
|
|
scrapeGameNames->setState(Settings::getInstance()->getBool("ScrapeGameNames"));
|
|
|
|
s->addWithLabel("GAME NAMES", scrapeGameNames);
|
|
|
|
s->addSaveFunc([scrapeGameNames, s] {
|
|
|
|
if (scrapeGameNames->getState() != Settings::getInstance()->getBool("ScrapeGameNames")) {
|
|
|
|
Settings::getInstance()->setBool("ScrapeGameNames", scrapeGameNames->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-06-21 12:25:28 +00:00
|
|
|
|
|
|
|
// Scrape ratings.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scrapeRatings = std::make_shared<SwitchComponent>();
|
|
|
|
scrapeRatings->setState(Settings::getInstance()->getBool("ScrapeRatings"));
|
|
|
|
s->addWithLabel("RATINGS", scrapeRatings);
|
|
|
|
s->addSaveFunc([scrapeRatings, s] {
|
|
|
|
if (scrapeRatings->getState() != Settings::getInstance()->getBool("ScrapeRatings")) {
|
|
|
|
Settings::getInstance()->setBool("ScrapeRatings", scrapeRatings->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-06-21 12:25:28 +00:00
|
|
|
|
2021-07-11 11:47:31 +00:00
|
|
|
// Ratings are not supported by TheGamesDB, so gray out the option if this scraper is selected.
|
2020-08-05 17:31:59 +00:00
|
|
|
if (Settings::getInstance()->getString("Scraper") == "thegamesdb") {
|
2022-09-03 10:44:49 +00:00
|
|
|
scrapeRatings->setEnabled(false);
|
|
|
|
scrapeRatings->setOpacity(DISABLED_OPACITY);
|
|
|
|
scrapeRatings->getParent()
|
|
|
|
->getChild(scrapeRatings->getChildIndex() - 1)
|
2021-07-07 18:03:42 +00:00
|
|
|
->setOpacity(DISABLED_OPACITY);
|
2020-08-05 17:31:59 +00:00
|
|
|
}
|
|
|
|
|
2021-10-27 17:23:57 +00:00
|
|
|
// Scrape controllers (arcade systems only).
|
2022-01-19 17:01:54 +00:00
|
|
|
auto scrapeControllers = std::make_shared<SwitchComponent>();
|
2021-10-27 17:23:57 +00:00
|
|
|
scrapeControllers->setState(Settings::getInstance()->getBool("ScrapeControllers"));
|
2021-10-28 19:00:23 +00:00
|
|
|
s->addWithLabel("CONTROLLERS (ARCADE SYSTEMS ONLY)", scrapeControllers);
|
2021-10-27 17:23:57 +00:00
|
|
|
s->addSaveFunc([scrapeControllers, s] {
|
|
|
|
if (scrapeControllers->getState() !=
|
|
|
|
Settings::getInstance()->getBool("ScrapeControllers")) {
|
|
|
|
Settings::getInstance()->setBool("ScrapeControllers", scrapeControllers->getState());
|
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Controllers are not supported by TheGamesDB, so gray out the option if this scraper is
|
|
|
|
// selected.
|
|
|
|
if (Settings::getInstance()->getString("Scraper") == "thegamesdb") {
|
|
|
|
scrapeControllers->setEnabled(false);
|
|
|
|
scrapeControllers->setOpacity(DISABLED_OPACITY);
|
|
|
|
scrapeControllers->getParent()
|
|
|
|
->getChild(scrapeControllers->getChildIndex() - 1)
|
|
|
|
->setOpacity(DISABLED_OPACITY);
|
|
|
|
}
|
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
// Scrape other metadata.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scrapeMetadata = std::make_shared<SwitchComponent>();
|
|
|
|
scrapeMetadata->setState(Settings::getInstance()->getBool("ScrapeMetadata"));
|
|
|
|
s->addWithLabel("OTHER METADATA", scrapeMetadata);
|
|
|
|
s->addSaveFunc([scrapeMetadata, s] {
|
|
|
|
if (scrapeMetadata->getState() != Settings::getInstance()->getBool("ScrapeMetadata")) {
|
|
|
|
Settings::getInstance()->setBool("ScrapeMetadata", scrapeMetadata->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-06-21 12:25:28 +00:00
|
|
|
|
2020-08-05 20:38:44 +00:00
|
|
|
// Scrape videos.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scrapeVideos = std::make_shared<SwitchComponent>();
|
|
|
|
scrapeVideos->setState(Settings::getInstance()->getBool("ScrapeVideos"));
|
|
|
|
s->addWithLabel("VIDEOS", scrapeVideos);
|
|
|
|
s->addSaveFunc([scrapeVideos, s] {
|
|
|
|
if (scrapeVideos->getState() != Settings::getInstance()->getBool("ScrapeVideos")) {
|
|
|
|
Settings::getInstance()->setBool("ScrapeVideos", scrapeVideos->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-08-05 20:38:44 +00:00
|
|
|
|
2021-07-11 11:47:31 +00:00
|
|
|
// Videos are not supported by TheGamesDB, so gray out the option if this scraper is selected.
|
2020-08-05 20:38:44 +00:00
|
|
|
if (Settings::getInstance()->getString("Scraper") == "thegamesdb") {
|
2022-09-03 10:44:49 +00:00
|
|
|
scrapeVideos->setEnabled(false);
|
|
|
|
scrapeVideos->setOpacity(DISABLED_OPACITY);
|
|
|
|
scrapeVideos->getParent()
|
|
|
|
->getChild(scrapeVideos->getChildIndex() - 1)
|
2021-07-07 18:03:42 +00:00
|
|
|
->setOpacity(DISABLED_OPACITY);
|
2020-08-05 20:38:44 +00:00
|
|
|
}
|
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
// Scrape screenshots images.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scrapeScreenshots = std::make_shared<SwitchComponent>();
|
|
|
|
scrapeScreenshots->setState(Settings::getInstance()->getBool("ScrapeScreenshots"));
|
|
|
|
s->addWithLabel("SCREENSHOT IMAGES", scrapeScreenshots);
|
|
|
|
s->addSaveFunc([scrapeScreenshots, s] {
|
|
|
|
if (scrapeScreenshots->getState() !=
|
2021-07-07 18:03:42 +00:00
|
|
|
Settings::getInstance()->getBool("ScrapeScreenshots")) {
|
2022-09-03 10:44:49 +00:00
|
|
|
Settings::getInstance()->setBool("ScrapeScreenshots", scrapeScreenshots->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-06-21 12:25:28 +00:00
|
|
|
|
2021-10-28 19:00:23 +00:00
|
|
|
// Scrape title screen images.
|
2022-01-19 17:01:54 +00:00
|
|
|
auto scrapeTitleScreens = std::make_shared<SwitchComponent>();
|
2021-10-28 19:00:23 +00:00
|
|
|
scrapeTitleScreens->setState(Settings::getInstance()->getBool("ScrapeTitleScreens"));
|
|
|
|
s->addWithLabel("TITLE SCREEN IMAGES", scrapeTitleScreens);
|
|
|
|
s->addSaveFunc([scrapeTitleScreens, s] {
|
|
|
|
if (scrapeTitleScreens->getState() !=
|
|
|
|
Settings::getInstance()->getBool("ScrapeTitleScreens")) {
|
|
|
|
Settings::getInstance()->setBool("ScrapeTitleScreens", scrapeTitleScreens->getState());
|
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Scrape box cover images.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scrapeCovers = std::make_shared<SwitchComponent>();
|
|
|
|
scrapeCovers->setState(Settings::getInstance()->getBool("ScrapeCovers"));
|
|
|
|
s->addWithLabel("BOX COVER IMAGES", scrapeCovers);
|
|
|
|
s->addSaveFunc([scrapeCovers, s] {
|
|
|
|
if (scrapeCovers->getState() != Settings::getInstance()->getBool("ScrapeCovers")) {
|
|
|
|
Settings::getInstance()->setBool("ScrapeCovers", scrapeCovers->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-06-21 12:25:28 +00:00
|
|
|
|
2021-10-28 19:00:23 +00:00
|
|
|
// Scrape box back cover images.
|
2022-01-19 17:01:54 +00:00
|
|
|
auto scrapeBackCovers = std::make_shared<SwitchComponent>();
|
2021-10-28 19:00:23 +00:00
|
|
|
scrapeBackCovers->setState(Settings::getInstance()->getBool("ScrapeBackCovers"));
|
|
|
|
s->addWithLabel("BOX BACK COVER IMAGES", scrapeBackCovers);
|
|
|
|
s->addSaveFunc([scrapeBackCovers, s] {
|
|
|
|
if (scrapeBackCovers->getState() != Settings::getInstance()->getBool("ScrapeBackCovers")) {
|
|
|
|
Settings::getInstance()->setBool("ScrapeBackCovers", scrapeBackCovers->getState());
|
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
// Scrape marquee images.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scrapeMarquees = std::make_shared<SwitchComponent>();
|
|
|
|
scrapeMarquees->setState(Settings::getInstance()->getBool("ScrapeMarquees"));
|
|
|
|
s->addWithLabel("MARQUEE (WHEEL) IMAGES", scrapeMarquees);
|
|
|
|
s->addSaveFunc([scrapeMarquees, s] {
|
|
|
|
if (scrapeMarquees->getState() != Settings::getInstance()->getBool("ScrapeMarquees")) {
|
|
|
|
Settings::getInstance()->setBool("ScrapeMarquees", scrapeMarquees->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-06-21 12:25:28 +00:00
|
|
|
|
|
|
|
// Scrape 3D box images.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scrape3dBoxes = std::make_shared<SwitchComponent>();
|
|
|
|
scrape3dBoxes->setState(Settings::getInstance()->getBool("Scrape3DBoxes"));
|
|
|
|
s->addWithLabel("3D BOX IMAGES", scrape3dBoxes);
|
|
|
|
s->addSaveFunc([scrape3dBoxes, s] {
|
|
|
|
if (scrape3dBoxes->getState() != Settings::getInstance()->getBool("Scrape3DBoxes")) {
|
|
|
|
Settings::getInstance()->setBool("Scrape3DBoxes", scrape3dBoxes->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-06-21 12:25:28 +00:00
|
|
|
|
2021-07-11 11:47:31 +00:00
|
|
|
// 3D box images are not supported by TheGamesDB, so gray out the option if this scraper
|
2020-08-05 17:31:59 +00:00
|
|
|
// is selected.
|
|
|
|
if (Settings::getInstance()->getString("Scraper") == "thegamesdb") {
|
2022-09-03 10:44:49 +00:00
|
|
|
scrape3dBoxes->setEnabled(false);
|
|
|
|
scrape3dBoxes->setOpacity(DISABLED_OPACITY);
|
|
|
|
scrape3dBoxes->getParent()
|
|
|
|
->getChild(scrape3dBoxes->getChildIndex() - 1)
|
2021-07-07 18:03:42 +00:00
|
|
|
->setOpacity(DISABLED_OPACITY);
|
2020-08-05 17:31:59 +00:00
|
|
|
}
|
|
|
|
|
2021-10-28 19:00:23 +00:00
|
|
|
// Scrape physical media images.
|
2022-01-19 17:01:54 +00:00
|
|
|
auto scrapePhysicalMedia = std::make_shared<SwitchComponent>();
|
2021-10-28 19:00:23 +00:00
|
|
|
scrapePhysicalMedia->setState(Settings::getInstance()->getBool("ScrapePhysicalMedia"));
|
|
|
|
s->addWithLabel("PHYSICAL MEDIA IMAGES", scrapePhysicalMedia);
|
|
|
|
s->addSaveFunc([scrapePhysicalMedia, s] {
|
|
|
|
if (scrapePhysicalMedia->getState() !=
|
|
|
|
Settings::getInstance()->getBool("ScrapePhysicalMedia")) {
|
|
|
|
Settings::getInstance()->setBool("ScrapePhysicalMedia",
|
|
|
|
scrapePhysicalMedia->getState());
|
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Physical media images are not supported by TheGamesDB, so gray out the option if this
|
|
|
|
// scraper is selected.
|
|
|
|
if (Settings::getInstance()->getString("Scraper") == "thegamesdb") {
|
|
|
|
scrapePhysicalMedia->setEnabled(false);
|
|
|
|
scrapePhysicalMedia->setOpacity(DISABLED_OPACITY);
|
|
|
|
scrapePhysicalMedia->getParent()
|
|
|
|
->getChild(scrapePhysicalMedia->getChildIndex() - 1)
|
|
|
|
->setOpacity(DISABLED_OPACITY);
|
|
|
|
}
|
|
|
|
|
2022-01-16 09:43:12 +00:00
|
|
|
// Scrape fan art images.
|
2022-01-19 17:01:54 +00:00
|
|
|
auto scrapeFanArt = std::make_shared<SwitchComponent>();
|
2022-01-16 09:43:12 +00:00
|
|
|
scrapeFanArt->setState(Settings::getInstance()->getBool("ScrapeFanArt"));
|
|
|
|
s->addWithLabel("FAN ART IMAGES", scrapeFanArt);
|
|
|
|
s->addSaveFunc([scrapeFanArt, s] {
|
|
|
|
if (scrapeFanArt->getState() != Settings::getInstance()->getBool("ScrapeFanArt")) {
|
|
|
|
Settings::getInstance()->setBool("ScrapeFanArt", scrapeFanArt->getState());
|
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
mWindow->pushGui(s);
|
2020-06-06 11:10:33 +00:00
|
|
|
}
|
|
|
|
|
2021-06-07 21:02:42 +00:00
|
|
|
void GuiScraperMenu::openMiximageOptions()
|
|
|
|
{
|
2022-01-19 17:01:54 +00:00
|
|
|
auto s = new GuiSettings("MIXIMAGE SETTINGS");
|
2021-06-07 21:02:42 +00:00
|
|
|
|
|
|
|
// Miximage resolution.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto miximageResolution = std::make_shared<OptionListComponent<std::string>>(
|
2022-01-19 17:01:54 +00:00
|
|
|
getHelpStyle(), "MIXIMAGE RESOLUTION", false);
|
2022-09-03 10:44:49 +00:00
|
|
|
std::string selectedResolution {Settings::getInstance()->getString("MiximageResolution")};
|
|
|
|
miximageResolution->add("1280x960", "1280x960", selectedResolution == "1280x960");
|
|
|
|
miximageResolution->add("1920x1440", "1920x1440", selectedResolution == "1920x1440");
|
|
|
|
miximageResolution->add("640x480", "640x480", selectedResolution == "640x480");
|
2021-06-07 21:02:42 +00:00
|
|
|
// If there are no objects returned, then there must be a manually modified entry in the
|
|
|
|
// configuration file. Simply set the resolution to "1280x960" in this case.
|
2022-09-03 10:44:49 +00:00
|
|
|
if (miximageResolution->getSelectedObjects().size() == 0)
|
|
|
|
miximageResolution->selectEntry(0);
|
|
|
|
s->addWithLabel("MIXIMAGE RESOLUTION", miximageResolution);
|
|
|
|
s->addSaveFunc([miximageResolution, s] {
|
|
|
|
if (miximageResolution->getSelected() !=
|
2021-07-07 18:03:42 +00:00
|
|
|
Settings::getInstance()->getString("MiximageResolution")) {
|
|
|
|
Settings::getInstance()->setString("MiximageResolution",
|
2022-09-03 10:44:49 +00:00
|
|
|
miximageResolution->getSelected());
|
2021-06-07 21:02:42 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Screenshot scaling method.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto miximageScaling = std::make_shared<OptionListComponent<std::string>>(
|
2022-01-19 17:01:54 +00:00
|
|
|
getHelpStyle(), "SCREENSHOT SCALING", false);
|
2022-09-03 10:44:49 +00:00
|
|
|
std::string selectedScaling {Settings::getInstance()->getString("MiximageScreenshotScaling")};
|
|
|
|
miximageScaling->add("sharp", "sharp", selectedScaling == "sharp");
|
|
|
|
miximageScaling->add("smooth", "smooth", selectedScaling == "smooth");
|
2021-06-07 21:02:42 +00:00
|
|
|
// If there are no objects returned, then there must be a manually modified entry in the
|
|
|
|
// configuration file. Simply set the scaling method to "sharp" in this case.
|
2022-09-03 10:44:49 +00:00
|
|
|
if (miximageScaling->getSelectedObjects().size() == 0)
|
|
|
|
miximageScaling->selectEntry(0);
|
|
|
|
s->addWithLabel("SCREENSHOT SCALING METHOD", miximageScaling);
|
|
|
|
s->addSaveFunc([miximageScaling, s] {
|
|
|
|
if (miximageScaling->getSelected() !=
|
2021-07-07 18:03:42 +00:00
|
|
|
Settings::getInstance()->getString("MiximageScreenshotScaling")) {
|
|
|
|
Settings::getInstance()->setString("MiximageScreenshotScaling",
|
2022-09-03 10:44:49 +00:00
|
|
|
miximageScaling->getSelected());
|
2021-06-07 21:02:42 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-10-30 17:01:58 +00:00
|
|
|
// Box/cover size.
|
2022-01-19 17:01:54 +00:00
|
|
|
auto miximageBoxSize =
|
|
|
|
std::make_shared<OptionListComponent<std::string>>(getHelpStyle(), "BOX SIZE", false);
|
2022-09-03 10:44:49 +00:00
|
|
|
std::string selectedBoxSize {Settings::getInstance()->getString("MiximageBoxSize")};
|
2021-10-30 17:01:58 +00:00
|
|
|
miximageBoxSize->add("small", "small", selectedBoxSize == "small");
|
|
|
|
miximageBoxSize->add("medium", "medium", selectedBoxSize == "medium");
|
|
|
|
miximageBoxSize->add("large", "large", selectedBoxSize == "large");
|
|
|
|
// If there are no objects returned, then there must be a manually modified entry in the
|
|
|
|
// configuration file. Simply set the box size to "medium" in this case.
|
|
|
|
if (miximageBoxSize->getSelectedObjects().size() == 0)
|
|
|
|
miximageBoxSize->selectEntry(0);
|
|
|
|
s->addWithLabel("BOX SIZE", miximageBoxSize);
|
|
|
|
s->addSaveFunc([miximageBoxSize, s] {
|
|
|
|
if (miximageBoxSize->getSelected() !=
|
|
|
|
Settings::getInstance()->getString("MiximageBoxSize")) {
|
|
|
|
Settings::getInstance()->setString("MiximageBoxSize", miximageBoxSize->getSelected());
|
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Physical media size.
|
|
|
|
auto miximagePhysicalMediaSize = std::make_shared<OptionListComponent<std::string>>(
|
2022-01-19 17:01:54 +00:00
|
|
|
getHelpStyle(), "PHYSICAL MEDIA SIZE", false);
|
2022-09-03 10:44:49 +00:00
|
|
|
std::string selectedPhysicalMediaSize {
|
|
|
|
Settings::getInstance()->getString("MiximagePhysicalMediaSize")};
|
2021-10-30 17:01:58 +00:00
|
|
|
miximagePhysicalMediaSize->add("small", "small", selectedPhysicalMediaSize == "small");
|
|
|
|
miximagePhysicalMediaSize->add("medium", "medium", selectedPhysicalMediaSize == "medium");
|
|
|
|
miximagePhysicalMediaSize->add("large", "large", selectedPhysicalMediaSize == "large");
|
|
|
|
// If there are no objects returned, then there must be a manually modified entry in the
|
|
|
|
// configuration file. Simply set the physical media size to "medium" in this case.
|
|
|
|
if (miximagePhysicalMediaSize->getSelectedObjects().size() == 0)
|
|
|
|
miximagePhysicalMediaSize->selectEntry(0);
|
|
|
|
s->addWithLabel("PHYSICAL MEDIA SIZE", miximagePhysicalMediaSize);
|
|
|
|
s->addSaveFunc([miximagePhysicalMediaSize, s] {
|
|
|
|
if (miximagePhysicalMediaSize->getSelected() !=
|
|
|
|
Settings::getInstance()->getString("MiximagePhysicalMediaSize")) {
|
|
|
|
Settings::getInstance()->setString("MiximagePhysicalMediaSize",
|
|
|
|
miximagePhysicalMediaSize->getSelected());
|
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-06-07 21:02:42 +00:00
|
|
|
// Whether to generate miximages when scraping.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto miximageGenerate = std::make_shared<SwitchComponent>();
|
|
|
|
miximageGenerate->setState(Settings::getInstance()->getBool("MiximageGenerate"));
|
|
|
|
s->addWithLabel("GENERATE MIXIMAGES WHEN SCRAPING", miximageGenerate);
|
|
|
|
s->addSaveFunc([miximageGenerate, s] {
|
|
|
|
if (miximageGenerate->getState() != Settings::getInstance()->getBool("MiximageGenerate")) {
|
|
|
|
Settings::getInstance()->setBool("MiximageGenerate", miximageGenerate->getState());
|
2021-06-07 21:02:42 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Whether to overwrite miximages (both for the scraper and offline generator).
|
2022-09-03 10:44:49 +00:00
|
|
|
auto miximageOverwrite = std::make_shared<SwitchComponent>();
|
|
|
|
miximageOverwrite->setState(Settings::getInstance()->getBool("MiximageOverwrite"));
|
|
|
|
s->addWithLabel("OVERWRITE MIXIMAGES (SCRAPER/OFFLINE GENERATOR)", miximageOverwrite);
|
|
|
|
s->addSaveFunc([miximageOverwrite, s] {
|
|
|
|
if (miximageOverwrite->getState() !=
|
2021-07-07 18:03:42 +00:00
|
|
|
Settings::getInstance()->getBool("MiximageOverwrite")) {
|
2022-09-03 10:44:49 +00:00
|
|
|
Settings::getInstance()->setBool("MiximageOverwrite", miximageOverwrite->getState());
|
2021-06-07 21:02:42 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Whether to remove letterboxes from the screenshots.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto miximageRemoveLetterboxes = std::make_shared<SwitchComponent>();
|
|
|
|
miximageRemoveLetterboxes->setState(
|
|
|
|
Settings::getInstance()->getBool("MiximageRemoveLetterboxes"));
|
|
|
|
s->addWithLabel("REMOVE LETTERBOXES FROM SCREENSHOTS", miximageRemoveLetterboxes);
|
|
|
|
s->addSaveFunc([miximageRemoveLetterboxes, s] {
|
|
|
|
if (miximageRemoveLetterboxes->getState() !=
|
2021-07-07 18:03:42 +00:00
|
|
|
Settings::getInstance()->getBool("MiximageRemoveLetterboxes")) {
|
2021-06-07 21:02:42 +00:00
|
|
|
Settings::getInstance()->setBool("MiximageRemoveLetterboxes",
|
2022-09-03 10:44:49 +00:00
|
|
|
miximageRemoveLetterboxes->getState());
|
2021-06-07 21:02:42 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Whether to remove pillarboxes from the screenshots.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto miximageRemovePillarboxes = std::make_shared<SwitchComponent>();
|
|
|
|
miximageRemovePillarboxes->setState(
|
|
|
|
Settings::getInstance()->getBool("MiximageRemovePillarboxes"));
|
|
|
|
s->addWithLabel("REMOVE PILLARBOXES FROM SCREENSHOTS", miximageRemovePillarboxes);
|
|
|
|
s->addSaveFunc([miximageRemovePillarboxes, s] {
|
|
|
|
if (miximageRemovePillarboxes->getState() !=
|
2021-07-07 18:03:42 +00:00
|
|
|
Settings::getInstance()->getBool("MiximageRemovePillarboxes")) {
|
2021-06-07 21:02:42 +00:00
|
|
|
Settings::getInstance()->setBool("MiximageRemovePillarboxes",
|
2022-09-03 10:44:49 +00:00
|
|
|
miximageRemovePillarboxes->getState());
|
2021-06-07 21:02:42 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-10-30 17:01:58 +00:00
|
|
|
// Whether to rotate horizontally oriented boxes.
|
2022-01-19 17:01:54 +00:00
|
|
|
auto miximageRotateBoxes = std::make_shared<SwitchComponent>();
|
2021-10-30 17:01:58 +00:00
|
|
|
miximageRotateBoxes->setState(
|
|
|
|
Settings::getInstance()->getBool("MiximageRotateHorizontalBoxes"));
|
|
|
|
s->addWithLabel("ROTATE HORIZONTALLY ORIENTED BOXES", miximageRotateBoxes);
|
|
|
|
s->addSaveFunc([miximageRotateBoxes, s] {
|
|
|
|
if (miximageRotateBoxes->getState() !=
|
|
|
|
Settings::getInstance()->getBool("MiximageRotateHorizontalBoxes")) {
|
|
|
|
Settings::getInstance()->setBool("MiximageRotateHorizontalBoxes",
|
|
|
|
miximageRotateBoxes->getState());
|
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-06-07 21:02:42 +00:00
|
|
|
// Whether to include marquee images.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto miximageIncludeMarquee = std::make_shared<SwitchComponent>();
|
|
|
|
miximageIncludeMarquee->setState(Settings::getInstance()->getBool("MiximageIncludeMarquee"));
|
|
|
|
s->addWithLabel("INCLUDE MARQUEE IMAGE", miximageIncludeMarquee);
|
|
|
|
s->addSaveFunc([miximageIncludeMarquee, s] {
|
|
|
|
if (miximageIncludeMarquee->getState() !=
|
2021-07-07 18:03:42 +00:00
|
|
|
Settings::getInstance()->getBool("MiximageIncludeMarquee")) {
|
|
|
|
Settings::getInstance()->setBool("MiximageIncludeMarquee",
|
2022-09-03 10:44:49 +00:00
|
|
|
miximageIncludeMarquee->getState());
|
2021-06-07 21:02:42 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Whether to include box images.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto miximageIncludeBox = std::make_shared<SwitchComponent>();
|
|
|
|
miximageIncludeBox->setState(Settings::getInstance()->getBool("MiximageIncludeBox"));
|
|
|
|
s->addWithLabel("INCLUDE BOX IMAGE", miximageIncludeBox);
|
|
|
|
s->addSaveFunc([miximageIncludeBox, s] {
|
|
|
|
if (miximageIncludeBox->getState() !=
|
|
|
|
Settings::getInstance()->getBool("MiximageIncludeBox")) {
|
|
|
|
Settings::getInstance()->setBool("MiximageIncludeBox", miximageIncludeBox->getState());
|
2021-06-07 21:02:42 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Whether to use cover image if there is no 3D box image.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto miximageCoverFallback = std::make_shared<SwitchComponent>();
|
|
|
|
miximageCoverFallback->setState(Settings::getInstance()->getBool("MiximageCoverFallback"));
|
|
|
|
s->addWithLabel("USE COVER IMAGE IF 3D BOX IS MISSING", miximageCoverFallback);
|
|
|
|
s->addSaveFunc([miximageCoverFallback, s] {
|
|
|
|
if (miximageCoverFallback->getState() !=
|
2021-07-07 18:03:42 +00:00
|
|
|
Settings::getInstance()->getBool("MiximageCoverFallback")) {
|
|
|
|
Settings::getInstance()->setBool("MiximageCoverFallback",
|
2022-09-03 10:44:49 +00:00
|
|
|
miximageCoverFallback->getState());
|
2021-06-07 21:02:42 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-10-30 17:01:58 +00:00
|
|
|
// Whether to include physical media images.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto miximageIncludePhysicalMedia = std::make_shared<SwitchComponent>();
|
|
|
|
miximageIncludePhysicalMedia->setState(
|
2021-10-30 17:01:58 +00:00
|
|
|
Settings::getInstance()->getBool("MiximageIncludePhysicalMedia"));
|
2022-09-03 10:44:49 +00:00
|
|
|
s->addWithLabel("INCLUDE PHYSICAL MEDIA IMAGE", miximageIncludePhysicalMedia);
|
|
|
|
s->addSaveFunc([miximageIncludePhysicalMedia, s] {
|
|
|
|
if (miximageIncludePhysicalMedia->getState() !=
|
2021-10-30 17:01:58 +00:00
|
|
|
Settings::getInstance()->getBool("MiximageIncludePhysicalMedia")) {
|
|
|
|
Settings::getInstance()->setBool("MiximageIncludePhysicalMedia",
|
2022-09-03 10:44:49 +00:00
|
|
|
miximageIncludePhysicalMedia->getState());
|
2021-10-30 17:01:58 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-06-09 18:56:41 +00:00
|
|
|
// Miximage offline generator.
|
2022-09-03 10:44:49 +00:00
|
|
|
ComponentListRow offlineGeneratorRow;
|
|
|
|
offlineGeneratorRow.elements.clear();
|
|
|
|
offlineGeneratorRow.addElement(std::make_shared<TextComponent>("OFFLINE GENERATOR",
|
|
|
|
Font::get(FONT_SIZE_MEDIUM),
|
|
|
|
0x777777FF),
|
|
|
|
true);
|
|
|
|
offlineGeneratorRow.addElement(makeArrow(), false);
|
|
|
|
offlineGeneratorRow.makeAcceptInputHandler(
|
2021-07-07 18:03:42 +00:00
|
|
|
std::bind(&GuiScraperMenu::openOfflineGenerator, this, s));
|
2022-09-03 10:44:49 +00:00
|
|
|
s->addRow(offlineGeneratorRow);
|
2021-06-09 18:56:41 +00:00
|
|
|
|
2021-06-07 21:02:42 +00:00
|
|
|
mWindow->pushGui(s);
|
|
|
|
}
|
|
|
|
|
2021-06-09 18:56:41 +00:00
|
|
|
void GuiScraperMenu::openOfflineGenerator(GuiSettings* settings)
|
|
|
|
{
|
|
|
|
if (mSystems->getSelectedObjects().empty()) {
|
2022-01-19 17:01:54 +00:00
|
|
|
mWindow->pushGui(new GuiMsgBox(getHelpStyle(),
|
2021-11-04 09:07:08 +00:00
|
|
|
"THE OFFLINE GENERATOR USES THE SAME SYSTEM\n"
|
2021-07-07 18:03:42 +00:00
|
|
|
"SELECTIONS AS THE SCRAPER, SO PLEASE SELECT\n"
|
|
|
|
"AT LEAST ONE SYSTEM TO GENERATE IMAGES FOR"));
|
2021-06-09 18:56:41 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Always save the settings before starting the generator, in case any of the
|
|
|
|
// miximage settings were modified.
|
|
|
|
settings->save();
|
|
|
|
// Also unset the save flag so that a double saving does not take place when closing
|
|
|
|
// the miximage options menu later on.
|
|
|
|
settings->setNeedsSaving(false);
|
|
|
|
|
|
|
|
// Build the queue of games to process.
|
|
|
|
std::queue<FileData*> gameQueue;
|
2022-09-03 10:44:49 +00:00
|
|
|
std::vector<SystemData*> systems {mSystems->getSelectedObjects()};
|
2021-06-09 18:56:41 +00:00
|
|
|
|
2021-11-17 16:35:34 +00:00
|
|
|
for (auto sys = systems.cbegin(); sys != systems.cend(); ++sys) {
|
2022-09-03 10:44:49 +00:00
|
|
|
std::vector<FileData*> games {(*sys)->getRootFolder()->getChildrenRecursive()};
|
2021-06-09 18:56:41 +00:00
|
|
|
|
|
|
|
// Sort the games by "filename, ascending".
|
|
|
|
std::stable_sort(games.begin(), games.end(), FileSorts::SortTypes.at(0).comparisonFunction);
|
|
|
|
|
|
|
|
for (FileData* game : games)
|
|
|
|
gameQueue.push(game);
|
|
|
|
}
|
|
|
|
|
2022-01-19 17:01:54 +00:00
|
|
|
mWindow->pushGui(new GuiOfflineGenerator(gameQueue));
|
2021-06-09 18:56:41 +00:00
|
|
|
}
|
|
|
|
|
2021-06-07 21:02:42 +00:00
|
|
|
void GuiScraperMenu::openOtherOptions()
|
2020-06-06 11:10:33 +00:00
|
|
|
{
|
2022-01-19 17:01:54 +00:00
|
|
|
auto s = new GuiSettings("OTHER SETTINGS");
|
2020-06-21 12:25:28 +00:00
|
|
|
|
|
|
|
// Scraper region.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperRegion =
|
2022-01-19 17:01:54 +00:00
|
|
|
std::make_shared<OptionListComponent<std::string>>(getHelpStyle(), "REGION", false);
|
2022-09-03 10:44:49 +00:00
|
|
|
std::string selectedScraperRegion {Settings::getInstance()->getString("ScraperRegion")};
|
2021-07-07 18:03:42 +00:00
|
|
|
// clang-format off
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperRegion->add("Europe", "eu", selectedScraperRegion == "eu");
|
|
|
|
scraperRegion->add("Japan", "jp", selectedScraperRegion == "jp");
|
|
|
|
scraperRegion->add("USA", "us", selectedScraperRegion == "us");
|
|
|
|
scraperRegion->add("World", "wor", selectedScraperRegion == "wor");
|
2021-07-07 18:03:42 +00:00
|
|
|
// clang-format on
|
2021-01-26 20:04:16 +00:00
|
|
|
// If there are no objects returned, then there must be a manually modified entry in the
|
2021-06-07 21:02:42 +00:00
|
|
|
// configuration file. Simply set the region to "Europe" in this case.
|
2022-09-03 10:44:49 +00:00
|
|
|
if (scraperRegion->getSelectedObjects().size() == 0)
|
|
|
|
scraperRegion->selectEntry(0);
|
|
|
|
s->addWithLabel("REGION", scraperRegion);
|
|
|
|
s->addSaveFunc([scraperRegion, s] {
|
|
|
|
if (scraperRegion->getSelected() != Settings::getInstance()->getString("ScraperRegion")) {
|
|
|
|
Settings::getInstance()->setString("ScraperRegion", scraperRegion->getSelected());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
2020-06-21 12:25:28 +00:00
|
|
|
});
|
|
|
|
|
2021-07-11 11:47:31 +00:00
|
|
|
// Regions are not supported by TheGamesDB, so gray out the option if this scraper is selected.
|
2020-08-05 17:31:59 +00:00
|
|
|
if (Settings::getInstance()->getString("Scraper") == "thegamesdb") {
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperRegion->setEnabled(false);
|
|
|
|
scraperRegion->setOpacity(DISABLED_OPACITY);
|
|
|
|
scraperRegion->getParent()
|
|
|
|
->getChild(scraperRegion->getChildIndex() - 1)
|
2021-07-07 18:03:42 +00:00
|
|
|
->setOpacity(DISABLED_OPACITY);
|
2020-08-05 17:31:59 +00:00
|
|
|
}
|
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
// Scraper language.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperLanguage = std::make_shared<OptionListComponent<std::string>>(
|
2022-01-19 17:01:54 +00:00
|
|
|
getHelpStyle(), "PREFERRED LANGUAGE", false);
|
2022-09-03 10:44:49 +00:00
|
|
|
std::string selectedScraperLanguage {Settings::getInstance()->getString("ScraperLanguage")};
|
2021-07-07 18:03:42 +00:00
|
|
|
// clang-format off
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperLanguage->add("English", "en", selectedScraperLanguage == "en");
|
|
|
|
scraperLanguage->add("Español", "es", selectedScraperLanguage == "es");
|
|
|
|
scraperLanguage->add("Português", "pt", selectedScraperLanguage == "pt");
|
|
|
|
scraperLanguage->add("Français", "fr", selectedScraperLanguage == "fr");
|
|
|
|
scraperLanguage->add("Deutsch", "de", selectedScraperLanguage == "de");
|
|
|
|
scraperLanguage->add("Italiano", "it", selectedScraperLanguage == "it");
|
|
|
|
scraperLanguage->add("Nederlands", "nl", selectedScraperLanguage == "nl");
|
|
|
|
scraperLanguage->add("日本語", "ja", selectedScraperLanguage == "ja");
|
|
|
|
scraperLanguage->add("简体中文", "zh", selectedScraperLanguage == "zh");
|
|
|
|
scraperLanguage->add("한국어", "ko", selectedScraperLanguage == "ko");
|
|
|
|
scraperLanguage->add("Русский", "ru", selectedScraperLanguage == "ru");
|
|
|
|
scraperLanguage->add("Dansk", "da", selectedScraperLanguage == "da");
|
|
|
|
scraperLanguage->add("Suomi", "fi", selectedScraperLanguage == "fi");
|
|
|
|
scraperLanguage->add("Svenska", "sv", selectedScraperLanguage == "sv");
|
|
|
|
scraperLanguage->add("Magyar", "hu", selectedScraperLanguage == "hu");
|
|
|
|
scraperLanguage->add("Norsk", "no", selectedScraperLanguage == "no");
|
|
|
|
scraperLanguage->add("Polski", "pl", selectedScraperLanguage == "pl");
|
|
|
|
scraperLanguage->add("Čeština", "cz", selectedScraperLanguage == "cz");
|
|
|
|
scraperLanguage->add("Slovenčina", "sk", selectedScraperLanguage == "sk");
|
|
|
|
scraperLanguage->add("Türkçe", "tr", selectedScraperLanguage == "tr");
|
2021-07-11 11:31:43 +00:00
|
|
|
// clang-format on
|
2021-01-26 20:04:16 +00:00
|
|
|
// If there are no objects returned, then there must be a manually modified entry in the
|
2021-06-07 21:02:42 +00:00
|
|
|
// configuration file. Simply set the language to "English" in this case.
|
2022-09-03 10:44:49 +00:00
|
|
|
if (scraperLanguage->getSelectedObjects().size() == 0)
|
|
|
|
scraperLanguage->selectEntry(0);
|
|
|
|
s->addWithLabel("PREFERRED LANGUAGE", scraperLanguage);
|
|
|
|
s->addSaveFunc([scraperLanguage, s] {
|
|
|
|
if (scraperLanguage->getSelected() !=
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getString("ScraperLanguage")) {
|
2022-09-03 10:44:49 +00:00
|
|
|
Settings::getInstance()->setString("ScraperLanguage", scraperLanguage->getSelected());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
2020-06-21 12:25:28 +00:00
|
|
|
});
|
|
|
|
|
2021-07-11 11:47:31 +00:00
|
|
|
// Languages are not supported by TheGamesDB, so gray out the option if this scraper is
|
|
|
|
// selected.
|
2020-08-05 17:31:59 +00:00
|
|
|
if (Settings::getInstance()->getString("Scraper") == "thegamesdb") {
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperLanguage->setEnabled(false);
|
|
|
|
scraperLanguage->setOpacity(DISABLED_OPACITY);
|
|
|
|
scraperLanguage->getParent()
|
|
|
|
->getChild(scraperLanguage->getChildIndex() - 1)
|
2021-07-11 11:31:43 +00:00
|
|
|
->setOpacity(DISABLED_OPACITY);
|
2020-08-05 17:31:59 +00:00
|
|
|
}
|
|
|
|
|
2020-10-19 19:05:04 +00:00
|
|
|
// Overwrite files and data.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperOverwriteData = std::make_shared<SwitchComponent>();
|
|
|
|
scraperOverwriteData->setState(Settings::getInstance()->getBool("ScraperOverwriteData"));
|
|
|
|
s->addWithLabel("OVERWRITE FILES AND DATA", scraperOverwriteData);
|
|
|
|
s->addSaveFunc([scraperOverwriteData, s] {
|
|
|
|
if (scraperOverwriteData->getState() !=
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperOverwriteData")) {
|
2020-11-05 17:18:11 +00:00
|
|
|
Settings::getInstance()->setBool("ScraperOverwriteData",
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperOverwriteData->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-10-19 19:05:04 +00:00
|
|
|
|
2020-12-18 15:35:19 +00:00
|
|
|
// Halt scraping on invalid media files.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperHaltOnInvalidMedia = std::make_shared<SwitchComponent>();
|
|
|
|
scraperHaltOnInvalidMedia->setState(
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperHaltOnInvalidMedia"));
|
2022-09-03 10:44:49 +00:00
|
|
|
s->addWithLabel("HALT ON INVALID MEDIA FILES", scraperHaltOnInvalidMedia);
|
|
|
|
s->addSaveFunc([scraperHaltOnInvalidMedia, s] {
|
|
|
|
if (scraperHaltOnInvalidMedia->getState() !=
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperHaltOnInvalidMedia")) {
|
2020-12-18 15:35:19 +00:00
|
|
|
Settings::getInstance()->setBool("ScraperHaltOnInvalidMedia",
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperHaltOnInvalidMedia->getState());
|
2020-12-18 15:35:19 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-01-26 20:36:25 +00:00
|
|
|
// Search using metadata names.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperSearchMetadataName = std::make_shared<SwitchComponent>();
|
|
|
|
scraperSearchMetadataName->setState(
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperSearchMetadataName"));
|
2022-09-03 10:44:49 +00:00
|
|
|
s->addWithLabel("SEARCH USING METADATA NAMES", scraperSearchMetadataName);
|
|
|
|
s->addSaveFunc([scraperSearchMetadataName, s] {
|
|
|
|
if (scraperSearchMetadataName->getState() !=
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperSearchMetadataName")) {
|
2020-11-05 17:18:11 +00:00
|
|
|
Settings::getInstance()->setBool("ScraperSearchMetadataName",
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperSearchMetadataName->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-10-10 11:05:12 +00:00
|
|
|
|
2022-01-03 17:20:49 +00:00
|
|
|
// Include actual folders when scraping.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperIncludeFolders = std::make_shared<SwitchComponent>();
|
|
|
|
scraperIncludeFolders->setState(Settings::getInstance()->getBool("ScraperIncludeFolders"));
|
|
|
|
s->addWithLabel("SCRAPE ACTUAL FOLDERS", scraperIncludeFolders);
|
|
|
|
s->addSaveFunc([scraperIncludeFolders, s] {
|
|
|
|
if (scraperIncludeFolders->getState() !=
|
2022-01-03 17:20:49 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperIncludeFolders")) {
|
|
|
|
Settings::getInstance()->setBool("ScraperIncludeFolders",
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperIncludeFolders->getState());
|
2022-01-03 17:20:49 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
// Interactive scraping.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperInteractive = std::make_shared<SwitchComponent>();
|
|
|
|
scraperInteractive->setState(Settings::getInstance()->getBool("ScraperInteractive"));
|
|
|
|
s->addWithLabel("INTERACTIVE MODE", scraperInteractive);
|
|
|
|
s->addSaveFunc([scraperInteractive, s] {
|
|
|
|
if (scraperInteractive->getState() !=
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperInteractive")) {
|
2022-09-03 10:44:49 +00:00
|
|
|
Settings::getInstance()->setBool("ScraperInteractive", scraperInteractive->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-06-21 12:25:28 +00:00
|
|
|
|
|
|
|
// Semi-automatic scraping.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperSemiautomatic = std::make_shared<SwitchComponent>();
|
|
|
|
scraperSemiautomatic->setState(Settings::getInstance()->getBool("ScraperSemiautomatic"));
|
|
|
|
s->addWithLabel("AUTO-ACCEPT SINGLE GAME MATCHES", scraperSemiautomatic);
|
|
|
|
s->addSaveFunc([scraperSemiautomatic, s] {
|
|
|
|
if (scraperSemiautomatic->getState() !=
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperSemiautomatic")) {
|
2020-06-21 12:25:28 +00:00
|
|
|
Settings::getInstance()->setBool("ScraperSemiautomatic",
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperSemiautomatic->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-06-21 12:25:28 +00:00
|
|
|
|
2021-07-11 11:47:31 +00:00
|
|
|
// If interactive mode is set to off, then gray out this option.
|
2020-12-15 17:49:43 +00:00
|
|
|
if (!Settings::getInstance()->getBool("ScraperInteractive")) {
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperSemiautomatic->setEnabled(false);
|
|
|
|
scraperSemiautomatic->setOpacity(DISABLED_OPACITY);
|
|
|
|
scraperSemiautomatic->getParent()
|
|
|
|
->getChild(scraperSemiautomatic->getChildIndex() - 1)
|
2021-07-11 11:31:43 +00:00
|
|
|
->setOpacity(DISABLED_OPACITY);
|
2020-12-15 17:49:43 +00:00
|
|
|
}
|
|
|
|
|
2020-08-06 09:27:16 +00:00
|
|
|
// Respect the per-file multi-scraper exclusion flag.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperRespectExclusions = std::make_shared<SwitchComponent>();
|
|
|
|
scraperRespectExclusions->setState(
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperRespectExclusions"));
|
2022-09-03 10:44:49 +00:00
|
|
|
s->addWithLabel("RESPECT PER-FILE SCRAPER EXCLUSIONS", scraperRespectExclusions);
|
|
|
|
s->addSaveFunc([scraperRespectExclusions, s] {
|
|
|
|
if (scraperRespectExclusions->getState() !=
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperRespectExclusions")) {
|
2020-08-06 09:27:16 +00:00
|
|
|
Settings::getInstance()->setBool("ScraperRespectExclusions",
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperRespectExclusions->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-08-06 09:27:16 +00:00
|
|
|
|
2020-08-06 13:12:04 +00:00
|
|
|
// Exclude files recursively for excluded folders.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperExcludeRecursively = std::make_shared<SwitchComponent>();
|
|
|
|
scraperExcludeRecursively->setState(
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperExcludeRecursively"));
|
2022-09-03 10:44:49 +00:00
|
|
|
s->addWithLabel("EXCLUDE FOLDERS RECURSIVELY", scraperExcludeRecursively);
|
|
|
|
s->addSaveFunc([scraperExcludeRecursively, s] {
|
|
|
|
if (scraperExcludeRecursively->getState() !=
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperExcludeRecursively")) {
|
2020-08-06 13:12:04 +00:00
|
|
|
Settings::getInstance()->setBool("ScraperExcludeRecursively",
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperExcludeRecursively->getState());
|
2020-11-05 17:18:11 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
2020-08-06 13:12:04 +00:00
|
|
|
|
2021-07-11 11:47:31 +00:00
|
|
|
// If respecting excluded files is set to off, then gray out this option.
|
2020-12-15 17:49:43 +00:00
|
|
|
if (!Settings::getInstance()->getBool("ScraperRespectExclusions")) {
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperExcludeRecursively->setEnabled(false);
|
|
|
|
scraperExcludeRecursively->setOpacity(DISABLED_OPACITY);
|
|
|
|
scraperExcludeRecursively->getParent()
|
|
|
|
->getChild(scraperExcludeRecursively->getChildIndex() - 1)
|
2021-07-11 11:31:43 +00:00
|
|
|
->setOpacity(DISABLED_OPACITY);
|
2020-12-15 17:49:43 +00:00
|
|
|
}
|
|
|
|
|
2022-04-09 13:14:48 +00:00
|
|
|
// Convert underscores to spaces when searching.
|
|
|
|
auto scraperConvertUnderscores = std::make_shared<SwitchComponent>();
|
|
|
|
scraperConvertUnderscores->setState(
|
|
|
|
Settings::getInstance()->getBool("ScraperConvertUnderscores"));
|
|
|
|
s->addWithLabel("CONVERT UNDERSCORES TO SPACES WHEN SEARCHING", scraperConvertUnderscores);
|
|
|
|
s->addSaveFunc([scraperConvertUnderscores, s] {
|
|
|
|
if (scraperConvertUnderscores->getState() !=
|
|
|
|
Settings::getInstance()->getBool("ScraperConvertUnderscores")) {
|
|
|
|
Settings::getInstance()->setBool("ScraperConvertUnderscores",
|
|
|
|
scraperConvertUnderscores->getState());
|
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2022-09-20 20:45:32 +00:00
|
|
|
// Whether to remove dots from game names when searching using the automatic scraper.
|
|
|
|
auto scraperAutomaticRemoveDots = std::make_shared<SwitchComponent>();
|
|
|
|
scraperAutomaticRemoveDots->setState(
|
|
|
|
Settings::getInstance()->getBool("ScraperAutomaticRemoveDots"));
|
|
|
|
s->addWithLabel("REMOVE DOTS FROM SEARCHES WHEN AUTO-SCRAPING", scraperAutomaticRemoveDots);
|
|
|
|
s->addSaveFunc([scraperAutomaticRemoveDots, s] {
|
|
|
|
if (scraperAutomaticRemoveDots->getState() !=
|
|
|
|
Settings::getInstance()->getBool("ScraperAutomaticRemoveDots")) {
|
|
|
|
Settings::getInstance()->setBool("ScraperAutomaticRemoveDots",
|
|
|
|
scraperAutomaticRemoveDots->getState());
|
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// This is not needed for TheGamesDB, so gray out the option if this scraper is selected.
|
|
|
|
if (Settings::getInstance()->getString("Scraper") == "thegamesdb") {
|
|
|
|
scraperAutomaticRemoveDots->setEnabled(false);
|
|
|
|
scraperAutomaticRemoveDots->setOpacity(DISABLED_OPACITY);
|
|
|
|
scraperAutomaticRemoveDots->getParent()
|
|
|
|
->getChild(scraperAutomaticRemoveDots->getChildIndex() - 1)
|
|
|
|
->setOpacity(DISABLED_OPACITY);
|
|
|
|
}
|
|
|
|
|
2022-06-16 17:56:41 +00:00
|
|
|
// Whether to fallback to additional regions.
|
|
|
|
auto scraperRegionFallback = std::make_shared<SwitchComponent>(mWindow);
|
|
|
|
scraperRegionFallback->setState(Settings::getInstance()->getBool("ScraperRegionFallback"));
|
|
|
|
s->addWithLabel("ENABLE FALLBACK TO ADDITIONAL REGIONS", scraperRegionFallback);
|
|
|
|
s->addSaveFunc([scraperRegionFallback, s] {
|
|
|
|
if (scraperRegionFallback->getState() !=
|
|
|
|
Settings::getInstance()->getBool("ScraperRegionFallback")) {
|
|
|
|
Settings::getInstance()->setBool("ScraperRegionFallback",
|
|
|
|
scraperRegionFallback->getState());
|
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Regions are not supported by TheGamesDB, so gray out the option if this scraper is selected.
|
|
|
|
if (Settings::getInstance()->getString("Scraper") == "thegamesdb") {
|
|
|
|
scraperRegionFallback->setEnabled(false);
|
|
|
|
scraperRegionFallback->setOpacity(DISABLED_OPACITY);
|
|
|
|
scraperRegionFallback->getParent()
|
|
|
|
->getChild(scraperRegionFallback->getChildIndex() - 1)
|
|
|
|
->setOpacity(DISABLED_OPACITY);
|
|
|
|
}
|
|
|
|
|
2021-05-24 16:51:16 +00:00
|
|
|
// Retry search on peer verification errors (TLS/certificate issues).
|
2022-09-03 10:44:49 +00:00
|
|
|
auto scraperRetryPeerVerification = std::make_shared<SwitchComponent>();
|
|
|
|
scraperRetryPeerVerification->setState(
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperRetryPeerVerification"));
|
2022-09-03 10:44:49 +00:00
|
|
|
s->addWithLabel("AUTO-RETRY ON PEER VERIFICATION ERRORS", scraperRetryPeerVerification);
|
|
|
|
s->addSaveFunc([scraperRetryPeerVerification, s] {
|
|
|
|
if (scraperRetryPeerVerification->getState() !=
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperRetryPeerVerification")) {
|
2021-05-24 16:51:16 +00:00
|
|
|
Settings::getInstance()->setBool("ScraperRetryPeerVerification",
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperRetryPeerVerification->getState());
|
2021-05-24 16:51:16 +00:00
|
|
|
s->setNeedsSaving();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2021-07-11 11:47:31 +00:00
|
|
|
// The TLS/certificate issue is not present for TheGamesDB, so gray out the option if this
|
|
|
|
// scraper is selected.
|
|
|
|
if (Settings::getInstance()->getString("Scraper") == "thegamesdb") {
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperRetryPeerVerification->setEnabled(false);
|
|
|
|
scraperRetryPeerVerification->setOpacity(DISABLED_OPACITY);
|
|
|
|
scraperRetryPeerVerification->getParent()
|
|
|
|
->getChild(scraperRetryPeerVerification->getChildIndex() - 1)
|
2021-07-11 11:47:31 +00:00
|
|
|
->setOpacity(DISABLED_OPACITY);
|
|
|
|
}
|
|
|
|
|
2020-12-15 17:49:43 +00:00
|
|
|
// Switch callbacks.
|
2022-09-03 10:44:49 +00:00
|
|
|
auto interactiveToggleFunc = [scraperSemiautomatic]() {
|
|
|
|
if (scraperSemiautomatic->getEnabled()) {
|
|
|
|
scraperSemiautomatic->setEnabled(false);
|
|
|
|
scraperSemiautomatic->setOpacity(DISABLED_OPACITY);
|
|
|
|
scraperSemiautomatic->getParent()
|
|
|
|
->getChild(scraperSemiautomatic->getChildIndex() - 1)
|
2021-07-11 11:31:43 +00:00
|
|
|
->setOpacity(DISABLED_OPACITY);
|
2020-12-15 17:49:43 +00:00
|
|
|
}
|
|
|
|
else {
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperSemiautomatic->setEnabled(true);
|
|
|
|
scraperSemiautomatic->setOpacity(1.0f);
|
|
|
|
scraperSemiautomatic->getParent()
|
|
|
|
->getChild(scraperSemiautomatic->getChildIndex() - 1)
|
2022-02-11 21:10:25 +00:00
|
|
|
->setOpacity(1.0f);
|
2020-12-15 17:49:43 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-09-03 10:44:49 +00:00
|
|
|
auto excludeRecursivelyToggleFunc = [scraperExcludeRecursively]() {
|
|
|
|
if (scraperExcludeRecursively->getEnabled()) {
|
|
|
|
scraperExcludeRecursively->setEnabled(false);
|
|
|
|
scraperExcludeRecursively->setOpacity(DISABLED_OPACITY);
|
|
|
|
scraperExcludeRecursively->getParent()
|
|
|
|
->getChild(scraperExcludeRecursively->getChildIndex() - 1)
|
2021-07-11 11:31:43 +00:00
|
|
|
->setOpacity(DISABLED_OPACITY);
|
2020-12-15 17:49:43 +00:00
|
|
|
}
|
|
|
|
else {
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperExcludeRecursively->setEnabled(true);
|
|
|
|
scraperExcludeRecursively->setOpacity(1.0f);
|
|
|
|
scraperExcludeRecursively->getParent()
|
|
|
|
->getChild(scraperExcludeRecursively->getChildIndex() - 1)
|
2022-02-11 21:10:25 +00:00
|
|
|
->setOpacity(1.0f);
|
2020-12-15 17:49:43 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-09-03 10:44:49 +00:00
|
|
|
scraperInteractive->setCallback(interactiveToggleFunc);
|
|
|
|
scraperRespectExclusions->setCallback(excludeRecursivelyToggleFunc);
|
2020-12-15 17:49:43 +00:00
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
mWindow->pushGui(s);
|
2020-06-06 11:10:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GuiScraperMenu::pressedStart()
|
|
|
|
{
|
2020-11-05 17:18:11 +00:00
|
|
|
// If the scraper service has been changed, then save the settings as otherwise the
|
|
|
|
// wrong scraper would be used.
|
|
|
|
if (mScraper->getSelected() != Settings::getInstance()->getString("Scraper"))
|
|
|
|
mMenu.save();
|
2020-06-21 12:25:28 +00:00
|
|
|
|
2022-09-03 10:44:49 +00:00
|
|
|
std::vector<SystemData*> sys {mSystems->getSelectedObjects()};
|
2021-11-17 16:35:34 +00:00
|
|
|
for (auto it = sys.cbegin(); it != sys.cend(); ++it) {
|
2020-06-21 12:25:28 +00:00
|
|
|
if ((*it)->getPlatformIds().empty()) {
|
2021-02-08 19:56:11 +00:00
|
|
|
std::string warningString;
|
|
|
|
if (sys.size() == 1) {
|
|
|
|
warningString = "The selected system does not have a\n"
|
2021-07-11 11:31:43 +00:00
|
|
|
"platform set, results may be inaccurate\n"
|
|
|
|
"Continue anyway?";
|
2021-02-08 19:56:11 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
warningString = "At least one of your selected\n"
|
2021-07-11 11:31:43 +00:00
|
|
|
"systems does not have a platform\n"
|
|
|
|
"set, results may be inaccurate\n"
|
|
|
|
"Continue anyway?";
|
2021-02-08 19:56:11 +00:00
|
|
|
}
|
2022-01-19 17:01:54 +00:00
|
|
|
mWindow->pushGui(new GuiMsgBox(getHelpStyle(), Utils::String::toUpper(warningString),
|
|
|
|
"YES", std::bind(&GuiScraperMenu::start, this), "NO",
|
|
|
|
nullptr));
|
2020-06-21 12:25:28 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
start();
|
2020-06-06 11:10:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void GuiScraperMenu::start()
|
|
|
|
{
|
2021-01-17 10:58:58 +00:00
|
|
|
if (mSystems->getSelectedObjects().empty()) {
|
2021-07-11 11:31:43 +00:00
|
|
|
mWindow->pushGui(
|
2022-01-19 17:01:54 +00:00
|
|
|
new GuiMsgBox(getHelpStyle(), "PLEASE SELECT AT LEAST ONE SYSTEM TO SCRAPE"));
|
2021-01-17 10:58:58 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-09-03 10:44:49 +00:00
|
|
|
bool contentToScrape {false};
|
|
|
|
std::string scraperService {Settings::getInstance()->getString("Scraper")};
|
2021-01-17 10:58:58 +00:00
|
|
|
|
|
|
|
// Check if there is actually any type of content selected for scraping.
|
|
|
|
do {
|
|
|
|
if (Settings::getInstance()->getBool("ScrapeGameNames")) {
|
|
|
|
contentToScrape = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (scraperService == "screenscraper" &&
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScrapeRatings")) {
|
2021-01-17 10:58:58 +00:00
|
|
|
contentToScrape = true;
|
|
|
|
break;
|
|
|
|
}
|
2021-10-27 17:23:57 +00:00
|
|
|
if (scraperService == "screenscraper" &&
|
|
|
|
Settings::getInstance()->getBool("ScrapeControllers")) {
|
|
|
|
contentToScrape = true;
|
|
|
|
break;
|
|
|
|
}
|
2021-01-17 10:58:58 +00:00
|
|
|
if (Settings::getInstance()->getBool("ScrapeMetadata")) {
|
|
|
|
contentToScrape = true;
|
|
|
|
break;
|
|
|
|
}
|
2021-07-11 11:31:43 +00:00
|
|
|
if (scraperService == "screenscraper" && Settings::getInstance()->getBool("ScrapeVideos")) {
|
2021-01-17 10:58:58 +00:00
|
|
|
contentToScrape = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (Settings::getInstance()->getBool("ScrapeScreenshots")) {
|
|
|
|
contentToScrape = true;
|
|
|
|
break;
|
|
|
|
}
|
2021-10-28 19:00:23 +00:00
|
|
|
if (Settings::getInstance()->getBool("ScrapeTitleScreens")) {
|
|
|
|
contentToScrape = true;
|
|
|
|
break;
|
|
|
|
}
|
2021-01-17 10:58:58 +00:00
|
|
|
if (Settings::getInstance()->getBool("ScrapeCovers")) {
|
|
|
|
contentToScrape = true;
|
|
|
|
break;
|
|
|
|
}
|
2022-01-15 17:29:38 +00:00
|
|
|
if (Settings::getInstance()->getBool("ScrapeBackCovers")) {
|
|
|
|
contentToScrape = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (Settings::getInstance()->getBool("ScrapeFanArt")) {
|
2021-10-28 19:00:23 +00:00
|
|
|
contentToScrape = true;
|
|
|
|
break;
|
|
|
|
}
|
2021-01-17 10:58:58 +00:00
|
|
|
if (Settings::getInstance()->getBool("ScrapeMarquees")) {
|
|
|
|
contentToScrape = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (scraperService == "screenscraper" &&
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("Scrape3DBoxes")) {
|
2021-01-17 10:58:58 +00:00
|
|
|
contentToScrape = true;
|
|
|
|
break;
|
|
|
|
}
|
2021-10-28 19:00:23 +00:00
|
|
|
if (scraperService == "screenscraper" &&
|
|
|
|
Settings::getInstance()->getBool("ScrapePhysicalMedia")) {
|
|
|
|
contentToScrape = true;
|
|
|
|
break;
|
|
|
|
}
|
2021-01-17 10:58:58 +00:00
|
|
|
} while (0);
|
|
|
|
|
|
|
|
if (!contentToScrape) {
|
2022-01-19 17:01:54 +00:00
|
|
|
mWindow->pushGui(
|
|
|
|
new GuiMsgBox(getHelpStyle(), "PLEASE SELECT AT LEAST ONE CONTENT TYPE TO SCRAPE"));
|
2021-01-17 10:58:58 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-12-16 16:35:23 +00:00
|
|
|
std::queue<ScraperSearchParams> searches =
|
2021-07-11 11:31:43 +00:00
|
|
|
getSearches(mSystems->getSelectedObjects(), mFilters->getSelected());
|
2020-06-21 12:25:28 +00:00
|
|
|
|
|
|
|
if (searches.empty()) {
|
2021-07-11 11:31:43 +00:00
|
|
|
mWindow->pushGui(
|
2022-01-19 17:01:54 +00:00
|
|
|
new GuiMsgBox(getHelpStyle(), "ALL GAMES WERE FILTERED, NOTHING TO SCRAPE"));
|
2020-06-21 12:25:28 +00:00
|
|
|
}
|
|
|
|
else {
|
2022-09-03 10:44:49 +00:00
|
|
|
GuiScraperMulti* gsm {
|
|
|
|
new GuiScraperMulti(searches, Settings::getInstance()->getBool("ScraperInteractive"))};
|
2020-06-21 12:25:28 +00:00
|
|
|
mWindow->pushGui(gsm);
|
2021-01-17 11:21:33 +00:00
|
|
|
mMenu.setCursorToList();
|
|
|
|
mMenu.setCursorToFirstListEntry();
|
2020-06-21 12:25:28 +00:00
|
|
|
}
|
2020-06-06 11:10:33 +00:00
|
|
|
}
|
|
|
|
|
2021-07-11 11:31:43 +00:00
|
|
|
std::queue<ScraperSearchParams> GuiScraperMenu::getSearches(std::vector<SystemData*> systems,
|
|
|
|
GameFilterFunc selector)
|
2020-06-06 11:10:33 +00:00
|
|
|
{
|
2020-06-21 12:25:28 +00:00
|
|
|
std::queue<ScraperSearchParams> queue;
|
2021-11-17 16:35:34 +00:00
|
|
|
for (auto sys = systems.cbegin(); sys != systems.cend(); ++sys) {
|
2022-09-03 10:44:49 +00:00
|
|
|
std::vector<FileData*> games {(*sys)->getRootFolder()->getScrapeFilesRecursive(
|
2021-07-11 11:31:43 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperIncludeFolders"),
|
|
|
|
Settings::getInstance()->getBool("ScraperExcludeRecursively"),
|
2022-09-03 10:44:49 +00:00
|
|
|
Settings::getInstance()->getBool("ScraperRespectExclusions"))};
|
2021-11-17 16:35:34 +00:00
|
|
|
for (auto game = games.cbegin(); game != games.cend(); ++game) {
|
2020-08-06 13:12:04 +00:00
|
|
|
if (selector((*sys), (*game))) {
|
2020-06-21 12:25:28 +00:00
|
|
|
ScraperSearchParams search;
|
|
|
|
search.game = *game;
|
|
|
|
search.system = *sys;
|
|
|
|
|
|
|
|
queue.push(search);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return queue;
|
2020-06-06 11:10:33 +00:00
|
|
|
}
|
|
|
|
|
2021-07-11 11:31:43 +00:00
|
|
|
void GuiScraperMenu::addEntry(const std::string& name,
|
|
|
|
unsigned int color,
|
|
|
|
bool add_arrow,
|
|
|
|
const std::function<void()>& func)
|
2020-06-06 11:10:33 +00:00
|
|
|
{
|
2022-09-03 10:44:49 +00:00
|
|
|
std::shared_ptr<Font> font {Font::get(FONT_SIZE_MEDIUM)};
|
2020-06-06 11:10:33 +00:00
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
// Populate the list.
|
|
|
|
ComponentListRow row;
|
2022-01-19 17:01:54 +00:00
|
|
|
row.addElement(std::make_shared<TextComponent>(name, font, color), true);
|
2020-06-06 11:10:33 +00:00
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
if (add_arrow) {
|
2022-01-19 17:01:54 +00:00
|
|
|
std::shared_ptr<ImageComponent> bracket {makeArrow()};
|
2020-06-21 12:25:28 +00:00
|
|
|
row.addElement(bracket, false);
|
|
|
|
}
|
2020-06-06 11:10:33 +00:00
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
row.makeAcceptInputHandler(func);
|
|
|
|
mMenu.addRow(row);
|
2020-06-06 11:10:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool GuiScraperMenu::input(InputConfig* config, Input input)
|
|
|
|
{
|
2020-06-21 12:25:28 +00:00
|
|
|
if (GuiComponent::input(config, input))
|
|
|
|
return true;
|
2020-06-06 11:10:33 +00:00
|
|
|
|
2021-01-02 15:28:47 +00:00
|
|
|
if (config->isMappedTo("y", input) && input.value != 0)
|
|
|
|
pressedStart();
|
|
|
|
|
2020-12-18 15:35:19 +00:00
|
|
|
if (config->isMappedTo("b", input) && input.value != 0) {
|
2020-06-21 12:25:28 +00:00
|
|
|
delete this;
|
|
|
|
return true;
|
|
|
|
}
|
2020-06-06 11:10:33 +00:00
|
|
|
|
2020-06-21 12:25:28 +00:00
|
|
|
return false;
|
2020-06-06 11:10:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<HelpPrompt> GuiScraperMenu::getHelpPrompts()
|
|
|
|
{
|
2022-09-03 10:44:49 +00:00
|
|
|
std::vector<HelpPrompt> prompts {mMenu.getHelpPrompts()};
|
2020-06-21 12:25:28 +00:00
|
|
|
prompts.push_back(HelpPrompt("b", "back"));
|
2022-12-05 20:40:33 +00:00
|
|
|
prompts.push_back(HelpPrompt("y", "start scraper"));
|
2020-06-21 12:25:28 +00:00
|
|
|
return prompts;
|
2020-06-06 11:10:33 +00:00
|
|
|
}
|