MythTV  master
gamesettings.cpp
Go to the documentation of this file.
1 // C++
2 #include <array>
3 
4 // Qt
5 #include <QCoreApplication>
6 
7 // MythTV
8 #include <libmythbase/mythdb.h>
9 #include <libmythbase/mythdirs.h>
10 
11 // MythGame
12 #include "gamesettings.h"
13 
14 struct GameTypes {
15  QString m_nameStr;
16  QString m_idStr;
17  QString m_extensions;
18 };
19 
20 const std::array<GameTypes,12> GameTypeList
21 {{
22  { QT_TRANSLATE_NOOP("(GameTypes)", "OTHER"), "OTHER", "" },
23  { QT_TRANSLATE_NOOP("(GameTypes)", "AMIGA"), "AMIGA", "adf,ipf" },
24  { QT_TRANSLATE_NOOP("(GameTypes)", "ATARI"), "ATARI", "bin,a26" },
25  { QT_TRANSLATE_NOOP("(GameTypes)", "GAMEGEAR"), "GAMEGEAR", "gg" },
26  { QT_TRANSLATE_NOOP("(GameTypes)", "GENESIS/MEGADRIVE"), "GENESIS", "smd,bin,md" },
27  { QT_TRANSLATE_NOOP("(GameTypes)", "MAME"), "MAME", "" },
28  { QT_TRANSLATE_NOOP("(GameTypes)", "N64"), "N64", "v64,n64" },
29  { QT_TRANSLATE_NOOP("(GameTypes)", "NES"), "NES", "zip,nes" },
30  { QT_TRANSLATE_NOOP("(GameTypes)", "PC GAME"), "PC", "" },
31  { QT_TRANSLATE_NOOP("(GameTypes)", "PCE/TG16"),"PCE", "pce" },
32  { QT_TRANSLATE_NOOP("(GameTypes)", "SEGA/MASTER SYSTEM"), "SEGA", "sms" },
33  { QT_TRANSLATE_NOOP("(GameTypes)", "SNES"), "SNES", "zip,smc,sfc,fig,swc" }
34 }};
35 
36 QString GetGameTypeName(const QString &GameType)
37 {
38  auto sametype = [GameType](const auto & console)
39  { return console.m_idStr == GameType; };
40  const auto *const con = std::find_if(GameTypeList.cbegin(), GameTypeList.cend(), sametype);
41  return (con != GameTypeList.cend())
42  ? QCoreApplication::translate("(GameTypes)", con->m_nameStr.toUtf8())
43  : "";
44 }
45 
46 QString GetGameTypeExtensions(const QString &GameType)
47 {
48  auto sametype = [GameType](const auto & console)
49  { return console.m_idStr == GameType; };
50  const auto *const con = std::find_if(GameTypeList.cbegin(), GameTypeList.cend(), sametype);
51  return (con != GameTypeList.cend()) ? con->m_extensions : "";
52 }
53 
54 // -----------------------------------------------------------------------
55 
56 // General Settings
57 #undef TR
58 #define TR GameGeneralSettings::tr
59 
61 {
62  auto *gc = new HostTextEditSetting("GameAllTreeLevels");
63  gc->setLabel(TR("Game display order"));
64  gc->setValue("system gamename");
65  gc->setHelpText(TR("Order in which to sort the "
66  "games - this is for all "
67  "systems. Available choices: "
68  "system, year, genre and "
69  "gamename"));
70  return gc;
71 }
72 
74 {
75  auto *gc = new HostTextEditSetting("GameFavTreeLevels");
76  gc->setLabel(TR("Favorite display order"));
77  gc->setValue("gamename");
78  gc->setHelpText(TR("Order in which to sort the "
79  "games marked as favorites "
80  "- this is for all systems. "
81  "Available choices: system, "
82  "year, genre and gamename"));
83  return gc;
84 }
85 
87 {
88  auto *gc = new HostCheckBoxSetting("GameDeepScan");
89  gc->setLabel(TR("Indepth Game Scan"));
90  gc->setHelpText(
91  TR("Enabling this causes a game scan to "
92  "gather CRC values and attempt to find out "
93  "more detailed information about the game: "
94  "NOTE this can greatly increase the time a "
95  "game scan takes based on the amount of "
96  "games scanned."));
97  return gc;
98 }
99 
101 {
102  auto *gc = new HostCheckBoxSetting("GameRemovalPrompt");
103  gc->setLabel(TR("Prompt for removal of deleted ROM(s)"));
104  gc->setHelpText(TR("This enables a prompt for "
105  "removing deleted ROMs from "
106  "the database during a game "
107  "scan"));
108 
109  return gc;
110 }
111 
113 {
114  auto *gc = new HostCheckBoxSetting("GameShowFileNames");
115  gc->setLabel(TR("Display Files Names in Game "
116  "Tree"));
117  gc->setHelpText(TR("Enabling this causes the "
118  "filenames to be displayed in "
119  "the game tree rather than the "
120  "trimmed/looked up game name"));
121  return gc;
122 }
123 
125 {
126  auto *gc = new HostCheckBoxSetting("GameTreeView");
127  gc->setLabel(TR("Hash filenames in display"));
128  gc->setValue(0);
129  gc->setHelpText(TR("Enable hashing of names in "
130  "the display tree. This can "
131  "make navigating long lists "
132  "a little faster"));
133  return gc;
134 }
135 
137 {
138  auto *gc = new HostTextEditSetting("mythgame.screenshotdir");
139  gc->setLabel(TR("Directory where Game Screenshots "
140  "are stored"));
141  gc->setValue(GetConfDir() + "/MythGame/Screenshots");
142  gc->setHelpText(TR("This directory will be the "
143  "default browse location when "
144  "assigning screenshots."));
145  return gc;
146 }
147 
149 {
150  auto *gc = new HostTextEditSetting("mythgame.fanartdir");
151  gc->setLabel(TR("Directory where Game Fanart is "
152  "stored"));
153  gc->setValue(GetConfDir() + "/MythGame/Fanart");
154  gc->setHelpText(TR("This directory will be the "
155  "default browse location when "
156  "assigning fanart."));
157  return gc;
158 }
159 
161 {
162  auto *gc = new HostTextEditSetting("mythgame.boxartdir");
163  gc->setLabel(TR("Directory where Game Boxart is "
164  "stored"));
165  gc->setValue(GetConfDir() + "/MythGame/Boxart");
166  gc->setHelpText(TR("This directory will be the "
167  "default browse location when "
168  "assigning boxart."));
169  return gc;
170 }
171 
173 {
174  setLabel(tr("MythGame Settings -- General"));
184 }
185 
186 // -----------------------------------------------------------------------
187 
188 // Player Settings
189 #undef TR
190 #define TR GamePlayerSetting::tr
191 
194 {
195  GameDBStorage(StorageUser *user, const PlayerId &id, const QString &name)
196  : SimpleDBStorage(user, "gameplayers", name), m_id(id) {}
197 protected:
198  const PlayerId &m_id;
199 
200  QString GetWhereClause(MSqlBindings &bindings) const override // SimpleStorage
201  {
202  bindings.insert(":PLAYERID", m_id.Value());
203  return "gameplayerid = :PLAYERID";
204  }
205 
206  QString GetSetClause(MSqlBindings &bindings) const override // SimpleStorage
207  {
208  bindings.insert(":SETPLAYERID", m_id.Value());
209  bindings.insert(":SETCOLUMN", m_user->GetDBValue());
210  return QString("gameplayerid = :SETPLAYERID, "
211  "%2 = :SETCOLUMN").arg(GetColumnName());
212  }
213 };
214 
217 {
218  explicit TextEdit(const PlayerId &parent, const QString& column) :
219  MythUITextEditSetting(new GameDBStorage(this, parent, column))
220  {}
221 };
222 
223 struct Name : public TextEdit
224 {
225  explicit Name(const PlayerId &parent)
226  : TextEdit(parent, "playername")
227  {
228  setLabel(TR("Player Name"));
229  setHelpText(TR("Name of this Game and or Emulator"));
230  }
231 };
232 
233 struct Command : public TextEdit
234 {
235  explicit Command(const PlayerId &parent)
236  : TextEdit(parent, "commandline")
237  {
238  setLabel(TR("Command"));
239  setHelpText(TR("Binary and optional parameters. Multiple commands "
240  "separated with \';\' . Use \%s for the ROM name. "
241  "\%d1, \%d2, \%d3 and \%d4 represent disks in a "
242  "multidisk/game. %s auto appended if not specified"));
243  }
244 };
245 
247 {
248  explicit GameType(const PlayerId &parent) :
249  MythUIComboBoxSetting(new GameDBStorage(this, parent, "gametype"))
250  {
251  //: Game type
252  setLabel(TR("Type"));
253  for (const auto & console : GameTypeList)
254  {
255  addSelection(QCoreApplication::translate("(GameTypes)",
256  console.m_nameStr.toUtf8()),
257  console.m_idStr);
258  }
259  setValue(0);
260  setHelpText(TR("Type of Game/Emulator. Mostly for informational "
261  "purposes and has little effect on the "
262  "function of your system."));
263  }
264 };
265 
266 struct RomPath : public TextEdit
267 {
268  explicit RomPath(const PlayerId &parent)
269  : TextEdit(parent, "rompath")
270  {
271  setLabel(TR("ROM Path"));
272  setHelpText(TR("Location of the ROM files for this emulator"));
273  }
274 };
275 
276 struct WorkingDirPath : public TextEdit
277 {
278  explicit WorkingDirPath(const PlayerId &parent)
279  : TextEdit(parent, "workingpath")
280  {
281  setLabel(TR("Working Directory"));
282  setHelpText(TR("Directory to change to before launching emulator. "
283  "Blank is usually fine"));
284  }
285 };
286 
287 struct Extensions : public TextEdit
288 {
289  explicit Extensions(const PlayerId &parent)
290  : TextEdit(parent, "extensions")
291  {
292  setLabel(TR("File Extensions"));
293  setHelpText(TR("A comma separated list of all file extensions for this "
294  "emulator. Blank means any file under ROM PATH is "
295  "considered to be used with this emulator"));
296  }
297 };
298 
300 {
301  explicit AllowMultipleRoms(const PlayerId &parent) :
302  MythUICheckBoxSetting(new GameDBStorage(this, parent, "spandisks"))
303  {
304  setLabel(TR("Allow games to span multiple ROMs/disks"));
305  setHelpText(TR("This setting means that we will look for items like "
306  "game.1.rom, game.2.rom and consider them a single game."));
307  }
308 };
309 
312  : m_id(id)
313 {
314  setName(name);
315 
316  // Pre-set name for new players
317  auto *nameChild = new Name(m_id);
318  nameChild->setValue(name);
319 
320  addChild(nameChild);
321  addChild(new GameType(m_id));
322  addChild(new Command(m_id));
323  addChild(new RomPath(m_id));
325  addChild(new Extensions(m_id));
327 }
328 
330 {
331  // Allocate id for new player
332  m_id.Save();
334 }
335 
337 {
338  MSqlQuery query(MSqlQuery::InitCon());
339  query.prepare("DELETE FROM gameplayers "
340  "WHERE gameplayerid = :PLAYERID");
341 
342  query.bindValue(":PLAYERID", m_id.Value());
343 
344  if (!query.exec() || !query.isActive())
345  MythDB::DBError("Deleting MythGamePlayerSettings:", query);
346 }
347 
348 // -----------------------------------------------------------------------
349 
351 {
352  setLabel(tr("Game Players"));
353 }
354 
356 {
357  clearSettings();
358 
359  auto *newPlayer = new ButtonStandardSetting(tr("(New Game Player)"));
360  addChild(newPlayer);
361  connect(newPlayer, &ButtonStandardSetting::clicked,
363 
364  //: %1 is the player/emulator name, %2 is the type of player/emulator
365  QString playerDisp = tr("%1 (%2)", "Game player/emulator display");
366 
367  MSqlQuery query(MSqlQuery::InitCon());
368  query.prepare("SELECT gameplayerid, playername, gametype "
369  "FROM gameplayers "
370  "WHERE playername <> '' "
371  "ORDER BY playername;");
372 
373  if (!query.exec() || !query.isActive())
374  {
375  MythDB::DBError("GamePlayersSetting::Load", query);
376  }
377  else
378  {
379  while (query.next())
380  {
381  int id = query.value(0).toInt();
382  QString name = query.value(1).toString();
383  QString type = query.value(2).toString();
384 
385  auto *child = new GamePlayerSetting(name, id);
386  addChild(child);
387  child->setLabel(playerDisp.arg(name, GetGameTypeName(type)));
388  }
389  }
390 
392 }
393 
395 {
396  MythScreenStack *stack = GetMythMainWindow()->GetStack("popup stack");
397  auto *nameDialog = new MythTextInputDialog(stack, tr("Player Name"));
398 
399  if (nameDialog->Create())
400  {
401  stack->AddScreen(nameDialog);
402  connect(nameDialog, &MythTextInputDialog::haveResult,
404  }
405  else
406  {
407  delete nameDialog;
408  }
409 }
410 
411 void GamePlayersList::CreateNewPlayer(const QString& name)
412 {
413  if (name.isEmpty())
414  return;
415 
416  // Database name must be unique
417  for (StandardSetting* child : std::as_const(*getSubSettings()))
418  {
419  if (child->getName() == name)
420  {
421  LOG(VB_GENERAL, LOG_ERR,
422  QString("Player name %1 is already used").arg(name));
423  return;
424  }
425  }
426 
427  addChild(new GamePlayerSetting(name));
428 
429  // Redraw list
430  setVisible(true);
431 }
Extensions::Extensions
Extensions(const PlayerId &parent)
Definition: gamesettings.cpp:289
MSqlBindings
QMap< QString, QVariant > MSqlBindings
typedef for a map of string -> string bindings for generic queries.
Definition: mythdbcon.h:100
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:215
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:812
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
GetGameTypeName
QString GetGameTypeName(const QString &GameType)
Definition: gamesettings.cpp:36
StandardSetting::setName
virtual void setName(const QString &name)
Definition: standardsettings.cpp:253
mythdb.h
DBStorage::m_user
StorageUser * m_user
Definition: mythstorage.h:50
GameDBStorage::GetSetClause
QString GetSetClause(MSqlBindings &bindings) const override
Definition: gamesettings.cpp:206
GamePlayersList::GamePlayersList
GamePlayersList()
Definition: gamesettings.cpp:350
RomPath
Definition: gamesettings.cpp:266
ButtonStandardSetting
Definition: standardsettings.h:450
GameDBStorage
Game player database table reader/writer.
Definition: gamesettings.cpp:193
GamePlayerSetting::m_id
PlayerId m_id
Definition: gamesettings.h:37
HostTextEditSetting
Definition: standardsettings.h:168
RomPath::RomPath
RomPath(const PlayerId &parent)
Definition: gamesettings.cpp:268
GamePlayersList::NewPlayerDialog
void NewPlayerDialog() const
Definition: gamesettings.cpp:394
musicbrainzngs.musicbrainz.user
string user
Definition: musicbrainz.py:287
AllowMultipleRoms::AllowMultipleRoms
AllowMultipleRoms(const PlayerId &parent)
Definition: gamesettings.cpp:301
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
MythScreenStack
Definition: mythscreenstack.h:16
Extensions
Definition: gamesettings.cpp:287
DBStorage::GetColumnName
QString GetColumnName(void) const
Definition: mythstorage.h:47
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:618
GameType::GameType
GameType(const PlayerId &parent)
Definition: gamesettings.cpp:248
StandardSetting::clearSettings
virtual void clearSettings()
Definition: standardsettings.cpp:160
StorageUser::GetDBValue
virtual QString GetDBValue(void) const =0
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
GameTypes
Definition: gamesettings.cpp:14
mythdirs.h
GameTypes::m_extensions
QString m_extensions
Definition: gamesettings.cpp:17
SimpleDBStorage
Definition: mythstorage.h:55
GameTypes::m_nameStr
QString m_nameStr
Definition: gamesettings.cpp:15
MythTextInputDialog::haveResult
void haveResult(QString)
HostCheckBoxSetting
Definition: standardsettings.h:417
AllowMultipleRoms
Definition: gamesettings.cpp:299
GameFavTreeLevels
static HostTextEditSetting * GameFavTreeLevels()
Definition: gamesettings.cpp:73
GamePlayersList::CreateNewPlayer
void CreateNewPlayer(const QString &name)
Definition: gamesettings.cpp:411
GameTypes::m_idStr
QString m_idStr
Definition: gamesettings.cpp:16
ButtonStandardSetting::clicked
void clicked()
GameShowFileNames
static HostCheckBoxSetting * GameShowFileNames()
Definition: gamesettings.cpp:112
GetBoxartDir
static HostTextEditSetting * GetBoxartDir()
Definition: gamesettings.cpp:160
StandardSetting::addChild
virtual void addChild(StandardSetting *child)
Definition: standardsettings.cpp:71
Command
Definition: gamesettings.cpp:233
GamePlayerSetting::Save
void Save() override
Definition: gamesettings.cpp:329
GetConfDir
QString GetConfDir(void)
Definition: mythdirs.cpp:256
StandardSetting::getSubSettings
virtual QList< StandardSetting * > * getSubSettings()
Definition: standardsettings.cpp:146
MythUIComboBoxSetting
Definition: standardsettings.h:218
AutoIncrementSetting::Save
void Save(void) override
Definition: standardsettings.cpp:325
GameDBStorage::GetWhereClause
QString GetWhereClause(MSqlBindings &bindings) const override
Definition: gamesettings.cpp:200
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:550
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:225
StandardSetting::Load
virtual void Load(void)
Definition: standardsettings.cpp:214
StandardSetting::setHelpText
virtual void setHelpText(const QString &str)
Definition: standardsettings.h:37
GamePlayerSetting::deleteEntry
void deleteEntry() override
Definition: gamesettings.cpp:336
StandardSetting::Save
virtual void Save(void)
Definition: standardsettings.cpp:233
GameRemovalPrompt
static HostCheckBoxSetting * GameRemovalPrompt()
Definition: gamesettings.cpp:100
GamePlayersList::Load
void Load() override
Definition: gamesettings.cpp:355
WorkingDirPath
Definition: gamesettings.cpp:276
uint
unsigned int uint
Definition: compat.h:81
GamePlayerSetting
Definition: gamesettings.h:26
StandardSetting::setLabel
virtual void setLabel(QString str)
Definition: standardsettings.h:34
gamesettings.h
PlayerId::Value
int Value() const
Definition: gamesettings.h:23
GetFanartDir
static HostTextEditSetting * GetFanartDir()
Definition: gamesettings.cpp:148
MythUIComboBoxSetting::addSelection
void addSelection(const QString &label, QString value=QString(), bool select=false)
Definition: standardsettings.cpp:503
GameDeepScan
static HostCheckBoxSetting * GameDeepScan()
Definition: gamesettings.cpp:86
GameDBStorage::m_id
const PlayerId & m_id
Definition: gamesettings.cpp:198
MythUITextEditSetting
Definition: standardsettings.h:146
TextEdit
Base for Game textual settings.
Definition: gamesettings.cpp:216
Name
Definition: channelsettings.cpp:71
Command::Command
Command(const PlayerId &parent)
Definition: gamesettings.cpp:235
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:888
GameAllTreeLevels
static HostTextEditSetting * GameAllTreeLevels()
Definition: gamesettings.cpp:60
GameGeneralSettings::GameGeneralSettings
GameGeneralSettings()
Definition: gamesettings.cpp:172
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:322
StandardSetting::setVisible
void setVisible(bool visible)
Definition: standardsettings.cpp:60
StandardSetting
Definition: standardsettings.h:29
GameTypeList
const std::array< GameTypes, 12 > GameTypeList
Definition: gamesettings.cpp:21
PlayerId
Definition: gamesettings.h:18
TextEdit::TextEdit
TextEdit(const PlayerId &parent, const QString &column)
Definition: gamesettings.cpp:218
GameType
Definition: gamesettings.cpp:246
MythUICheckBoxSetting
Definition: standardsettings.h:390
GameTreeView
static HostCheckBoxSetting * GameTreeView()
Definition: gamesettings.cpp:124
MythTextInputDialog
Dialog prompting the user to enter a text string.
Definition: mythdialogbox.h:314
GamePlayerSetting::GamePlayerSetting
GamePlayerSetting(const QString &name, uint id=0)
Settings for a game player.
Definition: gamesettings.cpp:311
GameDBStorage::GameDBStorage
GameDBStorage(StorageUser *user, const PlayerId &id, const QString &name)
Definition: gamesettings.cpp:195
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
Name::Name
Name(const PlayerId &parent)
Definition: gamesettings.cpp:225
GetScreenshotDir
static HostTextEditSetting * GetScreenshotDir()
Definition: gamesettings.cpp:136
WorkingDirPath::WorkingDirPath
WorkingDirPath(const PlayerId &parent)
Definition: gamesettings.cpp:278
MythUIComboBoxSetting::setValue
void setValue(int value) override
Definition: standardsettings.cpp:483
TR
#define TR
Definition: gamesettings.cpp:190
GetGameTypeExtensions
QString GetGameTypeExtensions(const QString &GameType)
Definition: gamesettings.cpp:46
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:837
StorageUser
Definition: mythstorage.h:15