MythTV  master
mythtv/programs/mythtv-setup/main.cpp
Go to the documentation of this file.
1 #include <unistd.h>
2 #include <fcntl.h>
3 
4 #include <iostream>
5 #include <memory>
6 
7 #include <QString>
8 #include <QDir>
9 #include <QMap>
10 #include <QApplication>
11 #include <QFileInfo>
12 
13 #include "mythconfig.h"
14 #include "mythcontext.h"
15 #include "mythdbcon.h"
16 #include "dbutil.h"
17 #include "loggingserver.h"
18 #include "mythlogging.h"
19 #include "mythversion.h"
20 #include "langsettings.h"
21 #include "mythtranslation.h"
22 #include "exitcodes.h"
23 #include "exitprompt.h"
24 #include "storagegroupeditor.h"
25 #include "myththemedmenu.h"
26 #include "mythuihelper.h"
27 #include "mythdirs.h"
28 #include "channelscanner_cli.h"
29 #include "scanwizardconfig.h"
30 #include "scaninfo.h"
31 #include "channelimporter.h"
32 #include "cardutil.h"
33 #include "dbcheck.h"
34 #include "videosource.h"
35 #include "channeleditor.h"
36 #include "remoteutil.h"
37 #include "backendsettings.h"
38 #include "checksetup.h"
39 #include "startprompt.h"
40 #include "mythsystemevent.h"
41 #include "expertsettingseditor.h"
42 #include "commandlineparser.h"
43 #include "profilegroup.h"
44 #include "signalhandling.h"
45 #include "mythmiscutil.h"
46 #include "ssdp.h"
47 #include "cleanupguard.h"
48 #include "mythdisplay.h"
49 
50 using namespace std;
51 
54 
56 static QString logfile;
57 
58 static void cleanup()
59 {
61 
62  delete gContext;
63  gContext = nullptr;
64 
66 }
67 
68 static void SetupMenuCallback(void* /* data */, QString& selection)
69 {
70  QString sel = selection.toLower();
71 
72  if (sel == "general")
73  {
75  auto *ssd = new StandardSettingDialog(mainStack, "generalsettings",
76  new BackendSettings());
77 
78  if (ssd->Create())
79  mainStack->AddScreen(ssd);
80  else
81  delete ssd;
82  }
83  else if (sel == "capture cards")
84  {
86  auto *ssd = new StandardSettingDialog(mainStack, "capturecardeditor",
87  new CaptureCardEditor());
88 
89  if (ssd->Create())
90  mainStack->AddScreen(ssd);
91  else
92  delete ssd;
93  }
94  else if (sel == "video sources")
95  {
97  auto *ssd = new StandardSettingDialog(mainStack, "videosourceeditor",
98  new VideoSourceEditor());
99  if (ssd->Create())
100  mainStack->AddScreen(ssd);
101  else
102  delete ssd;
103  }
104  else if (sel == "card inputs")
105  {
107  auto *ssd = new StandardSettingDialog(mainStack, "cardinputeditor",
108  new CardInputEditor());
109 
110  if (ssd->Create())
111  mainStack->AddScreen(ssd);
112  else
113  delete ssd;
114  }
115  else if (sel == "recording profile")
116  {
118  auto *ssd = new StandardSettingDialog(mainStack, "recordingprofileeditor",
119  new ProfileGroupEditor());
120 
121  if (ssd->Create())
122  mainStack->AddScreen(ssd);
123  else
124  delete ssd;
125  }
126  else if (sel == "channel editor")
127  {
129 
130  auto *chanedit = new ChannelEditor(mainStack);
131 
132  if (chanedit->Create())
133  mainStack->AddScreen(chanedit);
134  else
135  delete chanedit;
136  }
137  else if (sel == "storage groups")
138  {
140  auto *ssd = new StandardSettingDialog(mainStack, "storagegroupeditor",
141  new StorageGroupListEditor());
142 
143  if (ssd->Create())
144  mainStack->AddScreen(ssd);
145  else
146  delete ssd;
147  }
148  else if (sel == "systemeventeditor")
149  {
151 
152  auto *msee = new MythSystemEventEditor(mainStack, "System Event Editor");
153 
154  if (msee->Create())
155  mainStack->AddScreen(msee);
156  else
157  delete msee;
158  }
159  else if (sel.startsWith("exiting_app") || (sel == "standby_mode"))
160  {
161  if (!exitPrompt)
162  exitPrompt = new ExitPrompter();
164  }
165  else
166  LOG(VB_GENERAL, LOG_ERR, "Unknown menu action: " + selection);
167 }
168 
169 static bool RunMenu(const QString& themedir, const QString& themename)
170 {
171  QByteArray tmp = themedir.toLocal8Bit();
172  menu = new MythThemedMenu(
173  QString(tmp.constData()), "setup.xml",
174  GetMythMainWindow()->GetMainStack(), "mainmenu", false);
175 
176  if (menu->foundTheme())
177  {
180  return true;
181  }
182 
183  LOG(VB_GENERAL, LOG_ERR, QString("Couldn't use theme '%1'").arg(themename));
184  delete menu;
185  menu = nullptr;
186 
187  return false;
188 }
189 
190 // If the theme specified in the DB is somehow broken, try a standard one:
191 //
192 static bool resetTheme(QString themedir, const QString &badtheme)
193 {
194  QString themename = DEFAULT_UI_THEME;
195 
196  if (badtheme == DEFAULT_UI_THEME)
197  themename = FALLBACK_UI_THEME;
198 
199  LOG(VB_GENERAL, LOG_ERR,
200  QString("Overriding broken theme '%1' with '%2'")
201  .arg(badtheme).arg(themename));
202 
203  gCoreContext->OverrideSettingForSession("Theme", themename);
204  themedir = GetMythUI()->FindThemeDir(themename);
205 
207  GetMythUI()->LoadQtConfig();
208  GetMythMainWindow()->Init();
210 
211  return RunMenu(themedir, themename);
212 }
213 
214 static int reloadTheme(void)
215 {
216  QString themename = gCoreContext->GetSetting("Theme", DEFAULT_UI_THEME);
217  QString themedir = GetMythUI()->FindThemeDir(themename);
218  if (themedir.isEmpty())
219  {
220  LOG(VB_GENERAL, LOG_ERR, QString("Couldn't find theme '%1'")
221  .arg(themename));
222  return GENERIC_EXIT_NO_THEME;
223  }
224 
226 
228 
229  GetMythUI()->LoadQtConfig();
230 
231  if (menu)
232  {
233  menu->Close();
234  }
235  GetMythMainWindow()->Init();
238 
239  if (!RunMenu(themedir, themename) && !resetTheme(themedir, themename))
240  return GENERIC_EXIT_NO_THEME;
241 
242  return 0;
243 }
244 
245 int main(int argc, char *argv[])
246 {
247  QString geometry;
248  QString display;
249  bool doScan = false;
250  bool doScanList = false;
251  bool doScanSaveOnly = false;
252  bool scanInteractive = true;
253  bool expertMode = false;
254  uint scanImport = 0;
255  bool scanFTAOnly = false;
256  bool scanLCNOnly = false;
257  bool scanCompleteOnly = false;
258  bool scanFullChannelSearch = false;
259  bool scanRemoveDuplicates = false;
260  bool addFullTS = false;
261  ServiceRequirements scanServiceRequirements = kRequireAV;
262  uint scanCardId = 0;
263  QString frequencyStandard = "atsc";
264  QString modulation = "vsb8";
265  QString region = "us";
266  QString scanInputName = "";
267 
269  if (!cmdline.Parse(argc, argv))
270  {
271  cmdline.PrintHelp();
273  }
274 
275  if (cmdline.toBool("showhelp"))
276  {
277  cmdline.PrintHelp();
278  return GENERIC_EXIT_OK;
279  }
280 
281  if (cmdline.toBool("showversion"))
282  {
284  return GENERIC_EXIT_OK;
285  }
286 
287  bool quiet = false;
288  bool use_display = true;
289  if (cmdline.toBool("scan"))
290  {
291  quiet = true;
292  use_display = false;
293  }
294 
295  std::unique_ptr<QCoreApplication> app {nullptr};
296  CleanupGuard callCleanup(cleanup);
297 
298  if (use_display)
299  {
301  app = std::make_unique<QApplication>(argc, argv);
302  }
303  else
304  {
305  app = std::make_unique<QCoreApplication>(argc, argv);
306  }
307  QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHTV_SETUP);
308 
309 #ifndef _WIN32
310  QList<int> signallist;
311  signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
312  << SIGILL;
313 #if ! CONFIG_DARWIN
314  signallist << SIGRTMIN;
315 #endif
316  SignalHandler::Init(signallist);
317  SignalHandler::SetHandler(SIGHUP, logSigHup);
318 #endif
319 
320  if (cmdline.toBool("display"))
321  display = cmdline.toString("display");
322  if (cmdline.toBool("geometry"))
323  geometry = cmdline.toString("geometry");
324 
325  QString mask("general");
326  int retval = cmdline.ConfigureLogging(mask, quiet);
327  if (retval != GENERIC_EXIT_OK)
328  return retval;
329 
330  if (cmdline.toBool("expert"))
331  expertMode = true;
332  if (cmdline.toBool("scanlist"))
333  doScanList = true;
334  if (cmdline.toBool("savescan"))
335  doScanSaveOnly = true;
336  if (cmdline.toBool("scannoninteractive"))
337  scanInteractive = false;
338 
339  if (cmdline.toBool("importscan"))
340  scanImport = cmdline.toUInt("importscan");
341  if (cmdline.toBool("ftaonly"))
342  scanFTAOnly = true;
343  if (cmdline.toBool("lcnonly"))
344  scanLCNOnly = true;
345  if (cmdline.toBool("completeonly"))
346  scanCompleteOnly = true;
347  if (cmdline.toBool("fullsearch"))
348  scanFullChannelSearch = true;
349  if (cmdline.toBool("removeduplicates"))
350  scanRemoveDuplicates = true;
351  if (cmdline.toBool("addfullts"))
352  addFullTS = true;
353  if (cmdline.toBool("servicetype"))
354  {
355  scanServiceRequirements = kRequireNothing;
356  if (cmdline.toString("servicetype").contains("radio"))
357  scanServiceRequirements = kRequireAudio;
358  if (cmdline.toString("servicetype").contains("tv"))
359  scanServiceRequirements = kRequireAV;
360  if (cmdline.toString("servicetype").contains("tv+radio") ||
361  cmdline.toString("servicetype").contains("radio+tv"))
362  scanServiceRequirements = kRequireAudio;
363  if (cmdline.toString("servicetype").contains("all"))
364  scanServiceRequirements = kRequireNothing;
365  }
366 
367  if (!cmdline.toBool("noupnp"))
368  {
369  // start looking for any uPnP devices we can use like VBoxes
370  SSDP::Instance()->PerformSearch("ssdp:all");
371  }
372  if (cmdline.toBool("scan"))
373  {
374  scanCardId = cmdline.toUInt("scan");
375  doScan = true;
376  }
377  if (cmdline.toBool("freqstd"))
378  frequencyStandard = cmdline.toString("freqstd").toLower();
379  if (cmdline.toBool("modulation"))
380  modulation = cmdline.toString("modulation").toLower();
381  if (cmdline.toBool("region"))
382  region = cmdline.toString("region").toLower();
383  if (cmdline.toBool("inputname"))
384  scanInputName = cmdline.toString("inputname");
385 
386  if (!display.isEmpty())
387  {
389  }
390 
391  if (!geometry.isEmpty())
392  {
394  }
395 
397 
399  if (!gContext->Init(use_display,false,true)) // No Upnp, Prompt for db
400  {
401  LOG(VB_GENERAL, LOG_ERR, "Failed to init MythContext, exiting.");
403  }
404 
406 
407  if (!GetMythDB()->HaveSchema())
408  {
409  if (!InitializeMythSchema())
410  return GENERIC_EXIT_DB_ERROR;
411  }
412 
413  setHttpProxy();
414 
415  if (use_display)
416  {
417  GetMythUI()->LoadQtConfig();
418 
419  QString fileprefix = GetConfDir();
420 
421  QDir dir(fileprefix);
422  if (!dir.exists())
423  dir.mkdir(fileprefix);
424  }
425 
426  if (doScan)
427  {
428  bool okCardID = scanCardId != 0U;
429 
430  if (scanInputName.isEmpty())
431  scanInputName = CardUtil::GetInputName(scanCardId);
432 
433  bool okInputName = (scanInputName == CardUtil::GetInputName(scanCardId)
434  && scanInputName != "None");
435 
436  doScan = (okCardID && okInputName);
437 
438  if (!okCardID)
439  {
440  cerr << "You must enter a valid cardid to scan." << endl;
441  vector<uint> cardids = CardUtil::GetInputIDs();
442  if (cardids.empty())
443  {
444  cerr << "But no cards have been defined on this host"
445  << endl;
447  }
448  cerr << "Valid cards: " << endl;
449  for (uint id : cardids)
450  {
451  fprintf(stderr, "%5u: %s %s\n", id,
452  CardUtil::GetRawInputType(id).toLatin1().constData(),
453  CardUtil::GetVideoDevice(id).toLatin1().constData());
454  }
456  }
457 
458  if (!okInputName)
459  {
460  cerr << "You must enter a valid input to scan this card."
461  << endl;
462  cerr << "Valid input: "
463  << CardUtil::GetInputName(scanCardId).toLatin1().constData()
464  << endl;
466  }
467  }
468 
469  if (doScan)
470  {
471  int ret = 0;
472  uint inputid = scanCardId;
473  uint sourceid = CardUtil::GetSourceID(inputid);
474  QMap<QString,QString> startChan;
475  {
476  ChannelScannerCLI scanner(doScanSaveOnly, scanInteractive);
477 
478  int scantype = ScanTypeSetting::FullScan_ATSC;
479  if (frequencyStandard == "atsc")
480  scantype = ScanTypeSetting::FullScan_ATSC; // NOLINT(bugprone-branch-clone)
481  else if (frequencyStandard == "dvbt")
483  else if (frequencyStandard == "mpeg")
485  else if (frequencyStandard == "iptv")
486  {
488  scanner.ImportM3U(scanCardId, scanInputName, sourceid, true);
489  }
490  else if (frequencyStandard == "extern")
492  else
494 
495  scanner.Scan(scantype,
496  /* cardid */ scanCardId,
497  /* inputname */ scanInputName,
498  /* sourceid */ sourceid,
499  /* ignore signal timeout */ false,
500  /* follow_nit */ true,
501  /* test decryption */ true,
502  scanFTAOnly,
503  scanLCNOnly,
504  scanCompleteOnly,
505  scanFullChannelSearch,
506  scanRemoveDuplicates,
507  addFullTS,
508  scanServiceRequirements,
509  // stuff needed for particular scans
510  /* mplexid */ 0,
511  startChan, frequencyStandard, modulation, region);
512  ret = QCoreApplication::exec();
513  }
514  return (ret) ? GENERIC_EXIT_NOT_OK : GENERIC_EXIT_OK;
515  }
516 
517  if (doScanList)
518  {
519  vector<ScanInfo> scans = LoadScanList();
520 
521  cout<<" scanid cardid sourceid processed date"<<endl;
522  for (auto & scan : scans)
523  {
524  printf("%5i %6i %8i %8s %20s\n",
525  scan.m_scanid, scan.m_cardid,
526  scan.m_sourceid, (scan.m_processed) ? "yes" : "no",
527  scan.m_scandate.toString(Qt::ISODate)
528  .toLatin1().constData());
529  }
530  cout<<endl;
531 
532  return GENERIC_EXIT_OK;
533  }
534 
535  if (scanImport)
536  {
537  cout<<"*** SCAN IMPORT START ***"<<endl;
538  {
539  ScanDTVTransportList list = LoadScan(scanImport);
540  ChannelImporter ci(false, true, true, true, false,
541  scanFTAOnly, scanLCNOnly,
542  scanCompleteOnly,
543  scanFullChannelSearch,
544  scanRemoveDuplicates,
545  scanServiceRequirements);
546  ci.Process(list);
547  }
548  cout<<"*** SCAN IMPORT END ***"<<endl;
549  return GENERIC_EXIT_OK;
550  }
551 
552  MythTranslation::load("mythfrontend");
553 
554  QString themename = gCoreContext->GetSetting("Theme", DEFAULT_UI_THEME);
555  QString themedir = GetMythUI()->FindThemeDir(themename);
556  if (themedir.isEmpty())
557  {
558  LOG(VB_GENERAL, LOG_ERR, QString("Couldn't find theme '%1'")
559  .arg(themename));
560  return GENERIC_EXIT_NO_THEME;
561  }
562 
563  MythMainWindow *mainWindow = GetMythMainWindow();
564  mainWindow->Init();
565  mainWindow->setWindowTitle(QObject::tr("MythTV Setup"));
566 
567  // We must reload the translation after a language change and this
568  // also means clearing the cached/loaded theme strings, so reload the
569  // theme which also triggers a translation reload
571  {
572  if (!reloadTheme())
573  return GENERIC_EXIT_NO_THEME;
574  }
575 
577  {
578  LOG(VB_GENERAL, LOG_ERR,
579  "MySQL time zone support is missing. "
580  "Please install it and try again. "
581  "See 'mysql_tzinfo_to_sql' for assistance.");
583  }
584 
585  if (!UpgradeTVDatabaseSchema(true))
586  {
587  LOG(VB_GENERAL, LOG_ERR, "Couldn't upgrade database to new schema.");
589  }
590 
591  // Refresh Global/Main Menu keys after DB update in case there was no DB
592  // when they were written originally
593  mainWindow->ReloadKeys();
594 
595  if (!startPrompt)
596  startPrompt = new StartPrompter();
598 
599  // Let the user select buttons, type values, scan for channels, etc.
600  if (!RunMenu(themedir, themename) && !resetTheme(themedir, themename))
601  return GENERIC_EXIT_NO_THEME;
602 
603  ExpertSettingsEditor *expertEditor = nullptr;
604  if (expertMode)
605  {
607  expertEditor =
608  new ExpertSettingsEditor(mainStack, "Expert Settings Editor");
609  if (expertEditor->Create())
610  mainStack->AddScreen(expertEditor);
611  else
612  {
613  delete expertEditor;
614  expertEditor = nullptr;
615  LOG(VB_GENERAL, LOG_ERR,
616  "Unable to create expert settings editor window");
617  return GENERIC_EXIT_OK;
618  }
619  }
620 
621  QCoreApplication::exec();
622 }
623 
624 /* vim: set expandtab tabstop=4 shiftwidth=4: */
vector< ScanInfo > LoadScanList(void)
Definition: scaninfo.cpp:270
static void ConfigureQtGUI(int SwapInterval=1)
Shared static initialistaion code for all MythTV GUI applications.
#define GENERIC_EXIT_DB_ERROR
Database error.
Definition: exitcodes.h:17
Startup context for MythTV.
Definition: mythcontext.h:42
QString FindThemeDir(const QString &themename, bool doFallback=true)
Returns the full path to the theme denoted by themename.
stderr
Definition: ttvdb.py:1426
def scan(profile, smoonURL, gate)
Definition: scan.py:57
static QString GetInputName(uint inputid)
Definition: cardutil.cpp:1700
static QString themedir
Definition: mythdirs.cpp:21
void LoadQtConfig(void)
void handleStart()
Definition: startprompt.cpp:35
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
void setHttpProxy(void)
Get network proxy settings from OS, and use for [Q]Http[Comms].
bool toBool(const QString &key) const
Returns stored QVariant as a boolean.
bool Create(void) override
Creates the UI screen.
static void PrintVersion(void)
Print application version information.
void PrintHelp(void) const
Print command line option help.
void Scan(int scantype, uint cardid, const QString &inputname, uint sourceid, bool do_ignore_signal_timeout, bool do_follow_nit, bool do_test_decryption, bool do_fta_only, bool do_lcn_only, bool do_complete_only, bool do_full_channel_search, bool do_remove_duplicates, bool do_add_full_ts, ServiceRequirements service_requirements, uint mplexid, const QMap< QString, QString > &startChan, const QString &freq_std, const QString &mod, const QString &tbl, const QString &tbl_start=QString(), const QString &tbl_end=QString())
static void Init(QList< int > &signallist, QObject *parent=nullptr)
static bool resetTheme(QString themedir, const QString &badtheme)
void DestroyMythMainWindow(void)
void setCallback(void(*lcallback)(void *, QString &), void *data)
Set the themed menus callback function and data for that function.
#define DEFAULT_UI_THEME
Definition: mythuihelper.h:12
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythScreenStack * GetMainStack()
virtual bool ImportM3U(uint cardid, const QString &inputname, uint sourceid, bool is_mpts)
MythContext * gContext
This global variable contains the MythContext instance for the application.
Definition: mythcontext.cpp:62
static guint32 * tmp
Definition: goom_core.cpp:30
static MythThemedMenu * menu
static void SetupMenuCallback(void *, QString &selection)
int main(int argc, char *argv[])
#define MYTH_APPNAME_MYTHTV_SETUP
static void SetX11Display(const QString &display)
This needs to be set before MythUIHelper is initialized so that the MythUIHelper::Init() can detect X...
QString GetConfDir(void)
Definition: mythdirs.cpp:224
virtual void Close()
void ApplySettingsOverride(void)
Apply all overrides to the global context.
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
void PerformSearch(const QString &sST, uint timeout_secs=2)
Definition: ssdp.cpp:201
#define GENERIC_EXIT_DB_NOTIMEZONE
Missing DB time zone support.
Definition: exitcodes.h:36
void OverrideSettingForSession(const QString &key, const QString &value)
QString GetSetting(const QString &key, const QString &defaultval="")
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
static void ParseGeometryOverride(const QString &geometry)
Parse an X11 style command line geometry string.
bool InitializeMythSchema(void)
command to get the the initial database layout from an empty database:
Definition: dbcheck.cpp:3706
static void load(const QString &module_name)
Load a QTranslator for the user's preferred language.
static void Done(void)
unsigned int uint
Definition: compat.h:140
static vector< uint > GetInputIDs(const QString &videodevice=QString(), const QString &rawtype=QString(), const QString &inputname=QString(), QString hostname=QString())
Returns all inputids of inputs that uses the specified videodevice if specified, and optionally rawty...
Definition: cardutil.cpp:1271
static void SetHandler(int signum, SigHandlerFunc handler)
MythCommFlagCommandLineParser cmdline
static bool prompt(bool force=false)
Ask the user for the language to use.
StartPrompter * startPrompt
MythUIHelper * GetMythUI()
static void reload()
Reload all active translators based on the current language setting.
MythMainWindow * GetMythMainWindow(void)
int ConfigureLogging(const QString &mask="general", bool progress=false)
Read in logging options and initialize the logging interface.
static QString GetVideoDevice(uint inputid)
Definition: cardutil.h:279
#define FALLBACK_UI_THEME
Definition: mythuihelper.h:13
static int reloadTheme(void)
Themed menu class, used for main menus in MythTV frontend.
static SSDP * Instance()
Definition: ssdp.cpp:54
bool foundTheme(void) const
Returns true iff a theme has been found by a previous call to SetMenuTheme().
virtual bool Parse(int argc, const char *const *argv)
Loop through argv and populate arguments with values.
#define SIGHUP
Definition: compat.h:213
void SetEffectsEnabled(bool enable)
void Process(const ScanDTVTransportList &_transports, int sourceid=-1)
ServiceRequirements
#define MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
Definition: mythversion.h:16
bool Init(bool gui=true, bool promptForBackend=false, bool disableAutoDiscovery=false, bool ignoreDB=false)
An editor for MythSystemEvent handler commands.
ExitPrompter * exitPrompt
ScanDTVTransportList LoadScan(uint scanid)
Definition: scaninfo.cpp:77
static uint GetSourceID(uint inputid)
Definition: cardutil.cpp:1769
static QString GetRawInputType(uint inputid)
Definition: cardutil.h:277
Default UTC.
Definition: mythdate.h:14
vector< ScanDTVTransport > ScanDTVTransportList
Definition: dtvmultiplex.h:143
#define GENERIC_EXIT_NO_THEME
No Theme available.
Definition: exitcodes.h:14
MythDB * GetMythDB(void)
Definition: mythdb.cpp:46
#define GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
Definition: exitcodes.h:13
static QString logfile
#define GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:15
Scans the transport when there is no tuner (for ASI)
void Init(bool mayReInit=true)
#define GENERIC_EXIT_NOT_OK
Exited with error.
Definition: exitcodes.h:11
uint toUInt(const QString &key) const
Returns stored QVariant as an unsigned integer, falling to default if not provided.
void ReinitDone(void)
void ReloadKeys(void)
static void cleanup()
static bool RunMenu(const QString &themedir, const QString &themename)
static bool CheckTimeZoneSupport(void)
Check if MySQL has working timz zone support.
Definition: dbutil.cpp:869
#define GENERIC_EXIT_DB_OUTOFDATE
Database needs upgrade.
Definition: exitcodes.h:16
bool UpgradeTVDatabaseSchema(const bool upgradeAllowed, const bool upgradeIfNoUI, const bool informSystemd)
Called from outside dbcheck.cpp to update the schema.
Definition: dbcheck.cpp:362
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23