Ticket #4264: ctxrestr.9.patch
File ctxrestr.9.patch, 168.4 KB (added by , 18 years ago) |
---|
-
mythtv/libs/libmythtv/dbsettings.cpp
1 #include "libmyth/mythcontext.h" 2 #include "libmyth/mythdbcon.h" 3 #include "dbsettings.h" 4 #include <qfile.h> 5 #include <qdir.h> 6 7 class MythDbSettings1: public VerticalConfigurationGroup { 8 public: 9 MythDbSettings1(const QString &DBhostOverride = QString::null); 10 11 void load(); 12 void save(); 13 14 protected: 15 TransLabelSetting *info; 16 TransLineEditSetting *dbHostName; 17 TransCheckBoxSetting *dbHostPing; 18 TransLineEditSetting *dbPort; 19 TransLineEditSetting *dbName; 20 TransLineEditSetting *dbUserName; 21 TransLineEditSetting *dbPassword; 22 TransComboBoxSetting *dbType; 23 24 QString m_DBhostOverride; 25 }; 26 27 class MythDbSettings2: public VerticalConfigurationGroup { 28 public: 29 MythDbSettings2(); 30 31 void load(); 32 void save(); 33 34 protected: 35 TransCheckBoxSetting *localEnabled; 36 TransLineEditSetting *localHostName; 37 TransCheckBoxSetting *wolEnabled; 38 TransSpinBoxSetting *wolReconnect; 39 TransSpinBoxSetting *wolRetry; 40 TransLineEditSetting *wolCommand; 41 }; 42 43 44 45 class LocalHostNameSettings : public TriggeredConfigurationGroup 46 { 47 public: 48 LocalHostNameSettings(Setting *checkbox, ConfigurationGroup *group) : 49 TriggeredConfigurationGroup(false, false, false, false) 50 { 51 setLabel(QObject::tr("Use custom identifier for frontend preferences")); 52 addChild(checkbox); 53 setTrigger(checkbox); 54 55 addTarget("1", group); 56 addTarget("0", new VerticalConfigurationGroup(true)); 57 } 58 }; 59 60 class WOLsqlSettings : public TriggeredConfigurationGroup 61 { 62 public: 63 WOLsqlSettings(Setting *checkbox, ConfigurationGroup *group) : 64 TriggeredConfigurationGroup(false, false, false, false) 65 { 66 setLabel(QObject::tr("Backend Server Wakeup settings")); 67 68 addChild(checkbox); 69 setTrigger(checkbox); 70 71 addTarget("1", group); 72 addTarget("0", new VerticalConfigurationGroup(true)); 73 } 74 }; 75 76 MythDbSettings1::MythDbSettings1(const QString &DbHostOverride) : 77 VerticalConfigurationGroup(false, true, false, false) 78 { 79 m_DBhostOverride = DbHostOverride; 80 81 setLabel(QObject::tr("Database Configuration") + " 1/2"); 82 83 info = new TransLabelSetting(); 84 85 MSqlQuery query(MSqlQuery::InitCon()); 86 if (query.isConnected()) 87 info->setValue(QObject::tr("All database settings take effect when " 88 "you restart this program.")); 89 else 90 info->setValue(QObject::tr("Myth could not connect to the database. " 91 "Please verify your database settings " 92 "below.")); 93 addChild(info); 94 95 VerticalConfigurationGroup* dbServer = new VerticalConfigurationGroup(); 96 dbServer->setLabel(QObject::tr("Database Server Settings")); 97 dbHostName = new TransLineEditSetting(true); 98 dbHostName->setLabel(QObject::tr("Hostname")); 99 dbHostName->setHelpText(QObject::tr("The host name or IP address of " 100 "the machine hosting the database. " 101 "This information is required.")); 102 dbServer->addChild(dbHostName); 103 104 HorizontalConfigurationGroup* g = 105 new HorizontalConfigurationGroup(false, false); 106 107 dbHostPing = new TransCheckBoxSetting(); 108 dbHostPing->setLabel(QObject::tr("Ping test server?")); 109 dbHostPing->setHelpText(QObject::tr("Test basic host connectivity using " 110 "the ping command. Turn off if your " 111 "host or network don't support ping " 112 "(ICMP ECHO) packets")); 113 g->addChild(dbHostPing); 114 115 // Some extra horizontal space: 116 TransLabelSetting *l = new TransLabelSetting(); 117 l->setValue(" "); 118 g->addChild(l); 119 120 dbServer->addChild(g); 121 122 dbPort = new TransLineEditSetting(true); 123 dbPort->setLabel(QObject::tr("Port")); 124 dbPort->setHelpText(QObject::tr("The port number the database is running " 125 "on. Leave blank if using the default " 126 "port (3306).")); 127 g->addChild(dbPort); 128 129 dbName = new TransLineEditSetting(true); 130 dbName->setLabel(QObject::tr("Database name")); 131 dbName->setHelpText(QObject::tr("The name of the database. " 132 "This information is required.")); 133 dbServer->addChild(dbName); 134 135 dbUserName = new TransLineEditSetting(true); 136 dbUserName->setLabel(QObject::tr("User")); 137 dbUserName->setHelpText(QObject::tr("The user name to use while " 138 "connecting to the database. " 139 "This information is required.")); 140 dbServer->addChild(dbUserName); 141 142 dbPassword = new TransLineEditSetting(true); 143 dbPassword->setLabel(QObject::tr("Password")); 144 dbPassword->setHelpText(QObject::tr("The password to use while " 145 "connecting to the database. " 146 "This information is required.")); 147 dbServer->addChild(dbPassword); 148 149 dbType = new TransComboBoxSetting(false); 150 dbType->setLabel(QObject::tr("Database type")); 151 dbType->addSelection(QObject::tr("MySQL"), "QMYSQL3"); 152 dbType->setValue(0); 153 dbType->setHelpText(QObject::tr("The database implementation used " 154 "for your server.")); 155 dbType->setEnabled(false); 156 //dbServer->addChild(dbType); 157 158 addChild(dbServer); 159 160 } 161 162 MythDbSettings2::MythDbSettings2(void) : 163 VerticalConfigurationGroup(false, true, false, false) 164 { 165 setLabel(QObject::tr("Database Configuration") + " 2/2"); 166 167 localEnabled = new TransCheckBoxSetting(); 168 localEnabled->setLabel(QObject::tr("Use custom identifier for frontend " 169 "preferences")); 170 localEnabled->setHelpText(QObject::tr("If this frontend's host name " 171 "changes often, check this box " 172 "and provide a network-unique " 173 "name to identify it. " 174 "If unchecked, the frontend " 175 "machine's local host name will " 176 "be used to save preferences in " 177 "the database.")); 178 179 localHostName = new TransLineEditSetting(true); 180 localHostName->setLabel(QObject::tr("Custom identifier")); 181 localHostName->setHelpText(QObject::tr("An identifier to use while " 182 "saving the settings for this " 183 "frontend.")); 184 185 VerticalConfigurationGroup *group1 = 186 new VerticalConfigurationGroup(false); 187 group1->addChild(localHostName); 188 189 LocalHostNameSettings *sub3 = 190 new LocalHostNameSettings(localEnabled, group1); 191 addChild(sub3); 192 193 wolEnabled = new TransCheckBoxSetting(); 194 wolEnabled->setLabel(QObject::tr("Enable Database Server Wakeup")); 195 wolEnabled->setHelpText(QObject::tr("If checked, the frontend will use " 196 "database wakeup parameters to " 197 "reconnect to the database server.")); 198 199 wolReconnect = new TransSpinBoxSetting(0, 60, 1, true); 200 wolReconnect->setLabel(QObject::tr("Reconnect time")); 201 wolReconnect->setHelpText(QObject::tr("The time in seconds to wait for " 202 "the server to wake up.")); 203 204 wolRetry = new TransSpinBoxSetting(1, 10, 1, true); 205 wolRetry->setLabel(QObject::tr("Retry attempts")); 206 wolRetry->setHelpText(QObject::tr("The number of retries to wake the " 207 "server before the frontend gives " 208 "up.")); 209 210 wolCommand = new TransLineEditSetting(true); 211 wolCommand->setLabel(QObject::tr("Wake command")); 212 wolCommand->setHelpText(QObject::tr("The command executed on this " 213 "frontend to wake up the database " 214 "server (eg. sudo /etc/init.d/mysql " 215 "restart).")); 216 217 HorizontalConfigurationGroup *group2 = 218 new HorizontalConfigurationGroup(false, false); 219 group2->addChild(wolReconnect); 220 group2->addChild(wolRetry); 221 222 VerticalConfigurationGroup *group3 = 223 new VerticalConfigurationGroup(false); 224 group3->addChild(group2); 225 group3->addChild(wolCommand); 226 227 WOLsqlSettings *sub4 = 228 new WOLsqlSettings(wolEnabled, group3); 229 addChild(sub4); 230 } 231 232 void MythDbSettings1::load() 233 { 234 if (gDBparams.dbName.isEmpty() || gDBparams.dbHostName.isEmpty() 235 || gDBparams.dbUserName.isEmpty() 236 || gDBparams.dbPassword.isEmpty()) 237 info->setValue(info->getValue() + "\n" + 238 QObject::tr("Required fields are" 239 " marked with an asterisk (*).")); 240 241 if (gDBparams.dbHostName.isEmpty()) 242 { 243 dbHostName->setLabel("* " + dbHostName->getLabel()); 244 dbHostName->setValue(m_DBhostOverride); 245 } 246 else 247 dbHostName->setValue(gDBparams.dbHostName); 248 249 dbHostPing->setValue(gDBparams.dbHostPing); 250 251 if (gDBparams.dbPort) 252 dbPort->setValue(QString::number(gDBparams.dbPort)); 253 254 dbUserName->setValue(gDBparams.dbUserName); 255 if (gDBparams.dbUserName.isEmpty()) 256 dbUserName->setLabel("* " + dbUserName->getLabel()); 257 dbPassword->setValue(gDBparams.dbPassword); 258 if (gDBparams.dbPassword.isEmpty()) 259 dbPassword->setLabel("* " + dbPassword->getLabel()); 260 dbName->setValue(gDBparams.dbName); 261 if (gDBparams.dbName.isEmpty()) 262 dbName->setLabel("* " + dbName->getLabel()); 263 264 if (gDBparams.dbType == "QMYSQL3") 265 dbType->setValue(0); 266 else if (gDBparams.dbType == "QPSQL7") 267 dbType->setValue(1); 268 } 269 270 void MythDbSettings2::load() 271 { 272 localEnabled->setValue(gDBparams.localEnabled); 273 localHostName->setValue(gDBparams.localHostName); 274 275 wolEnabled->setValue(gDBparams.wolEnabled); 276 wolReconnect->setValue(gDBparams.wolReconnect); 277 wolRetry->setValue(gDBparams.wolRetry); 278 wolCommand->setValue(gDBparams.wolCommand); 279 } 280 281 void MythDbSettings1::save() 282 { 283 gDBparams.dbHostName = dbHostName->getValue(); 284 gDBparams.dbHostPing = dbHostPing->boolValue(); 285 gDBparams.dbPort = dbPort->getValue().toInt(); 286 gDBparams.dbUserName = dbUserName->getValue(); 287 gDBparams.dbPassword = dbPassword->getValue(); 288 gDBparams.dbName = dbName->getValue(); 289 gDBparams.dbType = dbType->getValue(); 290 291 gContext->SaveDatabaseParams(gDBparams); 292 } 293 294 void MythDbSettings2::save() 295 { 296 gDBparams.localEnabled = localEnabled->boolValue(); 297 gDBparams.localHostName = localHostName->getValue(); 298 299 gDBparams.wolEnabled = wolEnabled->boolValue(); 300 gDBparams.wolReconnect = wolReconnect->intValue(); 301 gDBparams.wolRetry = wolRetry->intValue(); 302 gDBparams.wolCommand = wolCommand->getValue(); 303 304 gContext->SaveDatabaseParams(gDBparams); 305 } 306 307 DatabaseSettings::DatabaseSettings(const QString &DBhostOverride) 308 { 309 addChild(new MythDbSettings1(DBhostOverride)); 310 addChild(new MythDbSettings2()); 311 } 312 313 void DatabaseSettings::addDatabaseSettings(ConfigurationWizard *wizard) 314 { 315 wizard->addChild(new MythDbSettings1()); 316 wizard->addChild(new MythDbSettings2()); 317 } -
mythtv/libs/libmythtv/libmythtv.pro
27 27 DEPENDPATH += ../libmythlivemedia/UsageEnvironment/include 28 28 DEPENDPATH += ../libmythlivemedia/UsageEnvironment 29 29 30 LIBS += -L../libmyth -L../libavutil -L../libavcodec -L../libavformat 30 LIBS += -L../libmyth -L../libmythupnp -L../libmythui 31 LIBS += -L../libavutil -L../libavcodec -L../libavformat 31 32 LIBS += -L../libmythmpeg2 -L../libmythdvdnav 32 33 LIBS += -L../libmythfreemheg -L../libmythlivemedia 33 LIBS += -lmyth-$${LIBVERSION} -lmythavutil-$${LIBVERSION} 34 LIBS += -lmyth-$${LIBVERSION} -lmythupnp-$${LIBVERSION} -lmythui-$${LIBVERSION} 35 LIBS += -lmythavutil-$${LIBVERSION} 34 36 LIBS += -lmythavcodec-$${LIBVERSION} -lmythdvdnav-$${LIBVERSION} 35 37 LIBS += -lmythavformat-$${LIBVERSION} -lmythmpeg2-$${LIBVERSION} 36 38 LIBS += -lmythfreemheg-$${LIBVERSION} -lmythlivemedia-$${LIBVERSION} 37 39 LIBS += $$EXTRA_LIBS 38 40 39 41 TARGETDEPS += ../libmyth/libmyth-$${MYTH_SHLIB_EXT} 42 TARGETDEPS += ../libmythupnp/libmythupnp-$${MYTH_SHLIB_EXT} 43 TARGETDEPS += ../libmythui/libmythui-$${MYTH_SHLIB_EXT} 40 44 TARGETDEPS += ../libavutil/libmythavutil-$${MYTH_SHLIB_EXT} 41 45 TARGETDEPS += ../libavcodec/libmythavcodec-$${MYTH_SHLIB_EXT} 42 46 TARGETDEPS += ../libavformat/libmythavformat-$${MYTH_SHLIB_EXT} … … 78 82 # DVDUtils uses Objective-C++, activated by .mm suffix 79 83 QMAKE_EXT_CPP += .mm 80 84 } 81 82 # There is a dependence on some stuff in libmythui.83 # It isn't built yet, so we have to ignore these for now:84 QMAKE_LFLAGS_SHLIB += -flat_namespace -undefined warning85 #LIBS += -lmythui-$${LIBVERSION} -L../libmythui86 87 QMAKE_LFLAGS_SHLIB += -seg1addr 0xC900000088 85 } 89 86 90 87 cygwin:QMAKE_LFLAGS_SHLIB += -Wl,--noinhibit-exec … … 142 139 HEADERS += channeleditor.h channelsettings.h 143 140 HEADERS += previewgenerator.h transporteditor.h 144 141 HEADERS += importicons.h 142 HEADERS += backendselect.h dbsettings.h 143 HEADERS += mythcontextui.h 145 144 146 145 SOURCES += programinfo.cpp proglist.cpp 147 146 SOURCES += storagegroup.cpp … … 165 164 SOURCES += channeleditor.cpp channelsettings.cpp 166 165 SOURCES += previewgenerator.cpp transporteditor.cpp 167 166 SOURCES += importicons.cpp 167 SOURCES += backendselect.cpp dbsettings.cpp 168 SOURCES += mythcontextui.cpp 168 169 169 170 # DiSEqC 170 171 HEADERS += diseqc.h diseqcsettings.h … … 521 522 POST_TARGETDEPS += libmythui-bootstrap.a 522 523 } 523 524 524 # install headers required by mytharchive 525 # install headers required by mytharchivehelper 525 526 inc.path = $${PREFIX}/include/mythtv/libmythtv/ 526 inc.files = programinfo.h remoteutil.h recordingtypes.h527 inc.files = mythcontextui.h programinfo.h remoteutil.h recordingtypes.h 527 528 528 529 INSTALLS += inc -
mythtv/libs/libmythtv/backendselect.h
1 #ifndef __BACKENDSELECT_H__ 2 #define __BACKENDSELECT_H__ 3 4 //#include <qlistbox.h> 5 6 #include "libmyth/mythdialogs.h" 7 #include "libmyth/mythwidgets.h" 8 #include "libmythupnp/upnpdevice.h" 9 10 class ListBoxDevice : public QListBoxText 11 { 12 public: 13 14 ListBoxDevice(QListBox *list, const QString &name, DeviceLocation *dev) 15 : QListBoxText(list, name) 16 { 17 if ((m_dev = dev) != NULL) 18 m_dev->AddRef(); 19 } 20 21 virtual ~ListBoxDevice() 22 { 23 if (m_dev != NULL) 24 m_dev->Release(); 25 } 26 27 DeviceLocation *m_dev; 28 }; 29 30 typedef QMap< QString, ListBoxDevice *> ItemMap; 31 32 33 class BackendSelect : public MythDialog 34 { 35 Q_OBJECT 36 37 public: 38 BackendSelect(MythMainWindow *parent, DatabaseParams *params); 39 virtual ~BackendSelect(); 40 41 void customEvent(QCustomEvent *e); 42 43 QString m_PIN; 44 QString m_USN; 45 46 47 public slots: 48 49 void Accept (void); ///< Linked to the OK button 50 void Manual (void); ///< Linked to 'Configure Manually' button 51 void Search (void); 52 53 54 protected: 55 56 void AddItem (DeviceLocation *dev); 57 bool Connect (DeviceLocation *dev); 58 void CreateUI (void); 59 void FillListBox(void); 60 void RemoveItem(QString URN); 61 62 DatabaseParams *m_DBparams; 63 ItemMap m_devices; 64 MythMainWindow *m_parent; 65 MythListBox *m_backends; 66 }; 67 68 #endif -
mythtv/libs/libmythtv/mythcontextui.h
1 #ifndef __MYTHCONTEXTUI_H__ 2 #define __MYTHCONTEXTUI_H__ 3 4 #include <mythexp.h> 5 #include <libmythui/mythmainwindow.h> 6 #include <libmythupnp/upnp.h> 7 8 class MythContextGUI; 9 class MythContextTTY; 10 11 /// 12 /// Some common implementation details for MythContextGUI and MythContextTTY 13 /// 14 /// This would normally be hidden in mythcontextui.cpp, but having it here 15 /// makes the class hierarchy simpler, and it is only programs/*/main.cpp 16 /// that will be recompiled if this class's members are changed. 17 18 class MHIDDEN MythContextUI : MythContext 19 { 20 friend class MythContextGUI; 21 friend class MythContextTTY; 22 23 public: 24 MythContextUI(MythContextGUI *parent, const QString &binVersion); 25 ~MythContextUI(); 26 27 int PromptForSchemaUpgrade(const QString &dbver, const QString ¤t); 28 29 30 private: 31 const QString BinaryVersionError(void); 32 bool FindDatabase(const bool prompt = false, 33 const bool noPrompt = false); 34 const QString PluginVersionError(const QString &pluginName, 35 const QString &libMythVersion, 36 const QString &pluginVersion); 37 38 // These deal with mysql.txt 39 void LoadDatabaseSettings(); 40 bool LoadSettingsFile(); 41 bool PromptForDatabaseParams(const QString &error); 42 43 // These deal with config.xml and UPnP 44 bool InitUPnP(void); 45 void DeleteUPnP(void); 46 int ChooseBackend(const QString &error); 47 48 int UPnPautoconf(const int milliSeconds = 2000); 49 bool DefaultUPnP(QString &error); 50 bool UPnPconnect(const DeviceLocation *device, const QString &PIN); 51 52 53 void BackupDBhostname (void) { m_DBhostCp = gDBparams.dbHostName; }; 54 void RestoreDBhostname(void) { gDBparams.dbHostName = m_DBhostCp; }; 55 QString TestDBconnection (void); 56 57 58 QString m_binVersion; ///< Version of the the calling program 59 bool m_disableLibPopup; 60 QString m_DBhostCp; 61 62 bool m_GUI; ///< Is the parent a GUI context? 63 MythContextGUI *m_parent; 64 MythMainWindow *m_win; 65 66 // For UPnP autodiscovery: 67 HttpServer *m_HTTP; 68 UPnp *m_UPnP; 69 XmlConfiguration *m_XML; 70 }; 71 72 /// GUI-based MythContext 73 74 class MPUBLIC MythContextGUI : MythContextUI 75 { 76 public: 77 MythContextGUI(const QString &binVersion); 78 ~MythContextGUI(); 79 80 bool Init(UPnp *UPnPclient = NULL, 81 const bool promptForBackend = false, 82 const bool bypassAutoDiscovery = false); 83 bool TestPopupVersion(const QString &pluginName, 84 const QString &libMythVersion, 85 const QString &pluginVersion); 86 void SetDisableLibraryPopup(const bool check) 87 { m_disableLibPopup = check; }; 88 89 void attachToWin(QWidget *child) { m_win->attach(child); }; 90 void detachFromWin(QWidget *child) { m_win->detach(child); }; 91 int NormalizeFontSize(const int pointSize) 92 { if (m_win) return m_win->NormalizeFontSize(pointSize); else puts("###################################### NormalizeFontSize() - Window is NULL"); return 1; }; 93 bool TranslateKeyPress(const QString &context, 94 QKeyEvent *e, 95 QStringList &actions, bool allowJumps) 96 { return m_win->TranslateKeyPress(context, e, actions, allowJumps); }; 97 98 MythMainWindow *CreateMainWindow(void); 99 MythMainWindow *TempMainWindow(bool languagePrompt = true); 100 void EndTempWindow(void); 101 }; 102 103 /// Non-GUI MythContext 104 /// 105 /// The name is a misnomer. A program's output might not 106 /// be in a terminal-connected shell (and thus !isatty()) 107 108 class MPUBLIC MythContextTTY : MythContextUI 109 { 110 public: 111 MythContextTTY(const QString &binVersion); 112 ~MythContextTTY(); 113 114 bool Init(UPnp *UPnPclient); 115 116 bool TestPopupVersion(const QString &, 117 const QString &, 118 const QString &) { return false; } 119 void SetDisableLibraryPopup(const bool) {}; 120 121 void attachToWin(QWidget *child) {}; 122 void detachFromWin(QWidget *child) {}; 123 int NormalizeFontSize(const int pointSize) { return pointSize; }; 124 bool TranslateKeyPress(const QString &, 125 QKeyEvent *, 126 QStringList &, bool) { return false; } 127 128 MythMainWindow * CreateMainWindow(void) { return NULL; }; 129 }; 130 131 // Prompt the user and get a value. Currently only used in a TTY context, 132 // but putting them here allows them to be used directly by anything. 133 134 MPUBLIC QString getResponse(const QString &query, const QString &def); 135 MPUBLIC int intResponse(const QString &query, const int def); 136 137 #endif -
mythtv/libs/libmythtv/dbsettings.h
1 #ifndef DBSETTINGS_H 2 #define DBSETTINGS_H 3 4 #include "libmyth/mythconfigdialogs.h" 5 6 class MPUBLIC DatabaseSettings: public ConfigurationWizard { 7 public: 8 DatabaseSettings(const QString &DBhostOverride = QString::null); 9 10 // This routine calls wizard->addChild() for each of 11 // the database configuration screens. This allows 12 // the number of DB config screens to change. 13 static void addDatabaseSettings(ConfigurationWizard *wizard); 14 }; 15 16 #endif -
mythtv/libs/libmythtv/mythcontextui.cpp
1 #include <qdir.h> 2 3 #include "backendselect.h" 4 #include "dbsettings.h" 5 #include "mythcontextui.h" 6 7 #include "libmyth/dialogbox.h" 8 #include "libmyth/langsettings.h" 9 #include "libmyth/mythcontext.h" 10 #include "libmyth/oldsettings.h" 11 #include "libmyth/util.h" 12 #include "libmythui/mythmainwindow.h" 13 #include "libmythupnp/mythxmlclient.h" 14 15 16 MythContextUI::MythContextUI(MythContextGUI *parent, const QString &binVersion) 17 { 18 m_binVersion = binVersion; 19 m_disableLibPopup = false; // Only used in MythContextGui 20 m_GUI = (bool)parent; 21 m_parent = parent; // ,, ,, ,, ,, 22 m_win = NULL; // ,, ,, ,, ,, 23 24 m_HTTP = NULL, m_UPnP = NULL, m_XML = NULL; 25 26 // Set this early, so that our Init code can use it 27 if (!gContext) 28 gContext = this; 29 } 30 31 MythContextUI::~MythContextUI() 32 { 33 DeleteUPnP(); 34 }; 35 36 /** 37 * \brief Try to prevent silent, automatic database upgrades 38 * \returns -1 to use the existing schema, 0 to exit, 1 to upgrade. 39 * 40 * The GUI prompts have no defaults, so that nothing dangerous 41 * will happen if the user hits return a few times. 42 * Hopefully this will force users to stop and think? 43 * Similarly, the shell command prompting requires an explicit "yes". 44 * Non-interactive shells default to old behaviour (upgrading) 45 */ 46 int MythContextUI::PromptForSchemaUpgrade(const QString &dbver, 47 const QString ¤t) 48 { 49 bool autoUpgrade = false; 50 bool connections = false; // Are (other) FE/BEs connected? 51 bool expertMode = false; // Use existing schema? Multiple buttons? 52 QString message; 53 int returnValue = MYTH_SCHEMA_UPGRADE; 54 bool upgradable = (dbver.toUInt() < current.toUInt()); 55 QString warnOtherCl = QObject::tr("There are also other" 56 " clients using this database. " 57 "They should be shut down first."); 58 59 60 // No current DBSchemaVer? Empty database, so upgrade to create tables 61 if (dbver.isEmpty()) 62 { 63 VERBOSE(VB_GENERAL, "No current database version. Auto upgrading"); 64 return MYTH_SCHEMA_UPGRADE; 65 } 66 67 68 // Users and developers can choose to live dangerously, 69 // either to silently and automatically upgrade, 70 // or an expert option to allow use of existing: 71 switch (gContext->GetNumSetting("DBSchemaAutoUpgrade")) 72 { 73 case 1: autoUpgrade = true; break; 74 case -1: expertMode = true; break; 75 default: break; 76 } 77 78 79 // FIXME: Don't know how to determine this 80 //if (getActiveConnections() > 1) 81 // connections = true; 82 83 84 // Deal with the trivial case first (No user prompting required) 85 if (autoUpgrade && upgradable && !connections) 86 return MYTH_SCHEMA_UPGRADE; 87 88 89 // Build up strings used both in GUI and command shell contexts: 90 if (upgradable) 91 { 92 if (autoUpgrade && connections) 93 { 94 message = QObject::tr("Error: MythTV cannot upgrade the" 95 " schema of this datatase because" 96 " other clients are using it.\n\n" 97 "Please shut them down before upgrading."); 98 returnValue = MYTH_SCHEMA_ERROR; 99 } 100 else 101 { 102 message = QObject::tr("Warning: MythTV wants to upgrade" 103 " your database schema, from %1 to %2."); 104 if (expertMode) 105 message += "\n\n" + 106 QObject::tr("You can try using the old schema," 107 " but that may cause problems."); 108 } 109 } 110 else // This client is too old 111 { 112 if (expertMode) 113 message = QObject::tr("Warning: MythTV database has newer" 114 " schema (%1) than expected (%2)."); 115 else 116 { 117 message = QObject::tr("Error: MythTV database has newer" 118 " schema (%1) than expected (%2)."); 119 returnValue = MYTH_SCHEMA_ERROR; 120 } 121 } 122 123 if (message.contains("%1")) 124 message = message.arg(dbver).arg(current); 125 126 127 if (m_GUI) 128 { 129 bool createdTempWindow = false; 130 131 if (!m_win) 132 { 133 m_parent->TempMainWindow(); 134 createdTempWindow = true; 135 } 136 137 if (returnValue == MYTH_SCHEMA_ERROR) 138 { 139 MythPopupBox::showOkPopup( 140 m_win, "Database Upgrade Error", 141 message, QObject::tr("Exit")); 142 } 143 else 144 { 145 QStringList buttonNames; 146 147 buttonNames += QObject::tr("Exit"); 148 buttonNames += QObject::tr("Upgrade"); 149 if (expertMode) 150 buttonNames += QObject::tr("Use current schema"); 151 152 DialogCode selected = MythPopupBox::ShowButtonPopup( 153 m_win, "Database Upgrade", message, 154 buttonNames, kDialogCodeButton0); 155 156 // The annoying extra confirmation: 157 if (kDialogCodeButton1 == selected) 158 { 159 message = QObject::tr("This cannot be un-done, so having a" 160 " database backup would be a good idea."); 161 if (connections) 162 message += "\n\n" + warnOtherCl; 163 164 selected = MythPopupBox::ShowButtonPopup( 165 m_win, "Database Upgrade", message, 166 buttonNames, kDialogCodeButton0); 167 } 168 169 switch (selected) 170 { 171 case kDialogCodeRejected: 172 case kDialogCodeButton0: 173 returnValue = MYTH_SCHEMA_EXIT; break; 174 case kDialogCodeButton1: 175 returnValue = MYTH_SCHEMA_UPGRADE; break; 176 case kDialogCodeButton2: 177 returnValue = MYTH_SCHEMA_USE_EXISTING; break; 178 default: 179 returnValue = MYTH_SCHEMA_ERROR; 180 } 181 } 182 183 if (createdTempWindow) 184 { 185 m_parent->EndTempWindow(); 186 RestoreDBhostname(); 187 } 188 189 return returnValue; 190 } 191 192 // We are not in a GUI environment, so try to prompt the user in the shell 193 194 if (!isatty(fileno(stdin)) || !isatty(fileno(stdout))) 195 { 196 if (expertMode || !upgradable) 197 { 198 cout << "Console non-interactive. Using existing schema." << endl; 199 return MYTH_SCHEMA_USE_EXISTING; 200 } 201 202 cout << "Console is not interactive, cannot ask user about" 203 << " upgrading database schema." << endl << "Upgrading." << endl; 204 return MYTH_SCHEMA_UPGRADE; 205 } 206 207 208 QString resp; 209 210 cout << endl << message << endl << endl; 211 212 if (expertMode) 213 { 214 resp = getResponse("Would you like to use the existing schema?", "yes"); 215 if (!resp || resp.left(1).lower() == "y") 216 return MYTH_SCHEMA_USE_EXISTING; 217 } 218 219 resp = getResponse("\nShall I upgrade this database?", "yes"); 220 if (resp && resp.left(1).lower() != "y") 221 return MYTH_SCHEMA_EXIT; 222 223 if (connections) 224 cout << endl << warnOtherCl <<endl; 225 226 resp = getResponse("\nA database backup might be a good idea" 227 "\nAre you sure you want to upgrade?", "no"); 228 if (!resp || resp.left(1).lower() == "n") 229 return MYTH_SCHEMA_EXIT; 230 231 return MYTH_SCHEMA_UPGRADE; 232 } 233 234 235 236 /** 237 * Check the version passed from main.cpp with this library version. 238 */ 239 const QString MythContextUI::BinaryVersionError(void) 240 { 241 if (m_binVersion == MYTH_BINARY_VERSION) 242 return QString::null; 243 244 QString err = "This app was compiled against libmyth version: %1" 245 " but the library is version: %2\n" 246 "You probably want to recompile everything," 247 " and do a 'make distclean' first."; 248 err = QObject::tr(err).arg(m_binVersion).arg(MYTH_BINARY_VERSION); 249 250 VERBOSE(VB_IMPORTANT, err); 251 252 return err; 253 } 254 255 256 /** 257 * Get database connection settings and test connectivity. 258 * 259 * Can use UPnP AutoDiscovery to locate backends, and get their DB settings. 260 * The user can force the AutoDiscovery chooser with the --prompt argument, 261 * and disable it by using the --disable-autodiscovery argument. 262 * There is also an autoconfigure function, which counts the backends, 263 * and if there is exactly one, uses it as above. 264 * 265 * Despite its name, the disable argument currently only disables the chooser. 266 * If set, autoconfigure will still be attempted in some situations. 267 */ 268 bool MythContextUI::FindDatabase(const bool prompt, const bool noPrompt) 269 { 270 // The two bool. args actually form a Yes/Maybe/No (A tristate bool :-) 271 bool manualSelect = prompt && !noPrompt; 272 273 // In addition to the UI chooser, we can also try to autoconfigure 274 bool autoSelect = !manualSelect; 275 276 QString failure; 277 278 279 // 1. Load either mysql.txt, or use sensible "localhost" defaults: 280 LoadDatabaseSettings(); 281 282 283 // 2. If the user isn't forcing up the chooser UI, look for a default 284 // backend in config.xml, then test DB settings we've got so far: 285 if (!manualSelect) 286 { 287 // config.xml may contain a backend host UUID and PIN. 288 // If so, try to AutoDiscover UPnP server, and use its DB settings: 289 290 if (DefaultUPnP(failure)) // Probably a valid backend, 291 autoSelect = manualSelect = false; // so disable any further UPnP 292 else 293 if (failure.length()) 294 VERBOSE(VB_IMPORTANT, failure); 295 296 BackupDBhostname(); 297 failure = TestDBconnection(); 298 if (failure.isEmpty()) 299 goto DBfound; 300 RestoreDBhostname(); 301 } 302 303 VERBOSE(VB_GENERAL, "FindDatabase() - After looking up config.xml, DB now " + gDBparams.dbHostName); 304 305 // 3. Try to automatically find the single backend: 306 if (autoSelect) 307 { 308 int count = UPnPautoconf(); 309 310 if (count == 0) 311 failure = "No UPnP backends found"; 312 313 if (count == 1) 314 { 315 BackupDBhostname(); 316 failure = TestDBconnection(); 317 if (failure.isEmpty()) 318 goto DBfound; 319 RestoreDBhostname(); 320 } 321 322 if (count > 1 || count == -1) // Multiple BEs, or needs PIN. 323 manualSelect = !noPrompt; // If allowed, prompt user 324 325 VERBOSE(VB_GENERAL, "FindDatabase() - After UPnPautoconf(), DB now " + gDBparams.dbHostName); 326 } 327 328 if (!m_GUI) 329 manualSelect = false; // no interactive command-line chooser yet 330 331 332 333 // Last, get the user to select a backend from a possible list: 334 if (manualSelect) 335 { 336 switch (ChooseBackend(QString::null)) 337 { 338 case -1: // User asked to configure database manually 339 if (PromptForDatabaseParams("")) 340 break; 341 else 342 goto NoDBfound; // User cancelled - changed their mind? 343 344 case 0: // User cancelled. Exit application 345 goto NoDBfound; 346 347 case 1: // User selected a backend, so gDBparams 348 break; // should now contain the database details 349 350 default: 351 goto NoDBfound; 352 } 353 failure = TestDBconnection(); 354 VERBOSE(VB_GENERAL, "FindDatabase() - After ChooseBackend(), DB now " + gDBparams.dbHostName); 355 } 356 357 358 // Queries the user for the DB info, using the command 359 // line or the GUI depending on the application. 360 while (failure.length()) 361 { 362 VERBOSE(VB_IMPORTANT, failure); 363 if (( manualSelect && ChooseBackend(failure)) || 364 (!manualSelect && PromptForDatabaseParams(failure))) 365 { 366 failure = TestDBconnection(); 367 if (failure.length()) 368 VERBOSE(VB_IMPORTANT, failure); 369 } 370 else 371 goto NoDBfound; 372 } 373 374 DBfound: 375 VERBOSE(VB_GENERAL, 376 "FindDatabase() - Success! Using DB at " + gDBparams.dbHostName); 377 DeleteUPnP(); 378 gContext->ResetDatabase(); 379 if (!MSqlQuery::testDBConnection()) 380 { 381 VERBOSE(VB_GENERAL, "FindDatabase() - After ResetDatabase(), DB now " 382 + gDBparams.dbHostName); 383 return false; 384 } 385 DeleteUPnP(); 386 return true; 387 388 NoDBfound: 389 VERBOSE(VB_IMPORTANT, "FindDatabase() failed"); 390 DeleteUPnP(); 391 return false; 392 } 393 394 395 /** 396 * Check the compiled in version of a plugin against libmyth's version. 397 */ 398 const QString MythContextUI::PluginVersionError(const QString &name, 399 const QString &libversion, 400 const QString &pluginversion) 401 { 402 if (libversion == pluginversion) 403 return QString::null; 404 405 QString err = "The " + name + " plugin was compiled against libmyth " + 406 "version: " + pluginversion + ", but the installed " + 407 "libmyth is at version: " + libversion + ". You probably " + 408 "want to recompile the " + name + " plugin after doing a " + 409 "make distclean."; 410 411 VERBOSE(VB_IMPORTANT, err); 412 413 return err; 414 } 415 416 417 /** 418 * Load database and host settings from mysql.txt, or set some defaults 419 * 420 * \returns true if mysql.txt was parsed 421 */ 422 void MythContextUI::LoadDatabaseSettings(void) 423 { 424 if (LoadSettingsFile()) 425 { 426 if (gDBparams.dbHostName.isEmpty()) 427 { 428 VERBOSE(VB_IMPORTANT, 429 "DBHostName is not set in mysql.txt. Assuming localhost"); 430 gDBparams.dbHostName = "localhost"; 431 } 432 if (gDBparams.dbUserName.isEmpty()) 433 VERBOSE(VB_IMPORTANT, "DBUserName is not set in mysql.txt"); 434 if (gDBparams.dbPassword.isEmpty()) 435 VERBOSE(VB_IMPORTANT, "DBPassword is not set in mysql.txt"); 436 if (gDBparams.dbName.isEmpty()) 437 VERBOSE(VB_IMPORTANT, "DBName is not set in mysql.txt"); 438 } 439 else 440 { 441 VERBOSE(VB_GENERAL, "Unable to read configuration file mysql.txt"); 442 443 gContext->DefaultDatabaseSettings(); 444 } 445 446 447 QString hostname = gDBparams.localHostName; 448 if (hostname.isEmpty() || hostname == "my-unique-identifier-goes-here") 449 { 450 char localhostname[1024]; 451 452 VERBOSE(VB_IMPORTANT, "Empty LocalHostName."); 453 if (gethostname(localhostname, 1024)) 454 { 455 VERBOSE(VB_IMPORTANT, 456 "LoadDBSettings() - could not determine host name." + ENO); 457 hostname = "localhost"; 458 } 459 else 460 hostname = localhostname; 461 } 462 463 VERBOSE(VB_GENERAL, QString("Using localhost value of %1").arg(hostname)); 464 465 gContext->SetHostName(hostname); 466 } 467 468 469 /** 470 * Load mysql.txt and parse its values into m_DBparams 471 */ 472 bool MythContextUI::LoadSettingsFile(void) 473 { 474 Settings s; 475 476 if (!s.LoadSettingsFiles("mysql.txt", gContext->GetInstallPrefix())) 477 return false; 478 gDBparams.dbHostName = s.GetSetting("DBHostName"); 479 gDBparams.dbHostPing = s.GetSetting("DBHostPing") != "no"; 480 gDBparams.dbPort = s.GetNumSetting("DBPort"); 481 gDBparams.dbUserName = s.GetSetting("DBUserName"); 482 gDBparams.dbPassword = s.GetSetting("DBPassword"); 483 gDBparams.dbName = s.GetSetting("DBName"); 484 gDBparams.dbType = s.GetSetting("DBType"); 485 486 gDBparams.localHostName = s.GetSetting("LocalHostName"); 487 gDBparams.localEnabled = gDBparams.localHostName.length() > 0; 488 489 gDBparams.wolReconnect = s.GetNumSetting("WOLsqlReconnectWaitTime"); 490 gDBparams.wolEnabled = gDBparams.wolReconnect > 0; 491 492 gDBparams.wolRetry = s.GetNumSetting("WOLsqlConnectRetry"); 493 gDBparams.wolCommand = s.GetSetting("WOLsqlCommand"); 494 495 return true; 496 } 497 498 499 /** 500 * Ask the user for DB host, user/password, port, et c. 501 * 502 * Since this is pure UI code, it should be moved into the parents? 503 */ 504 bool MythContextUI::PromptForDatabaseParams(const QString &error) 505 { 506 bool accepted = false; 507 if (m_GUI) 508 { 509 BackupDBhostname(); 510 m_parent->TempMainWindow(); 511 512 // Tell the user what went wrong: 513 if (error.length()) 514 MythPopupBox::showOkPopup(m_win, "DB connect failure", error); 515 516 // ask user for database parameters 517 DatabaseSettings settings(m_DBhostCp); 518 accepted = (settings.exec() == QDialog::Accepted); 519 if (!accepted) 520 VERBOSE(VB_IMPORTANT, "User cancelled database configuration"); 521 522 m_parent->EndTempWindow(); 523 RestoreDBhostname(); 524 } 525 else 526 { 527 DatabaseParams params = gDBparams; 528 QString response; 529 530 // give user chance to skip config 531 cout << endl << error << endl << endl; 532 response = getResponse("Would you like to configure the database " 533 "connection now?", 534 "yes"); 535 if (!response || response.left(1).lower() != "y") 536 return false; 537 538 params.dbHostName = getResponse("Database host name:", 539 params.dbHostName); 540 response = getResponse("Should I test connectivity to this host " 541 "using the ping command?", "yes"); 542 params.dbHostPing = (!response || response.left(1).lower() != "y"); 543 544 params.dbPort = intResponse("Database non-default port:", 545 params.dbPort); 546 params.dbName = getResponse("Database name:", 547 params.dbName); 548 params.dbUserName = getResponse("Database user name:", 549 params.dbUserName); 550 params.dbPassword = getResponse("Database password:", 551 params.dbPassword); 552 553 params.localHostName = getResponse("Unique identifier for this machine " 554 "(if empty, the local host name " 555 "will be used):", 556 params.localHostName); 557 params.localEnabled = !params.localHostName.isEmpty(); 558 559 response = getResponse("Would you like to use Wake-On-LAN to retry " 560 "database connections?", 561 (params.wolEnabled ? "yes" : "no")); 562 if (response) 563 params.wolEnabled = (response.left(1).lower() == "y"); 564 565 if (params.wolEnabled) 566 { 567 params.wolReconnect = intResponse("Seconds to wait for " 568 "reconnection:", 569 params.wolReconnect); 570 params.wolRetry = intResponse("Number of times to retry:", 571 params.wolRetry); 572 params.wolCommand = getResponse("Command to use to wake server:", 573 params.wolCommand); 574 } 575 576 accepted = gContext->SaveDatabaseParams(params); 577 } 578 return accepted; 579 } 580 581 582 /** 583 * If the program doesn't provide a UPnP client, we setup one here 584 */ 585 bool MythContextUI::InitUPnP(void) 586 { 587 if (m_UPnP) 588 return true; 589 590 VERBOSE(VB_UPNP, "Setting UPnP client for backend autodiscovery..."); 591 592 if (!m_XML) 593 m_XML = new XmlConfiguration(""); // No file - use defaults only 594 595 m_UPnP = new UPnp(); 596 m_UPnP->SetConfiguration(m_XML); 597 598 int port=6549; 599 m_HTTP = new HttpServer(port); 600 601 if (!m_HTTP->ok()) 602 { 603 VERBOSE(VB_IMPORTANT, "MCP::InitUPnP() - HttpServer Create Error"); 604 DeleteUPnP(); 605 return false; 606 } 607 608 if (!m_UPnP->Initialize(port, m_HTTP)) 609 { 610 VERBOSE(VB_IMPORTANT, "MCP::InitUPnP() - UPnp::Initialize() Error"); 611 DeleteUPnP(); 612 return false; 613 } 614 615 // Create a dummy device description 616 UPnpDevice &device = UPnp::g_UPnpDeviceDesc.m_rootDevice; 617 device.m_sDeviceType = "urn:schemas-upnp-org:device:MythContextClient:1"; 618 619 m_UPnP->Start(); 620 621 return true; 622 } 623 624 625 /** 626 * Delete the local client to allow some other code to create another one 627 */ 628 void MythContextUI::DeleteUPnP(void) 629 { 630 if (m_UPnP && !m_HTTP) // Init was passed an existing UPnP 631 return; // so let the caller delete it cleanly 632 633 if (m_UPnP) 634 { 635 // This takes a few seconds, so inform the user: 636 VERBOSE(VB_GENERAL, "Deleting UPnP client..."); 637 638 delete m_UPnP; // This also deletes m_XML 639 m_UPnP = NULL; 640 m_XML = NULL; 641 } 642 643 if (m_HTTP) 644 { 645 delete m_HTTP; 646 m_HTTP = NULL; 647 } 648 } 649 650 651 /** 652 * Search for backends via UPnP, put up a UI for the user to choose one 653 */ 654 int MythContextUI::ChooseBackend(const QString &error) 655 { 656 if (!InitUPnP()) 657 return -1; 658 659 BackupDBhostname(); 660 m_parent->TempMainWindow(false); 661 662 // Tell the user what went wrong: 663 if (error.length()) 664 MythPopupBox::showOkPopup(m_win, "DB connect failure", error); 665 666 VERBOSE(VB_GENERAL, "Putting up the UPnP backend chooser"); 667 668 BackendSelect *BEsel = new BackendSelect(m_win, &gDBparams); 669 switch (BEsel->exec()) 670 { 671 case kDialogCodeRejected: 672 VERBOSE(VB_IMPORTANT, "User canceled database configuration"); 673 return 0; 674 675 case kDialogCodeButton0: 676 VERBOSE(VB_IMPORTANT, "User requested Manual Config"); 677 RestoreDBhostname(); 678 return -1; 679 } 680 //BEsel->hide(); 681 //BEsel->deleteLater(); 682 683 QStringList buttons; 684 QString message; 685 686 buttons += QObject::tr("Save database details"); 687 buttons += QObject::tr("Save backend details"); 688 buttons += QObject::tr("Don't Save"); 689 690 message = QObject::tr("Save that backend or database as the default?"); 691 692 DialogCode selected = MythPopupBox::ShowButtonPopup(m_win, "Save default", 693 message, buttons, kDialogCodeButton2); 694 switch (selected) 695 { 696 case kDialogCodeButton0: 697 gContext->SaveDatabaseParams(gDBparams); 698 // User prefers mysql.txt, so throw away UPnP backend details: 699 m_XML->SetValue(UPnp::kDefaultUSN, ""); 700 m_XML->Save(); 701 break; 702 case kDialogCodeButton1: 703 if (BEsel->m_PIN.length()) 704 m_XML->SetValue(UPnp::kDefaultPIN, BEsel->m_PIN); 705 m_XML->SetValue(UPnp::kDefaultUSN, BEsel->m_USN); 706 m_XML->Save(); 707 break; 708 } 709 710 delete BEsel; 711 m_parent->EndTempWindow(); 712 713 return 1; 714 } 715 716 717 /** 718 * If there is only a single UPnP backend, use it. 719 * 720 * This does <i>not</i> prompt for PIN entry. If the backend requires one, 721 * it will fail, and the caller needs to put up a UI to ask for one. 722 */ 723 int MythContextUI::UPnPautoconf(const int milliSeconds) 724 { 725 if (!InitUPnP()) 726 return 0; 727 728 SSDPCacheEntries *backends = NULL; 729 int count; 730 QString LOC = "UPnPautoconf() - "; 731 QTime timer; 732 733 m_UPnP->PerformSearch(UPnp::kBackendURI); 734 for (timer.start(); timer.elapsed() < milliSeconds; usleep(25000)) 735 { 736 backends = m_UPnP->g_SSDPCache.Find(UPnp::kBackendURI); 737 if (backends) 738 { 739 backends->AddRef(); 740 break; 741 } 742 putchar('.'); 743 } 744 putchar('\n'); 745 746 if (!backends) 747 { 748 VERBOSE(VB_GENERAL, LOC + "No UPnP backends found"); 749 return 0; 750 } 751 752 753 // This could be tied to VB_UPNP? 754 //m_UPnP->g_SSDPCache.Dump(); 755 756 757 count = backends->Count(); 758 switch (count) 759 { 760 case 0: 761 VERBOSE(VB_IMPORTANT, 762 LOC + "No UPnP backends found, but SSDP::Find() not NULL!"); 763 break; 764 case 1: 765 VERBOSE(VB_GENERAL, LOC + "Found one UPnP backend"); 766 break; 767 default: 768 VERBOSE(VB_GENERAL, 769 (LOC + "More than one UPnP backend found (%1)").arg(count)); 770 } 771 772 if (count != 1) 773 { 774 backends->Release(); 775 return count; 776 } 777 778 779 // Get this backend's location: 780 backends->Lock(); 781 DeviceLocation *BE = backends->GetEntryMap()->begin().data(); 782 backends->Unlock(); 783 backends->Release(); 784 785 // We don't actually know the backend's access PIN, so this will 786 // only work for ones that have PIN access disabled (i.e. 0000) 787 if (UPnPconnect(BE, QString::null)) 788 return 1; 789 return -1; // Try to force chooser & PIN 790 } 791 792 793 /** 794 * Get the default backend from config.xml, use UPnP to find it. 795 * 796 * Sets a string if there any connection problems 797 */ 798 bool MythContextUI::DefaultUPnP(QString &error) 799 { 800 XmlConfiguration *XML = new XmlConfiguration("config.xml"); 801 QString loc = "MCP::DefaultUPnP() - "; 802 QString PIN = XML->GetValue(UPnp::kDefaultPIN, ""); 803 QString USN = XML->GetValue(UPnp::kDefaultUSN, ""); 804 805 delete XML; 806 807 if (USN.isEmpty()) 808 { 809 VERBOSE(VB_UPNP, loc + "No default UPnP backend"); 810 return false; 811 } 812 813 VERBOSE(VB_UPNP, loc + "config.xml has default " + 814 QString("PIN '%1' and host USN: %2") 815 .arg(PIN).arg(USN)); 816 817 if (!InitUPnP()) 818 { 819 error = "UPnP is broken?"; 820 return false; 821 } 822 823 m_UPnP->PerformSearch(UPnp::kBackendURI); 824 DeviceLocation *pDevLoc = m_UPnP->g_SSDPCache.Find(UPnp::kBackendURI, USN); 825 if (!pDevLoc) 826 { 827 error = "Cannot find default UPnP backend"; 828 return false; 829 830 } 831 832 if (UPnPconnect(pDevLoc, PIN)) 833 return true; 834 835 error = "Cannot connect to default backend via UPnP. Wrong saved PIN?"; 836 return false; 837 } 838 839 840 /** 841 * Query a backend via UPnP for its database connection parameters 842 */ 843 bool MythContextUI::UPnPconnect(const DeviceLocation *backend, 844 const QString &PIN) 845 { 846 QString error; 847 QString LOC = "UPnPconnect() - "; 848 QString URL = backend->m_sLocation; 849 MythXMLClient XML(URL); 850 851 VERBOSE(VB_UPNP, LOC + QString("Trying host at %1").arg(URL)); 852 switch (XML.GetConnectionInfo(PIN, &gDBparams, error)) 853 { 854 case UPnPResult_Success: 855 break; 856 857 case UPnPResult_ActionNotAuthorized: 858 // The stored PIN is probably not correct. 859 // We could prompt for the PIN and try again, but that needs a UI. 860 // Easier to fail for now, and put up the full UI selector later 861 VERBOSE(VB_UPNP, LOC + error + ". Wrong PIN?"); 862 return false; 863 864 default: 865 VERBOSE(VB_UPNP, LOC + error); 866 return false; 867 } 868 869 VERBOSE(VB_UPNP, LOC + "Got database hostname: " + gDBparams.dbHostName); 870 871 return true; 872 } 873 874 875 /** 876 * Some quick sanity checks before opening a database connection 877 */ 878 QString MythContextUI::TestDBconnection(void) 879 { 880 BackupDBhostname(); 881 return gContext->TestDBconnection(); 882 } 883 884 885 ////////////////////////////////////////////////////////////////////////////// 886 // 2 sub-classes of MythContext that differ only in whether they support a GUI 887 ////////////////////////////////////////////////////////////////////////////// 888 889 MythContextGUI::MythContextGUI(const QString &binVersion) 890 : MythContextUI(this, binVersion) {} 891 892 MythContextTTY::MythContextTTY(const QString &binVersion) 893 : MythContextUI(NULL, binVersion) {} 894 895 MythContextGUI::~MythContextGUI(void) {} 896 897 MythContextTTY::~MythContextTTY(void) {} 898 899 bool MythContextGUI::Init(UPnp *UPnPclient, 900 const bool promptForBackend, const bool noPrompt) 901 { 902 if (UPnPclient) 903 { 904 m_UPnP = UPnPclient; 905 m_XML = (XmlConfiguration *)UPnp::g_pConfig; 906 } 907 908 QString mismatch = BinaryVersionError(); 909 if (mismatch.length()) 910 { 911 MythPopupBox::showOkPopup(TempMainWindow(true), 912 "Library version error", mismatch); 913 EndTempWindow(); 914 return false; 915 } 916 917 if (!FindDatabase(promptForBackend, noPrompt)) 918 return false; 919 920 return gContext->Init(true); 921 } 922 923 bool MythContextTTY::Init(UPnp *UPnPclient) 924 { 925 if (UPnPclient) 926 { 927 m_UPnP = UPnPclient; 928 m_XML = (XmlConfiguration *)UPnp::g_pConfig; 929 } 930 931 if (BinaryVersionError().length()) 932 return false; 933 934 if (!FindDatabase()) 935 return false; 936 937 return gContext->Init(false); 938 } 939 940 941 MythMainWindow * MythContextGUI::CreateMainWindow(void) 942 { 943 LoadQtConfig(); 944 945 m_win = GetMythMainWindow(); 946 m_win->Init(); 947 SetMainWindow(m_win); 948 949 return m_win; 950 } 951 952 /** 953 * \brief Setup a minimal themed main window, and prompt for user's language. 954 * 955 * Used for warnings before the database is opened, or bootstrapping pages. 956 * After using the window, call EndTempWindow(). 957 * 958 * \bug Some of these settings (<i>e.g.</I> window size, theme) 959 * seem to be used after the temp window is destroyed. 960 * 961 * \bug The default theme here is blue, but as of [12377], 962 * G.A.N.T is now meant to be the default? 963 * A simple change to make, but Nigel prefers 964 * "blue" for these initial screens and popups 965 */ 966 MythMainWindow * MythContextGUI::TempMainWindow(bool languagePrompt) 967 { 968 if (m_win) 969 return m_win; 970 971 // We clear the hostname so MSqlQuery will fail, instead of long 972 // timeouts per DB value, or hundreds of lines of DB connect errors. 973 // We save the value for later possible editing in the DbSettings pages 974 if (gDBparams.dbHostName.length()) 975 { 976 m_DBhostCp = gDBparams.dbHostName; 977 gDBparams.dbHostName = ""; 978 } 979 980 gContext->SetSetting("Theme", "blue"); 981 #ifdef Q_WS_MACX 982 // Myth looks horrible in default Mac style for Qt 983 gContext->SetSetting("Style", "Windows"); 984 #endif 985 gContext->LoadQtConfig(); 986 987 m_win = MythMainWindow::getMainWindow(false); 988 m_win->Init(); 989 SetMainWindow(m_win); 990 991 if (languagePrompt) 992 { 993 // ask user for language settings 994 LanguageSettings::prompt(); 995 LanguageSettings::load("mythfrontend"); 996 } 997 998 return m_win; 999 } 1000 1001 void MythContextGUI::EndTempWindow(void) 1002 { 1003 m_win = NULL; 1004 SetMainWindow(NULL); 1005 DestroyMythMainWindow(); 1006 } 1007 1008 bool MythContextGUI::TestPopupVersion(const QString &pluginName, 1009 const QString &libMythVersion, 1010 const QString &pluginVersion) 1011 { 1012 QString warning = PluginVersionError(pluginName, 1013 libMythVersion, pluginVersion); 1014 if (warning.length()) 1015 { 1016 if (!m_win) 1017 m_parent->TempMainWindow(true); 1018 1019 warning = QObject::tr(warning); 1020 1021 if (m_win && !m_disableLibPopup) 1022 { 1023 DialogBox *dlg = new DialogBox(m_win, warning); 1024 dlg->AddButton("OK"); 1025 dlg->exec(); 1026 dlg->deleteLater(); 1027 } 1028 1029 return false; 1030 } 1031 1032 return true; 1033 } 1034 1035 1036 QString getResponse(const QString &query, const QString &def) 1037 { 1038 cout << query; 1039 1040 if (def != "") 1041 cout << " [" << def << "] "; 1042 else 1043 cout << " "; 1044 1045 if (!isatty(fileno(stdin)) || !isatty(fileno(stdout))) 1046 { 1047 cout << endl << "[console is not interactive, using default '" 1048 << def << "']" << endl; 1049 return def; 1050 } 1051 1052 char response[80]; 1053 cin.clear(); 1054 cin.getline(response, 80); 1055 if (!cin.good()) 1056 { 1057 cout << endl; 1058 VERBOSE(VB_IMPORTANT, "Read from stdin failed"); 1059 return NULL; 1060 } 1061 1062 QString qresponse = response; 1063 1064 if (qresponse == "") 1065 qresponse = def; 1066 1067 return qresponse; 1068 } 1069 1070 int intResponse(const QString &query, const int def) 1071 { 1072 QString str_resp = getResponse(query, QString("%1").arg(def)); 1073 if (!str_resp) 1074 return false; 1075 bool ok; 1076 int resp = str_resp.toInt(&ok); 1077 return (ok ? resp : def); 1078 } -
mythtv/libs/libmythtv/backendselect.cpp
1 /** 2 * \class BackendSelect 3 * \desc Classes to Prompt user for a master backend. 4 * 5 * \author Originally based on masterselection.cpp/h by David Blain. 6 */ 7 8 #include "backendselect.h" 9 10 #include "libmyth/mythdialogs.h" 11 #include "libmythupnp/mythxmlclient.h" 12 #include "libmythupnp/upnp.h" 13 14 15 BackendSelect::BackendSelect(MythMainWindow *parent, DatabaseParams *params) 16 : MythDialog(parent, "BackEnd Selection", TRUE) 17 { 18 m_parent = parent; 19 m_DBparams = params; 20 puts("Creating a backendSelect"); 21 CreateUI(); 22 23 UPnp::AddListener(this); 24 25 //Search(); 26 FillListBox(); 27 28 m_backends->setFocus(); 29 } 30 31 BackendSelect::~BackendSelect() 32 { 33 UPnp::RemoveListener(this); 34 35 ItemMap::iterator it; 36 for (it = m_devices.begin(); it != m_devices.end(); ++it) 37 { 38 ListBoxDevice *item = it.data(); 39 40 if (item != NULL) 41 delete item; 42 } 43 44 m_devices.clear(); 45 } 46 47 void BackendSelect::Accept(void) 48 { 49 DeviceLocation *dev; 50 QListBoxItem *selected = m_backends->selectedItem(); 51 52 if (!selected) 53 return; 54 55 dev = ((ListBoxDevice *)selected)->m_dev; 56 57 if (!dev) 58 reject(); 59 60 dev->AddRef(); 61 if (Connect(dev)) 62 accept(); 63 } 64 65 void BackendSelect::AddItem(DeviceLocation *dev) 66 { 67 if (!dev) 68 return; 69 70 QString USN = dev->m_sUSN; 71 72 // The devices' USN should be unique. Don't add if it is already there: 73 if (m_devices.find(USN) == m_devices.end()) 74 { 75 ListBoxDevice *item; 76 QString name; 77 78 if (print_verbose_messages & VB_UPNP) 79 name = dev->GetNameAndDetails(true); 80 else 81 name = dev->GetFriendlyName(true); 82 83 item = new ListBoxDevice(m_backends, name, dev); 84 m_devices.insert(USN, item); 85 86 // Pre-select at least one item: 87 if (m_backends->numRows() == 1) 88 m_backends->setSelected(0, true); 89 } 90 91 dev->Release(); 92 } 93 94 /** 95 * Attempt UPnP connection to a backend device, get its DB details. 96 * Will loop until a valid PIN is entered. 97 */ 98 bool BackendSelect::Connect(DeviceLocation *dev) 99 { 100 QString error; 101 QString message; 102 UPnPResultCode stat; 103 MythXMLClient *xml; 104 105 m_USN = dev->m_sUSN; 106 xml = new MythXMLClient(dev->m_sLocation); 107 stat = xml->GetConnectionInfo(m_PIN, m_DBparams, message); 108 error = dev->GetFriendlyName(true); 109 if (error == "<Unknown>") 110 error = dev->m_sLocation; 111 error += ". " + message; 112 dev->Release(); 113 114 switch (stat) 115 { 116 case UPnPResult_Success: 117 VERBOSE(VB_UPNP, "Connect() - success. New hostname: " 118 + m_DBparams->dbHostName); 119 return true; 120 121 case UPnPResult_HumanInterventionRequired: 122 VERBOSE(VB_UPNP, error); 123 MythPopupBox::showOkPopup(m_parent, "", QObject::tr(message)); 124 break; 125 126 case UPnPResult_ActionNotAuthorized: 127 VERBOSE(VB_UPNP, "Access denied for " + error + ". Wrong PIN?"); 128 message = "Please enter the backend access PIN"; 129 do 130 { 131 m_PIN = MythPopupBox::showPasswordPopup( 132 m_parent, "Backend PIN entry", QObject::tr(message)); 133 stat = xml->GetConnectionInfo(m_PIN, m_DBparams, message); 134 } 135 while (stat == UPnPResult_ActionNotAuthorized); 136 if (stat == UPnPResult_Success) 137 return true; 138 139 default: 140 VERBOSE(VB_UPNP, "GetConnectionInfo() failed for " + error); 141 MythPopupBox::showOkPopup(m_parent, "", QObject::tr(message)); 142 } 143 144 // Back to the list, so the user can choose a different backend: 145 m_backends->setFocus(); 146 return false; 147 } 148 149 void BackendSelect::CreateUI(void) 150 { 151 // Probably should all be members, and deleted by ~BackendSelect() 152 QLabel *label; 153 QGridLayout *layout; 154 MythPushButton *cancel; 155 MythPushButton *manual; 156 MythPushButton *OK; 157 //MythPushButton *search; // I don't see the need for this? 158 159 160 label = new QLabel(QObject::tr("Please select default Myth Backend Server"), this); 161 label->setBackgroundOrigin(QWidget::WindowOrigin); 162 163 m_backends = new MythListBox(this); 164 OK = new MythPushButton(QObject::tr("OK"), this); 165 cancel = new MythPushButton(QObject::tr("Cancel"), this); 166 manual = new MythPushButton(QObject::tr("Configure Manually"), this); 167 //search = new MythPushButton(QObject::tr("Search"), this); 168 169 170 layout = new QGridLayout(this, 5, 5, 40); 171 layout->addMultiCellWidget(label, 0, 0, 1, 3); 172 layout->addMultiCellWidget(m_backends, 1, 1, 0, 4); 173 174 layout->addMultiCellWidget(manual, 4, 4, 0, 1); 175 //layout->addWidget(search, 4, 0); 176 //layout->addWidget(manual, 4, 1); 177 layout->addWidget(cancel, 4, 3); 178 layout->addWidget(OK , 4, 4); 179 180 181 connect(m_backends, SIGNAL(accepted(int)), SLOT(Accept())); 182 //connect(search, SIGNAL(clicked()), SLOT(Search())); 183 connect(manual, SIGNAL(clicked()), SLOT(Manual())); 184 connect(cancel, SIGNAL(clicked()), SLOT(reject())); 185 connect(OK, SIGNAL(clicked()), SLOT(Accept())); 186 } 187 188 void BackendSelect::customEvent(QCustomEvent *e) 189 { 190 if (MythEvent::MythEventMessage != ((MythEvent::Type)(e->type()))) 191 return; 192 193 194 MythEvent *me = (MythEvent *)e; 195 QString message = me->Message(); 196 QString URI = me->ExtraData(0); 197 QString URN = me->ExtraData(1); 198 QString URL = me->ExtraData(2); 199 200 201 VERBOSE(VB_UPNP, "BackendSelect::customEvent(" + message 202 + ", " + URI + ", " + URN + ", " + URL + ")"); 203 204 if (message.startsWith("SSDP_ADD") && 205 URI.startsWith("urn:schemas-mythtv-org:device:MasterMediaServer:")) 206 { 207 DeviceLocation *devLoc = UPnp::g_SSDPCache.Find(URI, URN); 208 209 if (devLoc != NULL) 210 { 211 devLoc->AddRef(); 212 AddItem(devLoc); 213 } 214 else 215 VERBOSE(VB_UPNP, "Can't add host - not in SSDP cache?"); 216 } 217 else if (message.startsWith("SSDP_REMOVE")) 218 { 219 //-=>Note: This code will never get executed until 220 // SSDPCache is changed to handle NotifyRemove correctly 221 RemoveItem(URN); 222 } 223 } 224 225 void BackendSelect::FillListBox(void) 226 { 227 EntryMap::Iterator it; 228 EntryMap ourMap; 229 DeviceLocation *pDevLoc; 230 231 232 SSDPCacheEntries *pEntries = UPnp::g_SSDPCache.Find(UPnp::kBackendURI); 233 234 if (!pEntries) 235 return; 236 237 pEntries->AddRef(); 238 pEntries->Lock(); 239 240 EntryMap *pMap = pEntries->GetEntryMap(); 241 242 for (it = pMap->begin(); it != pMap->end(); ++it) 243 { 244 pDevLoc = (DeviceLocation *)it.data(); 245 246 if (!pDevLoc) 247 continue; 248 249 pDevLoc->AddRef(); 250 ourMap.insert(pDevLoc->m_sUSN, pDevLoc); 251 } 252 253 254 pEntries->Unlock(); 255 pEntries->Release(); 256 257 for (it = ourMap.begin(); it != ourMap.end(); ++it) 258 { 259 pDevLoc = (DeviceLocation *)it.data(); 260 AddItem(pDevLoc); 261 pDevLoc->Release(); 262 } 263 } 264 265 void BackendSelect::Manual(void) 266 { 267 done(kDialogCodeButton0); 268 } 269 270 void BackendSelect::RemoveItem(QString USN) 271 { 272 ItemMap::iterator it = m_devices.find(USN); 273 274 if (it != m_devices.end()) 275 { 276 ListBoxDevice *item = it.data(); 277 278 if (item != NULL) 279 delete item; 280 281 m_devices.remove(it); 282 } 283 } 284 285 void BackendSelect::Search(void) 286 { 287 UPnp::PerformSearch(UPnp::kBackendURI); 288 } -
mythtv/libs/libmythui/mythmainwindow.cpp
226 226 * If this is a temporary window, which is used to bootstrap 227 227 * the database, passing false prevents any database access. 228 228 * 229 * \sa MythContext Private::TempMainWindow()229 * \sa MythContextGUI::TempMainWindow() 230 230 */ 231 231 MythMainWindow *MythMainWindow::getMainWindow(const bool useDB) 232 232 { -
mythtv/libs/libmyth/mythdialogs.cpp
75 75 gContext->ThemeWidget(this); 76 76 } 77 77 78 parent->attach(this);78 gContext->attachToWin(this); 79 79 m_parent = parent; 80 80 } 81 81 … … 95 95 { 96 96 if (m_parent) 97 97 { 98 m_parent->detach(this);98 gContext->detachFromWin(this); 99 99 m_parent = NULL; 100 100 } 101 101 } … … 214 214 bool handled = false; 215 215 QStringList actions; 216 216 217 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions))217 if (gContext->TranslateKeyPress("qt", e, actions)) 218 218 { 219 219 for (unsigned int i = 0; i < actions.size() && !handled; i++) 220 220 { … … 509 509 { 510 510 bool handled = false; 511 511 QStringList actions; 512 gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions);512 gContext->TranslateKeyPress("qt", e, actions); 513 513 for (unsigned int i = 0; i < actions.size() && !handled; i++) 514 514 { 515 515 QString action = actions[i]; … … 890 890 { 891 891 bool handled = false; 892 892 QStringList actions; 893 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions))893 if (gContext->TranslateKeyPress("qt", e, actions)) 894 894 { 895 895 for (unsigned int i = 0; i < actions.size() && !handled; i++) 896 896 { … … 1708 1708 { 1709 1709 bool handled = false; 1710 1710 QStringList actions; 1711 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions))1711 if (gContext->TranslateKeyPress("qt", e, actions)) 1712 1712 { 1713 1713 for (unsigned int i = 0; i < actions.size() && !handled; i++) 1714 1714 { … … 1770 1770 { 1771 1771 bool handled = false; 1772 1772 QStringList actions; 1773 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions))1773 if (gContext->TranslateKeyPress("qt", e, actions)) 1774 1774 { 1775 1775 for (unsigned int i = 0; i < actions.size() && !handled; i++) 1776 1776 { … … 1990 1990 { 1991 1991 bool handled = false; 1992 1992 QStringList actions; 1993 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions))1993 if (gContext->TranslateKeyPress("qt", e, actions)) 1994 1994 { 1995 1995 for (unsigned int i = 0; i < actions.size() && !handled; i++) 1996 1996 { … … 2254 2254 m_showRtArrow = false; 2255 2255 m_showLtArrow = false; 2256 2256 2257 m_parent->attach(this);2257 gContext->attachToWin(this); 2258 2258 } 2259 2259 2260 2260 MythScrollDialog::~MythScrollDialog() 2261 2261 { 2262 m_parent->detach(this);2262 gContext->detachFromWin(this); 2263 2263 delete m_bgPixmap; 2264 2264 2265 2265 if (m_upArrowPix) … … 2370 2370 bool handled = false; 2371 2371 QStringList actions; 2372 2372 2373 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions))2373 if (gContext->TranslateKeyPress("qt", e, actions)) 2374 2374 { 2375 2375 for (unsigned int i = 0; i < actions.size() && !handled; i++) 2376 2376 { -
mythtv/libs/libmyth/dbsettings.cpp
1 #include "mythcontext.h"2 #include "mythdbcon.h"3 #include "dbsettings.h"4 #include <qfile.h>5 #include <qdir.h>6 7 class MythDbSettings1: public VerticalConfigurationGroup {8 public:9 MythDbSettings1(const QString &DBhostOverride = QString::null);10 11 void load();12 void save();13 14 protected:15 TransLabelSetting *info;16 TransLineEditSetting *dbHostName;17 TransCheckBoxSetting *dbHostPing;18 TransLineEditSetting *dbPort;19 TransLineEditSetting *dbName;20 TransLineEditSetting *dbUserName;21 TransLineEditSetting *dbPassword;22 TransComboBoxSetting *dbType;23 24 QString m_DBhostOverride;25 };26 27 class MythDbSettings2: public VerticalConfigurationGroup {28 public:29 MythDbSettings2();30 31 void load();32 void save();33 34 protected:35 TransCheckBoxSetting *localEnabled;36 TransLineEditSetting *localHostName;37 TransCheckBoxSetting *wolEnabled;38 TransSpinBoxSetting *wolReconnect;39 TransSpinBoxSetting *wolRetry;40 TransLineEditSetting *wolCommand;41 };42 43 44 45 class LocalHostNameSettings : public TriggeredConfigurationGroup46 {47 public:48 LocalHostNameSettings(Setting *checkbox, ConfigurationGroup *group) :49 TriggeredConfigurationGroup(false, false, false, false)50 {51 setLabel(QObject::tr("Use custom identifier for frontend preferences"));52 addChild(checkbox);53 setTrigger(checkbox);54 55 addTarget("1", group);56 addTarget("0", new VerticalConfigurationGroup(true));57 }58 };59 60 class WOLsqlSettings : public TriggeredConfigurationGroup61 {62 public:63 WOLsqlSettings(Setting *checkbox, ConfigurationGroup *group) :64 TriggeredConfigurationGroup(false, false, false, false)65 {66 setLabel(QObject::tr("Backend Server Wakeup settings"));67 68 addChild(checkbox);69 setTrigger(checkbox);70 71 addTarget("1", group);72 addTarget("0", new VerticalConfigurationGroup(true));73 }74 };75 76 MythDbSettings1::MythDbSettings1(const QString &DbHostOverride) :77 VerticalConfigurationGroup(false, true, false, false)78 {79 m_DBhostOverride = DbHostOverride;80 81 setLabel(QObject::tr("Database Configuration") + " 1/2");82 83 info = new TransLabelSetting();84 85 MSqlQuery query(MSqlQuery::InitCon());86 if (query.isConnected())87 info->setValue(QObject::tr("All database settings take effect when "88 "you restart this program."));89 else90 info->setValue(QObject::tr("Myth could not connect to the database. "91 "Please verify your database settings "92 "below."));93 addChild(info);94 95 VerticalConfigurationGroup* dbServer = new VerticalConfigurationGroup();96 dbServer->setLabel(QObject::tr("Database Server Settings"));97 dbHostName = new TransLineEditSetting(true);98 dbHostName->setLabel(QObject::tr("Hostname"));99 dbHostName->setHelpText(QObject::tr("The host name or IP address of "100 "the machine hosting the database. "101 "This information is required."));102 dbServer->addChild(dbHostName);103 104 HorizontalConfigurationGroup* g =105 new HorizontalConfigurationGroup(false, false);106 107 dbHostPing = new TransCheckBoxSetting();108 dbHostPing->setLabel(QObject::tr("Ping test server?"));109 dbHostPing->setHelpText(QObject::tr("Test basic host connectivity using "110 "the ping command. Turn off if your "111 "host or network don't support ping "112 "(ICMP ECHO) packets"));113 g->addChild(dbHostPing);114 115 // Some extra horizontal space:116 TransLabelSetting *l = new TransLabelSetting();117 l->setValue(" ");118 g->addChild(l);119 120 dbServer->addChild(g);121 122 dbPort = new TransLineEditSetting(true);123 dbPort->setLabel(QObject::tr("Port"));124 dbPort->setHelpText(QObject::tr("The port number the database is running "125 "on. Leave blank if using the default "126 "port (3306)."));127 g->addChild(dbPort);128 129 dbName = new TransLineEditSetting(true);130 dbName->setLabel(QObject::tr("Database name"));131 dbName->setHelpText(QObject::tr("The name of the database. "132 "This information is required."));133 dbServer->addChild(dbName);134 135 dbUserName = new TransLineEditSetting(true);136 dbUserName->setLabel(QObject::tr("User"));137 dbUserName->setHelpText(QObject::tr("The user name to use while "138 "connecting to the database. "139 "This information is required."));140 dbServer->addChild(dbUserName);141 142 dbPassword = new TransLineEditSetting(true);143 dbPassword->setLabel(QObject::tr("Password"));144 dbPassword->setHelpText(QObject::tr("The password to use while "145 "connecting to the database. "146 "This information is required."));147 dbServer->addChild(dbPassword);148 149 dbType = new TransComboBoxSetting(false);150 dbType->setLabel(QObject::tr("Database type"));151 dbType->addSelection(QObject::tr("MySQL"), "QMYSQL3");152 dbType->setValue(0);153 dbType->setHelpText(QObject::tr("The database implementation used "154 "for your server."));155 dbType->setEnabled(false);156 //dbServer->addChild(dbType);157 158 addChild(dbServer);159 160 }161 162 MythDbSettings2::MythDbSettings2(void) :163 VerticalConfigurationGroup(false, true, false, false)164 {165 setLabel(QObject::tr("Database Configuration") + " 2/2");166 167 localEnabled = new TransCheckBoxSetting();168 localEnabled->setLabel(QObject::tr("Use custom identifier for frontend "169 "preferences"));170 localEnabled->setHelpText(QObject::tr("If this frontend's host name "171 "changes often, check this box "172 "and provide a network-unique "173 "name to identify it. "174 "If unchecked, the frontend "175 "machine's local host name will "176 "be used to save preferences in "177 "the database."));178 179 localHostName = new TransLineEditSetting(true);180 localHostName->setLabel(QObject::tr("Custom identifier"));181 localHostName->setHelpText(QObject::tr("An identifier to use while "182 "saving the settings for this "183 "frontend."));184 185 VerticalConfigurationGroup *group1 =186 new VerticalConfigurationGroup(false);187 group1->addChild(localHostName);188 189 LocalHostNameSettings *sub3 =190 new LocalHostNameSettings(localEnabled, group1);191 addChild(sub3);192 193 wolEnabled = new TransCheckBoxSetting();194 wolEnabled->setLabel(QObject::tr("Enable Database Server Wakeup"));195 wolEnabled->setHelpText(QObject::tr("If checked, the frontend will use "196 "database wakeup parameters to "197 "reconnect to the database server."));198 199 wolReconnect = new TransSpinBoxSetting(0, 60, 1, true);200 wolReconnect->setLabel(QObject::tr("Reconnect time"));201 wolReconnect->setHelpText(QObject::tr("The time in seconds to wait for "202 "the server to wake up."));203 204 wolRetry = new TransSpinBoxSetting(1, 10, 1, true);205 wolRetry->setLabel(QObject::tr("Retry attempts"));206 wolRetry->setHelpText(QObject::tr("The number of retries to wake the "207 "server before the frontend gives "208 "up."));209 210 wolCommand = new TransLineEditSetting(true);211 wolCommand->setLabel(QObject::tr("Wake command"));212 wolCommand->setHelpText(QObject::tr("The command executed on this "213 "frontend to wake up the database "214 "server (eg. sudo /etc/init.d/mysql "215 "restart)."));216 217 HorizontalConfigurationGroup *group2 =218 new HorizontalConfigurationGroup(false, false);219 group2->addChild(wolReconnect);220 group2->addChild(wolRetry);221 222 VerticalConfigurationGroup *group3 =223 new VerticalConfigurationGroup(false);224 group3->addChild(group2);225 group3->addChild(wolCommand);226 227 WOLsqlSettings *sub4 =228 new WOLsqlSettings(wolEnabled, group3);229 addChild(sub4);230 }231 232 void MythDbSettings1::load()233 {234 DatabaseParams params = gContext->GetDatabaseParams();235 236 if (params.dbHostName.isEmpty() ||237 params.dbUserName.isEmpty() ||238 params.dbPassword.isEmpty() ||239 params.dbName.isEmpty())240 info->setValue(info->getValue() + "\n" +241 QObject::tr("Required fields are"242 " marked with an asterisk (*)."));243 244 if (params.dbHostName.isEmpty())245 {246 dbHostName->setLabel("* " + dbHostName->getLabel());247 dbHostName->setValue(m_DBhostOverride);248 }249 else250 dbHostName->setValue(params.dbHostName);251 252 dbHostPing->setValue(params.dbHostPing);253 254 if (params.dbPort)255 dbPort->setValue(QString::number(params.dbPort));256 257 dbUserName->setValue(params.dbUserName);258 if (params.dbUserName.isEmpty())259 dbUserName->setLabel("* " + dbUserName->getLabel());260 dbPassword->setValue(params.dbPassword);261 if (params.dbPassword.isEmpty())262 dbPassword->setLabel("* " + dbPassword->getLabel());263 dbName->setValue(params.dbName);264 if (params.dbName.isEmpty())265 dbName->setLabel("* " + dbName->getLabel());266 267 if (params.dbType == "QMYSQL3")268 dbType->setValue(0);269 else if (params.dbType == "QPSQL7")270 dbType->setValue(1);271 }272 273 void MythDbSettings2::load()274 {275 DatabaseParams params = gContext->GetDatabaseParams();276 277 localEnabled->setValue(params.localEnabled);278 localHostName->setValue(params.localHostName);279 280 wolEnabled->setValue(params.wolEnabled);281 wolReconnect->setValue(params.wolReconnect);282 wolRetry->setValue(params.wolRetry);283 wolCommand->setValue(params.wolCommand);284 }285 286 void MythDbSettings1::save()287 {288 DatabaseParams params = gContext->GetDatabaseParams();289 290 params.dbHostName = dbHostName->getValue();291 params.dbHostPing = dbHostPing->boolValue();292 params.dbPort = dbPort->getValue().toInt();293 params.dbUserName = dbUserName->getValue();294 params.dbPassword = dbPassword->getValue();295 params.dbName = dbName->getValue();296 params.dbType = dbType->getValue();297 298 gContext->SaveDatabaseParams(params);299 }300 301 void MythDbSettings2::save()302 {303 DatabaseParams params = gContext->GetDatabaseParams();304 305 params.localEnabled = localEnabled->boolValue();306 params.localHostName = localHostName->getValue();307 308 params.wolEnabled = wolEnabled->boolValue();309 params.wolReconnect = wolReconnect->intValue();310 params.wolRetry = wolRetry->intValue();311 params.wolCommand = wolCommand->getValue();312 313 gContext->SaveDatabaseParams(params);314 }315 316 DatabaseSettings::DatabaseSettings(const QString &DBhostOverride)317 {318 addChild(new MythDbSettings1(DBhostOverride));319 addChild(new MythDbSettings2());320 }321 322 void DatabaseSettings::addDatabaseSettings(ConfigurationWizard *wizard)323 {324 wizard->addChild(new MythDbSettings1());325 wizard->addChild(new MythDbSettings2());326 } -
mythtv/libs/libmyth/mythwidgets.cpp
66 66 qt_delete(popup); 67 67 68 68 popup = new VirtualKeyboard(gContext->GetMainWindow(), this); 69 gContext-> GetMainWindow()->detach(popup);69 gContext->detachFromWin(popup); 70 70 popup->exec(); 71 71 72 72 qt_delete(popup); … … 78 78 bool handled = false; 79 79 QStringList actions; 80 80 if ((!popup || !popup->isShown()) && 81 (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions, !allowVirtualKeyboard)))81 (gContext->TranslateKeyPress("qt", e, actions, !allowVirtualKeyboard))) 82 82 { 83 83 for (unsigned int i = 0; i < actions.size() && !handled; i++) 84 84 { … … 189 189 { 190 190 bool handled = false; 191 191 QStringList actions; 192 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions))192 if (gContext->TranslateKeyPress("qt", e, actions)) 193 193 { 194 194 for (unsigned int i = 0; i < actions.size() && !handled; i++) 195 195 { … … 239 239 { 240 240 bool handled = false; 241 241 QStringList actions; 242 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions))242 if (gContext->TranslateKeyPress("qt", e, actions)) 243 243 { 244 244 for (unsigned int i = 0; i < actions.size() && !handled; i++) 245 245 { … … 305 305 306 306 bool handled = false; 307 307 QStringList actions; 308 if (gContext->GetMainWindow()->TranslateKeyPress("qt", (QKeyEvent *)e, 309 actions)) 308 if (gContext->TranslateKeyPress("qt", (QKeyEvent *)e, actions)) 310 309 { 311 310 for (unsigned int i = 0; i < actions.size() && !handled; i++) 312 311 { … … 375 374 { 376 375 bool handled = false; 377 376 QStringList actions; 378 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions))377 if (gContext->TranslateKeyPress("qt", e, actions)) 379 378 { 380 379 for (unsigned int i = 0; i < actions.size() && !handled; i++) 381 380 { … … 467 466 qt_delete(popup); 468 467 469 468 popup = new VirtualKeyboard(gContext->GetMainWindow(), this); 470 gContext-> GetMainWindow()->detach(popup);469 gContext->detachFromWin(popup); 471 470 popup->exec(); 472 471 473 472 qt_delete(popup); … … 478 477 bool handled = false; 479 478 QStringList actions; 480 479 if ((!popup || !popup->isShown()) && 481 gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions, false))480 gContext->TranslateKeyPress("qt", e, actions, false)) 482 481 { 483 482 for (unsigned int i = 0; i < actions.size() && !handled; i++) 484 483 { … … 860 859 QStringList actions; 861 860 862 861 if ((!popup || !popup->isShown()) && 863 gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions, false))862 gContext->TranslateKeyPress("qt", e, actions, false)) 864 863 { 865 864 for (unsigned int i = 0; i < actions.size() && !handled; i++) 866 865 { … … 1124 1123 qt_delete(popup); 1125 1124 1126 1125 popup = new VirtualKeyboard(gContext->GetMainWindow(), this); 1127 gContext-> GetMainWindow()->detach(popup);1126 gContext->detachFromWin(popup); 1128 1127 popup->exec(); 1129 1128 1130 1129 qt_delete(popup); … … 1157 1156 int tmpRow = currentRow(); 1158 1157 bool handled = false; 1159 1158 QStringList actions; 1160 if (gContext->GetMainWindow()->TranslateKeyPress("qt", (QKeyEvent *)e, 1161 actions)) 1159 if (gContext->TranslateKeyPress("qt", (QKeyEvent *)e, actions)) 1162 1160 { 1163 1161 for (unsigned int i = 0; i < actions.size() && !handled; i++) 1164 1162 { … … 1242 1240 QStringList actions; 1243 1241 keyPressActions.clear(); 1244 1242 1245 if (gContext->GetMainWindow()->TranslateKeyPress("qt", (QKeyEvent *)e, 1246 actions)) 1243 if (gContext->TranslateKeyPress("qt", (QKeyEvent *)e, actions)) 1247 1244 { 1248 1245 keyPressActions = actions; 1249 1246 … … 1369 1366 1370 1367 bool handled = false; 1371 1368 QStringList actions; 1372 gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions);1369 gContext->TranslateKeyPress("qt", e, actions); 1373 1370 1374 1371 for (unsigned int i = 0; i < actions.size() && !handled; i++) 1375 1372 { … … 1490 1487 { 1491 1488 bool handled = false; 1492 1489 QStringList actions; 1493 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions))1490 if (gContext->TranslateKeyPress("qt", e, actions)) 1494 1491 { 1495 1492 for (unsigned int i = 0; i < actions.size() && !handled; i++) 1496 1493 { -
mythtv/libs/libmyth/xmlparse.cpp
286 286 if (baseFont && !haveSize) 287 287 size = baseFont->face.pointSize(); 288 288 else 289 size = GetMythMainWindow()->NormalizeFontSize(size);289 size = gContext->NormalizeFontSize(size); 290 290 291 291 // If we don't have to, don't load the font. 292 292 if (!haveFace && baseFont) -
mythtv/libs/libmyth/uitypes.cpp
6000 6000 { 6001 6001 bool handled = false; 6002 6002 QStringList actions; 6003 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions, false))6003 if (gContext->TranslateKeyPress("qt", e, actions, false)) 6004 6004 { 6005 6005 for (unsigned int i = 0; i < actions.size() && !handled; i++) 6006 6006 { -
mythtv/libs/libmyth/dbsettings.h
1 #ifndef DBSETTINGS_H2 #define DBSETTINGS_H3 4 #include "mythconfigdialogs.h"5 6 class MPUBLIC DatabaseSettings: public ConfigurationWizard {7 public:8 DatabaseSettings(const QString &DBhostOverride = QString::null);9 10 // This routine calls wizard->addChild() for each of11 // the database configuration screens. This allows12 // the number of DB config screens to change.13 static void addDatabaseSettings(ConfigurationWizard *wizard);14 };15 16 #endif -
mythtv/libs/libmyth/mythcontext.cpp
27 27 #include "mythplugin.h" 28 28 #include "screensaver.h" 29 29 #include "DisplayRes.h" 30 #include "backendselect.h"31 #include "dbsettings.h"32 30 #include "langsettings.h" 33 31 #include "mythdbcon.h" 34 32 #include "util-x11.h" … … 36 34 #include "themeinfo.h" 37 35 38 36 #include "libmythui/mythmainwindow.h" 39 #include "libmythupnp/mythxmlclient.h"40 #include "libmythupnp/upnp.h"41 37 42 38 #ifdef USING_MINGW 43 39 #include <winsock2.h> … … 58 54 const QString kPluginLibSuffix = ".so"; 59 55 #endif 60 56 61 MythContext *gContext = NULL; 62 QMutex MythContext::verbose_mutex(true); 63 QString MythContext::x11_display = QString::null; 57 MythContext *gContext = NULL; 58 DatabaseParams gDBparams; 59 QMutex MythContext::verbose_mutex(true); 60 QString MythContext::x11_display = QString::null; 64 61 65 62 unsigned int print_verbose_messages = VB_IMPORTANT | VB_GENERAL; 66 63 QString verboseString = QString(" important general"); 67 64 68 65 QMutex avcodeclock(true); 69 66 70 // Some common UPnP search and XML value strings71 const QString gBackendURI = "urn:schemas-mythtv-org:device:MasterMediaServer:1";72 const QString kDefaultPIN = "UPnP/MythFrontend/DefaultBackend/SecurityPin";73 const QString kDefaultUSN = "UPnP/MythFrontend/DefaultBackend/USN";74 67 75 76 68 int parse_verbose_arg(QString arg) 77 69 { 78 70 QString option; … … 180 172 MythContextPrivate(MythContext *lparent); 181 173 ~MythContextPrivate(); 182 174 183 bool Init (const bool gui, UPnp *UPnPclient, 184 const bool prompt, const bool noPrompt); 185 bool FindDatabase(const bool prompt, const bool noPrompt); 175 bool Init(const bool gui); 186 176 187 177 bool IsWideMode() const {return (m_baseWidth == 1280);} 188 178 void SetWideMode() {m_baseWidth = 1280; m_baseHeight = 720;} 189 179 bool IsSquareMode() const {return (m_baseWidth == 800);} 190 180 void SetSquareMode() {m_baseWidth = 800; m_baseHeight = 600;} 191 181 192 void TempMainWindow(bool languagePrompt = true);193 void EndTempWindow(void);194 195 182 void GetScreenBounds(void); 196 183 void StoreGUIsettings(void); 197 184 198 185 void LoadLogSettings(void); 199 void LoadDatabaseSettings(void); 200 201 bool LoadSettingsFile(void); 186 187 void DefaultDatabaseSettings(void); 202 188 bool WriteSettingsFile(const DatabaseParams ¶ms, 203 189 bool overwrite = false); 204 bool FindSettingsProbs(void);205 190 206 QString getResponse(const QString &query, const QString &def);207 int intResponse(const QString &query, int def);208 bool PromptForDatabaseParams(const QString &error);209 QString TestDBconnection(void);210 void ResetDatabase(void);211 191 212 bool InitUPnP(void);213 void DeleteUPnP(void);214 int ChooseBackend(const QString &error);215 int UPnPautoconf(const int milliSeconds = 2000);216 bool DefaultUPnP(QString &error);217 bool UPnPconnect(const DeviceLocation *device, const QString &PIN);218 219 220 192 MythContext *parent; 221 193 222 194 Settings *m_settings; ///< connection stuff, theme, button style … … 248 220 QMutex m_hostnamelock; ///< Locking for thread-safe copying of: 249 221 QString m_localhostname; ///< hostname from mysql.txt or gethostname() 250 222 251 DatabaseParams m_DBparams; ///< Current database host & WOL details252 QString m_DBhostCp; ///< dbHostName backup253 254 UPnp *m_UPnP; ///< For automatic backend discover255 XmlConfiguration *m_XML;256 HttpServer *m_HTTP;257 258 223 QMutex serverSockLock; 259 224 bool attemptingToConnect; 260 225 … … 284 249 MythSocket *serverSock; 285 250 MythSocket *eventSock; 286 251 287 bool disablelibrarypopup;288 289 252 MythPluginManager *pluginmanager; 290 253 291 254 ScreenSaverControl *screensaver; … … 319 282 m_xbase(0), m_ybase(0), m_height(0), m_width(0), 320 283 m_baseWidth(800), m_baseHeight(600), 321 284 m_localhostname(QString::null), 322 m_UPnP(NULL), m_XML(NULL), m_HTTP(NULL),323 285 serverSockLock(false), 324 286 attemptingToConnect(false), 325 287 language(""), … … 330 292 themecachedir(QString::null), 331 293 bigfontsize(0), mediumfontsize(0), smallfontsize(0), 332 294 serverSock(NULL), eventSock(NULL), 333 disablelibrarypopup(false),334 295 pluginmanager(NULL), 335 296 screensaver(NULL), 336 297 m_logenable(-1), m_logmaxcount(-1), m_logprintlevel(-1), … … 375 336 { 376 337 imageCache.clear(); 377 338 378 DeleteUPnP();379 339 if (m_settings) 380 340 delete m_settings; 381 341 if (m_qtThemeSettings) … … 389 349 } 390 350 391 351 /** 392 * \brief Setup a minimal themed main window, and prompt for user's language.393 *394 * Used for warnings before the database is opened, or bootstrapping pages.395 * After using the window, call EndTempWindow().396 *397 * \bug Some of these settings (<i>e.g.</I> window size, theme)398 * seem to be used after the temp window is destroyed.399 *400 * \bug The default theme here is blue, but as of [12377],401 * G.A.N.T is now meant to be the default?402 * A simple change to make, but Nigel prefers403 * "blue" for these initial screens and popups404 */405 void MythContextPrivate::TempMainWindow(bool languagePrompt)406 {407 if (mainWindow)408 return;409 410 // We clear the hostname so MSqlQuery will fail, instead of long411 // timeouts per DB value, or hundreds of lines of DB connect errors.412 // We save the value for later possible editing in the DbSettings pages413 if (m_DBparams.dbHostName.length())414 {415 m_DBhostCp = m_DBparams.dbHostName;416 m_DBparams.dbHostName = "";417 }418 419 m_settings->SetSetting("Theme", "blue");420 #ifdef Q_WS_MACX421 // Myth looks horrible in default Mac style for Qt422 m_settings->SetSetting("Style", "Windows");423 #endif424 parent->LoadQtConfig();425 426 MythMainWindow *mainWindow = MythMainWindow::getMainWindow(false);427 mainWindow->Init();428 parent->SetMainWindow(mainWindow);429 430 if (languagePrompt)431 {432 // ask user for language settings433 LanguageSettings::prompt();434 LanguageSettings::load("mythfrontend");435 }436 }437 438 void MythContextPrivate::EndTempWindow(void)439 {440 parent->SetMainWindow(NULL);441 DestroyMythMainWindow();442 }443 444 /**445 352 * \brief Get screen size from Qt, respecting for user's multiple screen prefs 446 353 * 447 354 * If the windowing system environment has multiple screens … … 520 427 } 521 428 } 522 429 523 bool MythContextPrivate::Init(const bool gui, UPnp *UPnPclient, 524 const bool promptForBackend, const bool noPrompt) 430 bool MythContextPrivate::Init(const bool gui) 525 431 { 526 432 m_gui = gui; 527 if (UPnPclient)528 {529 m_UPnP = UPnPclient;530 m_XML = (XmlConfiguration *)UPnp::g_pConfig;531 }532 433 533 434 // Creates screen saver control if we will have a GUI 534 435 if (gui) 436 { 535 437 screensaver = ScreenSaverControl::get(); 536 438 537 // ---- database connection stuff ----538 539 if (!FindDatabase(promptForBackend, noPrompt))540 return false;541 542 // ---- keep all DB-using stuff below this line ----543 544 if (gui)545 {546 439 GetScreenBounds(); 547 440 StoreGUIsettings(); 548 441 } … … 551 444 } 552 445 553 446 /** 554 * Get database connection settings and test connectivity.555 *556 * Can use UPnP AutoDiscovery to locate backends, and get their DB settings.557 * The user can force the AutoDiscovery chooser with the --prompt argument,558 * and disable it by using the --disable-autodiscovery argument.559 * There is also an autoconfigure function, which counts the backends,560 * and if there is exactly one, uses it as above.561 *562 * Despite its name, the disable argument currently only disables the chooser.563 * If set, autoconfigure will still be attempted in some situations.564 */565 bool MythContextPrivate::FindDatabase(const bool prompt, const bool noPrompt)566 {567 // The two bool. args actually form a Yes/Maybe/No (A tristate bool :-)568 bool manualSelect = prompt && !noPrompt;569 570 // In addition to the UI chooser, we can also try to autoconfigure571 bool autoSelect = !manualSelect;572 573 QString failure;574 575 576 // 1. Load either mysql.txt, or use sensible "localhost" defaults:577 LoadDatabaseSettings();578 579 580 // 2. If the user isn't forcing up the chooser UI, look for a default581 // backend in config.xml, then test DB settings we've got so far:582 if (!manualSelect)583 {584 // config.xml may contain a backend host UUID and PIN.585 // If so, try to AutoDiscover UPnP server, and use its DB settings:586 587 if (DefaultUPnP(failure)) // Probably a valid backend,588 autoSelect = manualSelect = false; // so disable any further UPnP589 else590 if (failure.length())591 VERBOSE(VB_IMPORTANT, failure);592 593 failure = TestDBconnection();594 if (failure.isEmpty())595 goto DBfound;596 }597 598 599 // 3. Try to automatically find the single backend:600 if (autoSelect)601 {602 int count = UPnPautoconf();603 604 if (count == 0)605 failure = "No UPnP backends found";606 607 if (count == 1)608 {609 failure = TestDBconnection();610 if (failure.isEmpty())611 goto DBfound;612 }613 614 if (count > 1 || count == -1) // Multiple BEs, or needs PIN.615 manualSelect = !noPrompt; // If allowed, prompt user616 }617 618 if (!m_gui)619 manualSelect = false; // no interactive command-line chooser yet620 621 622 623 // Last, get the user to select a backend from a possible list:624 if (manualSelect)625 {626 switch (ChooseBackend(QString::null))627 {628 case -1: // User asked to configure database manually629 if (PromptForDatabaseParams(""))630 break;631 else632 goto NoDBfound; // User cancelled - changed their mind?633 634 case 0: // User cancelled. Exit application635 goto NoDBfound;636 637 case 1: // User selected a backend, so m_DBparams638 break; // should now contain the database details639 640 default:641 goto NoDBfound;642 }643 failure = TestDBconnection();644 }645 646 647 // Queries the user for the DB info, using the command648 // line or the GUI depending on the application.649 while (failure.length())650 {651 VERBOSE(VB_IMPORTANT, QString("%1").arg(failure));652 if (( manualSelect && ChooseBackend(failure)) ||653 (!manualSelect && PromptForDatabaseParams(failure)))654 {655 failure = TestDBconnection();656 if (failure.length())657 VERBOSE(VB_IMPORTANT, QString("%1").arg(failure));658 }659 else660 goto NoDBfound;661 }662 663 DBfound:664 //VERBOSE(VB_GENERAL, "FindDatabase() - Success!");665 ResetDatabase();666 DeleteUPnP();667 return true;668 669 NoDBfound:670 //VERBOSE(VB_GENERAL, "FindDatabase() - failed");671 DeleteUPnP();672 return false;673 }674 675 /**676 447 * Apply any user overrides to the screen geometry 677 448 */ 678 449 void MythContextPrivate::StoreGUIsettings() … … 744 515 m_logprintlevel = parent->GetNumSetting("LogPrintLevel", LP_ERROR); 745 516 } 746 517 747 /**748 * Load database and host settings from mysql.txt, or set some defaults749 *750 * \returns true if mysql.txt was parsed751 */752 void MythContextPrivate::LoadDatabaseSettings(void)753 {754 if (!LoadSettingsFile())755 {756 VERBOSE(VB_IMPORTANT, "Unable to read configuration file mysql.txt");757 758 // Sensible connection defaults.759 m_DBparams.dbHostName = "localhost";760 m_DBparams.dbHostPing = true;761 m_DBparams.dbPort = 0;762 m_DBparams.dbUserName = "mythtv";763 m_DBparams.dbPassword = "mythtv";764 m_DBparams.dbName = "mythconverg";765 m_DBparams.dbType = "QMYSQL3";766 m_DBparams.localEnabled = false;767 m_DBparams.localHostName = "my-unique-identifier-goes-here";768 m_DBparams.wolEnabled = false;769 m_DBparams.wolReconnect = 0;770 m_DBparams.wolRetry = 5;771 m_DBparams.wolCommand = "echo 'WOLsqlServerCommand not set'";772 }773 774 // Even if we have loaded the settings file, it may be incomplete,775 // so we check for missing values and warn user776 FindSettingsProbs();777 778 m_localhostname = m_DBparams.localHostName;779 if (m_localhostname.isEmpty() ||780 m_localhostname == "my-unique-identifier-goes-here")781 {782 char localhostname[1024];783 if (gethostname(localhostname, 1024))784 {785 VERBOSE(VB_IMPORTANT,786 "MCP: Error, could not determine host name." + ENO);787 localhostname[0] = '\0';788 }789 m_localhostname = localhostname;790 VERBOSE(VB_IMPORTANT, "Empty LocalHostName.");791 }792 793 VERBOSE(VB_GENERAL, QString("Using localhost value of %1")794 .arg(m_localhostname));795 }796 797 /**798 * Load mysql.txt and parse its values into m_DBparams799 */800 bool MythContextPrivate::LoadSettingsFile(void)801 {802 if (!m_settings->LoadSettingsFiles("mysql.txt", m_installprefix))803 return false;804 805 m_DBparams.dbHostName = m_settings->GetSetting("DBHostName");806 m_DBparams.dbHostPing = m_settings->GetSetting("DBHostPing") != "no";807 m_DBparams.dbPort = m_settings->GetNumSetting("DBPort");808 m_DBparams.dbUserName = m_settings->GetSetting("DBUserName");809 m_DBparams.dbPassword = m_settings->GetSetting("DBPassword");810 m_DBparams.dbName = m_settings->GetSetting("DBName");811 m_DBparams.dbType = m_settings->GetSetting("DBType");812 813 m_DBparams.localHostName = m_settings->GetSetting("LocalHostName");814 m_DBparams.localEnabled = m_DBparams.localHostName.length() > 0;815 816 m_DBparams.wolReconnect817 = m_settings->GetNumSetting("WOLsqlReconnectWaitTime");818 m_DBparams.wolEnabled = m_DBparams.wolReconnect > 0;819 820 m_DBparams.wolRetry = m_settings->GetNumSetting("WOLsqlConnectRetry");821 m_DBparams.wolCommand = m_settings->GetSetting("WOLsqlCommand");822 823 return true;824 }825 826 518 bool MythContextPrivate::WriteSettingsFile(const DatabaseParams ¶ms, 827 519 bool overwrite) 828 520 { … … 926 618 return true; 927 619 } 928 620 929 bool MythContextPrivate::FindSettingsProbs(void)930 {931 bool problems = false;932 933 if (m_DBparams.dbHostName.isEmpty())934 {935 problems = true;936 VERBOSE(VB_IMPORTANT, "DBHostName is not set in mysql.txt");937 VERBOSE(VB_IMPORTANT, "Assuming localhost");938 m_DBparams.dbHostName = "localhost";939 }940 if (m_DBparams.dbUserName.isEmpty())941 {942 problems = true;943 VERBOSE(VB_IMPORTANT, "DBUserName is not set in mysql.txt");944 }945 if (m_DBparams.dbPassword.isEmpty())946 {947 problems = true;948 VERBOSE(VB_IMPORTANT, "DBPassword is not set in mysql.txt");949 }950 if (m_DBparams.dbName.isEmpty())951 {952 problems = true;953 VERBOSE(VB_IMPORTANT, "DBName is not set in mysql.txt");954 }955 return problems;956 }957 958 QString MythContextPrivate::getResponse(const QString &query,959 const QString &def)960 {961 cout << query;962 963 if (def != "")964 cout << " [" << def << "] ";965 else966 cout << " ";967 968 if (!isatty(fileno(stdin)) || !isatty(fileno(stdout)))969 {970 cout << endl << "[console is not interactive, using default '"971 << def << "']" << endl;972 return def;973 }974 975 char response[80];976 cin.clear();977 cin.getline(response, 80);978 if (!cin.good())979 {980 cout << endl;981 VERBOSE(VB_IMPORTANT, "Read from stdin failed");982 return NULL;983 }984 985 QString qresponse = response;986 987 if (qresponse == "")988 qresponse = def;989 990 return qresponse;991 }992 993 int MythContextPrivate::intResponse(const QString &query, int def)994 {995 QString str_resp = getResponse(query, QString("%1").arg(def));996 if (!str_resp)997 return false;998 bool ok;999 int resp = str_resp.toInt(&ok);1000 return (ok ? resp : def);1001 }1002 1003 bool MythContextPrivate::PromptForDatabaseParams(const QString &error)1004 {1005 bool accepted = false;1006 if (m_gui)1007 {1008 TempMainWindow();1009 1010 // Tell the user what went wrong:1011 if (error.length())1012 MythPopupBox::showOkPopup(mainWindow, "DB connect failure", error);1013 1014 // ask user for database parameters1015 DatabaseSettings settings(m_DBhostCp);1016 accepted = (settings.exec() == QDialog::Accepted);1017 if (!accepted)1018 VERBOSE(VB_IMPORTANT, "User cancelled database configuration");1019 1020 EndTempWindow();1021 }1022 else1023 {1024 DatabaseParams params = parent->GetDatabaseParams();1025 QString response;1026 1027 // give user chance to skip config1028 cout << endl << error << endl << endl;1029 response = getResponse("Would you like to configure the database "1030 "connection now?",1031 "yes");1032 if (!response || response.left(1).lower() != "y")1033 return false;1034 1035 params.dbHostName = getResponse("Database host name:",1036 params.dbHostName);1037 response = getResponse("Should I test connectivity to this host "1038 "using the ping command?", "yes");1039 params.dbHostPing = (!response || response.left(1).lower() != "y");1040 1041 params.dbPort = intResponse("Database non-default port:",1042 params.dbPort);1043 params.dbName = getResponse("Database name:",1044 params.dbName);1045 params.dbUserName = getResponse("Database user name:",1046 params.dbUserName);1047 params.dbPassword = getResponse("Database password:",1048 params.dbPassword);1049 1050 params.localHostName = getResponse("Unique identifier for this machine "1051 "(if empty, the local host name "1052 "will be used):",1053 params.localHostName);1054 params.localEnabled = !params.localHostName.isEmpty();1055 1056 response = getResponse("Would you like to use Wake-On-LAN to retry "1057 "database connections?",1058 (params.wolEnabled ? "yes" : "no"));1059 if (response)1060 params.wolEnabled = (response.left(1).lower() == "y");1061 1062 if (params.wolEnabled)1063 {1064 params.wolReconnect = intResponse("Seconds to wait for "1065 "reconnection:",1066 params.wolReconnect);1067 params.wolRetry = intResponse("Number of times to retry:",1068 params.wolRetry);1069 params.wolCommand = getResponse("Command to use to wake server:",1070 params.wolCommand);1071 }1072 1073 accepted = parent->SaveDatabaseParams(params);1074 }1075 return accepted;1076 }1077 1078 621 /** 1079 622 * Some quick sanity checks before opening a database connection 1080 623 */ 1081 QString MythContext Private::TestDBconnection(void)624 QString MythContext::TestDBconnection(void) 1082 625 { 1083 bool doPing = m_DBparams.dbHostPing;626 bool doPing = gDBparams.dbHostPing; 1084 627 QString err; 1085 QString host = m_DBparams.dbHostName;1086 int port = m_DBparams.dbPort;628 QString host = gDBparams.dbHostName; 629 int port = gDBparams.dbPort; 1087 630 1088 631 1089 632 // 1. Check the supplied host or IP address, to prevent the app 1090 633 // appearing to hang if we cannot route to the machine: 1091 634 1092 635 // No need to ping myself 1093 if (host == "localhost" || host == "127.0.0.1" || host == m_localhostname) 636 if (host == "localhost" || host == "127.0.0.1" || 637 host == d->m_localhostname) 1094 638 doPing = false; 1095 639 1096 640 // If WOL is setup, the backend might be sleeping: 1097 if (doPing && m_DBparams.wolEnabled)1098 for (int attempt = 0; attempt < m_DBparams.wolRetry; ++attempt)641 if (doPing && gDBparams.wolEnabled) 642 for (int attempt = 0; attempt < gDBparams.wolRetry; ++attempt) 1099 643 { 1100 int wakeupTime = m_DBparams.wolReconnect;644 int wakeupTime = gDBparams.wolReconnect; 1101 645 1102 646 if (ping(host, wakeupTime)) 1103 647 { … … 1107 651 1108 652 VERBOSE(VB_GENERAL, QString("Trying to wake up host %1, attempt %2") 1109 653 .arg(host).arg(attempt)); 1110 system( m_DBparams.wolCommand);654 system(gDBparams.wolCommand); 1111 655 1112 656 VERBOSE(VB_GENERAL, 1113 657 QString("Waiting for %1 seconds").arg(wakeupTime)); 1114 sleep( m_DBparams.wolReconnect);658 sleep(gDBparams.wolReconnect); 1115 659 } 1116 660 1117 661 if (doPing) … … 1122 666 1123 667 if (doPing && !ping(host, 3)) // Fail after trying for 3 seconds 1124 668 { 1125 // Save, to display in DatabaseSettings screens1126 m_DBhostCp = m_DBparams.dbHostName;1127 1128 669 // Cause MSqlQuery to fail, instead of minutes timeout per DB value 1129 m_DBparams.dbHostName = "";670 gDBparams.dbHostName = ""; 1130 671 1131 672 err = QObject::tr("Cannot find (ping) database host %1 on the network"); 1132 673 return err.arg(host); … … 1162 703 * Any cached settings also need to be cleared, 1163 704 * so that they can be re-read from the new database 1164 705 */ 1165 void MythContext Private::ResetDatabase(void)706 void MythContext::ResetDatabase(void) 1166 707 { 1167 m_dbmanager.CloseDatabases();1168 parent->ClearSettingsCache();708 d->m_dbmanager.CloseDatabases(); 709 ClearSettingsCache(); 1169 710 } 1170 711 1171 712 1172 bool MythContextPrivate::InitUPnP(void)713 MythContext::MythContext() : QObject() 1173 714 { 1174 if (m_UPnP)1175 return true;1176 1177 VERBOSE(VB_UPNP, "Setting UPnP client for backend autodiscovery...");1178 1179 if (!m_XML)1180 m_XML = new XmlConfiguration(""); // No file - use defaults only1181 1182 m_UPnP = new UPnp();1183 m_UPnP->SetConfiguration(m_XML);1184 1185 int port=6549;1186 m_HTTP = new HttpServer(port);1187 1188 if (!m_HTTP->ok())1189 {1190 VERBOSE(VB_IMPORTANT, "MCP::InitUPnP() - HttpServer Create Error");1191 DeleteUPnP();1192 return false;1193 }1194 1195 if (!m_UPnP->Initialize(port, m_HTTP))1196 {1197 VERBOSE(VB_IMPORTANT, "MCP::InitUPnP() - UPnp::Initialize() Error");1198 DeleteUPnP();1199 return false;1200 }1201 1202 // Create a dummy device description1203 UPnpDevice &device = UPnp::g_UPnpDeviceDesc.m_rootDevice;1204 device.m_sDeviceType = "urn:schemas-upnp-org:device:MythContextClient:1";1205 1206 m_UPnP->Start();1207 1208 return true;1209 }1210 1211 void MythContextPrivate::DeleteUPnP(void)1212 {1213 if (m_UPnP && !m_HTTP) // Init was passed an existing UPnP1214 return; // so let the caller delete it cleanly1215 1216 if (m_UPnP)1217 {1218 // This takes a few seconds, so inform the user:1219 VERBOSE(VB_GENERAL, "Deleting UPnP client...");1220 1221 delete m_UPnP; // This also deletes m_XML1222 m_UPnP = NULL;1223 m_XML = NULL;1224 }1225 1226 if (m_HTTP)1227 {1228 delete m_HTTP;1229 m_HTTP = NULL;1230 }1231 }1232 1233 /**1234 * Search for backends via UPnP, put up a UI for the user to choose one1235 */1236 int MythContextPrivate::ChooseBackend(const QString &error)1237 {1238 if (!InitUPnP())1239 return -1;1240 1241 TempMainWindow();1242 1243 // Tell the user what went wrong:1244 if (error.length())1245 MythPopupBox::showOkPopup(mainWindow, "DB connect failure", error);1246 1247 VERBOSE(VB_GENERAL, "Putting up the UPnP backend chooser");1248 1249 BackendSelect *BEsel = new BackendSelect(mainWindow, &m_DBparams);1250 switch (BEsel->exec())1251 {1252 case kDialogCodeRejected:1253 VERBOSE(VB_IMPORTANT, "User canceled database configuration");1254 return 0;1255 1256 case kDialogCodeButton0:1257 VERBOSE(VB_IMPORTANT, "User requested Manual Config");1258 return -1;1259 }1260 //BEsel->hide();1261 //BEsel->deleteLater();1262 1263 QStringList buttons;1264 QString message;1265 1266 buttons += QObject::tr("Save database details");1267 buttons += QObject::tr("Save backend details");1268 buttons += QObject::tr("Don't Save");1269 1270 message = QObject::tr("Save that backend or database as the default?");1271 1272 DialogCode selected = MythPopupBox::ShowButtonPopup(1273 mainWindow, "Save default", message, buttons, kDialogCodeButton2);1274 switch (selected)1275 {1276 case kDialogCodeButton0:1277 WriteSettingsFile(m_DBparams, true);1278 // User prefers mysql.txt, so throw away default UPnP backend:1279 m_XML->SetValue(kDefaultUSN, "");1280 m_XML->Save();1281 break;1282 case kDialogCodeButton1:1283 if (BEsel->m_PIN.length())1284 m_XML->SetValue(kDefaultPIN, BEsel->m_PIN);1285 m_XML->SetValue(kDefaultUSN, BEsel->m_USN);1286 m_XML->Save();1287 break;1288 }1289 1290 delete BEsel;1291 EndTempWindow();1292 1293 return 1;1294 }1295 1296 /**1297 * If there is only a single UPnP backend, use it.1298 *1299 * This does <i>not</i> prompt for PIN entry. If the backend requires one,1300 * it will fail, and the caller needs to put up a UI to ask for one.1301 */1302 int MythContextPrivate::UPnPautoconf(const int milliSeconds)1303 {1304 if (!InitUPnP())1305 return 0;1306 1307 SSDPCacheEntries *backends = NULL;1308 int count;1309 QString LOC = "UPnPautoconf() - ";1310 QTime timer;1311 1312 m_UPnP->PerformSearch(gBackendURI);1313 for (timer.start(); timer.elapsed() < milliSeconds; usleep(25000))1314 {1315 backends = m_UPnP->g_SSDPCache.Find(gBackendURI);1316 if (backends)1317 {1318 backends->AddRef();1319 break;1320 }1321 putchar('.');1322 }1323 putchar('\n');1324 1325 if (!backends)1326 {1327 VERBOSE(VB_GENERAL, LOC + "No UPnP backends found");1328 return 0;1329 }1330 1331 1332 // This could be tied to VB_UPNP?1333 //m_UPnP->g_SSDPCache.Dump();1334 1335 1336 count = backends->Count();1337 switch (count)1338 {1339 case 0:1340 VERBOSE(VB_IMPORTANT,1341 LOC + "No UPnP backends found, but SSDP::Find() not NULL!");1342 break;1343 case 1:1344 VERBOSE(VB_GENERAL, LOC + "Found one UPnP backend");1345 break;1346 default:1347 VERBOSE(VB_GENERAL,1348 (LOC + "More than one UPnP backend found (%1)").arg(count));1349 }1350 1351 if (count != 1)1352 {1353 backends->Release();1354 return count;1355 }1356 1357 1358 // Get this backend's location:1359 backends->Lock();1360 DeviceLocation *BE = backends->GetEntryMap()->begin().data();1361 backends->Unlock();1362 backends->Release();1363 1364 // We don't actually know the backend's access PIN, so this will1365 // only work for ones that have PIN access disabled (i.e. 0000)1366 if (UPnPconnect(BE, QString::null))1367 return 1;1368 1369 return -1; // Try to force chooser & PIN1370 }1371 1372 /**1373 * Get the default backend from config.xml, use UPnP to find it.1374 *1375 * Sets a string if there any connection problems1376 */1377 bool MythContextPrivate::DefaultUPnP(QString &error)1378 {1379 XmlConfiguration *XML = new XmlConfiguration("config.xml");1380 QString loc = "MCP::DefaultUPnP() - ";1381 QString PIN = XML->GetValue(kDefaultPIN, "");1382 QString USN = XML->GetValue(kDefaultUSN, "");1383 1384 delete XML;1385 1386 if (USN.isEmpty())1387 {1388 VERBOSE(VB_UPNP, loc + "No default UPnP backend");1389 return false;1390 }1391 1392 VERBOSE(VB_UPNP, loc + "config.xml has default " +1393 QString("PIN '%1' and host USN: %2")1394 .arg(PIN).arg(USN));1395 1396 if (!InitUPnP())1397 {1398 error = "UPnP is broken?";1399 return false;1400 }1401 1402 m_UPnP->PerformSearch(gBackendURI);1403 DeviceLocation *pDevLoc = m_UPnP->g_SSDPCache.Find(gBackendURI, USN);1404 if (!pDevLoc)1405 {1406 error = "Cannot find default UPnP backend";1407 return false;1408 1409 }1410 1411 if (UPnPconnect(pDevLoc, PIN))1412 return true;1413 1414 error = "Cannot connect to default backend via UPnP. Wrong saved PIN?";1415 return false;1416 }1417 1418 /**1419 * Query a backend via UPnP for its database connection parameters1420 */1421 bool MythContextPrivate::UPnPconnect(const DeviceLocation *backend,1422 const QString &PIN)1423 {1424 QString error;1425 QString LOC = "UPnPconnect() - ";1426 QString URL = backend->m_sLocation;1427 MythXMLClient XML(URL);1428 1429 VERBOSE(VB_UPNP, LOC + QString("Trying host at %1").arg(URL));1430 switch (XML.GetConnectionInfo(PIN, &m_DBparams, error))1431 {1432 case UPnPResult_Success:1433 break;1434 1435 case UPnPResult_ActionNotAuthorized:1436 // The stored PIN is probably not correct.1437 // We could prompt for the PIN and try again, but that needs a UI.1438 // Easier to fail for now, and put up the full UI selector later1439 VERBOSE(VB_UPNP, LOC + error + ". Wrong PIN?");1440 return false;1441 1442 default:1443 VERBOSE(VB_UPNP, LOC + error);1444 return false;1445 }1446 1447 QString DBhost = m_DBparams.dbHostName;1448 VERBOSE(VB_UPNP, LOC + QString("Got database hostname: %1").arg(DBhost));1449 1450 return true;1451 }1452 1453 1454 MythContext::MythContext(const QString &binversion)1455 : QObject(), d(NULL), app_binary_version(binversion)1456 {1457 715 #ifdef USING_MINGW 1458 716 static bool WSAStarted = false; 1459 717 if (!WSAStarted) { … … 1468 726 d = new MythContextPrivate(this); 1469 727 } 1470 728 1471 bool MythContext::Init(const bool gui, UPnp *UPnPclient, 1472 const bool promptForBackend, 1473 const bool disableAutoDiscovery) 729 bool MythContext::Init(const bool gui) 1474 730 { 1475 if (app_binary_version != MYTH_BINARY_VERSION) 1476 { 1477 QString warning = 1478 QString("This app was compiled against libmyth version: %1" 1479 "\n\t\t\tbut the library is version: %2" 1480 "\n\t\t\tYou probably want to recompile everything, and do a" 1481 "\n\t\t\t'make distclean' first.") 1482 .arg(app_binary_version).arg(MYTH_BINARY_VERSION); 1483 1484 if (gui) 1485 { 1486 d->TempMainWindow(false); 1487 MythPopupBox::showOkPopup(d->mainWindow, 1488 "Library version error", warning); 1489 d->EndTempWindow(); 1490 } 1491 VERBOSE(VB_IMPORTANT, QString("%1").arg(warning)); 1492 731 if (!d->Init(gui)) 1493 732 return false; 1494 }1495 733 1496 if (!d->Init(gui, UPnPclient, promptForBackend, disableAutoDiscovery))1497 return false;1498 1499 734 ActivateSettingsCache(true); 1500 735 1501 736 return true; … … 1570 805 manageLock = true; 1571 806 d->serverSockLock.unlock(); 1572 807 } 1573 MythPopupBox::showOkPopup( d->mainWindow,808 MythPopupBox::showOkPopup(GetMainWindow(), 1574 809 "connection failure", 1575 810 tr("Could not connect to the " 1576 811 "master backend server -- is " … … 1818 1053 return tmp; 1819 1054 } 1820 1055 1056 void MythContext::SetHostName(QString localHost) 1057 { 1058 d->m_hostnamelock.lock(); 1059 d->m_localhostname = QDeepCopy<QString>(localHost); 1060 d->m_hostnamelock.unlock(); 1061 } 1062 1821 1063 QString MythContext::GetFilePrefix(void) 1822 1064 { 1823 1065 return GetSetting("RecordFilePrefix"); … … 3207 2449 VERBOSE(VB_IMPORTANT, 3208 2450 QString("Reconnection to backend server failed")); 3209 2451 if (d->m_height && d->m_width) 3210 MythPopupBox::showOkPopup( d->mainWindow, "connection failure",2452 MythPopupBox::showOkPopup(GetMainWindow(), "connection failure", 3211 2453 tr("The connection to the master backend " 3212 2454 "server has gone away for some reason.. " 3213 2455 "Is it running?")); … … 3279 2521 if (d->m_height && d->m_width) 3280 2522 { 3281 2523 qApp->lock(); 3282 MythPopupBox::showOkPopup( d->mainWindow,2524 MythPopupBox::showOkPopup(GetMainWindow(), 3283 2525 "Connection failure", 3284 2526 tr(QString("The server uses network " 3285 2527 "protocol version %1, " … … 3337 2579 QFont MythContext::GetBigFont(void) 3338 2580 { 3339 2581 QFont font = QApplication::font(); 3340 font.setPointSize( GetMythMainWindow()->NormalizeFontSize(d->bigfontsize));2582 font.setPointSize(NormalizeFontSize(d->bigfontsize)); 3341 2583 font.setWeight(QFont::Bold); 3342 2584 3343 2585 return font; … … 3346 2588 QFont MythContext::GetMediumFont(void) 3347 2589 { 3348 2590 QFont font = QApplication::font(); 3349 font.setPointSize( GetMythMainWindow()->NormalizeFontSize(d->mediumfontsize));2591 font.setPointSize(NormalizeFontSize(d->mediumfontsize)); 3350 2592 font.setWeight(QFont::Bold); 3351 2593 3352 2594 return font; … … 3355 2597 QFont MythContext::GetSmallFont(void) 3356 2598 { 3357 2599 QFont font = QApplication::font(); 3358 font.setPointSize( GetMythMainWindow()->NormalizeFontSize(d->smallfontsize));2600 font.setPointSize(NormalizeFontSize(d->smallfontsize)); 3359 2601 font.setWeight(QFont::Bold); 3360 2602 3361 2603 return font; … … 3397 2639 return d->mainWindow; 3398 2640 } 3399 2641 3400 /**3401 * \brief Try to prevent silent, automatic database upgrades3402 * \returns -1 to use the existing schema, 0 to exit, 1 to upgrade.3403 *3404 * The GUI prompts have no defaults, so that nothing dangerous3405 * will happen if the user hits return a few times.3406 * Hopefully this will force users to stop and think?3407 * Similarly, the shell command prompting requires an explicit "yes".3408 * Non-interactive shells default to old behaviour (upgrading)3409 */3410 int MythContext::PromptForSchemaUpgrade(const QString &dbver,3411 const QString ¤t)3412 {3413 bool autoUpgrade = false;3414 bool connections = false; // Are (other) FE/BEs connected?3415 bool expertMode = false; // Use existing schema? Multiple buttons?3416 QString message;3417 int returnValue = MYTH_SCHEMA_UPGRADE;3418 bool upgradable = (dbver.toUInt() < current.toUInt());3419 QString warnOtherCl = tr("There are also other clients using this"3420 " database. They should be shut down first.");3421 3422 3423 // No current DBSchemaVer? Empty database, so upgrade to create tables3424 if (dbver.isEmpty())3425 {3426 VERBOSE(VB_GENERAL, "No current database version. Auto upgrading");3427 return MYTH_SCHEMA_UPGRADE;3428 }3429 3430 3431 // Users and developers can choose to live dangerously,3432 // either to silently and automatically upgrade,3433 // or an expert option to allow use of existing:3434 switch (gContext->GetNumSetting("DBSchemaAutoUpgrade"))3435 {3436 case 1: autoUpgrade = true; break;3437 case -1: expertMode = true; break;3438 default: break;3439 }3440 3441 3442 // FIXME: Don't know how to determine this3443 //if (getActiveConnections() > 1)3444 // connections = true;3445 3446 3447 // Deal with the trivial case first (No user prompting required)3448 if (autoUpgrade && upgradable && !connections)3449 return MYTH_SCHEMA_UPGRADE;3450 3451 3452 // Build up strings used both in GUI and command shell contexts:3453 if (upgradable)3454 {3455 if (autoUpgrade && connections)3456 {3457 message = tr("Error: MythTV cannot upgrade the schema of this"3458 " datatase because other clients are using it.\n\n"3459 "Please shut them down before upgrading.");3460 returnValue = MYTH_SCHEMA_ERROR;3461 }3462 else3463 {3464 message = tr("Warning: MythTV wants to upgrade"3465 " your database schema, from %1 to %2.");3466 if (expertMode)3467 message += "\n\n" +3468 tr("You can try using the old schema,"3469 " but that may cause problems.");3470 }3471 }3472 else // This client is too old3473 {3474 if (expertMode)3475 message = tr("Warning: MythTV database has newer"3476 " schema (%1) than expected (%2).");3477 else3478 {3479 message = tr("Error: MythTV database has newer"3480 " schema (%1) than expected (%2).");3481 returnValue = MYTH_SCHEMA_ERROR;3482 }3483 }3484 3485 if (message.contains("%1"))3486 message = message.arg(dbver).arg(current);3487 3488 3489 if (d->m_gui)3490 {3491 bool createdTempWindow = false;3492 3493 if (!d->mainWindow)3494 {3495 d->TempMainWindow();3496 createdTempWindow = true;3497 }3498 3499 if (returnValue == MYTH_SCHEMA_ERROR)3500 {3501 MythPopupBox::showOkPopup(3502 d->mainWindow, "Database Upgrade Error",3503 message, QObject::tr("Exit"));3504 }3505 else3506 {3507 QStringList buttonNames;3508 3509 buttonNames += QObject::tr("Exit");3510 buttonNames += QObject::tr("Upgrade");3511 if (expertMode)3512 buttonNames += QObject::tr("Use current schema");3513 3514 DialogCode selected = MythPopupBox::ShowButtonPopup(3515 d->mainWindow, "Database Upgrade", message,3516 buttonNames, kDialogCodeButton0);3517 3518 // The annoying extra confirmation:3519 if (kDialogCodeButton1 == selected)3520 {3521 message = tr("This cannot be un-done, so having a"3522 " database backup would be a good idea.");3523 if (connections)3524 message += "\n\n" + warnOtherCl;3525 3526 selected = MythPopupBox::ShowButtonPopup(3527 d->mainWindow, "Database Upgrade", message,3528 buttonNames, kDialogCodeButton0);3529 }3530 3531 switch (selected)3532 {3533 case kDialogCodeRejected:3534 case kDialogCodeButton0:3535 returnValue = MYTH_SCHEMA_EXIT; break;3536 case kDialogCodeButton1:3537 returnValue = MYTH_SCHEMA_UPGRADE; break;3538 case kDialogCodeButton2:3539 returnValue = MYTH_SCHEMA_USE_EXISTING; break;3540 default:3541 returnValue = MYTH_SCHEMA_ERROR;3542 }3543 }3544 3545 if (createdTempWindow)3546 {3547 d->EndTempWindow();3548 d->m_DBparams.dbHostName = d->m_DBhostCp;3549 }3550 3551 return returnValue;3552 }3553 3554 // We are not in a GUI environment, so try to prompt the user in the shell3555 3556 if (!isatty(fileno(stdin)) || !isatty(fileno(stdout)))3557 {3558 if (expertMode)3559 {3560 cout << "Console non-interactive. Using existing schema." << endl;3561 return MYTH_SCHEMA_USE_EXISTING;3562 }3563 3564 cout << "Console is not interactive, cannot ask user about"3565 << " upgrading database schema." << endl << "Upgrading." << endl;3566 return MYTH_SCHEMA_UPGRADE;3567 }3568 3569 3570 QString resp;3571 3572 cout << endl << message << endl << endl;3573 3574 if (expertMode)3575 {3576 resp = d->getResponse("Would you like to use the existing schema?",3577 "yes");3578 if (!resp || resp.left(1).lower() == "y")3579 return MYTH_SCHEMA_USE_EXISTING;3580 }3581 3582 resp = d->getResponse("\nShall I upgrade this database?", "yes");3583 if (resp && resp.left(1).lower() != "y")3584 return MYTH_SCHEMA_EXIT;3585 3586 if (connections)3587 cout << endl << warnOtherCl <<endl;3588 3589 resp = d->getResponse("\nA database backup might be a good idea"3590 "\nAre you sure you want to upgrade?", "no");3591 if (!resp || resp.left(1).lower() == "n")3592 return MYTH_SCHEMA_EXIT;3593 3594 return MYTH_SCHEMA_UPGRADE;3595 }3596 3597 bool MythContext::TestPopupVersion(const QString &name,3598 const QString &libversion,3599 const QString &pluginversion)3600 {3601 if (libversion == pluginversion)3602 return true;3603 3604 QString err = "The " + name + " plugin was compiled against libmyth " +3605 "version: " + pluginversion + ", but the installed " +3606 "libmyth is at version: " + libversion + ". You probably " +3607 "want to recompile the " + name + " plugin after doing a " +3608 "make distclean.";3609 3610 if (GetMainWindow() && !d->disablelibrarypopup)3611 {3612 DialogBox *dlg = new DialogBox(gContext->GetMainWindow(), err);3613 dlg->AddButton("OK");3614 dlg->exec();3615 dlg->deleteLater();3616 }3617 3618 return false;3619 }3620 3621 void MythContext::SetDisableLibraryPopup(bool check)3622 {3623 d->disablelibrarypopup = check;3624 }3625 3626 2642 void MythContext::SetPluginManager(MythPluginManager *pmanager) 3627 2643 { 3628 2644 d->pluginmanager = pmanager; … … 3806 2822 return ret_val; 3807 2823 } 3808 2824 3809 DatabaseParams MythContext::GetDatabaseParams(void) 2825 /** 2826 * Set database connection defaults 2827 */ 2828 void MythContext::DefaultDatabaseSettings(void) 3810 2829 { 3811 return d->m_DBparams; 2830 gDBparams.dbHostName = "localhost"; 2831 gDBparams.dbHostPing = true; 2832 gDBparams.dbPort = 0; 2833 gDBparams.dbUserName = "mythtv"; 2834 gDBparams.dbPassword = "mythtv"; 2835 gDBparams.dbName = "mythconverg"; 2836 gDBparams.dbType = "QMYSQL3"; 2837 gDBparams.localEnabled = false; 2838 gDBparams.localHostName = "my-unique-identifier-goes-here"; 2839 gDBparams.wolEnabled = false; 2840 gDBparams.wolReconnect = 0; 2841 gDBparams.wolRetry = 5; 2842 gDBparams.wolCommand = "echo 'WOLsqlServerCommand not set'"; 3812 2843 } 3813 2844 2845 3814 2846 bool MythContext::SaveDatabaseParams(const DatabaseParams ¶ms) 3815 2847 { 3816 2848 bool ret = true; 3817 DatabaseParams cur_params = GetDatabaseParams();3818 2849 3819 2850 // only rewrite file if it has changed 3820 if (params.dbHostName != cur_params.dbHostName ||3821 params.dbHostPing != cur_params.dbHostPing ||3822 params.dbPort != cur_params.dbPort ||3823 params.dbUserName != cur_params.dbUserName ||3824 params.dbPassword != cur_params.dbPassword ||3825 params.dbName != cur_params.dbName ||3826 params.dbType != cur_params.dbType ||3827 params.localEnabled != cur_params.localEnabled ||3828 params.wolEnabled != cur_params.wolEnabled ||2851 if (params.dbHostName != gDBparams.dbHostName || 2852 params.dbHostPing != gDBparams.dbHostPing || 2853 params.dbPort != gDBparams.dbPort || 2854 params.dbUserName != gDBparams.dbUserName || 2855 params.dbPassword != gDBparams.dbPassword || 2856 params.dbName != gDBparams.dbName || 2857 params.dbType != gDBparams.dbType || 2858 params.localEnabled != gDBparams.localEnabled || 2859 params.wolEnabled != gDBparams.wolEnabled || 3829 2860 (params.localEnabled && 3830 (params.localHostName != cur_params.localHostName)) ||2861 (params.localHostName != gDBparams.localHostName)) || 3831 2862 (params.wolEnabled && 3832 (params.wolReconnect != cur_params.wolReconnect ||3833 params.wolRetry != cur_params.wolRetry ||3834 params.wolCommand != cur_params.wolCommand)))2863 (params.wolReconnect != gDBparams.wolReconnect || 2864 params.wolRetry != gDBparams.wolRetry || 2865 params.wolCommand != gDBparams.wolCommand))) 3835 2866 { 3836 2867 ret = d->WriteSettingsFile(params, true); 3837 2868 if (ret) 3838 2869 { 3839 2870 // Save the new settings: 3840 d->m_DBparams = params;2871 gDBparams = params; 3841 2872 3842 2873 // If database has changed, force its use: 3843 d->ResetDatabase();2874 ResetDatabase(); 3844 2875 } 3845 2876 } 3846 2877 return ret; -
mythtv/libs/libmyth/mythdbcon.cpp
59 59 60 60 if (!m_db->isOpen()) 61 61 { 62 DatabaseParams dbparms = gContext->GetDatabaseParams(); 63 m_db->setDatabaseName(dbparms.dbName); 64 m_db->setUserName(dbparms.dbUserName); 65 m_db->setPassword(dbparms.dbPassword); 66 m_db->setHostName(dbparms.dbHostName); 62 m_db->setDatabaseName(gDBparams.dbName); 63 m_db->setUserName(gDBparams.dbUserName); 64 m_db->setPassword(gDBparams.dbPassword); 65 m_db->setHostName(gDBparams.dbHostName); 67 66 68 if (! dbparms.dbHostName.length())// Bootstrapping without a database?67 if (!gDBparams.dbHostName.length())// Bootstrapping without a database? 69 68 { 70 69 connected = true; // Pretend to be connected 71 70 return true; // to reduce errors 72 71 } 73 72 74 if ( dbparms.dbPort)75 m_db->setPort( dbparms.dbPort);73 if (gDBparams.dbPort) 74 m_db->setPort(gDBparams.dbPort); 76 75 77 if ( dbparms.dbPort && dbparms.dbHostName == "localhost")76 if (gDBparams.dbPort && gDBparams.dbHostName == "localhost") 78 77 m_db->setHostName("127.0.0.1"); 79 78 80 79 connected = m_db->open(); 81 80 82 if (!connected && dbparms.wolEnabled)81 if (!connected && gDBparams.wolEnabled) 83 82 { 84 83 int trycount = 0; 85 84 86 while (!connected && trycount++ < dbparms.wolRetry)85 while (!connected && trycount++ < gDBparams.wolRetry) 87 86 { 88 87 VERBOSE(VB_GENERAL, QString( 89 88 "Using WOL to wakeup database server (Try %1 of %2)") 90 .arg(trycount).arg( dbparms.wolRetry));89 .arg(trycount).arg(gDBparams.wolRetry)); 91 90 92 system( dbparms.wolCommand);93 sleep( dbparms.wolReconnect);91 system(gDBparams.wolCommand); 92 sleep(gDBparams.wolReconnect); 94 93 connected = m_db->open(); 95 94 } 96 95 97 96 if (!connected) 98 97 { 99 VERBOSE(VB_IMPORTANT, "WOL failed, unable to connect to database!"); 98 VERBOSE(VB_IMPORTANT, 99 "WOL failed, unable to connect to database!"); 100 100 } 101 101 } 102 102 if (connected) -
mythtv/libs/libmyth/mythwizard.cpp
539 539 { 540 540 bool handled = false; 541 541 QStringList actions; 542 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions))542 if (gContext->TranslateKeyPress("qt", e, actions)) 543 543 { 544 544 for (unsigned int i = 0; i < actions.size() && !handled; i++) 545 545 { -
mythtv/libs/libmyth/mythcontext.h
142 142 { 143 143 Q_OBJECT 144 144 public: 145 MythContext( const QString &binversion);145 MythContext(); 146 146 virtual ~MythContext(); 147 147 148 bool Init(const bool gui = true, 149 UPnp *UPnPclient = NULL, 150 const bool promptForBackend = false, 151 const bool bypassAutoDiscovery = false); 148 bool Init(const bool gui = true); 152 149 153 150 QString GetMasterHostPrefix(void); 154 151 155 152 QString GetHostName(void); 153 void SetHostName(QString localHost); 156 154 157 155 void ClearSettingsCache(QString myKey = "", QString newVal = ""); 158 156 void ActivateSettingsCache(bool activate = true); … … 229 227 static void DBError(const QString &where, const QSqlQuery &query); 230 228 static QString DBErrorMessage(const QSqlError& err); 231 229 232 DatabaseParams GetDatabaseParams(void); 230 void DefaultDatabaseSettings(void); 231 void ResetDatabase(void); 233 232 bool SaveDatabaseParams(const DatabaseParams ¶ms); 233 QString TestDBconnection(void); 234 234 235 235 void LogEntry(const QString &module, int priority, 236 236 const QString &message, const QString &details); … … 282 282 void SetMainWindow(MythMainWindow *mainwin); 283 283 MythMainWindow *GetMainWindow(void); 284 284 285 int PromptForSchemaUpgrade(const QString &dbver, const QString ¤t); 286 bool TestPopupVersion(const QString &name, const QString &libversion, 287 const QString &pluginversion); 285 // These virtual methods are implemented by the MythContextGUI 286 // and MythContextTTY subclasses in libmythtv. Having them there 287 // simplifies the library dependencies (no cross-dependencies). 288 // 289 virtual int PromptForSchemaUpgrade(const QString &dbver, 290 const QString ¤t) = 0; 291 virtual bool TestPopupVersion(const QString &pluginName, 292 const QString &libMythVersion, 293 const QString &pluginVersion) = 0; 288 294 289 v oid SetDisableLibraryPopup(bool check);295 virtual void SetDisableLibraryPopup(bool check) = 0; 290 296 297 virtual void attachToWin(QWidget *child) = 0; 298 virtual void detachFromWin(QWidget *child) = 0; 299 virtual int NormalizeFontSize(const int pointSize) = 0; 300 virtual bool TranslateKeyPress(const QString &context, 301 QKeyEvent *e, 302 QStringList &actions, 303 bool allowJumps = true) = 0; 304 305 virtual MythMainWindow *CreateMainWindow(void) = 0; 306 307 291 308 void SetPluginManager(MythPluginManager *pmanager); 292 309 MythPluginManager *getPluginManager(void); 293 310 … … 344 361 void readyRead(MythSocket *sock); 345 362 void connectionFailed(MythSocket *sock) { (void)sock; } 346 363 347 MythContextPrivate *d; 348 QString app_binary_version; 364 MythContextPrivate *d; 349 365 350 QMutex locationLock;366 QMutex locationLock; 351 367 QValueList <QString> currentLocation; 352 368 }; 353 369 370 354 371 /// This global variable contains the MythContext instance for the application 355 372 extern MPUBLIC MythContext *gContext; 356 373 374 /// This global stores the context's current database host & WOL details 375 extern MPUBLIC DatabaseParams gDBparams; 376 357 377 /// This global variable is used to makes certain calls to avlib threadsafe. 358 378 extern MPUBLIC QMutex avcodeclock; 359 379 … … 366 386 MYTH_SCHEMA_USE_EXISTING = 4 367 387 }; 368 388 369 /// Service type for the backend's UPnP server370 extern MPUBLIC const QString gBackendURI;371 372 389 #endif 373 390 374 391 /* vim: set expandtab tabstop=4 shiftwidth=4: */ -
mythtv/libs/libmyth/mythconfigdialogs.cpp
100 100 bool handled = false; 101 101 QStringList actions; 102 102 103 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions))103 if (gContext->TranslateKeyPress("qt", e, actions)) 104 104 { 105 105 for (unsigned int i = 0; i < actions.size() && !handled; i++) 106 106 { -
mythtv/libs/libmyth/libmyth.pro
11 11 12 12 # Input 13 13 HEADERS += audiooutput.h audiooutputbase.h audiooutputnull.h 14 HEADERS += backendselect.h dbsettings.h dialogbox.h 15 HEADERS += DisplayRes.h DisplayResScreen.h exitcodes.h 14 HEADERS += dialogbox.h DisplayRes.h DisplayResScreen.h exitcodes.h 16 15 HEADERS += generictree.h httpcomms.h langsettings.h lcddevice.h 17 16 HEADERS += managedlist.h mythconfigdialogs.h mythconfiggroups.h 18 17 HEADERS += mythcontext.h mythdbcon.h mythdeque.h mythdialogs.h … … 27 26 HEADERS += compat.h 28 27 29 28 SOURCES += audiooutput.cpp audiooutputbase.cpp audiooutputnull.cpp 30 SOURCES += backendselect.cpp dbsettings.cpp dialogbox.cpp 31 SOURCES += DisplayRes.cpp DisplayResScreen.cpp 29 SOURCES += dialogbox.cpp DisplayRes.cpp DisplayResScreen.cpp 32 30 SOURCES += generictree.cpp httpcomms.cpp langsettings.cpp lcddevice.cpp 33 31 SOURCES += managedlist.cpp mythconfigdialogs.cpp mythconfiggroups.cpp 34 32 SOURCES += mythcontext.cpp mythdbcon.cpp mythdialogs.cpp … … 60 58 inc.files += visual.h volumebase.h output.h langsettings.h qmdcodec.h 61 59 inc.files += exitcodes.h mythconfig.h mythconfig.mak virtualkeyboard.h 62 60 inc.files += mythevent.h mythobservable.h mythsocket.h 63 inc.files += mythexp.h mythpluginapi.h compat.h 61 inc.files += mythexp.h mythpluginapi.h compat.h mythverbose.h 64 62 inc.files += mythstorage.h mythconfigdialogs.h mythconfiggroups.h 65 63 66 64 using_oss { … … 121 119 # Mac OS X Frameworks 122 120 FWKS = ApplicationServices AudioUnit Carbon CoreAudio IOKit 123 121 122 darwin_da : FWKS += DiskArbitration 123 124 124 # The following trick is tidier, and shortens the command line, but it 125 125 # depends on the shell expanding Csh-style braces. Luckily, Bash & Zsh do. 126 126 FC = $$join(FWKS,",","{","}") 127 127 128 128 QMAKE_CXXFLAGS += -F/System/Library/Frameworks/$${FC}.framework/Frameworks 129 129 LIBS += -framework $$join(FWKS," -framework ") 130 131 # There is a dependence on some stuff in libmythui and libmythupnp.132 # It isn't built yet, so we have to ignore these for now:133 QMAKE_LFLAGS_SHLIB += -flat_namespace -undefined warning134 135 QMAKE_LFLAGS_SHLIB += -seg1addr 0xC6000000136 130 } 137 131 138 132 linux { -
mythtv/libs/libmyth/backendselect.h
1 #ifndef __BACKENDSELECT_H__2 #define __BACKENDSELECT_H__3 4 #include "mythdialogs.h"5 #include "mythwidgets.h"6 7 #include "libmythupnp/upnpdevice.h"8 9 class ListBoxDevice : public QListBoxText10 {11 public:12 13 ListBoxDevice(QListBox *list, const QString &name, DeviceLocation *dev)14 : QListBoxText(list, name)15 {16 if ((m_dev = dev) != NULL)17 m_dev->AddRef();18 }19 20 virtual ~ListBoxDevice()21 {22 if (m_dev != NULL)23 m_dev->Release();24 }25 26 DeviceLocation *m_dev;27 };28 29 typedef QMap< QString, ListBoxDevice *> ItemMap;30 31 32 class BackendSelect : public MythDialog33 {34 Q_OBJECT35 36 public:37 BackendSelect(MythMainWindow *parent, DatabaseParams *params);38 virtual ~BackendSelect();39 40 void customEvent(QCustomEvent *e);41 42 QString m_PIN;43 QString m_USN;44 45 46 public slots:47 48 void Accept (void); ///< Linked to the OK button49 void Manual (void); ///< Linked to 'Configure Manually' button50 //void Search (void);51 52 53 protected:54 55 void AddItem (DeviceLocation *dev);56 bool Connect (DeviceLocation *dev);57 void CreateUI (void);58 void FillListBox(void);59 void RemoveItem (QString URN);60 61 DatabaseParams *m_DBparams;62 ItemMap m_devices;63 MythMainWindow *m_parent;64 MythListBox *m_backends;65 };66 67 #endif -
mythtv/libs/libmyth/virtualkeyboard.cpp
230 230 { 231 231 bool handled = false; 232 232 QStringList actions; 233 if (gContext-> GetMainWindow()->TranslateKeyPress("qt", e, actions, false))233 if (gContext->TranslateKeyPress("qt", e, actions, false)) 234 234 { 235 235 for (unsigned int i = 0; i < actions.size() && !handled; i++) 236 236 { -
mythtv/libs/libmyth/backendselect.cpp
1 /**2 * \class BackendSelect3 * \desc Classes to Prompt user for a master backend.4 *5 * \author Originally based on masterselection.cpp/h by David Blain.6 */7 8 #include "backendselect.h"9 #include "mythdialogs.h"10 #include "mythconfigdialogs.h"11 12 #include "libmythupnp/mythxmlclient.h"13 14 15 BackendSelect::BackendSelect(MythMainWindow *parent, DatabaseParams *params)16 : MythDialog(parent, "BackEnd Selection", TRUE)17 {18 m_parent = parent;19 m_DBparams = params;20 21 CreateUI();22 23 UPnp::AddListener(this);24 25 FillListBox();26 27 m_backends->setFocus();28 }29 30 BackendSelect::~BackendSelect()31 {32 UPnp::RemoveListener(this);33 34 ItemMap::iterator it;35 for (it = m_devices.begin(); it != m_devices.end(); ++it)36 {37 ListBoxDevice *item = it.data();38 39 if (item != NULL)40 delete item;41 }42 43 m_devices.clear();44 }45 46 void BackendSelect::Accept(void)47 {48 DeviceLocation *dev;49 QListBoxItem *selected = m_backends->selectedItem();50 51 if (!selected)52 return;53 54 dev = ((ListBoxDevice *)selected)->m_dev;55 56 if (!dev)57 reject();58 59 dev->AddRef();60 if (Connect(dev))61 accept();62 }63 64 void BackendSelect::AddItem(DeviceLocation *dev)65 {66 if (!dev)67 return;68 69 QString USN = dev->m_sUSN;70 71 // The devices' USN should be unique. Don't add if it is already there:72 if (m_devices.find(USN) == m_devices.end())73 {74 ListBoxDevice *item;75 QString name;76 77 if (print_verbose_messages & VB_UPNP)78 name = dev->GetNameAndDetails(true);79 else80 name = dev->GetFriendlyName(true);81 82 item = new ListBoxDevice(m_backends, name, dev);83 m_devices.insert(USN, item);84 85 // Pre-select at least one item:86 if (m_backends->numRows() == 1)87 m_backends->setSelected(0, true);88 }89 90 dev->Release();91 }92 93 /**94 * Attempt UPnP connection to a backend device, get its DB details.95 * Will loop until a valid PIN is entered.96 */97 bool BackendSelect::Connect(DeviceLocation *dev)98 {99 QString error;100 QString message;101 UPnPResultCode stat;102 MythXMLClient *xml;103 104 m_USN = dev->m_sUSN;105 xml = new MythXMLClient(dev->m_sLocation);106 stat = xml->GetConnectionInfo(m_PIN, m_DBparams, message);107 error = dev->GetFriendlyName(true);108 if (error == "<Unknown>")109 error = dev->m_sLocation;110 error += ". " + message;111 dev->Release();112 113 switch (stat)114 {115 case UPnPResult_Success:116 VERBOSE(VB_UPNP, "Connect() - success. New hostname: "117 + m_DBparams->dbHostName);118 return true;119 120 case UPnPResult_HumanInterventionRequired:121 VERBOSE(VB_UPNP, error);122 MythPopupBox::showOkPopup(m_parent, "", tr(message));123 break;124 125 case UPnPResult_ActionNotAuthorized:126 VERBOSE(VB_UPNP, "Access denied for " + error + ". Wrong PIN?");127 message = "Please enter the backend access PIN";128 do129 {130 m_PIN = MythPopupBox::showPasswordPopup(131 m_parent, "Backend PIN entry", tr(message));132 stat = xml->GetConnectionInfo(m_PIN, m_DBparams, message);133 }134 while (stat == UPnPResult_ActionNotAuthorized);135 if (stat == UPnPResult_Success)136 return true;137 138 default:139 VERBOSE(VB_UPNP, "GetConnectionInfo() failed for " + error);140 MythPopupBox::showOkPopup(m_parent, "", tr(message));141 }142 143 // Back to the list, so the user can choose a different backend:144 m_backends->setFocus();145 return false;146 }147 148 void BackendSelect::CreateUI(void)149 {150 // Probably should all be members, and deleted by ~BackendSelect()151 QLabel *label;152 QGridLayout *layout;153 MythPushButton *cancel;154 MythPushButton *manual;155 MythPushButton *OK;156 //MythPushButton *search; // I don't see the need for this?157 158 159 label = new QLabel(tr("Please select default Myth Backend Server"), this);160 label->setBackgroundOrigin(QWidget::WindowOrigin);161 162 m_backends = new MythListBox(this);163 OK = new MythPushButton(tr("OK"), this);164 cancel = new MythPushButton(tr("Cancel"), this);165 manual = new MythPushButton(tr("Configure Manually"), this);166 //search = new MythPushButton(tr("Search"), this);167 168 169 layout = new QGridLayout(this, 5, 5, 40);170 layout->addMultiCellWidget(label, 0, 0, 1, 3);171 layout->addMultiCellWidget(m_backends, 1, 1, 0, 4);172 173 layout->addMultiCellWidget(manual, 4, 4, 0, 1);174 //layout->addWidget(search, 4, 0);175 //layout->addWidget(manual, 4, 1);176 layout->addWidget(cancel, 4, 3);177 layout->addWidget(OK , 4, 4);178 179 180 connect(m_backends, SIGNAL(accepted(int)), SLOT(Accept()));181 //connect(search, SIGNAL(clicked()), SLOT(Search()));182 connect(manual, SIGNAL(clicked()), SLOT(Manual()));183 connect(cancel, SIGNAL(clicked()), SLOT(reject()));184 connect(OK, SIGNAL(clicked()), SLOT(Accept()));185 }186 187 void BackendSelect::customEvent(QCustomEvent *e)188 {189 if (MythEvent::MythEventMessage != ((MythEvent::Type)(e->type())))190 return;191 192 193 MythEvent *me = (MythEvent *)e;194 QString message = me->Message();195 QString URI = me->ExtraData(0);196 QString URN = me->ExtraData(1);197 QString URL = me->ExtraData(2);198 199 200 VERBOSE(VB_UPNP, "BackendSelect::customEvent(" + message201 + ", " + URI + ", " + URN + ", " + URL + ")");202 203 if (message.startsWith("SSDP_ADD") &&204 URI.startsWith("urn:schemas-mythtv-org:device:MasterMediaServer:"))205 {206 DeviceLocation *devLoc = UPnp::g_SSDPCache.Find(URI, URN);207 208 if (devLoc != NULL)209 {210 devLoc->AddRef();211 AddItem(devLoc);212 }213 }214 else if (message.startsWith("SSDP_REMOVE"))215 {216 //-=>Note: This code will never get executed until217 // SSDPCache is changed to handle NotifyRemove correctly218 RemoveItem(URN);219 }220 }221 222 void BackendSelect::FillListBox(void)223 {224 EntryMap::Iterator it;225 EntryMap ourMap;226 DeviceLocation *pDevLoc;227 228 229 SSDPCacheEntries *pEntries = UPnp::g_SSDPCache.Find(gBackendURI);230 231 if (!pEntries)232 return;233 234 pEntries->AddRef();235 pEntries->Lock();236 237 EntryMap *pMap = pEntries->GetEntryMap();238 239 for (it = pMap->begin(); it != pMap->end(); ++it)240 {241 pDevLoc = (DeviceLocation *)it.data();242 243 if (!pDevLoc)244 continue;245 246 pDevLoc->AddRef();247 ourMap.insert(pDevLoc->m_sUSN, pDevLoc);248 }249 250 251 pEntries->Unlock();252 pEntries->Release();253 254 for (it = ourMap.begin(); it != ourMap.end(); ++it)255 {256 pDevLoc = (DeviceLocation *)it.data();257 AddItem(pDevLoc);258 pDevLoc->Release();259 }260 }261 262 void BackendSelect::Manual(void)263 {264 done(kDialogCodeButton0);265 }266 267 void BackendSelect::RemoveItem(QString USN)268 {269 ItemMap::iterator it = m_devices.find(USN);270 271 if (it != m_devices.end())272 {273 ListBoxDevice *item = it.data();274 275 if (item != NULL)276 delete item;277 278 m_devices.remove(it);279 }280 }281 282 //void BackendSelect::Search(void)283 //{284 // UPnp::PerformSearch(gBackendURI);285 //} -
mythtv/libs/libmythupnp/upnp.cpp
17 17 // Global/Class Static variables 18 18 ////////////////////////////////////////////////////////////////////////////// 19 19 20 const QString UPnp::kBackendURI 21 = "urn:schemas-mythtv-org:device:MasterMediaServer:1"; 22 const QString UPnp::kDefaultPIN 23 = "UPnP/MythFrontend/DefaultBackend/SecurityPin"; 24 const QString UPnp::kDefaultUSN 25 = "UPnP/MythFrontend/DefaultBackend/USN"; 26 27 20 28 UPnpDeviceDesc UPnp::g_UPnpDeviceDesc; 21 29 TaskQueue *UPnp::g_pTaskQueue = NULL; 22 30 SSDP *UPnp::g_pSSDP = NULL; -
mythtv/libs/libmythupnp/libmythupnp.pro
46 46 target.path = $${PREFIX}/bin 47 47 } 48 48 49 inc.path = $${PREFIX}/include/mythtv/ upnp/49 inc.path = $${PREFIX}/include/mythtv/libmythupnp/ 50 50 51 51 inc.files = httprequest.h upnp.h ssdp.h taskqueue.h bufferedsocketdevice.h 52 52 inc.files += upnpdevice.h upnptasknotify.h upnptasksearch.h threadpool.h upnputil.h 53 53 inc.files += httpserver.h httpstatus.h upnpcds.h upnpcdsobjects.h 54 54 inc.files += eventing.h upnpcmgr.h upnptaskevent.h upnptaskcache.h ssdpcache.h 55 55 inc.files += upnpimpl.h multicast.h broadcast.h configuration.h 56 inc.files += soapclient.h mythxmlclient.h 56 inc.files += soapclient.h mythxmlclient.h refcounted.h 57 57 58 58 INSTALLS += inc 59 59 … … 63 63 freebsd:HEADERS += darwin-sendfile.h 64 64 freebsd:SOURCES += darwin-sendfile.c 65 65 66 macx { 67 HEADERS += darwin-sendfile.h 68 SOURCES += darwin-sendfile.c 69 70 # This lib depends on libmyth which depends on some stuff in libmythui. 71 # It isn't built yet, so we have to ignore these for now: 72 QMAKE_LFLAGS_SHLIB += -flat_namespace -undefined warning 73 } 66 macx:HEADERS += darwin-sendfile.h 67 macx:SOURCES += darwin-sendfile.c -
mythtv/libs/libmythupnp/upnp.h
99 99 int m_nServicePort; 100 100 101 101 public: 102 // Some common UPnP search and XML value strings: 102 103 104 /// Service type for the backend's UPnP server 105 static const QString kBackendURI; 106 107 // PIN and Unique Service Name of the default backend. 108 // Stored in config.xml: 109 static const QString kDefaultPIN; 110 static const QString kDefaultUSN; 111 112 113 103 114 static Configuration *g_pConfig; 104 115 105 116 static UPnpDeviceDesc g_UPnpDeviceDesc; -
mythtv/programs/mythuitest/main.cpp
5 5 #include <cstdlib> 6 6 using namespace std; 7 7 8 #include "mythmainwindow.h" 9 #include "mythuiimage.h" 10 #include "mythscreenstack.h" 11 #include "mythscreentype.h" 12 #include "myththemebase.h" 8 #include "libmythui/mythmainwindow.h" 9 #include "libmythui/mythuiimage.h" 10 #include "libmythui/mythscreenstack.h" 11 #include "libmythui/mythscreentype.h" 12 #include "libmythui/myththemebase.h" 13 #include "libmythtv/mythcontextui.h" 13 14 14 #include "mythcontext.h"15 16 15 #include "test1.h" 17 #include " oldsettings.h"16 #include "libmyth/oldsettings.h" 18 17 //#include "btnlisttest.h" 19 18 20 19 int main(int argc, char *argv[]) 21 20 { 22 21 QApplication a(argc, argv); 23 22 24 gContext = NULL; 25 gContext = new MythContext(MYTH_BINARY_VERSION); 23 gContext = (MythContext *) new MythContextGUI(MYTH_BINARY_VERSION); 26 24 gContext->Init(); 27 25 28 26 QString themename = gContext->GetSetting("Theme"); -
mythtv/programs/programs-libs.pro
10 10 LIBS += -L../../libs/libmythupnp 11 11 LIBS += -L../../libs/libmythlivemedia 12 12 13 LIBS += -lmyth tv-$$LIBVERSION -lmythavformat-$$LIBVERSION13 LIBS += -lmyth-$$LIBVERSION -lmythtv-$$LIBVERSION -lmythavformat-$$LIBVERSION 14 14 LIBS += -lmythavutil-$$LIBVERSION -lmythavcodec-$$LIBVERSION 15 15 LIBS += -lmythfreemheg-$$LIBVERSION 16 LIBS += -lmythui-$$LIBVERSION 16 17 LIBS += -lmythupnp-$$LIBVERSION 17 18 LIBS += -lmythlivemedia-$$LIBVERSION 18 LIBS += -lmyth -$$LIBVERSION -lmythui-$$LIBVERSION $$EXTRA_LIBS19 LIBS += -lmythui-$$LIBVERSION $$EXTRA_LIBS 19 20 mingw { 20 21 LIBS += -lpthread 21 22 CONFIG += console -
mythtv/programs/mythfrontend/globalsettings.cpp
22 22 #include "libmyth/mythconfig.h" 23 23 #include "libmyth/mythcontext.h" 24 24 #include "libmyth/mythdbcon.h" 25 #include "libmyth /dbsettings.h"25 #include "libmythtv/dbsettings.h" 26 26 #include "libmyth/langsettings.h" 27 27 #include "libmythtv/mpeg/iso639.h" 28 28 #include "playbackbox.h" -
mythtv/programs/mythfrontend/main.cpp
51 51 #include "lcddevice.h" 52 52 #include "langsettings.h" 53 53 54 #include "libmythtv/mythcontextui.h" 54 55 #include "libmythui/myththemedmenu.h" 55 56 #include "libmythui/myththemebase.h" 56 57 #include "mediarenderer.h" … … 1067 1068 MythContext::SetX11Display(display); 1068 1069 } 1069 1070 1070 gContext = new MythContext(MYTH_BINARY_VERSION);1071 MythContextGUI * context = new MythContextGUI(MYTH_BINARY_VERSION); 1071 1072 g_pUPnp = new MediaRenderer(); 1072 1073 1073 if (! gContext->Init(true,g_pUPnp, bPromptForBackend, bBypassAutoDiscovery))1074 if (!context->Init(g_pUPnp, bPromptForBackend, bBypassAutoDiscovery)) 1074 1075 { 1075 1076 VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting."); 1076 1077 return FRONTEND_EXIT_NO_MYTHCONTEXT; … … 1326 1327 return FRONTEND_EXIT_NO_THEME; 1327 1328 } 1328 1329 1329 gContext->LoadQtConfig();1330 MythMainWindow *mainWindow = gContext->CreateMainWindow(); 1330 1331 1331 MythMainWindow *mainWindow = GetMythMainWindow();1332 mainWindow->Init();1333 gContext->SetMainWindow(mainWindow);1334 1335 1332 gContext->UpdateImageCache(); 1336 1333 themeBase = new MythThemeBase(); 1337 1334 -
mythtv/programs/mythjobqueue/main.cpp
18 18 #include "libmyth/mythcontext.h" 19 19 #include "libmythtv/jobqueue.h" 20 20 #include "libmyth/mythdbcon.h" 21 #include "libmythtv/mythcontextui.h" 21 22 22 23 using namespace std; 23 24 … … 103 104 ++argpos; 104 105 } 105 106 106 gContext = NULL; 107 gContext = new MythContext(MYTH_BINARY_VERSION); 108 if (!gContext->Init(false)) 107 MythContextTTY *context = new MythContextTTY(MYTH_BINARY_VERSION); 108 if (!context->Init(NULL)) 109 109 { 110 110 VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting."); 111 111 return JOBQUEUE_EXIT_NO_MYTHCONTEXT; -
mythtv/programs/mythtranscode/main.cpp
14 14 #include <fstream> 15 15 using namespace std; 16 16 17 #include "exitcodes.h" 18 #include "programinfo.h" 19 #include "jobqueue.h" 20 #include "mythcontext.h" 21 #include "mythdbcon.h" 17 #include "libmyth/exitcodes.h" 18 #include "libmythtv/programinfo.h" 19 #include "libmythtv/jobqueue.h" 20 #include "libmyth/mythcontext.h" 21 #include "libmyth/mythdbcon.h" 22 #include "libmythtv/mythcontextui.h" 22 23 #include "transcode.h" 23 24 #include "mpeg2fix.h" 24 25 … … 396 397 } 397 398 398 399 // Load the context 399 gContext = NULL; 400 gContext = new MythContext(MYTH_BINARY_VERSION); 401 if (!gContext->Init(false)) 400 MythContextTTY *context = new MythContextTTY(MYTH_BINARY_VERSION); 401 if (!context->Init(NULL)) 402 402 { 403 403 VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting."); 404 404 return TRANSCODE_EXIT_NO_MYTHCONTEXT; -
mythtv/programs/mythcommflag/main.cpp
23 23 #include "libmythtv/jobqueue.h" 24 24 #include "libmythtv/remoteencoder.h" 25 25 #include "libmyth/mythdbcon.h" 26 #include "libmythtv/mythcontextui.h" 26 27 27 28 #include "CommDetector.h" 28 29 #include "CommDetectorBase.h" … … 922 923 ++argpos; 923 924 } 924 925 925 gContext = NULL; 926 gContext = new MythContext(MYTH_BINARY_VERSION); 927 if (!gContext->Init(false)) 926 MythContextTTY * context = new MythContextTTY(MYTH_BINARY_VERSION); 927 if (!context->Init(NULL)) 928 928 { 929 929 VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting."); 930 930 return COMMFLAG_EXIT_NO_MYTHCONTEXT; -
mythtv/programs/mythbackend/mythxml.cpp
1476 1476 return; 1477 1477 } 1478 1478 1479 DatabaseParams params = g Context->GetDatabaseParams();1479 DatabaseParams params = gDBparams; 1480 1480 1481 1481 // Check for DBHostName of "localhost" and change to public name or IP 1482 1482 -
mythtv/programs/mythbackend/main.cpp
41 41 #include "libmythtv/jobqueue.h" 42 42 #include "libmythtv/storagegroup.h" 43 43 #include "libmythtv/previewgenerator.h" 44 #include "libmythtv/mythcontextui.h" 44 45 45 46 #include "mediaserver.h" 46 47 #include "httpstatus.h" … … 741 742 pidfs.close(); 742 743 } 743 744 744 gContext = NULL; 745 gContext = new MythContext(MYTH_BINARY_VERSION); 746 if (!gContext->Init(false)) 745 MythContextTTY * context = new MythContextTTY(MYTH_BINARY_VERSION); 746 if (!context->Init(NULL)) 747 747 { 748 748 VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting."); 749 749 return BACKEND_EXIT_NO_MYTHCONTEXT; -
mythtv/programs/mythtv-setup/main.cpp
23 23 #include "libmyth/dialogbox.h" 24 24 #include "libmyth/exitcodes.h" 25 25 #include "libmyth/util.h" 26 #include "libmythtv/mythcontextui.h" 26 27 #include "libmythui/myththemedmenu.h" 27 28 #include "libmythui/myththemebase.h" 28 29 … … 240 241 MythContext::SetX11Display(display); 241 242 } 242 243 243 gContext = NULL; 244 gContext = new MythContext(MYTH_BINARY_VERSION); 245 246 if (!gContext->Init(true)) 244 MythContextGUI *context = new MythContextGUI(MYTH_BINARY_VERSION); 245 if (!context->Init()) 247 246 { 248 247 VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting."); 249 248 return -1; … … 279 278 UpgradeTVDatabaseSchema(); 280 279 281 280 gContext->SetSetting("Theme", "G.A.N.T"); 282 gContext->LoadQtConfig();283 281 284 282 QString fileprefix = MythContext::GetConfDir(); 285 283 … … 287 285 if (!dir.exists()) 288 286 dir.mkdir(fileprefix); 289 287 290 MythMainWindow *mainWindow = GetMythMainWindow(); 291 mainWindow->Init(); 292 gContext->SetMainWindow(mainWindow); 288 MythMainWindow *mainWindow = context->CreateMainWindow(); 293 289 294 290 gContext->UpdateImageCache(); 295 291 MythThemeBase *themeBase = new MythThemeBase(); -
mythtv/programs/mythlcdserver/main.cpp
16 16 #include <fcntl.h> 17 17 #include <signal.h> 18 18 19 #include "exitcodes.h" 20 #include "mythcontext.h" 21 #include "mythdbcon.h" 22 #include "tv_play.h" 19 #include "libmyth/exitcodes.h" 20 #include "libmyth/mythcontext.h" 21 #include "libmyth/mythdbcon.h" 22 #include "libmythtv/tv_play.h" 23 #include "libmythtv/mythcontextui.h" 23 24 #include "compat.h" 24 25 25 26 #include "lcdserver.h" … … 229 230 } 230 231 231 232 // Get the Myth context and db hooks 232 gContext = NULL; 233 gContext = new MythContext(MYTH_BINARY_VERSION); 234 if (!gContext->Init(false)) 233 MythContextTTY *context = new MythContextTTY(MYTH_BINARY_VERSION); 234 if (!context->Init(NULL)) 235 235 { 236 236 VERBOSE(VB_IMPORTANT, "lcdserver: Could not initialize myth context. " 237 237 "Exiting."); -
mythtv/programs/mythtv/main.cpp
6 6 #include <qregexp.h> 7 7 #include <qdir.h> 8 8 9 #include " tv_play.h"10 #include " programinfo.h"9 #include "libmythtv/tv_play.h" 10 #include "libmythtv/programinfo.h" 11 11 12 12 #include "libmyth/exitcodes.h" 13 13 #include "libmyth/mythcontext.h" 14 14 #include "libmyth/mythdbcon.h" 15 15 #include "libmyth/mythdialogs.h" 16 16 #include "libmyth/compat.h" 17 #include "libmythtv/mythcontextui.h" 17 18 18 19 #include <iostream> 19 20 using namespace std; … … 200 201 gContext->SetX11Display(display); 201 202 } 202 203 203 gContext = NULL; 204 gContext = new MythContext(MYTH_BINARY_VERSION); 205 if (!gContext->Init()) 204 MythContextGUI *context = new MythContextGUI(MYTH_BINARY_VERSION); 205 if (!context->Init()) 206 206 { 207 207 VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting."); 208 208 return TV_EXIT_NO_MYTHCONTEXT; … … 249 249 return TV_EXIT_NO_THEME; 250 250 } 251 251 252 gContext->LoadQtConfig();253 254 252 #if defined(Q_OS_MACX) 255 253 // Mac OS X doesn't define the AudioOutputDevice setting 256 254 #else … … 263 261 } 264 262 #endif 265 263 266 MythMainWindow *mainWindow = GetMythMainWindow(); 267 mainWindow->Init(); 268 gContext->SetMainWindow(mainWindow); 264 context->CreateMainWindow(); 269 265 270 266 TV::InitKeys(); 271 267 -
mythtv/programs/mythwelcome/main.cpp
14 14 #include "libmyth/compat.h" 15 15 16 16 #include "libmythtv/tv.h" 17 #include "libmythtv/mythcontextui.h" 17 18 18 19 #include "welcomedialog.h" 19 20 #include "welcomesettings.h" … … 38 39 39 40 QApplication a(argc, argv); 40 41 41 gContext = NULL; 42 gContext = new MythContext(MYTH_BINARY_VERSION); 42 gContext = (MythContext *) new MythContextGUI(MYTH_BINARY_VERSION); 43 43 if (!gContext->Init(false)) 44 44 { 45 45 VERBOSE(VB_IMPORTANT, "mythwelcome: Could not initialize myth context. " … … 122 122 123 123 LanguageSettings::load("mythfrontend"); 124 124 125 gContext->LoadQtConfig();125 MythMainWindow *mainWindow = gContext->CreateMainWindow(); 126 126 127 MythMainWindow *mainWindow = GetMythMainWindow();128 mainWindow->Init();129 gContext->SetMainWindow(mainWindow);130 131 127 initKeys(); 132 128 133 129 if (bShowSettings) -
mythtv/programs/mythfilldatabase/main.cpp
22 22 // filldata headers 23 23 #include "filldata.h" 24 24 25 26 #include "libmythtv/mythcontextui.h" 27 25 28 int main(int argc, char *argv[]) 26 29 { 27 30 QApplication a(argc, argv, false); … … 471 474 ++argpos; 472 475 } 473 476 474 gContext = NULL; 475 gContext = new MythContext(MYTH_BINARY_VERSION); 476 if (!gContext->Init(false)) 477 MythContextTTY *context = new MythContextTTY(MYTH_BINARY_VERSION); 478 if (!context->Init(NULL)) 477 479 { 478 480 VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting."); 479 481 return FILLDB_EXIT_NO_MYTHCONTEXT; -
mythtv/programs/mythshutdown/main.cpp
7 7 using namespace std; 8 8 #include <unistd.h> 9 9 10 #include <exitcodes.h>11 #include <mythcontext.h>12 #include <mythdbcon.h>10 #include "libmyth/exitcodes.h" 11 #include "libmyth/mythcontext.h" 12 #include "libmyth/mythdbcon.h" 13 13 #include "libmythtv/programinfo.h" 14 14 #include "libmythtv/jobqueue.h" 15 #include "tv.h" 16 #include "remoteutil.h" 17 #include "compat.h" 15 #include "libmythtv/tv.h" 16 #include "libmythtv/remoteutil.h" 17 #include "libmythtv/mythcontextui.h" 18 #include "libmyth/compat.h" 18 19 19 20 void setGlobalSetting(const QString &key, const QString &value) 20 21 { … … 712 713 713 714 QApplication a(argc, argv, false); 714 715 715 gContext = NULL; 716 gContext = new MythContext(MYTH_BINARY_VERSION); 717 if (!gContext->Init(false)) 716 MythContextTTY *context = new MythContextTTY(MYTH_BINARY_VERSION); 717 if (!context->Init(NULL)) 718 718 { 719 719 cout << "mythshutdown: Could not initialize myth context. " 720 720 "Exiting." << endl; -
mythplugins/programs-libs.pro
1 1 INCLUDEPATH += $${PREFIX}/include/mythtv 2 2 3 3 LIBS += -L$${PREFIX}/lib $$EXTRA_LIBS 4 LIBS += -lmyth-$$LIBVERSION -lmythui-$$LIBVERSION -lmythupnp-$$LIBVERSION5 4 5 # To initialise the MythContext subclass, we now need all these libraries. 6 LIBS += -lmythavcodec-$$LIBVERSION -lmythavutil-$$LIBVERSION 7 LIBS += -lmythavformat-$$LIBVERSION 8 LIBS += -lmythfreemheg-$$LIBVERSION -lmythlivemedia-$$LIBVERSION 9 LIBS += -lmythupnp-$$LIBVERSION -lmythtv-$$LIBVERSION 10 6 11 mac:using_firewire:using_backend:LIBS += -F$${CONFIG_MAC_AVC} -framework AVCVideoServices -
mythplugins/mytharchive/mytharchivehelper/main.cpp
29 29 #include <mythtv/exitcodes.h> 30 30 #include <mythtv/mythdbcon.h> 31 31 #include <mythtv/libmythtv/programinfo.h> 32 #include <mythtv/libmythtv/mythcontextui.h> 32 33 extern "C" { 33 34 #include <mythtv/ffmpeg/avcodec.h> 34 35 #include <mythtv/ffmpeg/avformat.h> … … 2249 2250 2250 2251 int getDBParamters(QString outFile) 2251 2252 { 2252 DatabaseParams params = g Context->GetDatabaseParams();2253 DatabaseParams params = gDBparams; 2253 2254 2254 2255 // save the db paramters to the file 2255 2256 QFile f(outFile); … … 2353 2354 2354 2355 QApplication a(argc, argv, false); 2355 2356 2356 gContext = NULL; 2357 gContext = new MythContext(MYTH_BINARY_VERSION); 2358 if (!gContext->Init(false)) 2357 MythContextTTY * context = new MythContextTTY(MYTH_BINARY_VERSION); 2358 if (!context->Init(false)) 2359 2359 { 2360 2360 cout << "mytharchivehelper: Could not initialize myth context. " 2361 2361 "Exiting." << endl;; -
mythplugins/mythbrowser/mythbrowser/main.cpp
21 21 #include "mythtv/mythcontext.h" 22 22 #include "mythtv/mythdbcon.h" 23 23 #include "mythtv/langsettings.h" 24 #include "libmythtv/mythcontextui.h" 24 25 25 26 26 27 static const char *version = "v0.32"; … … 94 95 95 96 KApplication a(argc,argv); 96 97 97 gContext = NULL; 98 gContext = new MythContext(MYTH_BINARY_VERSION); 99 if (!gContext->Init(true)) 98 gContext = (MythContext *) new MythContextGUI(MYTH_BINARY_VERSION); 99 if (!gContext->Init()) 100 100 { 101 101 VERBOSE(VB_IMPORTANT, "MythBrowser: Could not initialize myth context. Exiting."); 102 102 return FRONTEND_EXIT_NO_MYTHCONTEXT; … … 122 122 123 123 LanguageSettings::load("mythbrowser"); 124 124 125 gContext->LoadQtConfig(); 125 MythMainWindow *mainWindow = gContext->CreateMainWindow(); 126 126 127 setupKeys(); 127 128 128 MythMainWindow *mainWindow = GetMythMainWindow();129 mainWindow->Init();130 gContext->SetMainWindow(mainWindow);131 132 129 TabView *tabView = 133 130 new TabView(mainWindow, "mythbrowser", urls, zoom, width, height, 134 131 Qt::WStyle_Customize | Qt::WStyle_NoBorder); -
mythplugins/mythvideo/mtd/main.cpp
20 20 #include <mythtv/mythdbcon.h> 21 21 #include <mythtv/langsettings.h> 22 22 #include <mythtv/compat.h> 23 #include <mythtv/libmythtv/mythcontextui.h> 23 24 24 25 #include "../mythvideo/dbcheck.h" 25 26 #include "mtd.h" … … 112 113 // 113 114 // Get the Myth context and db hooks 114 115 // 115 116 gContext = NULL; 117 gContext = new MythContext(MYTH_BINARY_VERSION); 118 if (!gContext->Init(false)) 116 117 MythContextTTY * context = new MythContextTTY(MYTH_BINARY_VERSION); 118 if (!context->Init(false)) 119 119 { 120 120 cerr << "Could not initialize myth context. Exiting." << endl; 121 121 return FRONTEND_EXIT_NO_MYTHCONTEXT;