Ticket #4264: ctxrestr.9.patch

File ctxrestr.9.patch, 168.4 KB (added by Nigel, 18 years ago)

Patch against r15462

  • 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
     7class MythDbSettings1: public VerticalConfigurationGroup {
     8public:
     9    MythDbSettings1(const QString &DBhostOverride = QString::null);
     10
     11    void load();
     12    void save();
     13
     14protected:
     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
     27class MythDbSettings2: public VerticalConfigurationGroup {
     28public:
     29    MythDbSettings2();
     30
     31    void load();
     32    void save();
     33
     34protected:
     35    TransCheckBoxSetting *localEnabled;
     36    TransLineEditSetting *localHostName;
     37    TransCheckBoxSetting *wolEnabled;
     38    TransSpinBoxSetting  *wolReconnect;
     39    TransSpinBoxSetting  *wolRetry;
     40    TransLineEditSetting *wolCommand;
     41};
     42
     43
     44
     45class 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
     60class 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
     76MythDbSettings1::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
     162MythDbSettings2::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
     232void 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
     270void 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
     281void 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
     294void 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
     307DatabaseSettings::DatabaseSettings(const QString &DBhostOverride)
     308{
     309    addChild(new MythDbSettings1(DBhostOverride));
     310    addChild(new MythDbSettings2());
     311}
     312
     313void DatabaseSettings::addDatabaseSettings(ConfigurationWizard *wizard)
     314{
     315    wizard->addChild(new MythDbSettings1());
     316    wizard->addChild(new MythDbSettings2());
     317}
  • mythtv/libs/libmythtv/libmythtv.pro

     
    2727DEPENDPATH  += ../libmythlivemedia/UsageEnvironment/include
    2828DEPENDPATH  += ../libmythlivemedia/UsageEnvironment
    2929
    30 LIBS += -L../libmyth -L../libavutil -L../libavcodec -L../libavformat
     30LIBS += -L../libmyth -L../libmythupnp -L../libmythui
     31LIBS += -L../libavutil -L../libavcodec -L../libavformat
    3132LIBS += -L../libmythmpeg2 -L../libmythdvdnav
    3233LIBS += -L../libmythfreemheg -L../libmythlivemedia
    33 LIBS += -lmyth-$${LIBVERSION} -lmythavutil-$${LIBVERSION}
     34LIBS += -lmyth-$${LIBVERSION} -lmythupnp-$${LIBVERSION} -lmythui-$${LIBVERSION}
     35LIBS += -lmythavutil-$${LIBVERSION}
    3436LIBS += -lmythavcodec-$${LIBVERSION} -lmythdvdnav-$${LIBVERSION}
    3537LIBS += -lmythavformat-$${LIBVERSION} -lmythmpeg2-$${LIBVERSION}
    3638LIBS += -lmythfreemheg-$${LIBVERSION} -lmythlivemedia-$${LIBVERSION}
    3739LIBS += $$EXTRA_LIBS
    3840
    3941TARGETDEPS += ../libmyth/libmyth-$${MYTH_SHLIB_EXT}
     42TARGETDEPS += ../libmythupnp/libmythupnp-$${MYTH_SHLIB_EXT}
     43TARGETDEPS += ../libmythui/libmythui-$${MYTH_SHLIB_EXT}
    4044TARGETDEPS += ../libavutil/libmythavutil-$${MYTH_SHLIB_EXT}
    4145TARGETDEPS += ../libavcodec/libmythavcodec-$${MYTH_SHLIB_EXT}
    4246TARGETDEPS += ../libavformat/libmythavformat-$${MYTH_SHLIB_EXT}
     
    7882        # DVDUtils uses Objective-C++, activated by .mm suffix
    7983        QMAKE_EXT_CPP += .mm
    8084    }
    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 warning
    85     #LIBS += -lmythui-$${LIBVERSION} -L../libmythui
    86 
    87     QMAKE_LFLAGS_SHLIB += -seg1addr 0xC9000000
    8885}
    8986
    9087cygwin:QMAKE_LFLAGS_SHLIB += -Wl,--noinhibit-exec
     
    142139HEADERS += channeleditor.h          channelsettings.h
    143140HEADERS += previewgenerator.h       transporteditor.h
    144141HEADERS += importicons.h
     142HEADERS += backendselect.h          dbsettings.h
     143HEADERS += mythcontextui.h
    145144
    146145SOURCES += programinfo.cpp          proglist.cpp
    147146SOURCES += storagegroup.cpp
     
    165164SOURCES += channeleditor.cpp        channelsettings.cpp
    166165SOURCES += previewgenerator.cpp     transporteditor.cpp
    167166SOURCES += importicons.cpp
     167SOURCES += backendselect.cpp        dbsettings.cpp
     168SOURCES += mythcontextui.cpp
    168169
    169170# DiSEqC
    170171HEADERS += diseqc.h                 diseqcsettings.h
     
    521522    POST_TARGETDEPS += libmythui-bootstrap.a
    522523}
    523524
    524 # install headers required by mytharchive
     525# install headers required by mytharchivehelper
    525526inc.path = $${PREFIX}/include/mythtv/libmythtv/
    526 inc.files = programinfo.h remoteutil.h recordingtypes.h
     527inc.files = mythcontextui.h programinfo.h remoteutil.h recordingtypes.h
    527528
    528529INSTALLS += 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
     10class 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
     30typedef QMap< QString, ListBoxDevice *> ItemMap;
     31
     32
     33class 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
     8class MythContextGUI;
     9class 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 
     18class 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 &current);
     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
     74class 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
     108class 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
     134MPUBLIC QString getResponse(const QString &query, const QString &def);
     135MPUBLIC 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
     6class MPUBLIC DatabaseSettings: public ConfigurationWizard {
     7public:
     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
     16MythContextUI::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
     31MythContextUI::~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 */
     46int MythContextUI::PromptForSchemaUpgrade(const QString &dbver,
     47                                          const QString &current)
     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 */
     239const 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 */
     268bool 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
     374DBfound:
     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
     388NoDBfound:
     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 */
     398const 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 */
     422void 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 */
     472bool 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 */
     504bool 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 */
     585bool 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 */
     628void 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 */
     654int 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 */
     723int 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 */
     798bool 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 */
     843bool 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 */
     878QString 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
     889MythContextGUI::MythContextGUI(const QString &binVersion)
     890              : MythContextUI(this, binVersion) {}
     891
     892MythContextTTY::MythContextTTY(const QString &binVersion)
     893              : MythContextUI(NULL, binVersion) {}
     894
     895MythContextGUI::~MythContextGUI(void) {}
     896
     897MythContextTTY::~MythContextTTY(void) {}
     898
     899bool 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
     923bool 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
     941MythMainWindow * 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 */
     966MythMainWindow * 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
     1001void MythContextGUI::EndTempWindow(void)
     1002{
     1003    m_win = NULL;
     1004    SetMainWindow(NULL);
     1005    DestroyMythMainWindow();
     1006}
     1007
     1008bool 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
     1036QString 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
     1070int 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
     15BackendSelect::BackendSelect(MythMainWindow *parent, DatabaseParams *params)
     16             : MythDialog(parent, "BackEnd Selection", TRUE)
     17{
     18    m_parent   = parent;
     19    m_DBparams = params;
     20puts("Creating a backendSelect");
     21    CreateUI();
     22
     23    UPnp::AddListener(this);
     24
     25    //Search();
     26    FillListBox();
     27
     28    m_backends->setFocus();
     29}
     30
     31BackendSelect::~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
     47void 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
     65void 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 */
     98bool 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
     149void 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
     188void 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
     225void 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
     265void BackendSelect::Manual(void)
     266{
     267    done(kDialogCodeButton0);
     268}
     269
     270void 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
     285void BackendSelect::Search(void)
     286{
     287    UPnp::PerformSearch(UPnp::kBackendURI);
     288}
  • mythtv/libs/libmythui/mythmainwindow.cpp

     
    226226 *        If this is a temporary window, which is used to bootstrap
    227227 *        the database, passing false prevents any database access.
    228228 *
    229  * \sa    MythContextPrivate::TempMainWindow()
     229 * \sa    MythContextGUI::TempMainWindow()
    230230 */
    231231MythMainWindow *MythMainWindow::getMainWindow(const bool useDB)
    232232{
  • mythtv/libs/libmyth/mythdialogs.cpp

     
    7575        gContext->ThemeWidget(this);
    7676    }
    7777
    78     parent->attach(this);
     78    gContext->attachToWin(this);
    7979    m_parent = parent;
    8080}
    8181
     
    9595{
    9696    if (m_parent)
    9797    {
    98         m_parent->detach(this);
     98        gContext->detachFromWin(this);
    9999        m_parent = NULL;
    100100    }
    101101}
     
    214214    bool handled = false;
    215215    QStringList actions;
    216216
    217     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
     217    if (gContext->TranslateKeyPress("qt", e, actions))
    218218    {
    219219        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    220220        {
     
    509509{
    510510    bool handled = false;
    511511    QStringList actions;
    512     gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions);
     512    gContext->TranslateKeyPress("qt", e, actions);
    513513    for (unsigned int i = 0; i < actions.size() && !handled; i++)
    514514    {
    515515        QString action = actions[i];
     
    890890{
    891891    bool handled = false;
    892892    QStringList actions;
    893     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
     893    if (gContext->TranslateKeyPress("qt", e, actions))
    894894    {
    895895        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    896896        {
     
    17081708{
    17091709    bool handled = false;
    17101710    QStringList actions;
    1711     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
     1711    if (gContext->TranslateKeyPress("qt", e, actions))
    17121712    {
    17131713        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    17141714        {
     
    17701770{
    17711771    bool handled = false;
    17721772    QStringList actions;
    1773     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
     1773    if (gContext->TranslateKeyPress("qt", e, actions))
    17741774    {
    17751775        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    17761776        {
     
    19901990{
    19911991    bool handled = false;
    19921992    QStringList actions;
    1993     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
     1993    if (gContext->TranslateKeyPress("qt", e, actions))
    19941994    {
    19951995        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    19961996        {
     
    22542254    m_showRtArrow  = false;
    22552255    m_showLtArrow  = false;
    22562256   
    2257     m_parent->attach(this);
     2257    gContext->attachToWin(this);
    22582258}
    22592259
    22602260MythScrollDialog::~MythScrollDialog()
    22612261{
    2262     m_parent->detach(this);
     2262    gContext->detachFromWin(this);
    22632263    delete m_bgPixmap;
    22642264
    22652265    if (m_upArrowPix)
     
    23702370    bool handled = false;
    23712371    QStringList actions;
    23722372
    2373     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
     2373    if (gContext->TranslateKeyPress("qt", e, actions))
    23742374    {
    23752375        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    23762376        {
  • 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 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     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     else
    250         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

     
    6666    qt_delete(popup);
    6767
    6868    popup = new VirtualKeyboard(gContext->GetMainWindow(), this);
    69     gContext->GetMainWindow()->detach(popup);
     69    gContext->detachFromWin(popup);
    7070    popup->exec();
    7171
    7272    qt_delete(popup);
     
    7878    bool handled = false;
    7979    QStringList actions;
    8080    if ((!popup || !popup->isShown()) &&
    81         (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions, !allowVirtualKeyboard)))
     81        (gContext->TranslateKeyPress("qt", e, actions, !allowVirtualKeyboard)))
    8282    {
    8383        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    8484        {
     
    189189{
    190190    bool handled = false;
    191191    QStringList actions;
    192     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
     192    if (gContext->TranslateKeyPress("qt", e, actions))
    193193    {
    194194        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    195195        {
     
    239239{
    240240    bool handled = false;
    241241    QStringList actions;
    242     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
     242    if (gContext->TranslateKeyPress("qt", e, actions))
    243243    {
    244244        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    245245        {
     
    305305
    306306    bool handled = false;
    307307    QStringList actions;
    308     if (gContext->GetMainWindow()->TranslateKeyPress("qt", (QKeyEvent *)e,
    309                                                      actions))
     308    if (gContext->TranslateKeyPress("qt", (QKeyEvent *)e, actions))
    310309    {
    311310        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    312311        {
     
    375374{
    376375    bool handled = false;
    377376    QStringList actions;
    378     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
     377    if (gContext->TranslateKeyPress("qt", e, actions))
    379378    {
    380379        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    381380        {
     
    467466    qt_delete(popup);
    468467
    469468    popup = new VirtualKeyboard(gContext->GetMainWindow(), this);
    470     gContext->GetMainWindow()->detach(popup);
     469    gContext->detachFromWin(popup);
    471470    popup->exec();
    472471
    473472    qt_delete(popup);
     
    478477    bool handled = false;
    479478    QStringList actions;
    480479    if ((!popup || !popup->isShown()) &&
    481         gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions, false))
     480        gContext->TranslateKeyPress("qt", e, actions, false))
    482481    {
    483482        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    484483        {
     
    860859    QStringList actions;
    861860
    862861    if ((!popup || !popup->isShown()) &&
    863           gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions, false))
     862          gContext->TranslateKeyPress("qt", e, actions, false))
    864863    {
    865864        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    866865        {
     
    11241123    qt_delete(popup);
    11251124
    11261125    popup = new VirtualKeyboard(gContext->GetMainWindow(), this);
    1127     gContext->GetMainWindow()->detach(popup);
     1126    gContext->detachFromWin(popup);
    11281127    popup->exec();
    11291128
    11301129    qt_delete(popup);
     
    11571156    int tmpRow = currentRow();
    11581157    bool handled = false;
    11591158    QStringList actions;
    1160     if (gContext->GetMainWindow()->TranslateKeyPress("qt", (QKeyEvent *)e,
    1161                                                      actions))
     1159    if (gContext->TranslateKeyPress("qt", (QKeyEvent *)e, actions))
    11621160    {
    11631161        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    11641162        {
     
    12421240    QStringList actions;
    12431241    keyPressActions.clear();
    12441242
    1245     if (gContext->GetMainWindow()->TranslateKeyPress("qt", (QKeyEvent *)e,
    1246                                                      actions))
     1243    if (gContext->TranslateKeyPress("qt", (QKeyEvent *)e, actions))
    12471244    {
    12481245        keyPressActions = actions;
    12491246
     
    13691366
    13701367    bool handled = false;
    13711368    QStringList actions;
    1372     gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions);
     1369    gContext->TranslateKeyPress("qt", e, actions);
    13731370
    13741371    for (unsigned int i = 0; i < actions.size() && !handled; i++)
    13751372    {
     
    14901487{
    14911488    bool handled = false;
    14921489    QStringList actions;
    1493     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
     1490    if (gContext->TranslateKeyPress("qt", e, actions))
    14941491    {
    14951492        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    14961493        {
  • mythtv/libs/libmyth/xmlparse.cpp

     
    286286    if (baseFont && !haveSize)
    287287        size = baseFont->face.pointSize();
    288288    else   
    289         size = GetMythMainWindow()->NormalizeFontSize(size);
     289        size = gContext->NormalizeFontSize(size);
    290290   
    291291    // If we don't have to, don't load the font.
    292292    if (!haveFace && baseFont)
  • mythtv/libs/libmyth/uitypes.cpp

     
    60006000{
    60016001    bool handled = false;
    60026002    QStringList actions;
    6003     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions, false))
     6003    if (gContext->TranslateKeyPress("qt", e, actions, false))
    60046004    {
    60056005        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    60066006        {
  • mythtv/libs/libmyth/dbsettings.h

     
    1 #ifndef DBSETTINGS_H
    2 #define DBSETTINGS_H
    3 
    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 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/libmyth/mythcontext.cpp

     
    2727#include "mythplugin.h"
    2828#include "screensaver.h"
    2929#include "DisplayRes.h"
    30 #include "backendselect.h"
    31 #include "dbsettings.h"
    3230#include "langsettings.h"
    3331#include "mythdbcon.h"
    3432#include "util-x11.h"
     
    3634#include "themeinfo.h"
    3735
    3836#include "libmythui/mythmainwindow.h"
    39 #include "libmythupnp/mythxmlclient.h"
    40 #include "libmythupnp/upnp.h"
    4137
    4238#ifdef USING_MINGW
    4339#include <winsock2.h>
     
    5854const QString kPluginLibSuffix = ".so";
    5955#endif
    6056
    61 MythContext *gContext = NULL;
    62 QMutex MythContext::verbose_mutex(true);
    63 QString MythContext::x11_display = QString::null;
     57MythContext    *gContext = NULL;
     58DatabaseParams  gDBparams;
     59QMutex          MythContext::verbose_mutex(true);
     60QString         MythContext::x11_display = QString::null;
    6461
    6562unsigned int print_verbose_messages = VB_IMPORTANT | VB_GENERAL;
    6663QString verboseString = QString(" important general");
    6764
    6865QMutex avcodeclock(true);
    6966
    70 // Some common UPnP search and XML value strings
    71 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";
    7467
    75 
    7668int parse_verbose_arg(QString arg)
    7769{
    7870    QString option;
     
    180172    MythContextPrivate(MythContext *lparent);
    181173   ~MythContextPrivate();
    182174
    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);
    186176
    187177    bool IsWideMode() const {return (m_baseWidth == 1280);}
    188178    void SetWideMode() {m_baseWidth = 1280; m_baseHeight = 720;}
    189179    bool IsSquareMode() const {return (m_baseWidth == 800);}
    190180    void SetSquareMode() {m_baseWidth = 800; m_baseHeight = 600;}
    191181
    192     void TempMainWindow(bool languagePrompt = true);
    193     void EndTempWindow(void);
    194 
    195182    void GetScreenBounds(void);
    196183    void StoreGUIsettings(void);
    197184
    198185    void LoadLogSettings(void);
    199     void LoadDatabaseSettings(void);
    200    
    201     bool LoadSettingsFile(void);
     186
     187    void DefaultDatabaseSettings(void);
    202188    bool WriteSettingsFile(const DatabaseParams &params,
    203189                           bool overwrite = false);
    204     bool FindSettingsProbs(void);
    205190
    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);
    211191
    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 
    220192    MythContext *parent;
    221193
    222194    Settings *m_settings;          ///< connection stuff, theme, button style
     
    248220    QMutex  m_hostnamelock;      ///< Locking for thread-safe copying of:
    249221    QString m_localhostname;     ///< hostname from mysql.txt or gethostname()
    250222
    251     DatabaseParams  m_DBparams;  ///< Current database host & WOL details
    252     QString         m_DBhostCp;  ///< dbHostName backup
    253 
    254     UPnp             *m_UPnP;    ///< For automatic backend discover
    255     XmlConfiguration *m_XML;
    256     HttpServer       *m_HTTP;
    257 
    258223    QMutex serverSockLock;
    259224    bool attemptingToConnect;
    260225
     
    284249    MythSocket *serverSock;
    285250    MythSocket *eventSock;
    286251
    287     bool disablelibrarypopup;
    288 
    289252    MythPluginManager *pluginmanager;
    290253
    291254    ScreenSaverControl *screensaver;
     
    319282      m_xbase(0), m_ybase(0), m_height(0), m_width(0),
    320283      m_baseWidth(800), m_baseHeight(600),
    321284      m_localhostname(QString::null),
    322       m_UPnP(NULL), m_XML(NULL), m_HTTP(NULL),
    323285      serverSockLock(false),
    324286      attemptingToConnect(false),
    325287      language(""),
     
    330292      themecachedir(QString::null),
    331293      bigfontsize(0), mediumfontsize(0), smallfontsize(0),
    332294      serverSock(NULL), eventSock(NULL),
    333       disablelibrarypopup(false),
    334295      pluginmanager(NULL),
    335296      screensaver(NULL),
    336297      m_logenable(-1), m_logmaxcount(-1), m_logprintlevel(-1),
     
    375336{
    376337    imageCache.clear();
    377338
    378     DeleteUPnP();
    379339    if (m_settings)
    380340        delete m_settings;
    381341    if (m_qtThemeSettings)
     
    389349}
    390350
    391351/**
    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 prefers
    403  *        "blue" for these initial screens and popups
    404  */
    405 void MythContextPrivate::TempMainWindow(bool languagePrompt)
    406 {
    407     if (mainWindow)
    408         return;
    409 
    410     // We clear the hostname so MSqlQuery will fail, instead of long
    411     // timeouts per DB value, or hundreds of lines of DB connect errors.
    412     // We save the value for later possible editing in the DbSettings pages
    413     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_MACX
    421     // Myth looks horrible in default Mac style for Qt
    422     m_settings->SetSetting("Style", "Windows");
    423 #endif
    424     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 settings
    433         LanguageSettings::prompt();
    434         LanguageSettings::load("mythfrontend");
    435     }
    436 }
    437 
    438 void MythContextPrivate::EndTempWindow(void)
    439 {
    440     parent->SetMainWindow(NULL);
    441     DestroyMythMainWindow();
    442 }
    443 
    444 /**
    445352 * \brief Get screen size from Qt, respecting for user's multiple screen prefs
    446353 *
    447354 * If the windowing system environment has multiple screens
     
    520427    }
    521428}
    522429
    523 bool MythContextPrivate::Init(const bool gui, UPnp *UPnPclient,
    524                               const bool promptForBackend, const bool noPrompt)
     430bool MythContextPrivate::Init(const bool gui)
    525431{
    526432    m_gui = gui;
    527     if (UPnPclient)
    528     {
    529         m_UPnP = UPnPclient;
    530         m_XML  = (XmlConfiguration *)UPnp::g_pConfig;
    531     }
    532433
    533434    // Creates screen saver control if we will have a GUI
    534435    if (gui)
     436    {
    535437        screensaver = ScreenSaverControl::get();
    536438
    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     {
    546439        GetScreenBounds();
    547440        StoreGUIsettings();
    548441    }
     
    551444}
    552445
    553446/**
    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 autoconfigure
    571     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 default
    581     //    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 UPnP
    589         else
    590             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 user
    616     }
    617 
    618     if (!m_gui)
    619         manualSelect = false;  // no interactive command-line chooser yet
    620 
    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 manually
    629                 if (PromptForDatabaseParams(""))
    630                     break;
    631                 else
    632                     goto NoDBfound;   // User cancelled - changed their mind?
    633    
    634             case 0:   // User cancelled. Exit application
    635                 goto NoDBfound;
    636 
    637             case 1:    // User selected a backend, so m_DBparams
    638                 break; // should now contain the database details
    639 
    640             default:
    641                 goto NoDBfound;
    642         }
    643         failure = TestDBconnection();
    644     }
    645 
    646 
    647     // Queries the user for the DB info, using the command
    648     // 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         else
    660             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 /**
    676447 * Apply any user overrides to the screen geometry
    677448 */
    678449void MythContextPrivate::StoreGUIsettings()
     
    744515    m_logprintlevel = parent->GetNumSetting("LogPrintLevel", LP_ERROR);
    745516}
    746517
    747 /**     
    748  * Load database and host settings from mysql.txt, or set some defaults
    749  *
    750  * \returns true if mysql.txt was parsed
    751  */
    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 user
    776     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_DBparams
    799  */
    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.wolReconnect
    817         = 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 
    826518bool MythContextPrivate::WriteSettingsFile(const DatabaseParams &params,
    827519                                           bool overwrite)
    828520{
     
    926618    return true;
    927619}
    928620
    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     else
    966         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 parameters
    1015         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     else
    1023     {
    1024         DatabaseParams params = parent->GetDatabaseParams();
    1025         QString response;
    1026        
    1027         // give user chance to skip config
    1028         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 
    1078621/**
    1079622 * Some quick sanity checks before opening a database connection
    1080623 */
    1081 QString MythContextPrivate::TestDBconnection(void)
     624QString MythContext::TestDBconnection(void)
    1082625{
    1083     bool    doPing = m_DBparams.dbHostPing;
     626    bool    doPing = gDBparams.dbHostPing;
    1084627    QString err;
    1085     QString host   = m_DBparams.dbHostName;
    1086     int     port   = m_DBparams.dbPort;
     628    QString host   = gDBparams.dbHostName;
     629    int     port   = gDBparams.dbPort;
    1087630
    1088631
    1089632    // 1. Check the supplied host or IP address, to prevent the app
    1090633    //    appearing to hang if we cannot route to the machine:
    1091634
    1092635    // 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)
    1094638        doPing = false;
    1095639
    1096640    // 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)
    1099643        {
    1100             int wakeupTime = m_DBparams.wolReconnect;
     644            int wakeupTime = gDBparams.wolReconnect;
    1101645
    1102646            if (ping(host, wakeupTime))
    1103647            {
     
    1107651
    1108652            VERBOSE(VB_GENERAL, QString("Trying to wake up host %1, attempt %2")
    1109653                                .arg(host).arg(attempt));
    1110             system(m_DBparams.wolCommand);
     654            system(gDBparams.wolCommand);
    1111655
    1112656            VERBOSE(VB_GENERAL,
    1113657                    QString("Waiting for %1 seconds").arg(wakeupTime));
    1114             sleep(m_DBparams.wolReconnect);
     658            sleep(gDBparams.wolReconnect);
    1115659        }
    1116660
    1117661    if (doPing)
     
    1122666
    1123667    if (doPing && !ping(host, 3))  // Fail after trying for 3 seconds
    1124668    {
    1125         // Save, to display in DatabaseSettings screens
    1126         m_DBhostCp = m_DBparams.dbHostName;
    1127 
    1128669        // Cause MSqlQuery to fail, instead of minutes timeout per DB value
    1129         m_DBparams.dbHostName = "";
     670        gDBparams.dbHostName = "";
    1130671
    1131672        err = QObject::tr("Cannot find (ping) database host %1 on the network");
    1132673        return err.arg(host);
     
    1162703 * Any cached settings also need to be cleared,
    1163704 * so that they can be re-read from the new database
    1164705 */
    1165 void MythContextPrivate::ResetDatabase(void)
     706void MythContext::ResetDatabase(void)
    1166707{
    1167     m_dbmanager.CloseDatabases();
    1168     parent->ClearSettingsCache();
     708    d->m_dbmanager.CloseDatabases();
     709    ClearSettingsCache();
    1169710}
    1170711
    1171712
    1172 bool MythContextPrivate::InitUPnP(void)
     713MythContext::MythContext() : QObject()
    1173714{
    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 only
    1181 
    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 description
    1203     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 UPnP
    1214         return;             // so let the caller delete it cleanly
    1215 
    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_XML
    1222         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 one
    1235  */
    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 will
    1365     // 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 & PIN
    1370 }
    1371 
    1372 /**
    1373  * Get the default backend from config.xml, use UPnP to find it.
    1374  *
    1375  * Sets a string if there any connection problems
    1376  */
    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 parameters
    1420  */
    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 later
    1439             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 {
    1457715#ifdef USING_MINGW
    1458716    static bool WSAStarted = false;
    1459717    if (!WSAStarted) {
     
    1468726    d = new MythContextPrivate(this);
    1469727}
    1470728
    1471 bool MythContext::Init(const bool gui, UPnp *UPnPclient,
    1472                        const bool promptForBackend,
    1473                        const bool disableAutoDiscovery)
     729bool MythContext::Init(const bool gui)
    1474730{
    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))
    1493732        return false;
    1494     }
    1495733
    1496     if (!d->Init(gui, UPnPclient, promptForBackend, disableAutoDiscovery))
    1497         return false;
    1498 
    1499734    ActivateSettingsCache(true);
    1500735
    1501736    return true;
     
    1570805                        manageLock = true;
    1571806                        d->serverSockLock.unlock();
    1572807                    }
    1573                     MythPopupBox::showOkPopup(d->mainWindow,
     808                    MythPopupBox::showOkPopup(GetMainWindow(),
    1574809                                              "connection failure",
    1575810                                              tr("Could not connect to the "
    1576811                                                 "master backend server -- is "
     
    18181053    return tmp;
    18191054}
    18201055
     1056void MythContext::SetHostName(QString localHost)
     1057{
     1058    d->m_hostnamelock.lock();
     1059    d->m_localhostname = QDeepCopy<QString>(localHost);
     1060    d->m_hostnamelock.unlock();
     1061}
     1062
    18211063QString MythContext::GetFilePrefix(void)
    18221064{
    18231065    return GetSetting("RecordFilePrefix");
     
    32072449            VERBOSE(VB_IMPORTANT,
    32082450                    QString("Reconnection to backend server failed"));
    32092451            if (d->m_height && d->m_width)
    3210                 MythPopupBox::showOkPopup(d->mainWindow, "connection failure",
     2452                MythPopupBox::showOkPopup(GetMainWindow(), "connection failure",
    32112453                             tr("The connection to the master backend "
    32122454                                "server has gone away for some reason.. "
    32132455                                "Is it running?"));
     
    32792521        if (d->m_height && d->m_width)
    32802522        {
    32812523            qApp->lock();
    3282             MythPopupBox::showOkPopup(d->mainWindow,
     2524            MythPopupBox::showOkPopup(GetMainWindow(),
    32832525                                      "Connection failure",
    32842526                                      tr(QString("The server uses network "
    32852527                                                 "protocol version %1, "
     
    33372579QFont MythContext::GetBigFont(void)
    33382580{
    33392581    QFont font = QApplication::font();
    3340     font.setPointSize(GetMythMainWindow()->NormalizeFontSize(d->bigfontsize));
     2582    font.setPointSize(NormalizeFontSize(d->bigfontsize));
    33412583    font.setWeight(QFont::Bold);
    33422584
    33432585    return font;
     
    33462588QFont MythContext::GetMediumFont(void)
    33472589{
    33482590    QFont font = QApplication::font();
    3349     font.setPointSize(GetMythMainWindow()->NormalizeFontSize(d->mediumfontsize));
     2591    font.setPointSize(NormalizeFontSize(d->mediumfontsize));
    33502592    font.setWeight(QFont::Bold);
    33512593
    33522594    return font;
     
    33552597QFont MythContext::GetSmallFont(void)
    33562598{
    33572599    QFont font = QApplication::font();
    3358     font.setPointSize(GetMythMainWindow()->NormalizeFontSize(d->smallfontsize));
     2600    font.setPointSize(NormalizeFontSize(d->smallfontsize));
    33592601    font.setWeight(QFont::Bold);
    33602602
    33612603    return font;
     
    33972639    return d->mainWindow;
    33982640}
    33992641
    3400 /**
    3401  * \brief   Try to prevent silent, automatic database upgrades
    3402  * \returns -1 to use the existing schema, 0 to exit, 1 to upgrade.
    3403  *
    3404  * The GUI prompts have no defaults, so that nothing dangerous
    3405  * 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 &current)
    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 tables
    3424     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 this
    3443     //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         else
    3463         {
    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 old
    3473     {
    3474         if (expertMode)
    3475             message = tr("Warning: MythTV database has newer"
    3476                          " schema (%1) than expected (%2).");
    3477         else
    3478         {
    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         else
    3506         {
    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 shell
    3555 
    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 
    36262642void MythContext::SetPluginManager(MythPluginManager *pmanager)
    36272643{
    36282644    d->pluginmanager = pmanager;
     
    38062822    return ret_val;
    38072823}
    38082824
    3809 DatabaseParams MythContext::GetDatabaseParams(void)
     2825/**     
     2826 * Set database connection defaults
     2827 */
     2828void MythContext::DefaultDatabaseSettings(void)
    38102829{
    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'";
    38122843}
    38132844
     2845
    38142846bool MythContext::SaveDatabaseParams(const DatabaseParams &params)
    38152847{
    38162848    bool ret = true;
    3817     DatabaseParams cur_params = GetDatabaseParams();
    38182849   
    38192850    // 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          ||
    38292860        (params.localEnabled &&
    3830          (params.localHostName != cur_params.localHostName))  ||
     2861         (params.localHostName != gDBparams.localHostName))  ||
    38312862        (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)))
    38352866    {
    38362867        ret = d->WriteSettingsFile(params, true);
    38372868        if (ret)
    38382869        {
    38392870            // Save the new settings:
    3840             d->m_DBparams = params;
     2871            gDBparams = params;
    38412872
    38422873            // If database has changed, force its use:
    3843             d->ResetDatabase();
     2874            ResetDatabase();
    38442875        }
    38452876    }
    38462877    return ret;
  • mythtv/libs/libmyth/mythdbcon.cpp

     
    5959   
    6060    if (!m_db->isOpen())
    6161    {
    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);
    6766
    68         if (!dbparms.dbHostName.length())  // Bootstrapping without a database?
     67        if (!gDBparams.dbHostName.length())// Bootstrapping without a database?
    6968        {
    7069            connected = true;              // Pretend to be connected
    7170            return true;                   // to reduce errors
    7271        }
    7372
    74         if (dbparms.dbPort)
    75             m_db->setPort(dbparms.dbPort);
     73        if (gDBparams.dbPort)
     74            m_db->setPort(gDBparams.dbPort);
    7675
    77         if (dbparms.dbPort && dbparms.dbHostName == "localhost")
     76        if (gDBparams.dbPort && gDBparams.dbHostName == "localhost")
    7877            m_db->setHostName("127.0.0.1");
    7978
    8079        connected = m_db->open();
    8180
    82         if (!connected && dbparms.wolEnabled)
     81        if (!connected && gDBparams.wolEnabled)
    8382        {
    8483            int trycount = 0;
    8584               
    86             while (!connected && trycount++ < dbparms.wolRetry)
     85            while (!connected && trycount++ < gDBparams.wolRetry)
    8786            {
    8887                VERBOSE(VB_GENERAL, QString(
    8988                         "Using WOL to wakeup database server (Try %1 of %2)")
    90                          .arg(trycount).arg(dbparms.wolRetry));
     89                         .arg(trycount).arg(gDBparams.wolRetry));
    9190
    92                 system(dbparms.wolCommand);
    93                 sleep(dbparms.wolReconnect);
     91                system(gDBparams.wolCommand);
     92                sleep(gDBparams.wolReconnect);
    9493                connected = m_db->open();
    9594            }
    9695   
    9796            if (!connected)
    9897            {
    99                 VERBOSE(VB_IMPORTANT, "WOL failed, unable to connect to database!");
     98                VERBOSE(VB_IMPORTANT,
     99                        "WOL failed, unable to connect to database!");
    100100            }
    101101        }
    102102        if (connected)
  • mythtv/libs/libmyth/mythwizard.cpp

     
    539539{
    540540    bool handled = false;
    541541    QStringList actions;
    542     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
     542    if (gContext->TranslateKeyPress("qt", e, actions))
    543543    {
    544544        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    545545        {
  • mythtv/libs/libmyth/mythcontext.h

     
    142142{
    143143    Q_OBJECT
    144144  public:
    145     MythContext(const QString &binversion);
     145    MythContext();
    146146    virtual ~MythContext();
    147147
    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);
    152149
    153150    QString GetMasterHostPrefix(void);
    154151
    155152    QString GetHostName(void);
     153    void    SetHostName(QString localHost);
    156154
    157155    void ClearSettingsCache(QString myKey = "", QString newVal = "");
    158156    void ActivateSettingsCache(bool activate = true);
     
    229227    static void DBError(const QString &where, const QSqlQuery &query);
    230228    static QString DBErrorMessage(const QSqlError& err);
    231229
    232     DatabaseParams GetDatabaseParams(void);
     230    void DefaultDatabaseSettings(void);
     231    void ResetDatabase(void);
    233232    bool SaveDatabaseParams(const DatabaseParams &params);
     233    QString TestDBconnection(void);
    234234   
    235235    void LogEntry(const QString &module, int priority,
    236236                  const QString &message, const QString &details);
     
    282282    void SetMainWindow(MythMainWindow *mainwin);
    283283    MythMainWindow *GetMainWindow(void);
    284284
    285     int  PromptForSchemaUpgrade(const QString &dbver, const QString &current);
    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 &current) = 0;
     291    virtual bool TestPopupVersion(const QString &pluginName,
     292                                  const QString &libMythVersion,
     293                                  const QString &pluginVersion) = 0;
    288294
    289     void SetDisableLibraryPopup(bool check);
     295    virtual void SetDisableLibraryPopup(bool check) = 0;
    290296
     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
    291308    void SetPluginManager(MythPluginManager *pmanager);
    292309    MythPluginManager *getPluginManager(void);
    293310
     
    344361    void readyRead(MythSocket *sock);
    345362    void connectionFailed(MythSocket *sock) { (void)sock; }
    346363
    347     MythContextPrivate *d;
    348     QString app_binary_version;
     364    MythContextPrivate  *d;
    349365
    350     QMutex locationLock;
     366    QMutex               locationLock;
    351367    QValueList <QString> currentLocation;
    352368};
    353369
     370
    354371/// This global variable contains the MythContext instance for the application
    355372extern MPUBLIC MythContext *gContext;
    356373
     374/// This global stores the context's current database host & WOL details
     375extern MPUBLIC DatabaseParams gDBparams;
     376
    357377/// This global variable is used to makes certain calls to avlib threadsafe.
    358378extern MPUBLIC QMutex avcodeclock;
    359379
     
    366386    MYTH_SCHEMA_USE_EXISTING = 4
    367387};
    368388
    369 /// Service type for the backend's UPnP server
    370 extern MPUBLIC const QString gBackendURI;
    371 
    372389#endif
    373390
    374391/* vim: set expandtab tabstop=4 shiftwidth=4: */
  • mythtv/libs/libmyth/mythconfigdialogs.cpp

     
    100100    bool handled = false;
    101101    QStringList actions;
    102102
    103     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions))
     103    if (gContext->TranslateKeyPress("qt", e, actions))
    104104    {
    105105        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    106106        {
  • mythtv/libs/libmyth/libmyth.pro

     
    1111
    1212# Input
    1313HEADERS += audiooutput.h audiooutputbase.h audiooutputnull.h
    14 HEADERS += backendselect.h dbsettings.h dialogbox.h
    15 HEADERS += DisplayRes.h DisplayResScreen.h exitcodes.h
     14HEADERS += dialogbox.h DisplayRes.h DisplayResScreen.h exitcodes.h
    1615HEADERS += generictree.h httpcomms.h langsettings.h lcddevice.h
    1716HEADERS += managedlist.h mythconfigdialogs.h mythconfiggroups.h
    1817HEADERS += mythcontext.h mythdbcon.h mythdeque.h mythdialogs.h
     
    2726HEADERS += compat.h
    2827
    2928SOURCES += audiooutput.cpp audiooutputbase.cpp audiooutputnull.cpp
    30 SOURCES += backendselect.cpp dbsettings.cpp dialogbox.cpp
    31 SOURCES += DisplayRes.cpp DisplayResScreen.cpp
     29SOURCES += dialogbox.cpp DisplayRes.cpp DisplayResScreen.cpp
    3230SOURCES += generictree.cpp httpcomms.cpp langsettings.cpp lcddevice.cpp
    3331SOURCES += managedlist.cpp mythconfigdialogs.cpp mythconfiggroups.cpp
    3432SOURCES += mythcontext.cpp mythdbcon.cpp mythdialogs.cpp
     
    6058inc.files += visual.h volumebase.h output.h langsettings.h qmdcodec.h
    6159inc.files += exitcodes.h mythconfig.h mythconfig.mak virtualkeyboard.h
    6260inc.files += mythevent.h mythobservable.h mythsocket.h
    63 inc.files += mythexp.h mythpluginapi.h compat.h
     61inc.files += mythexp.h mythpluginapi.h compat.h mythverbose.h
    6462inc.files += mythstorage.h mythconfigdialogs.h mythconfiggroups.h
    6563
    6664using_oss {
     
    121119    # Mac OS X Frameworks
    122120    FWKS = ApplicationServices AudioUnit Carbon CoreAudio IOKit
    123121
     122    darwin_da : FWKS += DiskArbitration
     123
    124124    # The following trick is tidier, and shortens the command line, but it
    125125    # depends on the shell expanding Csh-style braces. Luckily, Bash & Zsh do.
    126126    FC = $$join(FWKS,",","{","}")
    127127
    128128    QMAKE_CXXFLAGS += -F/System/Library/Frameworks/$${FC}.framework/Frameworks
    129129    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 warning
    134 
    135     QMAKE_LFLAGS_SHLIB += -seg1addr 0xC6000000
    136130}
    137131
    138132linux {
  • 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 QListBoxText
    10 {
    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 MythDialog
    33 {
    34     Q_OBJECT
    35 
    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 button
    49         void Manual    (void);   ///< Linked to 'Configure Manually' button
    50         //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

     
    230230{
    231231    bool handled = false;
    232232    QStringList actions;
    233     if (gContext->GetMainWindow()->TranslateKeyPress("qt", e, actions, false))
     233    if (gContext->TranslateKeyPress("qt", e, actions, false))
    234234    {
    235235        for (unsigned int i = 0; i < actions.size() && !handled; i++)
    236236        {
  • mythtv/libs/libmyth/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 #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         else
    80             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             do
    129             {
    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(" + message
    201                      + ", " + 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 until
    217         //         SSDPCache is changed to handle NotifyRemove correctly
    218         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

     
    1717// Global/Class Static variables
    1818//////////////////////////////////////////////////////////////////////////////
    1919
     20const QString UPnp::kBackendURI
     21              = "urn:schemas-mythtv-org:device:MasterMediaServer:1";
     22const QString UPnp::kDefaultPIN
     23              = "UPnP/MythFrontend/DefaultBackend/SecurityPin";
     24const QString UPnp::kDefaultUSN
     25              = "UPnP/MythFrontend/DefaultBackend/USN";
     26
     27
    2028UPnpDeviceDesc   UPnp::g_UPnpDeviceDesc;
    2129TaskQueue       *UPnp::g_pTaskQueue     = NULL;
    2230SSDP            *UPnp::g_pSSDP          = NULL;
  • mythtv/libs/libmythupnp/libmythupnp.pro

     
    4646    target.path = $${PREFIX}/bin
    4747}
    4848
    49 inc.path = $${PREFIX}/include/mythtv/upnp/
     49inc.path = $${PREFIX}/include/mythtv/libmythupnp/
    5050
    5151inc.files  = httprequest.h upnp.h ssdp.h taskqueue.h bufferedsocketdevice.h
    5252inc.files += upnpdevice.h upnptasknotify.h upnptasksearch.h threadpool.h upnputil.h
    5353inc.files += httpserver.h httpstatus.h upnpcds.h upnpcdsobjects.h
    5454inc.files += eventing.h upnpcmgr.h upnptaskevent.h upnptaskcache.h ssdpcache.h
    5555inc.files += upnpimpl.h multicast.h broadcast.h configuration.h
    56 inc.files += soapclient.h mythxmlclient.h
     56inc.files += soapclient.h mythxmlclient.h refcounted.h
    5757
    5858INSTALLS += inc
    5959
     
    6363freebsd:HEADERS += darwin-sendfile.h
    6464freebsd:SOURCES += darwin-sendfile.c
    6565
    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 }
     66macx:HEADERS += darwin-sendfile.h
     67macx:SOURCES += darwin-sendfile.c
  • mythtv/libs/libmythupnp/upnp.h

     
    9999        int                     m_nServicePort;
    100100
    101101    public:
     102        // Some common UPnP search and XML value strings:
    102103
     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
    103114        static Configuration   *g_pConfig;
    104115
    105116        static UPnpDeviceDesc   g_UPnpDeviceDesc;
  • mythtv/programs/mythuitest/main.cpp

     
    55#include <cstdlib>
    66using namespace std;
    77
    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"
    1314
    14 #include "mythcontext.h"
    15 
    1615#include "test1.h"
    17 #include "oldsettings.h"
     16#include "libmyth/oldsettings.h"
    1817//#include "btnlisttest.h"
    1918
    2019int main(int argc, char *argv[])
    2120{
    2221    QApplication a(argc, argv);
    2322
    24     gContext = NULL;
    25     gContext = new MythContext(MYTH_BINARY_VERSION);
     23    gContext = (MythContext *) new MythContextGUI(MYTH_BINARY_VERSION);
    2624    gContext->Init();
    2725
    2826    QString themename = gContext->GetSetting("Theme");
  • mythtv/programs/programs-libs.pro

     
    1010LIBS += -L../../libs/libmythupnp
    1111LIBS += -L../../libs/libmythlivemedia
    1212
    13 LIBS += -lmythtv-$$LIBVERSION -lmythavformat-$$LIBVERSION
     13LIBS += -lmyth-$$LIBVERSION -lmythtv-$$LIBVERSION -lmythavformat-$$LIBVERSION
    1414LIBS += -lmythavutil-$$LIBVERSION -lmythavcodec-$$LIBVERSION
    1515LIBS += -lmythfreemheg-$$LIBVERSION
     16LIBS += -lmythui-$$LIBVERSION
    1617LIBS += -lmythupnp-$$LIBVERSION
    1718LIBS += -lmythlivemedia-$$LIBVERSION
    18 LIBS += -lmyth-$$LIBVERSION -lmythui-$$LIBVERSION $$EXTRA_LIBS
     19LIBS += -lmythui-$$LIBVERSION $$EXTRA_LIBS
    1920mingw {
    2021    LIBS += -lpthread
    2122    CONFIG += console
  • mythtv/programs/mythfrontend/globalsettings.cpp

     
    2222#include "libmyth/mythconfig.h"
    2323#include "libmyth/mythcontext.h"
    2424#include "libmyth/mythdbcon.h"
    25 #include "libmyth/dbsettings.h"
     25#include "libmythtv/dbsettings.h"
    2626#include "libmyth/langsettings.h"
    2727#include "libmythtv/mpeg/iso639.h"
    2828#include "playbackbox.h"
  • mythtv/programs/mythfrontend/main.cpp

     
    5151#include "lcddevice.h"
    5252#include "langsettings.h"
    5353
     54#include "libmythtv/mythcontextui.h"
    5455#include "libmythui/myththemedmenu.h"
    5556#include "libmythui/myththemebase.h"
    5657#include "mediarenderer.h"
     
    10671068        MythContext::SetX11Display(display);
    10681069    }
    10691070
    1070     gContext = new MythContext(MYTH_BINARY_VERSION);
     1071    MythContextGUI * context = new MythContextGUI(MYTH_BINARY_VERSION);
    10711072    g_pUPnp  = new MediaRenderer();
    10721073
    1073     if (!gContext->Init(true, g_pUPnp, bPromptForBackend, bBypassAutoDiscovery))
     1074    if (!context->Init(g_pUPnp, bPromptForBackend, bBypassAutoDiscovery))
    10741075    {
    10751076        VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting.");
    10761077        return FRONTEND_EXIT_NO_MYTHCONTEXT;
     
    13261327        return FRONTEND_EXIT_NO_THEME;
    13271328    }
    13281329
    1329     gContext->LoadQtConfig();
     1330    MythMainWindow *mainWindow = gContext->CreateMainWindow();
    13301331
    1331     MythMainWindow *mainWindow = GetMythMainWindow();
    1332     mainWindow->Init();
    1333     gContext->SetMainWindow(mainWindow);
    1334 
    13351332    gContext->UpdateImageCache();
    13361333    themeBase = new MythThemeBase();
    13371334
  • mythtv/programs/mythjobqueue/main.cpp

     
    1818#include "libmyth/mythcontext.h"
    1919#include "libmythtv/jobqueue.h"
    2020#include "libmyth/mythdbcon.h"
     21#include "libmythtv/mythcontextui.h"
    2122
    2223using namespace std;
    2324
     
    103104        ++argpos;
    104105    }
    105106
    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))
    109109    {
    110110        VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting.");
    111111        return JOBQUEUE_EXIT_NO_MYTHCONTEXT;
  • mythtv/programs/mythtranscode/main.cpp

     
    1414#include <fstream>
    1515using namespace std;
    1616
    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"
    2223#include "transcode.h"
    2324#include "mpeg2fix.h"
    2425
     
    396397    }
    397398
    398399    //  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))
    402402    {
    403403        VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting.");
    404404        return TRANSCODE_EXIT_NO_MYTHCONTEXT;
  • mythtv/programs/mythcommflag/main.cpp

     
    2323#include "libmythtv/jobqueue.h"
    2424#include "libmythtv/remoteencoder.h"
    2525#include "libmyth/mythdbcon.h"
     26#include "libmythtv/mythcontextui.h"
    2627
    2728#include "CommDetector.h"
    2829#include "CommDetectorBase.h"
     
    922923        ++argpos;
    923924    }
    924925
    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))
    928928    {
    929929        VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting.");
    930930        return COMMFLAG_EXIT_NO_MYTHCONTEXT;
  • mythtv/programs/mythbackend/mythxml.cpp

     
    14761476        return;
    14771477    }
    14781478
    1479     DatabaseParams params = gContext->GetDatabaseParams();
     1479    DatabaseParams params = gDBparams;
    14801480
    14811481    // Check for DBHostName of "localhost" and change to public name or IP
    14821482
  • mythtv/programs/mythbackend/main.cpp

     
    4141#include "libmythtv/jobqueue.h"
    4242#include "libmythtv/storagegroup.h"
    4343#include "libmythtv/previewgenerator.h"
     44#include "libmythtv/mythcontextui.h"
    4445
    4546#include "mediaserver.h"
    4647#include "httpstatus.h"
     
    741742        pidfs.close();
    742743    }
    743744
    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))
    747747    {
    748748        VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting.");
    749749        return BACKEND_EXIT_NO_MYTHCONTEXT;
  • mythtv/programs/mythtv-setup/main.cpp

     
    2323#include "libmyth/dialogbox.h"
    2424#include "libmyth/exitcodes.h"
    2525#include "libmyth/util.h"
     26#include "libmythtv/mythcontextui.h"
    2627#include "libmythui/myththemedmenu.h"
    2728#include "libmythui/myththemebase.h"
    2829
     
    240241        MythContext::SetX11Display(display);
    241242    }
    242243
    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())
    247246    {
    248247        VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting.");
    249248        return -1;
     
    279278    UpgradeTVDatabaseSchema();
    280279
    281280    gContext->SetSetting("Theme", "G.A.N.T");
    282     gContext->LoadQtConfig();
    283281
    284282    QString fileprefix = MythContext::GetConfDir();
    285283
     
    287285    if (!dir.exists())
    288286        dir.mkdir(fileprefix);
    289287
    290     MythMainWindow *mainWindow = GetMythMainWindow();
    291     mainWindow->Init();
    292     gContext->SetMainWindow(mainWindow);
     288    MythMainWindow *mainWindow = context->CreateMainWindow();
    293289
    294290    gContext->UpdateImageCache();
    295291    MythThemeBase *themeBase = new MythThemeBase();
  • mythtv/programs/mythlcdserver/main.cpp

     
    1616#include <fcntl.h>
    1717#include <signal.h>
    1818
    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"
    2324#include "compat.h"
    2425
    2526#include "lcdserver.h"
     
    229230    }
    230231
    231232    //  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))
    235235    {
    236236        VERBOSE(VB_IMPORTANT, "lcdserver: Could not initialize myth context. "
    237237                        "Exiting.");
  • mythtv/programs/mythtv/main.cpp

     
    66#include <qregexp.h>
    77#include <qdir.h>
    88
    9 #include "tv_play.h"
    10 #include "programinfo.h"
     9#include "libmythtv/tv_play.h"
     10#include "libmythtv/programinfo.h"
    1111
    1212#include "libmyth/exitcodes.h"
    1313#include "libmyth/mythcontext.h"
    1414#include "libmyth/mythdbcon.h"
    1515#include "libmyth/mythdialogs.h"
    1616#include "libmyth/compat.h"
     17#include "libmythtv/mythcontextui.h"
    1718
    1819#include <iostream>
    1920using namespace std;
     
    200201        gContext->SetX11Display(display);
    201202    }
    202203
    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())
    206206    {
    207207        VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting.");
    208208        return TV_EXIT_NO_MYTHCONTEXT;
     
    249249        return TV_EXIT_NO_THEME;
    250250    }
    251251   
    252     gContext->LoadQtConfig();
    253 
    254252#if defined(Q_OS_MACX)
    255253    // Mac OS X doesn't define the AudioOutputDevice setting
    256254#else
     
    263261    }
    264262#endif
    265263
    266     MythMainWindow *mainWindow = GetMythMainWindow();
    267     mainWindow->Init();
    268     gContext->SetMainWindow(mainWindow);
     264    context->CreateMainWindow();
    269265
    270266    TV::InitKeys();
    271267
  • mythtv/programs/mythwelcome/main.cpp

     
    1414#include "libmyth/compat.h"
    1515
    1616#include "libmythtv/tv.h"
     17#include "libmythtv/mythcontextui.h"
    1718
    1819#include "welcomedialog.h"
    1920#include "welcomesettings.h"
     
    3839
    3940    QApplication a(argc, argv);
    4041
    41     gContext = NULL;
    42     gContext = new MythContext(MYTH_BINARY_VERSION);
     42    gContext = (MythContext *) new MythContextGUI(MYTH_BINARY_VERSION);
    4343    if (!gContext->Init(false))
    4444    {
    4545        VERBOSE(VB_IMPORTANT, "mythwelcome: Could not initialize myth context. "
     
    122122
    123123    LanguageSettings::load("mythfrontend");
    124124
    125     gContext->LoadQtConfig();
     125    MythMainWindow *mainWindow = gContext->CreateMainWindow();
    126126
    127     MythMainWindow *mainWindow = GetMythMainWindow();
    128     mainWindow->Init();
    129     gContext->SetMainWindow(mainWindow);
    130 
    131127    initKeys();
    132128
    133129    if (bShowSettings)
  • mythtv/programs/mythfilldatabase/main.cpp

     
    2222// filldata headers
    2323#include "filldata.h"
    2424
     25
     26#include "libmythtv/mythcontextui.h"
     27
    2528int main(int argc, char *argv[])
    2629{
    2730    QApplication a(argc, argv, false);
     
    471474        ++argpos;
    472475    }
    473476
    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))
    477479    {
    478480        VERBOSE(VB_IMPORTANT, "Failed to init MythContext, exiting.");
    479481        return FILLDB_EXIT_NO_MYTHCONTEXT;
  • mythtv/programs/mythshutdown/main.cpp

     
    77using namespace std;
    88#include <unistd.h>
    99
    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"
    1313#include "libmythtv/programinfo.h"
    1414#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"
    1819
    1920void setGlobalSetting(const QString &key, const QString &value)
    2021{
     
    712713
    713714    QApplication a(argc, argv, false);
    714715
    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))
    718718    {
    719719        cout << "mythshutdown: Could not initialize myth context. "
    720720                "Exiting." << endl;
  • mythplugins/programs-libs.pro

     
    11INCLUDEPATH += $${PREFIX}/include/mythtv
    22
    33LIBS += -L$${PREFIX}/lib $$EXTRA_LIBS
    4 LIBS += -lmyth-$$LIBVERSION -lmythui-$$LIBVERSION -lmythupnp-$$LIBVERSION
    54
     5# To initialise the MythContext subclass, we now need all these libraries.
     6LIBS += -lmythavcodec-$$LIBVERSION  -lmythavutil-$$LIBVERSION
     7LIBS += -lmythavformat-$$LIBVERSION
     8LIBS += -lmythfreemheg-$$LIBVERSION -lmythlivemedia-$$LIBVERSION
     9LIBS += -lmythupnp-$$LIBVERSION     -lmythtv-$$LIBVERSION
     10
    611mac:using_firewire:using_backend:LIBS += -F$${CONFIG_MAC_AVC} -framework AVCVideoServices
  • mythplugins/mytharchive/mytharchivehelper/main.cpp

     
    2929#include <mythtv/exitcodes.h>
    3030#include <mythtv/mythdbcon.h>
    3131#include <mythtv/libmythtv/programinfo.h>
     32#include <mythtv/libmythtv/mythcontextui.h>
    3233extern "C" {
    3334#include <mythtv/ffmpeg/avcodec.h>
    3435#include <mythtv/ffmpeg/avformat.h>
     
    22492250
    22502251int getDBParamters(QString outFile)
    22512252{
    2252     DatabaseParams params = gContext->GetDatabaseParams();
     2253    DatabaseParams params = gDBparams;
    22532254
    22542255    // save the db paramters to the file
    22552256    QFile f(outFile);
     
    23532354
    23542355    QApplication a(argc, argv, false);
    23552356
    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))
    23592359    {
    23602360        cout << "mytharchivehelper: Could not initialize myth context. "
    23612361                "Exiting." << endl;;
  • mythplugins/mythbrowser/mythbrowser/main.cpp

     
    2121#include "mythtv/mythcontext.h"
    2222#include "mythtv/mythdbcon.h"
    2323#include "mythtv/langsettings.h"
     24#include "libmythtv/mythcontextui.h"
    2425
    2526
    2627static const char *version = "v0.32";
     
    9495
    9596    KApplication a(argc,argv);
    9697
    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())
    100100    {
    101101        VERBOSE(VB_IMPORTANT, "MythBrowser: Could not initialize myth context. Exiting.");
    102102        return FRONTEND_EXIT_NO_MYTHCONTEXT;
     
    122122
    123123    LanguageSettings::load("mythbrowser");
    124124
    125     gContext->LoadQtConfig();
     125    MythMainWindow *mainWindow = gContext->CreateMainWindow();
     126
    126127    setupKeys();
    127128
    128     MythMainWindow *mainWindow = GetMythMainWindow();
    129     mainWindow->Init();
    130     gContext->SetMainWindow(mainWindow);
    131 
    132129    TabView *tabView =
    133130            new TabView(mainWindow, "mythbrowser", urls, zoom, width, height,
    134131                        Qt::WStyle_Customize | Qt::WStyle_NoBorder);
  • mythplugins/mythvideo/mtd/main.cpp

     
    2020#include <mythtv/mythdbcon.h>
    2121#include <mythtv/langsettings.h>
    2222#include <mythtv/compat.h>
     23#include <mythtv/libmythtv/mythcontextui.h>
    2324
    2425#include "../mythvideo/dbcheck.h"
    2526#include "mtd.h"
     
    112113    //
    113114    //  Get the Myth context and db hooks
    114115    //   
    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))
    119119    {
    120120        cerr << "Could not initialize myth context. Exiting." << endl;
    121121        return FRONTEND_EXIT_NO_MYTHCONTEXT;