MythTV  master
mythcontext.cpp
Go to the documentation of this file.
1 #include <QCoreApplication>
2 #include <QDir>
3 #include <QFileInfo>
4 #include <QDebug>
5 #include <QHostInfo>
6 #include <QMutex>
7 #include <QDateTime>
8 #include <QTcpSocket>
9 #include <QEventLoop>
10 
11 #ifdef Q_OS_ANDROID
12 #include <QtAndroidExtras>
13 #endif
14 
15 #include <algorithm>
16 #include <cmath>
17 #include <iostream>
18 #include <queue>
19 #include <thread>
20 #include <vector>
21 
22 #include "config.h"
23 #include "mythcontext.h"
24 #include "exitcodes.h"
25 #include "mythdate.h"
26 #include "remotefile.h"
27 #include "backendselect.h"
28 #include "dbsettings.h"
29 #include "langsettings.h"
30 #include "mythtranslation.h"
31 #include "mythevent.h"
32 #include "dbutil.h"
33 #include "mythmediamonitor.h"
34 
35 #include "mythdb.h"
36 #include "mythdirs.h"
37 #include "mythversion.h"
38 #include "mythdialogbox.h"
39 #include "mythmainwindow.h"
40 #include "mythuihelper.h"
41 #include "mythimage.h"
42 #include "mythxmlclient.h"
43 #include "upnp.h"
44 #include "mythlogging.h"
45 #include "mythsystemlegacy.h"
46 #include "mythmiscutil.h"
47 
48 #include "mythplugin.h"
49 #include "portchecker.h"
50 #include "guistartup.h"
51 
52 #include <unistd.h> // for usleep(), gethostname
53 
54 #ifdef _WIN32
55 #include "compat.h"
56 #endif
57 
58 #define LOC QString("MythContext: ")
59 
60 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
61 #define qEnvironmentVariable getenv
62 #endif
63 
64 MythContext *gContext = nullptr;
65 
66 static const QString sLocation = "MythContext";
67 
68 class MythContextPrivate : public QObject
69 {
70  friend class MythContextSlotHandler;
71 
72  public:
73  explicit MythContextPrivate(MythContext *lparent);
74  ~MythContextPrivate() override;
75 
76  bool Init (bool gui,
77  bool promptForBackend,
78  bool disableAutoDiscovery,
79  bool ignoreDB);
80  bool FindDatabase(bool prompt, bool noAutodetect);
81 
82  void TempMainWindow(bool languagePrompt = true);
83  void EndTempWindow(void);
84 
85  bool LoadDatabaseSettings(void);
86  bool SaveDatabaseParams(const DatabaseParams &params, bool force);
87 
88  bool PromptForDatabaseParams(const QString &error);
89  QString TestDBconnection(bool prompt=true);
90  void SilenceDBerrors(void);
91  void EnableDBerrors(void);
92  void ResetDatabase(void) const;
93 
94  int ChooseBackend(const QString &error);
95  int UPnPautoconf(std::chrono::milliseconds milliSeconds = 2s);
96  bool DefaultUPnP(QString& Error);
97  bool UPnPconnect(const DeviceLocation *backend, const QString &PIN);
98  void ShowGuiStartup(void);
99  bool checkPort(QString &host, int port, std::chrono::seconds timeLimit) const;
100  static void processEvents(void);
101  bool saveSettingsCache(void);
102  void loadSettingsCacheOverride(void) const;
103  static void clearSettingsCacheOverride(void);
104 
105 
106  protected:
107  bool event(QEvent* /*e*/) override; // QObject
108 
109  void ShowConnectionFailurePopup(bool persistent);
110  void HideConnectionFailurePopup(void);
111 
112  void ShowVersionMismatchPopup(uint remote_version);
113 
114  public slots:
115  void OnCloseDialog();
116 
117  public:
118  MythContext *m_parent {nullptr};
119 
121  bool m_gui {false};
122 
124 
126  QString m_dbHostCp;
127 
129 
130  bool m_disableeventpopup {false};
131 
132  MythUIHelper *m_ui {nullptr};
135  QEventLoop *m_loop {nullptr};
136  bool m_needsBackend {false};
137  bool m_settingsCacheDirty {false};
138 
139  private:
141  int m_registration {-1};
142  QDateTime m_lastCheck;
143  QTcpSocket *m_socket {nullptr};
144  static const std::vector<QString> kSettingsToSave;
145 };
146 
147 static void exec_program_cb(const QString &cmd)
148 {
149  myth_system(cmd);
150 }
151 
152 static void exec_program_tv_cb(const QString &cmd)
153 {
154  QString s = cmd;
155  QStringList tokens = cmd.simplified().split(" ");
156  QStringList strlist;
157 
158  bool cardidok = false;
159  int wantcardid = tokens[0].toInt(&cardidok, 10);
160 
161  if (cardidok && wantcardid > 0)
162  {
163  strlist << QString("LOCK_TUNER %1").arg(wantcardid);
164  s = s.replace(0, tokens[0].length() + 1, "");
165  }
166  else
167  strlist << "LOCK_TUNER";
168 
170  int cardid = strlist[0].toInt();
171 
172  if (cardid >= 0)
173  {
174  s = s.arg(qPrintable(strlist[1]),
175  qPrintable(strlist[2]),
176  qPrintable(strlist[3]));
177 
178  myth_system(s);
179 
180  strlist = QStringList(QString("FREE_TUNER %1").arg(cardid));
182  }
183  else
184  {
185  QString label;
186 
187  if (cardidok)
188  {
189  if (cardid == -1)
190  {
191  label = QObject::tr("Could not find specified tuner (%1).")
192  .arg(wantcardid);
193  }
194  else
195  {
196  label = QObject::tr("Specified tuner (%1) is already in use.")
197  .arg(wantcardid);
198  }
199  }
200  else
201  {
202  label = QObject::tr("All tuners are currently in use. If you want "
203  "to watch TV, you can cancel one of the "
204  "in-progress recordings from the delete menu");
205  }
206 
207  LOG(VB_GENERAL, LOG_ALERT, QString("exec_program_tv: ") + label);
208 
209  ShowOkPopup(label);
210  }
211 }
212 
213 static void configplugin_cb(const QString &cmd)
214 {
216  if (!pmanager)
217  return;
218 
219  if (GetNotificationCenter() && pmanager->config_plugin(cmd.trimmed()))
220  {
222  QObject::tr("Failed to configure plugin"));
223  }
224 }
225 
226 static void plugin_cb(const QString &cmd)
227 {
229  if (!pmanager)
230  return;
231 
232  if (GetNotificationCenter() && pmanager->run_plugin(cmd.trimmed()))
233  {
234  ShowNotificationError(QObject::tr("Plugin failure"),
235  sLocation,
236  QObject::tr("%1 failed to run for some reason").arg(cmd));
237  }
238 }
239 
240 static void eject_cb(void)
241 {
243 }
244 
246  : m_parent(lparent),
247  m_sh(new MythContextSlotHandler(this))
248 {
249  m_loop = new QEventLoop(this);
251 }
252 
254 {
255  delete m_pConfig;
257  {
259  }
260 
261  delete m_loop;
262 
263  if (m_ui)
264  DestroyMythUI();
265  if (m_sh)
266  m_sh->deleteLater();
267 }
268 
279 void MythContextPrivate::TempMainWindow(bool languagePrompt)
280 {
281  if (HasMythMainWindow())
282  return;
283 
284  SilenceDBerrors();
285 
286 #ifdef Q_OS_DARWIN
287  // Qt 4.4 has window-focus problems
288  gCoreContext->OverrideSettingForSession("RunFrontendInWindow", "1");
289 #endif
290  GetMythUI()->Init();
291  MythMainWindow *mainWindow = MythMainWindow::getMainWindow(false);
292  mainWindow->Init();
293 
294  if (languagePrompt)
295  {
296  // ask user for language settings
298  MythTranslation::load("mythfrontend");
299  }
300 }
301 
303 {
304  if (HasMythMainWindow())
305  {
307  {
309  if (mainStack) {
310  mainStack->PopScreen(m_guiStartup, false);
311  m_guiStartup = nullptr;
312  }
313  }
314  }
315  EnableDBerrors();
316 }
317 
327 bool MythContextPrivate::checkPort(QString &host, int port, std::chrono::seconds timeLimit) const
328 {
329  PortChecker checker;
330  if (m_guiStartup)
332  return checker.checkPort(host, port, timeLimit);
333 }
334 
335 
336 bool MythContextPrivate::Init(const bool gui,
337  const bool promptForBackend,
338  const bool disableAutoDiscovery,
339  const bool ignoreDB)
340 {
341  gCoreContext->GetDB()->IgnoreDatabase(ignoreDB);
342  m_gui = gui;
344 
345  if (gCoreContext->IsFrontend())
346  m_needsBackend = true;
347 
348  // We don't have a database yet, so lets use the config.xml file.
349  m_pConfig = new XmlConfiguration("config.xml");
350 
351  // Creates screen saver control if we will have a GUI
352  if (gui)
353  m_ui = GetMythUI();
354 
355  // ---- database connection stuff ----
356 
357  if (!ignoreDB && !FindDatabase(promptForBackend, disableAutoDiscovery))
358  {
359  EndTempWindow();
360  return false;
361  }
362 
363  // ---- keep all DB-using stuff below this line ----
364 
365  // Prompt for language if this is a first time install and
366  // we didn't already do so.
367  if (m_gui && !gCoreContext->GetDB()->HaveSchema())
368  {
369  TempMainWindow(false);
371  MythTranslation::load("mythfrontend");
372  }
375 
376  // Close GUI Startup Window.
377  if (m_guiStartup) {
379  if (mainStack)
380  mainStack->PopScreen(m_guiStartup, false);
381  m_guiStartup=nullptr;
382  }
383  EndTempWindow();
384 
385  if (gui)
386  {
387  MythUIMenuCallbacks cbs {};
389  cbs.exec_program_tv = exec_program_tv_cb;
390  cbs.configplugin = configplugin_cb;
391  cbs.plugin = plugin_cb;
392  cbs.eject = eject_cb;
393 
394  m_ui->Init(cbs);
395  }
396 
397  return true;
398 }
399 
412 bool MythContextPrivate::FindDatabase(bool prompt, bool noAutodetect)
413 {
414  // We can only prompt if autodiscovery is enabled..
415  bool manualSelect = prompt && !noAutodetect;
416 
417  QString failure;
418 
419  // 1. Either load config.xml or use sensible "localhost" defaults:
420  bool loaded = LoadDatabaseSettings();
421  DatabaseParams dbParamsFromFile = m_dbParams;
422 
423  // In addition to the UI chooser, we can also try to autoSelect later,
424  // but only if we're not doing manualSelect and there was no
425  // valid config.xml
426  bool autoSelect = !manualSelect && !loaded && !noAutodetect;
427 
428  // 2. If the user isn't forcing up the chooser UI, look for a default
429  // backend in config.xml, then test DB settings we've got so far:
430  if (!manualSelect)
431  {
432  // config.xml may contain a backend host UUID and PIN.
433  // If so, try to AutoDiscover UPnP server, and use its DB settings:
434 
435  if (DefaultUPnP(failure)) // Probably a valid backend,
436  autoSelect = manualSelect = false; // so disable any further UPnP
437  else
438  if (!failure.isEmpty())
439  LOG(VB_GENERAL, LOG_ALERT, failure);
440 
441  failure = TestDBconnection(loaded);
442  if (failure.isEmpty())
443  goto DBfound;
445  return false;
447  autoSelect=true;
448  }
449 
450  // 3. Try to automatically find the single backend:
451  if (autoSelect)
452  {
453  int count = UPnPautoconf();
454 
455  if (count == 0)
456  failure = QObject::tr("No UPnP backends found", "Backend Setup");
457 
458  if (count == 1)
459  {
460  failure = TestDBconnection();
461  if (failure.isEmpty())
462  goto DBfound;
464  return false;
465  }
466 
467  // Multiple BEs, or needs PIN.
468  manualSelect |= (count > 1 || count == -1);
469  // Search requested
471  manualSelect=true;
472  }
473 
474  manualSelect &= m_gui; // no interactive command-line chooser yet
475 
476  // Queries the user for the DB info
477  do
478  {
479  if (manualSelect)
480  {
481  // Get the user to select a backend from a possible list:
482  auto d = (BackendSelection::Decision)ChooseBackend(failure);
483  switch (d)
484  {
486  break;
488  manualSelect = false;
489  break;
491  goto NoDBfound;
492  }
493  }
494 
495  if (!manualSelect)
496  {
497  if (!PromptForDatabaseParams(failure))
498  goto NoDBfound;
499  }
500  failure = TestDBconnection();
501  if (!failure.isEmpty())
502  LOG(VB_GENERAL, LOG_ALERT, failure);
504  return false;
506  manualSelect=true;
508  manualSelect=false;
509  }
510  while (!failure.isEmpty());
511 
512 DBfound:
513  LOG(VB_GENERAL, LOG_DEBUG, "FindDatabase() - Success!");
514  // If we got the database from UPNP then the wakeup settings are lost.
515  // Restore them.
516  m_dbParams.m_wolEnabled = dbParamsFromFile.m_wolEnabled;
517  m_dbParams.m_wolReconnect = dbParamsFromFile.m_wolReconnect;
518  m_dbParams.m_wolRetry = dbParamsFromFile.m_wolRetry;
519  m_dbParams.m_wolCommand = dbParamsFromFile.m_wolCommand;
520 
522  !loaded || m_dbParams.m_forceSave ||
523  dbParamsFromFile != m_dbParams);
524  EnableDBerrors();
525  ResetDatabase();
526  return true;
527 
528 NoDBfound:
529  LOG(VB_GENERAL, LOG_DEBUG, "FindDatabase() - failed");
530  return false;
531 }
532 
537 {
538  // try new format first
540 
541  m_dbParams.m_localHostName = m_pConfig->GetValue("LocalHostName", "");
544  m_dbParams.m_dbUserName = m_pConfig->GetValue(kDefaultDB + "UserName", "");
545  m_dbParams.m_dbPassword = m_pConfig->GetValue(kDefaultDB + "Password", "");
546  m_dbParams.m_dbName = m_pConfig->GetValue(kDefaultDB + "DatabaseName", "");
548 
550  m_pConfig->GetBoolValue(kDefaultWOL + "Enabled", false);
552  m_pConfig->GetDuration<std::chrono::seconds>(kDefaultWOL + "SQLReconnectWaitTime", 0s);
554  m_pConfig->GetValue(kDefaultWOL + "SQLConnectRetry", 5);
556  m_pConfig->GetValue(kDefaultWOL + "Command", "");
557 
558  bool ok = m_dbParams.IsValid("config.xml");
559  if (!ok) // if new format fails, try legacy format
560  {
563  kDefaultMFE + "DBHostName", "");
565  kDefaultMFE + "DBUserName", "");
567  kDefaultMFE + "DBPassword", "");
569  kDefaultMFE + "DBName", "");
571  kDefaultMFE + "DBPort", 0);
572  m_dbParams.m_forceSave = true;
573  ok = m_dbParams.IsValid("config.xml");
574  }
575  if (!ok)
577 
578  gCoreContext->GetDB()->SetDatabaseParams(m_dbParams);
579 
581  if (hostname.isEmpty() ||
582  hostname == "my-unique-identifier-goes-here")
583  {
584  QString localhostname = QHostInfo::localHostName();
585  if (localhostname.isEmpty())
586  {
587  LOG(VB_GENERAL, LOG_ALERT,
588  "MCP: Error, could not determine host name." + ENO);
589  }
590 #ifdef Q_OS_ANDROID
591 #define ANDROID_EXCEPTION_CHECK \
592  if (env->ExceptionCheck()) { \
593  env->ExceptionClear(); \
594  exception=true; \
595  }
596 
597  if ((localhostname == "localhost") || localhostname.isEmpty())
598  {
599  hostname = "android";
600  bool exception=false;
601  QAndroidJniEnvironment env;
602  QAndroidJniObject myID = QAndroidJniObject::fromString("android_id");
603  QAndroidJniObject activity = QtAndroid::androidActivity();
605  QAndroidJniObject appctx = activity.callObjectMethod
606  ("getApplicationContext","()Landroid/content/Context;");
608  QAndroidJniObject contentR = appctx.callObjectMethod
609  ("getContentResolver", "()Landroid/content/ContentResolver;");
611  QAndroidJniObject androidId = QAndroidJniObject::callStaticObjectMethod
612  ("android/provider/Settings$Secure","getString",
613  "(Landroid/content/ContentResolver;Ljava/lang/String;)Ljava/lang/String;",
614  contentR.object<jobject>(),
615  myID.object<jstring>());
617  if (exception)
618  LOG(VB_GENERAL, LOG_ALERT,
619  "Java exception looking for android id");
620  else
621  hostname = QString("android-%1").arg(androidId.toString());
622  }
623  else
624  hostname = localhostname;
625 #else
626  hostname = localhostname;
627 #endif
628  LOG(VB_GENERAL, LOG_INFO, "Empty LocalHostName. This is typical.");
629  }
630  else
631  {
632  m_dbParams.m_localEnabled = true;
633  }
634 
635  LOG(VB_GENERAL, LOG_INFO, QString("Using a profile name of: '%1' (Usually the "
636  "same as this host's name.)")
637  .arg(hostname));
639 
640  return ok;
641 }
642 
644  const DatabaseParams &params, bool force)
645 {
646  bool ret = true;
647 
648  // only rewrite file if it has changed
649  if (params != m_dbParams || force)
650  {
652  "LocalHostName", params.m_localHostName);
653 
655  kDefaultDB + "PingHost", params.m_dbHostPing);
656 
657  // If dbHostName is an IPV6 address with scope,
658  // remove the scope. Unescaped % signs are an
659  // xml violation
660  QString dbHostName(params.m_dbHostName);
661  QHostAddress addr;
662  if (addr.setAddress(dbHostName))
663  {
664  addr.setScopeId(QString());
665  dbHostName = addr.toString();
666  }
668  kDefaultDB + "Host", dbHostName);
670  kDefaultDB + "UserName", params.m_dbUserName);
672  kDefaultDB + "Password", params.m_dbPassword);
674  kDefaultDB + "DatabaseName", params.m_dbName);
676  kDefaultDB + "Port", params.m_dbPort);
677 
679  kDefaultWOL + "Enabled", params.m_wolEnabled);
681  kDefaultWOL + "SQLReconnectWaitTime", params.m_wolReconnect);
683  kDefaultWOL + "SQLConnectRetry", params.m_wolRetry);
685  kDefaultWOL + "Command", params.m_wolCommand);
686 
687  // clear out any legacy nodes..
688  m_pConfig->ClearValue(kDefaultMFE + "DBHostName");
689  m_pConfig->ClearValue(kDefaultMFE + "DBUserName");
690  m_pConfig->ClearValue(kDefaultMFE + "DBPassword");
691  m_pConfig->ClearValue(kDefaultMFE + "DBName");
692  m_pConfig->ClearValue(kDefaultMFE + "DBPort");
693  m_pConfig->ClearValue(kDefaultMFE + "DBHostPing");
694 
695  // actually save the file
696  m_pConfig->Save();
697 
698  // Save the new settings:
699  m_dbParams = params;
700  gCoreContext->GetDB()->SetDatabaseParams(m_dbParams);
701 
702  // If database has changed, force its use:
703  ResetDatabase();
704  }
705  return ret;
706 }
707 
709 {
710  if (d && d->m_loop
711  && d->m_loop->isRunning())
712  d->m_loop->exit();
713 }
714 
715 
717 {
718  bool accepted = false;
719  if (m_gui)
720  {
721  TempMainWindow();
722 
723  // Tell the user what went wrong:
724  if (!error.isEmpty())
726 
727  // ask user for database parameters
728 
729  EnableDBerrors();
731  auto *dbsetting = new DatabaseSettings();
732  auto *ssd = new StandardSettingDialog(mainStack, "databasesettings",
733  dbsetting);
734  if (ssd->Create())
735  {
736  mainStack->AddScreen(ssd);
737  connect(dbsetting, &DatabaseSettings::isClosing,
739  if (!m_loop->isRunning())
740  m_loop->exec();
741  }
742  else
743  delete ssd;
744  SilenceDBerrors();
745  EndTempWindow();
746  accepted = true;
747  }
748  else
749  {
751  QString response;
752  std::this_thread::sleep_for(1s);
753  // give user chance to skip config
754  std::cout << std::endl << error.toLocal8Bit().constData() << std::endl << std::endl;
755  response = getResponse("Would you like to configure the database "
756  "connection now?",
757  "no");
758  if (!response.startsWith('y', Qt::CaseInsensitive))
759  return false;
760 
761  params.m_dbHostName = getResponse("Database host name:",
762  params.m_dbHostName);
763  response = getResponse("Should I test connectivity to this host "
764  "using the ping command?", "yes");
765  params.m_dbHostPing = response.startsWith('y', Qt::CaseInsensitive);
766 
767  params.m_dbPort = intResponse("Database non-default port:",
768  params.m_dbPort);
769  params.m_dbName = getResponse("Database name:",
770  params.m_dbName);
771  params.m_dbUserName = getResponse("Database user name:",
772  params.m_dbUserName);
773  params.m_dbPassword = getResponse("Database password:",
774  params.m_dbPassword);
775 
776  params.m_localHostName = getResponse("Unique identifier for this machine "
777  "(if empty, the local host name "
778  "will be used):",
779  params.m_localHostName);
780  params.m_localEnabled = !params.m_localHostName.isEmpty();
781 
782  response = getResponse("Would you like to use Wake-On-LAN to retry "
783  "database connections?",
784  (params.m_wolEnabled ? "yes" : "no"));
785  params.m_wolEnabled = response.startsWith('y', Qt::CaseInsensitive);
786 
787  if (params.m_wolEnabled)
788  {
789  params.m_wolReconnect =
790  std::chrono::seconds(intResponse("Seconds to wait for "
791  "reconnection:",
792  params.m_wolReconnect.count()));
793  params.m_wolRetry = intResponse("Number of times to retry:",
794  params.m_wolRetry);
795  params.m_wolCommand = getResponse("Command to use to wake server or server MAC address:",
796  params.m_wolCommand);
797  }
798 
799  accepted = m_parent->SaveDatabaseParams(params);
800  }
801  return accepted;
802 }
803 
810 {
811  QString err;
812  QString host;
813 
814  // Jan 20, 2017
815  // Changed to use port check instead of ping
816 
817  int port = 0;
818 
819  // 1 = db awake, 2 = db listening, 3 = db connects,
820  // 4 = backend awake, 5 = backend listening
821  // 9 = all ok, 10 = quit
822 
823  enum startupStates {
824  st_start = 0,
825  st_dbAwake = 1,
826  st_dbStarted = 2,
827  st_dbConnects = 3,
828  st_beWOL = 4,
829  st_beAwake = 5,
830  st_success = 6
831  } startupState = st_start;
832 
833  static const std::array<const QString,7> kGuiStatuses
834  {"start","dbAwake","dbStarted","dbConnects","beWOL","beAwake",
835  "success" };
836 
837  auto secondsStartupScreenDelay = gCoreContext->GetDurSetting<std::chrono::seconds>("StartupScreenDelay",2s);
838  auto msStartupScreenDelay = std::chrono::duration_cast<std::chrono::milliseconds>(secondsStartupScreenDelay);
839  do
840  {
841  QElapsedTimer timer;
842  timer.start();
843  if (m_dbParams.m_dbHostName.isNull() && !m_dbHostCp.isEmpty())
844  host = m_dbHostCp;
845  else
846  host = m_dbParams.m_dbHostName;
847  port = m_dbParams.m_dbPort;
848  if (port == 0)
849  port = 3306;
850  std::chrono::seconds wakeupTime = 3s;
851  int attempts = 11;
852  if (m_dbParams.m_wolEnabled) {
853  wakeupTime = m_dbParams.m_wolReconnect;
854  attempts = m_dbParams.m_wolRetry + 1;
855  startupState = st_start;
856  }
857  else
858  startupState = st_dbAwake;
859  if (attempts < 6)
860  attempts = 6;
861  if (!prompt)
862  attempts=1;
863  if (wakeupTime < 5s)
864  wakeupTime = 5s;
865 
866  std::chrono::seconds progressTotal = wakeupTime * attempts;
867 
869  m_guiStartup->setTotal(progressTotal);
870 
871  QString beWOLCmd = QString();
872  QString backendIP = QString();
873  int backendPort = 0;
874  QString masterserver;
875 
876  for (int attempt = 0;
877  attempt < attempts && startupState != st_success;
878  ++attempt)
879  {
880  // The first time do everything with minimum timeout and
881  // no GUI, for the normal case where all is OK
882  // After that show the GUI (if this is a GUI program)
883 
884  LOG(VB_GENERAL, LOG_INFO,
885  QString("Start up testing connections. DB %1, BE %2, attempt %3, status %4, Delay: %5")
886  .arg(host, backendIP, QString::number(attempt),
887  kGuiStatuses[startupState],
888  QString::number(msStartupScreenDelay.count())) );
889 
890  std::chrono::seconds useTimeout = wakeupTime;
891  if (attempt == 0)
892  useTimeout=1s;
893 
894  if (m_gui && !m_guiStartup)
895  {
896  if (msStartupScreenDelay==0ms || timer.hasExpired(msStartupScreenDelay.count()))
897  {
898  ShowGuiStartup();
899  if (m_guiStartup)
900  m_guiStartup->setTotal(progressTotal);
901  }
902  }
904  {
905  if (attempt > 0)
906  m_guiStartup->setStatusState(kGuiStatuses[startupState]);
907  m_guiStartup->setMessageState("empty");
908  processEvents();
909  }
910  switch (startupState) {
911  case st_start:
913  {
914  if (attempt > 0)
916  if (!checkPort(host, port, useTimeout))
917  break;
918  }
919  startupState = st_dbAwake;
920  [[clang::fallthrough]];
921  case st_dbAwake:
922  if (!checkPort(host, port, useTimeout))
923  break;
924  startupState = st_dbStarted;
925  [[clang::fallthrough]];
926  case st_dbStarted:
927  // If the database is connecting with link-local
928  // address, it may have changed
929  if (m_dbParams.m_dbHostName != host)
930  {
931  m_dbParams.m_dbHostName = host;
932  gCoreContext->GetDB()->SetDatabaseParams(m_dbParams);
933  }
934  EnableDBerrors();
935  ResetDatabase();
937  {
938  for (std::chrono::seconds temp = 0s; temp < useTimeout * 2 ; temp++)
939  {
940  processEvents();
941  std::this_thread::sleep_for(500ms);
942  }
943  break;
944  }
945  startupState = st_dbConnects;
946  [[clang::fallthrough]];
947  case st_dbConnects:
948  if (m_needsBackend)
949  {
950  beWOLCmd = gCoreContext->GetSetting("WOLbackendCommand", "");
951  if (!beWOLCmd.isEmpty())
952  {
953  wakeupTime += gCoreContext->GetDurSetting<std::chrono::seconds>
954  ("WOLbackendReconnectWaitTime", 0s);
955  attempts += gCoreContext->GetNumSetting
956  ("WOLbackendConnectRetry", 0);
957  useTimeout = wakeupTime;
958  if (m_gui && !m_guiStartup && attempt == 0)
959  useTimeout=1s;
960  progressTotal = wakeupTime * attempts;
962  m_guiStartup->setTotal(progressTotal);
963  startupState = st_beWOL;
964  }
965  }
966  else {
967  startupState = st_success;
968  break;
969  }
970  masterserver = gCoreContext->GetSetting
971  ("MasterServerName");
972  backendIP = gCoreContext->GetSettingOnHost
973  ("BackendServerAddr", masterserver);
974  backendPort = MythCoreContext::GetMasterServerPort();
975  [[clang::fallthrough]];
976  case st_beWOL:
977  if (!beWOLCmd.isEmpty()) {
978  if (attempt > 0)
979  MythWakeup(beWOLCmd);
980  if (!checkPort(backendIP, backendPort, useTimeout))
981  break;
982  }
983  startupState = st_beAwake;
984  [[clang::fallthrough]];
985  case st_beAwake:
986  if (!checkPort(backendIP, backendPort, useTimeout))
987  break;
988  startupState = st_success;
989  [[clang::fallthrough]];
990  case st_success:
991  // Quiet compiler warning.
992  break;
993  }
994  if (m_guiStartup)
995  {
996  if (m_guiStartup->m_Exit
999  || m_guiStartup->m_Retry)
1000  break;
1001  }
1002  processEvents();
1003  }
1004  if (startupState == st_success)
1005  break;
1006 
1007  QString stateMsg = kGuiStatuses[startupState];
1008  stateMsg.append("Fail");
1009  LOG(VB_GENERAL, LOG_INFO,
1010  QString("Start up failure. host %1, status %2")
1011  .arg(host, stateMsg));
1012 
1013  if (m_gui && !m_guiStartup)
1014  {
1015  ShowGuiStartup();
1016  if (m_guiStartup)
1017  m_guiStartup->setTotal(progressTotal);
1018  }
1019 
1020  if (m_guiStartup
1021  && !m_guiStartup->m_Exit
1022  && !m_guiStartup->m_Setup
1023  && !m_guiStartup->m_Search
1024  && !m_guiStartup->m_Retry)
1025  {
1027  m_guiStartup->setStatusState(stateMsg);
1028  m_guiStartup->setMessageState("makeselection");
1029  m_loop->exec();
1030  }
1031  }
1032  while (m_guiStartup && m_guiStartup->m_Retry);
1033 
1034  if (startupState < st_dbAwake)
1035  {
1036  LOG(VB_GENERAL, LOG_WARNING, QString("Pinging to %1 failed, database will be unavailable").arg(host));
1037  SilenceDBerrors();
1038  err = QObject::tr(
1039  "Cannot find (ping) database host %1 on the network",
1040  "Backend Setup");
1041  return err.arg(host);
1042  }
1043 
1044  if (startupState < st_dbConnects)
1045  {
1046  SilenceDBerrors();
1047  return QObject::tr("Cannot login to database", "Backend Setup");
1048  }
1049 
1050  if (startupState < st_success)
1051  {
1052  return QObject::tr("Cannot connect to backend", "Backend Setup");
1053  }
1054 
1055  // Current DB connection may have been silenced (invalid):
1056  EnableDBerrors();
1057  ResetDatabase();
1058 
1059  return QString();
1060 }
1061 
1062 // Show the Gui Startup window.
1063 // This is called if there is a delay in startup for any reason
1064 // such as the database being unavailable
1066 {
1067  if (!m_gui)
1068  return;
1069  TempMainWindow(false);
1070  MythMainWindow *mainWindow = GetMythMainWindow();
1071  MythScreenStack *mainStack = mainWindow->GetMainStack();
1072  if (mainStack) {
1073  if (!m_guiStartup) {
1074  m_guiStartup = new GUIStartup(mainStack,m_loop);
1075  if (!m_guiStartup->Create()) {
1076  delete m_guiStartup;
1077  m_guiStartup = nullptr;
1078  }
1079  if (m_guiStartup) {
1080  mainStack->AddScreen(m_guiStartup, false);
1081  processEvents();
1082  }
1083  }
1084  }
1085 }
1086 
1096 {
1097  // This silences any DB errors from Get*Setting(),
1098  // (which is the vast majority of them)
1099  gCoreContext->GetDB()->SetSuppressDBMessages(true);
1100 
1101  // Save the configured hostname, so that we can
1102  // still display it in the DatabaseSettings screens
1103  if (!m_dbParams.m_dbHostName.isEmpty())
1105 
1106  m_dbParams.m_dbHostName.clear();
1107  gCoreContext->GetDB()->SetDatabaseParams(m_dbParams);
1108 }
1109 
1111 {
1112  // Restore (possibly) blanked hostname
1113  if (m_dbParams.m_dbHostName.isNull() && !m_dbHostCp.isEmpty())
1114  {
1116  gCoreContext->GetDB()->SetDatabaseParams(m_dbParams);
1117  }
1118 
1119  gCoreContext->GetDB()->SetSuppressDBMessages(false);
1120 }
1121 
1122 
1135 {
1137  gCoreContext->GetDB()->SetDatabaseParams(m_dbParams);
1139 }
1140 
1145 {
1146  TempMainWindow();
1147 
1148  // Tell the user what went wrong:
1149  if (!error.isEmpty())
1150  {
1151  LOG(VB_GENERAL, LOG_ERR, QString("Error: %1").arg(error));
1152  ShowOkPopup(error);
1153  }
1154 
1155  LOG(VB_GENERAL, LOG_INFO, "Putting up the UPnP backend chooser");
1156 
1159 
1160  EndTempWindow();
1161 
1162  return (int)ret;
1163 }
1164 
1171 int MythContextPrivate::UPnPautoconf(const std::chrono::milliseconds milliSeconds)
1172 {
1173  auto seconds = duration_cast<std::chrono::seconds>(milliSeconds);
1174  LOG(VB_GENERAL, LOG_INFO, QString("UPNP Search %1 secs")
1175  .arg(seconds.count()));
1176 
1178 
1179  // Search for a total of 'milliSeconds' ms, sending new search packet
1180  // about every 250 ms until less than one second remains.
1181  MythTimer totalTime; totalTime.start();
1182  MythTimer searchTime; searchTime.start();
1183  while (totalTime.elapsed() < milliSeconds)
1184  {
1185  usleep(25000);
1186  auto ttl = milliSeconds - totalTime.elapsed();
1187  if ((searchTime.elapsed() > 249ms) && (ttl > 1s))
1188  {
1189  auto ttlSeconds = duration_cast<std::chrono::seconds>(ttl);
1190  LOG(VB_GENERAL, LOG_INFO, QString("UPNP Search %1 secs")
1191  .arg(ttlSeconds.count()));
1192  SSDP::Instance()->PerformSearch(kBackendURI, ttlSeconds);
1193  searchTime.start();
1194  }
1195  }
1196 
1198 
1199  if (!backends)
1200  {
1201  LOG(VB_GENERAL, LOG_INFO, "No UPnP backends found");
1202  return 0;
1203  }
1204 
1205  int count = backends->Count();
1206  if (count)
1207  {
1208  LOG(VB_GENERAL, LOG_INFO,
1209  QString("Found %1 UPnP backends").arg(count));
1210  }
1211  else
1212  {
1213  LOG(VB_GENERAL, LOG_ERR,
1214  "No UPnP backends found, but SSDP::Find() not NULL");
1215  }
1216 
1217  if (count != 1)
1218  {
1219  backends->DecrRef();
1220  return count;
1221  }
1222 
1223  // Get this backend's location:
1224  DeviceLocation *BE = backends->GetFirst();
1225  backends->DecrRef();
1226  backends = nullptr;
1227 
1228  // We don't actually know the backend's access PIN, so this will
1229  // only work for ones that have PIN access disabled (i.e. 0000)
1230  int ret = (UPnPconnect(BE, QString())) ? 1 : -1;
1231 
1232  BE->DecrRef();
1233 
1234  return ret;
1235 }
1236 
1243 {
1244  static const QString loc = "DefaultUPnP() - ";
1245  QString pin = m_pConfig->GetValue(kDefaultPIN, "");
1246  QString usn = m_pConfig->GetValue(kDefaultUSN, "");
1247 
1248  if (usn.isEmpty())
1249  {
1250  LOG(VB_UPNP, LOG_INFO, loc + "No default UPnP backend");
1251  return false;
1252  }
1253 
1254  LOG(VB_UPNP, LOG_INFO, loc + QString("config.xml has default PIN '%1' and host USN: %2")
1255  .arg(pin, usn));
1256 
1257  // ----------------------------------------------------------------------
1258 
1259  std::chrono::milliseconds timeout_ms { 2s };
1260  auto timeout_s = duration_cast<std::chrono::seconds>(timeout_ms);
1261  LOG(VB_GENERAL, LOG_INFO, loc + QString("UPNP Search up to %1 secs")
1262  .arg(timeout_s.count()));
1263  SSDP::Instance()->PerformSearch(kBackendURI, timeout_s);
1264 
1265  // ----------------------------------------------------------------------
1266  // We need to give the server time to respond...
1267  // ----------------------------------------------------------------------
1268 
1269  DeviceLocation* devicelocation = nullptr;
1270  MythTimer totalTime;
1271  MythTimer searchTime;
1272  totalTime.start();
1273  searchTime.start();
1274  while (totalTime.elapsed() < timeout_ms)
1275  {
1276  devicelocation = SSDP::Find(kBackendURI, usn);
1277  if (devicelocation)
1278  break;
1279 
1280  usleep(25000);
1281 
1282  auto ttl = timeout_ms - totalTime.elapsed();
1283  if ((searchTime.elapsed() > 249ms) && (ttl > 1s))
1284  {
1285  auto ttlSeconds = duration_cast<std::chrono::seconds>(ttl);
1286  LOG(VB_GENERAL, LOG_INFO, loc + QString("UPNP Search up to %1 secs")
1287  .arg(ttlSeconds.count()));
1288  SSDP::Instance()->PerformSearch(kBackendURI, ttlSeconds);
1289  searchTime.start();
1290  }
1291  }
1292 
1293  // ----------------------------------------------------------------------
1294 
1295  if (!devicelocation)
1296  {
1297  Error = "Cannot find default UPnP backend";
1298  return false;
1299  }
1300 
1301  if (UPnPconnect(devicelocation, pin))
1302  {
1303  devicelocation->DecrRef();
1304  return true;
1305  }
1306 
1307  devicelocation->DecrRef();
1308  Error = "Cannot connect to default backend via UPnP. Wrong saved PIN?";
1309  return false;
1310 }
1311 
1316  const QString &PIN)
1317 {
1318  QString error;
1319  QString loc = "UPnPconnect() - ";
1320  QString URL = backend->m_sLocation;
1321  MythXMLClient client(URL);
1322 
1323  LOG(VB_UPNP, LOG_INFO, loc + QString("Trying host at %1").arg(URL));
1324  switch (client.GetConnectionInfo(PIN, &m_dbParams, error))
1325  {
1326  case UPnPResult_Success:
1327  gCoreContext->GetDB()->SetDatabaseParams(m_dbParams);
1328  LOG(VB_UPNP, LOG_INFO, loc +
1329  "Got database hostname: " + m_dbParams.m_dbHostName);
1330  return true;
1331 
1333  // The stored PIN is probably not correct.
1334  // We could prompt for the PIN and try again, but that needs a UI.
1335  // Easier to fail for now, and put up the full UI selector later
1336  LOG(VB_UPNP, LOG_ERR, loc + "Wrong PIN?");
1337  return false;
1338 
1339  default:
1340  LOG(VB_UPNP, LOG_ERR, loc + error);
1341  break;
1342  }
1343 
1344  // This backend may have a local DB with the default user/pass/DBname.
1345  // For whatever reason, we have failed to get anything back via UPnP,
1346  // so we might as well try the database directly as a last resort.
1347  QUrl theURL(URL);
1348  URL = theURL.host();
1349  if (URL.isEmpty())
1350  return false;
1351 
1352  LOG(VB_UPNP, LOG_INFO, "Trying default DB credentials at " + URL);
1353  m_dbParams.m_dbHostName = URL;
1354 
1355  return true;
1356 }
1357 
1359 {
1360  if (e->type() == MythEvent::MythEventMessage)
1361  {
1362  if (m_disableeventpopup)
1363  return true;
1364 
1366  {
1368  }
1369 
1370  auto *me = dynamic_cast<MythEvent*>(e);
1371  if (me == nullptr)
1372  return true;
1373 
1374  if (me->Message() == "VERSION_MISMATCH" && (1 == me->ExtraDataCount()))
1375  ShowVersionMismatchPopup(me->ExtraData(0).toUInt());
1376  else if (me->Message() == "CONNECTION_FAILURE")
1378  else if (me->Message() == "PERSISTENT_CONNECTION_FAILURE")
1380  else if (me->Message() == "CONNECTION_RESTABLISHED")
1382  return true;
1383  }
1384 
1385  return QObject::event(e);
1386 }
1387 
1389 {
1390  QDateTime now = MythDate::current();
1391 
1392  if (!GetNotificationCenter() || !m_ui || !m_ui->IsScreenSetup())
1393  return;
1394 
1395  if (m_lastCheck.isValid() && now < m_lastCheck)
1396  return;
1397 
1398  // When WOL is disallowed, standy mode,
1399  // we should not show connection failures.
1400  if (!gCoreContext->IsWOLAllowed())
1401  return;
1402 
1403  m_lastCheck = now.addMSecs(5000); // don't refresh notification more than every 5s
1404 
1405  QString description = (persistent) ?
1406  QObject::tr(
1407  "The connection to the master backend "
1408  "server has gone away for some reason. "
1409  "Is it running?") :
1410  QObject::tr(
1411  "Could not connect to the master backend server. Is "
1412  "it running? Is the IP address set for it in "
1413  "mythtv-setup correct?");
1414 
1415  QString message = QObject::tr("Could not connect to master backend");
1416  MythErrorNotification n(message, sLocation, description);
1417  n.SetId(m_registration);
1418  n.SetParent(this);
1420 }
1421 
1423 {
1424  if (!GetNotificationCenter())
1425  return;
1426 
1427  if (!m_lastCheck.isValid())
1428  return;
1429 
1430  MythCheckNotification n(QObject::tr("Backend is online"), sLocation);
1431  n.SetId(m_registration);
1432  n.SetParent(this);
1433  n.SetDuration(5s);
1435  m_lastCheck = QDateTime();
1436 }
1437 
1439 {
1440  if (m_mbeVersionPopup)
1441  return;
1442 
1443  QString message =
1444  QObject::tr(
1445  "The server uses network protocol version %1, "
1446  "but this client only understands version %2. "
1447  "Make sure you are running compatible versions of "
1448  "the backend and frontend.")
1449  .arg(remote_version).arg(MYTH_PROTO_VERSION);
1450 
1451  if (HasMythMainWindow() && m_ui && m_ui->IsScreenSetup())
1452  {
1455  }
1456  else
1457  {
1458  LOG(VB_GENERAL, LOG_ERR, LOC + message);
1459  qApp->exit(GENERIC_EXIT_SOCKET_ERROR);
1460  }
1461 }
1462 
1463 // Process Events while waiting for connection
1464 // return true if progress is 100%
1466 {
1467 // bool ret = false;
1468 // if (m_guiStartup)
1469 // ret = m_guiStartup->updateProgress();
1470  qApp->processEvents(QEventLoop::AllEvents, 250);
1471  qApp->processEvents(QEventLoop::AllEvents, 250);
1472 // return ret;
1473 }
1474 
1475 // cache some settings in cache/contextcache.xml
1476 // only call this if the database is available.
1477 
1478 const std::vector<QString> MythContextPrivate::kSettingsToSave
1479 { "Theme", "Language", "Country", "GuiHeight",
1480  "GuiOffsetX", "GuiOffsetY", "GuiWidth", "RunFrontendInWindow",
1481  "AlwaysOnTop", "HideMouseCursor", "ThemePainter", "libCECEnabled",
1482  "StartupScreenDelay" };
1483 
1484 
1486 {
1487  if (!m_gui)
1488  return true;
1489  QString cacheDirName = GetConfDir() + "/cache/";
1490  QDir dir(cacheDirName);
1491  dir.mkpath(cacheDirName);
1492  XmlConfiguration config = XmlConfiguration("cache/contextcache.xml");
1493  for (const auto & setting : kSettingsToSave)
1494  {
1495  QString cacheValue = config.GetValue("Settings/"+setting,QString());
1497  QString value = gCoreContext->GetSetting(setting,QString());
1498  if (value != cacheValue)
1499  {
1500  config.SetValue("Settings/"+setting,value);
1501  m_settingsCacheDirty = true;
1502  }
1503  }
1505  return config.Save();
1506 }
1507 
1509 {
1510  if (!m_gui)
1511  return;
1512  XmlConfiguration config = XmlConfiguration("cache/contextcache.xml");
1513  for (const auto & setting : kSettingsToSave)
1514  {
1515  if (!gCoreContext->GetSetting(setting,QString()).isEmpty())
1516  continue;
1517  QString value = config.GetValue("Settings/"+setting,QString());
1518  if (!value.isEmpty())
1519  gCoreContext->OverrideSettingForSession(setting, value);
1520  }
1521  // Prevent power off TV after temporary window
1522  gCoreContext->OverrideSettingForSession("PowerOffTVAllowed", nullptr);
1523 
1524  MythTranslation::load("mythfrontend");
1525 }
1526 
1528 {
1529  QString language = gCoreContext->GetSetting("Language",QString());
1530  for (const auto & setting : kSettingsToSave)
1532  // Restore power off TV setting
1533  gCoreContext->ClearOverrideSettingForSession("PowerOffTVAllowed");
1534 
1535  if (language != gCoreContext->GetSetting("Language",QString()))
1536  MythTranslation::load("mythfrontend");
1537 }
1538 
1539 
1541 {
1542  d->m_mbeVersionPopup = nullptr;
1543  qApp->exit(GENERIC_EXIT_SOCKET_ERROR);
1544 }
1545 
1546 MythContext::MythContext(QString binversion, bool needsBackend)
1547  : m_appBinaryVersion(std::move(binversion))
1548 {
1549 #ifdef _WIN32
1550  static bool WSAStarted = false;
1551  if (!WSAStarted) {
1552  WSADATA wsadata;
1553  int res = WSAStartup(MAKEWORD(2, 0), &wsadata);
1554  LOG(VB_SOCKET, LOG_INFO,
1555  QString("WSAStartup returned %1").arg(res));
1556  }
1557 #endif
1558 
1559  d = new MythContextPrivate(this);
1560  d->m_needsBackend = needsBackend;
1561 
1563 
1564  if (!gCoreContext || !gCoreContext->Init())
1565  {
1566  LOG(VB_GENERAL, LOG_EMERG, LOC + "Unable to allocate MythCoreContext");
1567  qApp->exit(GENERIC_EXIT_NO_MYTHCONTEXT);
1568  }
1569 }
1570 
1571 bool MythContext::Init(const bool gui,
1572  const bool promptForBackend,
1573  const bool disableAutoDiscovery,
1574  const bool ignoreDB)
1575 {
1576  if (!d)
1577  {
1578  LOG(VB_GENERAL, LOG_EMERG, LOC + "Init() Out-of-memory");
1579  return false;
1580  }
1581 
1582  qRegisterMetaType<std::chrono::seconds>("std::chrono::seconds");
1583  qRegisterMetaType<std::chrono::milliseconds>("std::chrono::milliseconds");
1584  qRegisterMetaType<std::chrono::microseconds>("std::chrono::microseconds");
1585 
1586  SetDisableEventPopup(true);
1587 
1589  {
1590  LOG(VB_GENERAL, LOG_EMERG,
1591  QString("Application binary version (%1) does not "
1592  "match libraries (%2)")
1594 
1595  QString warning = QObject::tr(
1596  "This application is not compatible "
1597  "with the installed MythTV libraries.");
1598  if (gui)
1599  {
1600  d->TempMainWindow(false);
1601  ShowOkPopup(warning);
1602  }
1603  LOG(VB_GENERAL, LOG_WARNING, warning);
1604 
1605  return false;
1606  }
1607 
1608 #ifdef _WIN32
1609  // HOME environment variable might not be defined
1610  // some libraries will fail without it
1611  QString home = getenv("HOME");
1612  if (home.isEmpty())
1613  {
1614  home = getenv("LOCALAPPDATA"); // Vista
1615  if (home.isEmpty())
1616  home = getenv("APPDATA"); // XP
1617  if (home.isEmpty())
1618  home = QString("."); // getenv("TEMP")?
1619 
1620  _putenv(QString("HOME=%1").arg(home).toLocal8Bit().constData());
1621  }
1622 #endif
1623 
1624  // If HOME isn't defined, we won't be able to use default confdir of
1625  // $HOME/.mythtv nor can we rely on a MYTHCONFDIR that references $HOME
1626  QString homedir = QDir::homePath();
1627  QString confdir = qEnvironmentVariable("MYTHCONFDIR");
1628  if ((homedir.isEmpty() || homedir == "/") &&
1629  (confdir.isEmpty() || confdir.contains("$HOME")))
1630  {
1631  QString warning = "Cannot locate your home directory."
1632  " Please set the environment variable HOME";
1633  if (gui)
1634  {
1635  d->TempMainWindow(false);
1636  ShowOkPopup(warning);
1637  }
1638  LOG(VB_GENERAL, LOG_WARNING, warning);
1639 
1640  return false;
1641  }
1642 
1643  if (!d->Init(gui, promptForBackend, disableAutoDiscovery, ignoreDB))
1644  {
1645  return false;
1646  }
1647 
1648  SetDisableEventPopup(false);
1650  if (d->m_settingsCacheDirty)
1651  {
1652 #ifndef Q_OS_ANDROID
1654 #endif
1655  d->m_settingsCacheDirty = false;
1656  }
1659 
1660  return true;
1661 }
1662 
1664 {
1665  gCoreContext->InitPower(false /*destroy*/);
1666  if (MThreadPool::globalInstance()->activeThreadCount())
1667  LOG(VB_GENERAL, LOG_INFO, "Waiting for threads to exit.");
1668 
1670  SSDP::Shutdown();
1672 
1673  LOG(VB_GENERAL, LOG_INFO, "Exiting");
1674 
1675  logStop();
1676 
1677  delete gCoreContext;
1678  gCoreContext = nullptr;
1679 
1680  delete d;
1681 }
1682 
1684 {
1685  d->m_disableeventpopup = check;
1686 }
1687 
1689 {
1690  return d->m_dbParams;
1691 }
1692 
1694 {
1695  return d->SaveDatabaseParams(params, false);
1696 }
1697 
1699 {
1700  return d->saveSettingsCache();
1701 }
1702 
1703 /* vim: set expandtab tabstop=4 shiftwidth=4: */
force
bool force
Definition: mythtv/programs/mythcommflag/main.cpp:73
Configuration::GetDuration
std::enable_if< std::chrono::__is_duration< T >::value, T >::type GetDuration(const QString &sSetting, T defaultval=T::zero())
Definition: configuration.h:40
MythContextPrivate::ShowConnectionFailurePopup
void ShowConnectionFailurePopup(bool persistent)
Definition: mythcontext.cpp:1388
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:315
MythTimer::elapsed
std::chrono::milliseconds elapsed(void)
Returns milliseconds elapsed since last start() or restart()
Definition: mythtimer.cpp:91
mythevent.h
XmlConfiguration::Save
bool Save(void) override
Definition: configuration.cpp:88
MythContext::MythContext
MythContext(QString binversion, bool needsBackend=false)
Definition: mythcontext.cpp:1546
Configuration::SetDuration
std::enable_if< std::chrono::__is_duration< T >::value, void >::type SetDuration(const QString &sSetting, T value)
Definition: configuration.h:44
MythEvent::MythEventMessage
static Type MythEventMessage
Definition: mythevent.h:79
ENO
#define ENO
This can be appended to the LOG args with "+".
Definition: mythlogging.h:72
PortChecker
Small class to handle TCP port checking and finding link-local context.
Definition: portchecker.h:44
GUIStartup::Create
bool Create(void) override
Definition: guistartup.cpp:70
DatabaseParams::m_dbHostName
QString m_dbHostName
database server
Definition: mythdbparams.h:22
MediaMonitor::ejectOpticalDisc
static void ejectOpticalDisc(void)
Eject a disk, unmount a drive, open a tray.
Definition: mythmediamonitor.cpp:980
MythContextSlotHandler::VersionMismatchPopupClosed
void VersionMismatchPopupClosed(void)
Definition: mythcontext.cpp:1540
MythPluginManager
Definition: mythplugin.h:62
dbutil.h
MythMainWindow::Init
void Init(bool MayReInit=true)
Definition: mythmainwindow.cpp:638
error
static void error(const char *str,...)
Definition: vbi.cpp:35
ReferenceCounter::DecrRef
virtual int DecrRef(void)
Decrements reference count and deletes on 0.
Definition: referencecounter.cpp:125
ShowNotificationError
void ShowNotificationError(const QString &msg, const QString &from, const QString &detail, const VNMask visibility, const MythNotification::Priority priority)
convenience utility to display error message as notification
Definition: mythnotificationcenter.cpp:1428
MythContextSlotHandler::MythContextPrivate
friend class MythContextPrivate
Definition: mythcontext.h:16
SSDP::PerformSearch
void PerformSearch(const QString &sST, std::chrono::seconds timeout=2s)
Definition: ssdp.cpp:202
MythContextPrivate::event
bool event(QEvent *) override
Definition: mythcontext.cpp:1358
mythdb.h
MythCoreContext::SendReceiveStringList
bool SendReceiveStringList(QStringList &strlist, bool quickTimeout=false, bool block=true)
Send a message to the backend and wait for a response.
Definition: mythcorecontext.cpp:1397
MythContextPrivate::kSettingsToSave
static const std::vector< QString > kSettingsToSave
Definition: mythcontext.cpp:144
MythContextPrivate::UPnPautoconf
int UPnPautoconf(std::chrono::milliseconds milliSeconds=2s)
If there is only a single UPnP backend, use it.
Definition: mythcontext.cpp:1171
MythTimer
A QElapsedTimer based timer to replace use of QTime as a timer.
Definition: mythtimer.h:13
MythCheckNotification
Definition: mythnotification.h:212
MythContextPrivate::DefaultUPnP
bool DefaultUPnP(QString &Error)
Get the default backend from config.xml, use UPnP to find it.
Definition: mythcontext.cpp:1242
MythContext::GetDatabaseParams
DatabaseParams GetDatabaseParams(void)
Definition: mythcontext.cpp:1688
DatabaseParams::m_forceSave
bool m_forceSave
set to true to force a save of the settings file
Definition: mythdbparams.h:40
MythNotification::SetDuration
void SetDuration(std::chrono::seconds Duration)
Contains a duration during which the notification will be displayed for. The duration is informative ...
Definition: mythnotification.cpp:136
MythContextPrivate::m_mbeVersionPopup
MythConfirmationDialog * m_mbeVersionPopup
Definition: mythcontext.cpp:140
MythNotificationCenter::Register
int Register(void *from)
An application can register in which case it will be assigned a reusable screen, which can be modifie...
Definition: mythnotificationcenter.cpp:1370
MythCoreContext::GetDBManager
MDBManager * GetDBManager(void)
Definition: mythcorecontext.cpp:891
MythUIHelper::IsScreenSetup
bool IsScreenSetup() const
Definition: mythuihelper.cpp:98
MythPluginManager::run_plugin
bool run_plugin(const QString &plugname)
Definition: mythplugin.cpp:159
DatabaseParams
Structure containing the basic Database parameters.
Definition: mythdbparams.h:10
dbsettings.h
mythplugin.h
MythCoreContext::InitLocale
void InitLocale(void)
Definition: mythcorecontext.cpp:1865
MythContext
Startup context for MythTV.
Definition: mythcontext.h:43
XmlConfiguration::GetValue
int GetValue(const QString &sSetting, int Default) override
Definition: configuration.cpp:210
MythMainWindow::getMainWindow
static MythMainWindow * getMainWindow(bool UseDB=true)
Return the existing main window, or create one.
Definition: mythmainwindow.cpp:78
MythXMLClient
Definition: mythxmlclient.h:32
MythContextPrivate::saveSettingsCache
bool saveSettingsCache(void)
Definition: mythcontext.cpp:1485
MythCoreContext::OverrideSettingForSession
void OverrideSettingForSession(const QString &key, const QString &value)
Definition: mythcorecontext.cpp:1363
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
MythContext::SetDisableEventPopup
void SetDisableEventPopup(bool check)
Definition: mythcontext.cpp:1683
MythContextPrivate::TestDBconnection
QString TestDBconnection(bool prompt=true)
Some quick sanity checks before opening a database connection.
Definition: mythcontext.cpp:809
mythxmlclient.h
kDefaultWOL
const QString kDefaultWOL
Definition: backendselect.h:23
mythdialogbox.h
MythScreenStack
Definition: mythscreenstack.h:16
SSDP::Find
static SSDPCacheEntries * Find(const QString &sURI)
Definition: ssdp.h:128
mythmediamonitor.h
MythContextPrivate::m_loop
QEventLoop * m_loop
Definition: mythcontext.cpp:135
MythContextPrivate::m_parent
MythContext * m_parent
Definition: mythcontext.cpp:118
confdir
static QString confdir
Definition: mythdirs.cpp:20
MythTimer::start
void start(void)
starts measuring elapsed time.
Definition: mythtimer.cpp:47
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythContextPrivate::~MythContextPrivate
~MythContextPrivate() override
Definition: mythcontext.cpp:253
MythContextPrivate::UPnPconnect
bool UPnPconnect(const DeviceLocation *backend, const QString &PIN)
Query a backend via UPnP for its database connection parameters.
Definition: mythcontext.cpp:1315
DatabaseSettings::isClosing
void isClosing(void)
MythContextPrivate::ShowVersionMismatchPopup
void ShowVersionMismatchPopup(uint remote_version)
Definition: mythcontext.cpp:1438
MythContextPrivate::checkPort
bool checkPort(QString &host, int port, std::chrono::seconds timeLimit) const
Check if a port is open and sort out the link-local scope.
Definition: mythcontext.cpp:327
mythdirs.h
MythContextPrivate::ShowGuiStartup
void ShowGuiStartup(void)
Definition: mythcontext.cpp:1065
myth_system
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
Definition: mythsystemlegacy.cpp:506
DeviceLocation
Definition: upnpdevice.h:209
MythContextPrivate::m_disableeventpopup
bool m_disableeventpopup
Definition: mythcontext.cpp:130
HasMythMainWindow
bool HasMythMainWindow(void)
Definition: mythmainwindow.cpp:107
MythCoreContext::InitPower
void InitPower(bool Create=true)
Definition: mythcorecontext.cpp:1852
GUIStartup::m_Search
bool m_Search
Definition: guistartup.h:62
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:10
DatabaseParams::m_wolReconnect
std::chrono::seconds m_wolReconnect
seconds to wait for reconnect
Definition: mythdbparams.h:35
MythContextPrivate::EnableDBerrors
void EnableDBerrors(void)
Definition: mythcontext.cpp:1110
XmlConfiguration
Definition: configuration.h:59
SSDP::Shutdown
static void Shutdown()
Definition: ssdp.cpp:65
langsettings.h
MythContext::m_appBinaryVersion
QString m_appBinaryVersion
Definition: mythcontext.h:63
InitializeMythDirs
void InitializeMythDirs(void)
Definition: mythdirs.cpp:30
DatabaseSettings
Definition: dbsettings.h:10
exec_program_tv_cb
static void exec_program_tv_cb(const QString &cmd)
Definition: mythcontext.cpp:152
mythversion.h
mythsystemlegacy.h
eject_cb
static void eject_cb(void)
Definition: mythcontext.cpp:240
MythCoreContext::ClearOverrideSettingForSession
void ClearOverrideSettingForSession(const QString &key)
Definition: mythcorecontext.cpp:1369
SSDP::Instance
static SSDP * Instance()
Definition: ssdp.cpp:55
Configuration::ClearValue
virtual void ClearValue(const QString &sSetting)=0
MythContext::d
MythContextPrivate * d
Definition: mythcontext.h:62
StandardSettingDialog
Definition: standardsettings.h:468
DatabaseParams::m_dbPort
int m_dbPort
database port
Definition: mythdbparams.h:24
kDefaultDB
const QString kDefaultDB
Definition: backendselect.h:22
mythdate.h
Configuration::SetValue
virtual void SetValue(const QString &sSetting, int value)=0
MDBManager::CloseDatabases
void CloseDatabases(void)
Definition: mythdbcon.cpp:472
upnp.h
guistartup.h
mythlogging.h
MythContextPrivate::m_settingsCacheDirty
bool m_settingsCacheDirty
Definition: mythcontext.cpp:137
MythContextPrivate::OnCloseDialog
void OnCloseDialog()
MythCoreContext::Init
bool Init(void)
Definition: mythcorecontext.cpp:246
GetConfDir
QString GetConfDir(void)
Definition: mythdirs.cpp:224
XmlConfiguration::SetValue
void SetValue(const QString &sSetting, int value) override
Definition: configuration.cpp:250
DatabaseParams::m_dbHostPing
bool m_dbHostPing
Can we test connectivity using ping?
Definition: mythdbparams.h:23
remotefile.h
MythContextPrivate::EndTempWindow
void EndTempWindow(void)
Definition: mythcontext.cpp:302
configplugin_cb
static void configplugin_cb(const QString &cmd)
Definition: mythcontext.cpp:213
MThreadPool::waitForDone
void waitForDone(void)
Definition: mthreadpool.cpp:574
MythContextPrivate::m_pConfig
Configuration * m_pConfig
Definition: mythcontext.cpp:128
compat.h
BackendSelection::kCancelConfigure
@ kCancelConfigure
Definition: backendselect.h:45
MythNotification::SetParent
void SetParent(void *Parent)
Contains the parent address. Required if id is set Id provided must match the parent address as provi...
Definition: mythnotification.cpp:98
MythContextPrivate::m_socket
QTcpSocket * m_socket
Definition: mythcontext.cpp:143
MythCoreContext::GetDurSetting
std::enable_if_t< std::chrono::__is_duration< T >::value, T > GetDurSetting(const QString &key, T defaultval=T::zero())
Definition: mythcorecontext.h:172
MSqlQuery::testDBConnection
static bool testDBConnection()
Checks DB connection + login (login info via Mythcontext)
Definition: mythdbcon.cpp:870
MythContextPrivate::MythContextPrivate
MythContextPrivate(MythContext *lparent)
Definition: mythcontext.cpp:245
MythContextPrivate::ChooseBackend
int ChooseBackend(const QString &error)
Search for backends via UPnP, put up a UI for the user to choose one.
Definition: mythcontext.cpp:1144
DestroyMythMainWindow
void DestroyMythMainWindow(void)
Definition: mythmainwindow.cpp:112
DeviceLocation::m_sLocation
QString m_sLocation
Definition: upnpdevice.h:235
MythCoreContext::IsFrontend
bool IsFrontend(void) const
is this process a frontend process
Definition: mythcorecontext.cpp:680
BackendSelection::kAcceptConfigure
@ kAcceptConfigure
Definition: backendselect.h:46
MythErrorNotification
Definition: mythnotification.h:198
getResponse
QString getResponse(const QString &query, const QString &def)
In an interactive shell, prompt the user to input a string.
Definition: mythmiscutil.cpp:461
MythCoreContext::GetDB
MythDB * GetDB(void)
Definition: mythcorecontext.cpp:1785
MythWakeup
bool MythWakeup(const QString &wakeUpCommand, uint flags, std::chrono::seconds timeout)
Definition: mythmiscutil.cpp:681
mythtranslation.h
Configuration::GetBoolValue
virtual bool GetBoolValue(const QString &sSetting, bool Default)=0
MythContextPrivate::SaveDatabaseParams
bool SaveDatabaseParams(const DatabaseParams &params, bool force)
Definition: mythcontext.cpp:643
DatabaseParams::m_dbPassword
QString m_dbPassword
DB password.
Definition: mythdbparams.h:26
portchecker.h
sLocation
static const QString sLocation
Definition: mythcontext.cpp:66
DatabaseParams::m_wolRetry
int m_wolRetry
times to retry to reconnect
Definition: mythdbparams.h:36
kBackendURI
const QString kBackendURI
Definition: backendselect.h:21
DatabaseParams::m_dbName
QString m_dbName
database name
Definition: mythdbparams.h:27
MythContextPrivate::PromptForDatabaseParams
bool PromptForDatabaseParams(const QString &error)
Definition: mythcontext.cpp:716
TaskQueue::Shutdown
static void Shutdown()
Definition: taskqueue.cpp:68
SSDPCacheEntries
Definition: ssdpcache.h:34
uint
unsigned int uint
Definition: compat.h:144
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:61
UPnPResult_ActionNotAuthorized
@ UPnPResult_ActionNotAuthorized
Definition: upnp.h:48
MythContextPrivate::m_ui
MythUIHelper * m_ui
Definition: mythcontext.cpp:132
MythContextPrivate::clearSettingsCacheOverride
static void clearSettingsCacheOverride(void)
Definition: mythcontext.cpp:1527
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:938
logStop
void logStop(void)
Entry point for stopping logging for an application.
Definition: logging.cpp:715
MythContextPrivate::m_registration
int m_registration
Definition: mythcontext.cpp:141
MythContextPrivate::m_masterhostname
QString m_masterhostname
master backend hostname
Definition: mythcontext.cpp:123
exec_program_cb
static void exec_program_cb(const QString &cmd)
Definition: mythcontext.cpp:147
MythUIMenuCallbacks::exec_program
void(* exec_program)(const QString &cmd)
Definition: mythuihelper.h:16
MythCoreContext::SetLocalHostname
void SetLocalHostname(const QString &hostname)
Definition: mythcorecontext.cpp:1758
MythContextSlotHandler::d
MythContextPrivate * d
Definition: mythcontext.h:31
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:30
GUIStartup::setTotal
void setTotal(std::chrono::seconds total)
Definition: guistartup.cpp:131
plugin_cb
static void plugin_cb(const QString &cmd)
Definition: mythcontext.cpp:226
GUIStartup::updateProgress
bool updateProgress(bool finished)
Definition: guistartup.cpp:147
MythPluginManager::config_plugin
bool config_plugin(const QString &plugname)
Definition: mythplugin.cpp:177
mythuihelper.h
MythContextPrivate::SilenceDBerrors
void SilenceDBerrors(void)
Cause MSqlDatabase::OpenDatabase() and MSqlQuery to fail silently.
Definition: mythcontext.cpp:1095
MYTH_BINARY_VERSION
#define MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
Definition: mythversion.h:15
MythContextPrivate::m_sh
MythContextSlotHandler * m_sh
Definition: mythcontext.cpp:133
MythCoreContext::GetMasterServerPort
static int GetMasterServerPort(void)
Returns the Master Backend control port If no master server port has been defined in the database,...
Definition: mythcorecontext.cpp:1006
MYTH_PROTO_VERSION
#define MYTH_PROTO_VERSION
Increment this whenever the MythTV network protocol changes.
Definition: mythversion.h:47
PortChecker::checkPort
bool checkPort(QString &host, int port, std::chrono::milliseconds timeLimit=30s, bool linkLocalOnly=false)
Check if a port is open and sort out the link-local scope.
Definition: portchecker.cpp:73
GUIStartup::m_Retry
bool m_Retry
Definition: guistartup.h:61
mythimage.h
DatabaseParams::LoadDefaults
void LoadDefaults(void)
Load sensible connection defaults.
Definition: mythdbparams.cpp:9
GUIStartup::setMessageState
bool setMessageState(const QString &name)
Definition: guistartup.cpp:120
MythContextPrivate::FindDatabase
bool FindDatabase(bool prompt, bool noAutodetect)
Get database connection settings and test connectivity.
Definition: mythcontext.cpp:412
GUIStartup::setStatusState
bool setStatusState(const QString &name)
Definition: guistartup.cpp:110
MythCoreContext
This class contains the runtime context for MythTV.
Definition: mythcorecontext.h:64
mythmiscutil.h
MythConfirmationDialog
Dialog asking for user confirmation. Ok and optional Cancel button.
Definition: mythdialogbox.h:272
MythContextPrivate::LoadDatabaseSettings
bool LoadDatabaseSettings(void)
Load database and host settings from config.xml, or set some defaults.
Definition: mythcontext.cpp:536
MythContext::SaveDatabaseParams
bool SaveDatabaseParams(const DatabaseParams &params)
Definition: mythcontext.cpp:1693
Configuration
Definition: configuration.h:20
MythContextPrivate::Init
bool Init(bool gui, bool promptForBackend, bool disableAutoDiscovery, bool ignoreDB)
Definition: mythcontext.cpp:336
GUIStartup
Definition: guistartup.h:53
intResponse
int intResponse(const QString &query, int def)
In an interactive shell, prompt the user to input a number.
Definition: mythmiscutil.cpp:491
MythContextPrivate::m_dbParams
DatabaseParams m_dbParams
Current database host & WOL details.
Definition: mythcontext.cpp:125
MythContextPrivate::HideConnectionFailurePopup
void HideConnectionFailurePopup(void)
Definition: mythcontext.cpp:1422
Configuration::Save
virtual bool Save(void)=0
DatabaseParams::m_wolCommand
QString m_wolCommand
command to use for wake-on-lan
Definition: mythdbparams.h:37
MythCoreContext::GetSettingOnHost
QString GetSettingOnHost(const QString &key, const QString &host, const QString &defaultval="")
Definition: mythcorecontext.cpp:952
LOC
#define LOC
Definition: mythcontext.cpp:58
LanguageSelection::prompt
static bool prompt(bool force=false)
Ask the user for the language to use.
Definition: langsettings.cpp:173
BackendSelection::kManualConfigure
@ kManualConfigure
Definition: backendselect.h:44
std
Definition: mythchrono.h:23
DatabaseParams::m_dbUserName
QString m_dbUserName
DB user name.
Definition: mythdbparams.h:25
GENERIC_EXIT_SOCKET_ERROR
#define GENERIC_EXIT_SOCKET_ERROR
Socket error.
Definition: exitcodes.h:18
BackendSelection::Decision
Decision
Definition: backendselect.h:42
GetNotificationCenter
MythNotificationCenter * GetNotificationCenter(void)
Definition: mythmainwindow.cpp:122
mythcontext.h
MythNotificationCenter::UnRegister
void UnRegister(void *from, int id, bool closeimemdiately=false)
Unregister the client.
Definition: mythnotificationcenter.cpp:1375
MythScreenStack::PopScreen
virtual void PopScreen(MythScreenType *screen=nullptr, bool allowFade=true, bool deleteScreen=true)
Definition: mythscreenstack.cpp:83
kDefaultUSN
const QString kDefaultUSN
Definition: backendselect.h:26
GENERIC_EXIT_NO_MYTHCONTEXT
#define GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
Definition: exitcodes.h:13
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:102
Configuration::GetValue
virtual int GetValue(const QString &sSetting, int Default)=0
BackendSelection::Prompt
static Decision Prompt(DatabaseParams *dbParams, Configuration *pConfig)
Definition: backendselect.cpp:47
MythNotification::SetId
void SetId(int Id)
Contains the application registration id.
Definition: mythnotification.cpp:85
MythXMLClient::GetConnectionInfo
UPnPResultCode GetConnectionInfo(const QString &sPin, DatabaseParams *pParams, QString &sMsg)
Definition: mythxmlclient.cpp:34
MythContextPrivate::TempMainWindow
void TempMainWindow(bool languagePrompt=true)
Setup a minimal themed main window, and prompt for user's language.
Definition: mythcontext.cpp:279
MythCoreContext::ActivateSettingsCache
void ActivateSettingsCache(bool activate=true)
Definition: mythcorecontext.cpp:859
MythContextPrivate::m_lastCheck
QDateTime m_lastCheck
Definition: mythcontext.cpp:142
MythContextPrivate::ResetDatabase
void ResetDatabase(void) const
Called when the user changes the DB connection settings.
Definition: mythcontext.cpp:1134
kDefaultPIN
const QString kDefaultPIN
Definition: backendselect.h:25
MythUIHelper::Init
void Init(MythUIMenuCallbacks &cbs)
Definition: mythuihelper.cpp:76
MythContextSlotHandler::OnCloseDialog
void OnCloseDialog(void)
Definition: mythcontext.cpp:708
MythContextPrivate::m_needsBackend
bool m_needsBackend
Definition: mythcontext.cpp:136
MythContextPrivate::processEvents
static void processEvents(void)
Definition: mythcontext.cpp:1465
GUIStartup::m_Setup
bool m_Setup
Definition: guistartup.h:60
MythCoreContext::ClearSettingsCache
void ClearSettingsCache(const QString &myKey=QString(""))
Definition: mythcorecontext.cpp:854
musicbrainzngs.caa.hostname
string hostname
Definition: caa.py:17
DatabaseParams::m_localEnabled
bool m_localEnabled
true if localHostName is not default
Definition: mythdbparams.h:30
UPnPResult_Success
@ UPnPResult_Success
Definition: upnp.h:37
backendselect.h
MythContextPrivate::m_dbHostCp
QString m_dbHostCp
dbHostName backup
Definition: mythcontext.cpp:126
d
static const iso6937table * d
Definition: iso6937tables.cpp:1025
MythCoreContext::IsWOLAllowed
bool IsWOLAllowed() const
Definition: mythcorecontext.cpp:660
MythUIHelper
Definition: mythuihelper.h:23
MythContextSlotHandler
Definition: mythcontext.h:14
DatabaseParams::m_wolEnabled
bool m_wolEnabled
true if wake-on-lan params are used
Definition: mythdbparams.h:34
MythTranslation::load
static void load(const QString &module_name)
Load a QTranslator for the user's preferred language.
Definition: mythtranslation.cpp:37
exitcodes.h
SSDPCacheEntries::Count
uint Count(void) const
Definition: ssdpcache.h:44
GetMythUI
MythUIHelper * GetMythUI()
Definition: mythuihelper.cpp:66
kDefaultMFE
const QString kDefaultMFE
Definition: backendselect.h:24
MThreadPool::globalInstance
static MThreadPool * globalInstance(void)
Definition: mthreadpool.cpp:317
MythCoreContext::GetPluginManager
MythPluginManager * GetPluginManager(void)
Definition: mythcorecontext.cpp:2122
mythmainwindow.h
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:49
DatabaseParams::m_localHostName
QString m_localHostName
name used for loading/saving settings
Definition: mythdbparams.h:31
MythCoreContext::SaveLocaleDefaults
void SaveLocaleDefaults(void)
Definition: mythcorecontext.cpp:1897
ShowOkPopup
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
Definition: mythdialogbox.cpp:563
MythContextPrivate::m_gui
bool m_gui
Should this context use GUI elements?
Definition: mythcontext.cpp:121
ANDROID_EXCEPTION_CHECK
#define ANDROID_EXCEPTION_CHECK
Definition: audiooutputaudiotrack.cpp:14
gContext
MythContext * gContext
This global variable contains the MythContext instance for the application.
Definition: mythcontext.cpp:64
PortChecker::cancelPortCheck
void cancelPortCheck(void)
Cancel the checkPort operation currently in progress.
Definition: portchecker.cpp:245
MythContext::Init
bool Init(bool gui=true, bool promptForBackend=false, bool disableAutoDiscovery=false, bool ignoreDB=false)
Definition: mythcontext.cpp:1571
MythMainWindow
Definition: mythmainwindow.h:35
DatabaseParams::IsValid
bool IsValid(const QString &source=QString("Unknown")) const
Definition: mythdbparams.cpp:36
MythContextPrivate::m_guiStartup
GUIStartup * m_guiStartup
Definition: mythcontext.cpp:134
SSDPCacheEntries::GetFirst
DeviceLocation * GetFirst(void)
Returns random entry in cache, returns nullptr when list is empty.
Definition: ssdpcache.cpp:80
MythContext::saveSettingsCache
bool saveSettingsCache(void)
Definition: mythcontext.cpp:1698
DestroyMythUI
void DestroyMythUI()
Definition: mythuihelper.cpp:71
GUIStartup::cancelPortCheck
void cancelPortCheck(void)
MythContextPrivate::loadSettingsCacheOverride
void loadSettingsCacheOverride(void) const
Definition: mythcontext.cpp:1508
MythContext::~MythContext
virtual ~MythContext()
Definition: mythcontext.cpp:1663
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:924
MythContextPrivate
Definition: mythcontext.cpp:68
MythNotificationCenter::Queue
bool Queue(const MythNotification &notification)
Queue a notification Queue() is thread-safe and can be called from anywhere.
Definition: mythnotificationcenter.cpp:1351
MythUIMenuCallbacks
Definition: mythuihelper.h:14
GUIStartup::m_Exit
bool m_Exit
Definition: guistartup.h:59
Configuration::SetBoolValue
virtual void SetBoolValue(const QString &sSetting, bool value)=0