From fb238f76d964145c67b34c9d72cd45350cca2263 Mon Sep 17 00:00:00 2001
From: Britney Fransen <brfransen@gmail.com>
Date: Wed, 20 Feb 2019 19:56:41 +0000
Subject: mythinstall: update for mythtv 30

added settings mythconfiggroups and mythdialogs for old settings that were removed in myth 30
---
 .../mythinstall/mythconfigdialogs.cpp              |  162 +++
 .../mythinstall/mythconfigdialogs.h                |   83 ++
 .../mythinstall/mythconfiggroups.cpp               |  701 +++++++++++
 .../MythVantage-app/mythinstall/mythconfiggroups.h |  274 +++++
 .../MythVantage-app/mythinstall/mythinstall.pro    |   19 +-
 .../MythVantage-app/mythinstall/settings.cpp       | 1236 ++++++++++++++++++++
 .../MythVantage-app/mythinstall/settings.h         |  835 +++++++++++++
 abs/core/mythinstall/PKGBUILD                      |   10 +-
 8 files changed, 3311 insertions(+), 9 deletions(-)
 create mode 100644 abs/core/mythinstall/MythVantage-app/mythinstall/mythconfigdialogs.cpp
 create mode 100644 abs/core/mythinstall/MythVantage-app/mythinstall/mythconfigdialogs.h
 create mode 100644 abs/core/mythinstall/MythVantage-app/mythinstall/mythconfiggroups.cpp
 create mode 100644 abs/core/mythinstall/MythVantage-app/mythinstall/mythconfiggroups.h
 create mode 100644 abs/core/mythinstall/MythVantage-app/mythinstall/settings.cpp
 create mode 100644 abs/core/mythinstall/MythVantage-app/mythinstall/settings.h

diff --git a/abs/core/mythinstall/MythVantage-app/mythinstall/mythconfigdialogs.cpp b/abs/core/mythinstall/MythVantage-app/mythinstall/mythconfigdialogs.cpp
new file mode 100644
index 0000000..f530872
--- /dev/null
+++ b/abs/core/mythinstall/MythVantage-app/mythinstall/mythconfigdialogs.cpp
@@ -0,0 +1,162 @@
+// -*- Mode: c++ -*-
+
+
+#include "mythconfigdialogs.h"
+
+#include "mythwizard.h"
+#include "mythuihelper.h"
+
+// C++ headers
+#include <vector>
+using std::vector;
+
+#include <QApplication>
+#include <QWidget>
+#include <QHBoxLayout>
+
+static void clear_widgets(vector<Configurable*> &children,
+                          vector<QWidget*>      &childwidget)
+{
+    for (uint i = 0; (i < childwidget.size()) && (i < children.size()); i++)
+    {
+        if (children[i] && childwidget[i])
+            children[i]->widgetInvalid(childwidget[i]);
+    }
+    childwidget.clear();
+}
+
+void ConfigurationDialogWidget::keyPressEvent(QKeyEvent* e)
+{
+    bool handled = false;
+    QStringList actions;
+
+    handled = GetMythMainWindow()->TranslateKeyPress("qt", e, actions);
+
+    for (int i = 0; i < actions.size() && !handled; i++)
+    {
+        const QString &action = actions[i];
+        handled = true;
+
+        if (action == "SELECT")
+            accept();
+        else if (action == "ESCAPE")
+            reject();
+        else if (action == "EDIT")
+            emit editButtonPressed();
+        else if (action == "DELETE")
+            emit deleteButtonPressed();
+        else
+            handled = false;
+    }
+
+    if (!handled)
+        MythDialog::keyPressEvent(e);
+}
+
+ConfigurationDialog::~ConfigurationDialog()
+{
+    clear_widgets(cfgChildren, childwidget);
+    cfgGrp->deleteLater();
+}
+
+MythDialog* ConfigurationDialog::dialogWidget(MythMainWindow *parent,
+                                              const char *widgetName)
+{
+    dialog = new ConfigurationDialogWidget(parent, widgetName);
+
+    float wmult = 0, hmult = 0;
+
+    GetMythUI()->GetScreenSettings(wmult, hmult);
+
+    QVBoxLayout *layout = new QVBoxLayout(dialog);
+    layout->setSpacing((int)(20 * hmult));
+
+    ChildList::iterator it = cfgChildren.begin();
+    childwidget.clear();
+    childwidget.resize(cfgChildren.size());
+    for (uint i = 0; it != cfgChildren.end(); ++it, ++i)
+    {
+        if ((*it)->isVisible())
+        {
+            childwidget[i] = (*it)->configWidget(cfgGrp, dialog);
+            layout->addWidget(childwidget[i]);
+        }
+    }
+
+    return dialog;
+}
+
+DialogCode ConfigurationDialog::exec(bool saveOnAccept, bool doLoad)
+{
+    if (doLoad)
+        Load();
+
+    MythDialog *dialog = dialogWidget(
+        GetMythMainWindow(), "Configuration Dialog");
+
+    dialog->Show();
+
+    DialogCode ret = dialog->exec();
+
+    if ((QDialog::Accepted == ret) && saveOnAccept)
+        Save();
+
+    clear_widgets(cfgChildren, childwidget);
+
+    dialog->deleteLater();
+    dialog = NULL;
+
+    return ret;
+}
+
+void ConfigurationDialog::addChild(Configurable *child)
+{
+    cfgChildren.push_back(child);
+    cfgGrp->addChild(child);
+}
+
+void ConfigurationDialog::setLabel(const QString &label)
+{
+    if (label.isEmpty())
+    {
+        cfgGrp->setUseLabel(false);
+        cfgGrp->setLabel("");
+    }
+    else
+    {
+        cfgGrp->setLabel(label);
+        cfgGrp->setUseLabel(true);
+        cfgGrp->setUseFrame(true);
+    }
+}
+
+MythDialog *ConfigurationWizard::dialogWidget(MythMainWindow *parent,
+                                              const char     *widgetName)
+{
+    MythWizard *wizard = new MythWizard(parent, widgetName);
+    dialog = wizard;
+
+    QObject::connect(cfgGrp, SIGNAL(changeHelpText(QString)),
+                     wizard, SLOT(  setHelpText(   QString)));
+
+    QWidget *widget = parent;
+#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
+    if (qApp->platformName().contains("egl"))
+        widget = wizard;
+#endif
+    QWidget *child = NULL;
+    ChildList::iterator it = cfgChildren.begin();
+    for (; it != cfgChildren.end(); ++it)
+    {
+        if (!(*it)->isVisible())
+            continue;
+
+        child = (*it)->configWidget(cfgGrp, widget);
+        wizard->addPage(child, (*it)->getLabel());
+    }
+
+    if (child)
+        wizard->setFinishEnabled(child, true);
+
+    return wizard;
+}
diff --git a/abs/core/mythinstall/MythVantage-app/mythinstall/mythconfigdialogs.h b/abs/core/mythinstall/MythVantage-app/mythinstall/mythconfigdialogs.h
new file mode 100644
index 0000000..4d9969c
--- /dev/null
+++ b/abs/core/mythinstall/MythVantage-app/mythinstall/mythconfigdialogs.h
@@ -0,0 +1,83 @@
+// -*- Mode: c++ -*-
+
+#ifndef MYTH_CONFIG_DIALOGS_H
+#define MYTH_CONFIG_DIALOGS_H
+
+// Qt headers
+#include <QObject>
+#include <QString>
+
+// MythTV headers
+#include "mythexp.h"
+#include "mythdialogs.h"
+#include "mythstorage.h"
+#include "mythconfiggroups.h"
+
+class MPUBLIC ConfigurationDialogWidget : public MythDialog
+{
+    Q_OBJECT
+
+        public:
+    ConfigurationDialogWidget(MythMainWindow *parent,
+                              const char     *widgetName) :
+        MythDialog(parent, widgetName) { }
+
+    virtual void keyPressEvent(QKeyEvent *e);
+
+  signals:
+    void editButtonPressed(void);
+    void deleteButtonPressed(void);
+};
+
+/** \class ConfigurationDialog
+ *  \brief A ConfigurationDialog that uses a ConfigurationGroup
+ *         all children on one page in a vertical layout.
+ */
+class MPUBLIC ConfigurationDialog : public Storage
+{
+  public:
+    ConfigurationDialog() : dialog(NULL), cfgGrp(new ConfigurationGroup()) { }
+    virtual ~ConfigurationDialog();
+
+    // Make a modal dialog containing configWidget
+    virtual MythDialog *dialogWidget(MythMainWindow *parent,
+                                     const char     *widgetName);
+
+    // Show a dialogWidget, and save if accepted
+    virtual DialogCode exec(bool saveOnExec = true, bool doLoad = true);
+
+    virtual void addChild(Configurable *child);
+
+    virtual Setting *byName(const QString &settingName)
+        { return cfgGrp->byName(settingName); }
+
+    void setLabel(const QString &label);
+
+    // Storage
+    virtual void Load(void) { cfgGrp->Load(); }
+    virtual void Save(void) { cfgGrp->Save(); }
+    virtual void Save(QString destination) { cfgGrp->Save(destination); }
+
+  protected:
+    typedef std::vector<Configurable*> ChildList;
+
+    ChildList           cfgChildren;
+    std::vector<QWidget*>    childwidget;
+    MythDialog         *dialog;
+    ConfigurationGroup *cfgGrp;
+};
+
+/** \class ConfigurationWizard
+ *  \brief A ConfigurationDialog that uses a ConfigurationGroup
+ *         with one child per page.
+ */
+class MPUBLIC ConfigurationWizard : public ConfigurationDialog
+{
+  public:
+    ConfigurationWizard() : ConfigurationDialog() {}
+
+    virtual MythDialog *dialogWidget(MythMainWindow *parent,
+                                     const char *widgetName);
+};
+
+#endif // MYTH_CONFIG_DIALOGS_H
diff --git a/abs/core/mythinstall/MythVantage-app/mythinstall/mythconfiggroups.cpp b/abs/core/mythinstall/MythVantage-app/mythinstall/mythconfiggroups.cpp
new file mode 100644
index 0000000..08cf134
--- /dev/null
+++ b/abs/core/mythinstall/MythVantage-app/mythinstall/mythconfiggroups.cpp
@@ -0,0 +1,701 @@
+#include <algorithm>
+
+using namespace std;
+
+#include <QStackedWidget>
+
+#include "mythconfiggroups.h"
+#include "mythcontext.h"
+#include "mythlogging.h"
+#include "mythuihelper.h"
+
+static void clear_widgets(vector<Configurable*> &children,
+                          vector<QWidget*>      &childwidget)
+{
+    for (uint i = 0; (i < childwidget.size()) && (i < children.size()); i++)
+    {
+        if (children[i] && childwidget[i])
+            children[i]->widgetInvalid(childwidget[i]);
+    }
+    childwidget.clear();
+}
+
+ConfigurationGroup::ConfigurationGroup(bool luselabel,   bool luseframe,
+                                       bool lzeroMargin, bool lzeroSpace) :
+    Setting(this),
+    uselabel(luselabel),     useframe(luseframe),
+    zeroMargin(lzeroMargin), zeroSpace(lzeroSpace)
+{
+    // Pre-calculate the margin and spacing that all sub-classes will use:
+
+    if (lzeroMargin)
+        margin = 2;
+    else
+    {
+        float wmult = 0, hmult = 0;
+
+        GetMythUI()->GetScreenSettings(wmult, hmult);
+
+        if (luselabel)
+            margin = (int)(28 * hmult * 0.5);
+        else
+            margin = (int)(10 * hmult * 0.5);
+    }
+
+    space = (lzeroSpace) ? 2 : -1;
+}
+
+ConfigurationGroup::~ConfigurationGroup()
+{
+    childList::iterator it = children.begin();
+    for (; it != children.end() ; ++it)
+    {
+        if (*it)
+        {
+            (*it)->disconnect();
+            (*it)->deleteLater();
+        }
+    }
+    children.clear();
+}
+
+void ConfigurationGroup::deleteLater(void)
+{
+    childList::iterator it = children.begin();
+    for (; it != children.end() ; ++it)
+    {
+        if (*it)
+            (*it)->disconnect();
+    }
+    Setting::deleteLater();
+}
+
+Setting *ConfigurationGroup::byName(const QString &name)
+{
+    Setting *tmp = NULL;
+
+    childList::iterator it = children.begin();
+    for (; !tmp && (it != children.end()); ++it)
+    {
+        if (*it)
+            tmp = (*it)->byName(name);
+    }
+
+    return tmp;
+}
+
+void ConfigurationGroup::Load(void)
+{
+    childList::iterator it = children.begin();
+    for (; it != children.end() ; ++it)
+        if (*it && (*it)->GetStorage())
+            (*it)->GetStorage()->Load();
+}
+
+void ConfigurationGroup::Save(void)
+{
+    childList::iterator it = children.begin();
+    for (; it != children.end() ; ++it)
+        if (*it && (*it)->GetStorage())
+            (*it)->GetStorage()->Save();
+}
+
+void ConfigurationGroup::Save(QString destination)
+{
+    childList::iterator it = children.begin();
+    for (; it != children.end() ; ++it)
+        if (*it && (*it)->GetStorage())
+            (*it)->GetStorage()->Save(destination);
+}
+
+void ConfigurationGroup::SetSaveRequired(void)
+{
+    childList::iterator it = children.begin();
+    for (; it != children.end() ; ++it)
+        if (*it && (*it)->GetStorage())
+            (*it)->GetStorage()->SetSaveRequired();
+}
+
+QWidget *VerticalConfigurationGroup::configWidget(
+    ConfigurationGroup *cg,
+    QWidget            *parent,
+    const char         *widgetName)
+{
+    if (layout)
+        layout->deleteLater();
+    layout = new QVBoxLayout();
+    layout->setMargin(margin);
+    layout->setSpacing((space<0) ? margin : space);
+
+    childwidget.resize(children.size());
+    for (uint i = 0; i < children.size(); i++)
+    {
+        if (children[i] && children[i]->isVisible())
+        {
+            childwidget[i] = children[i]->configWidget(cg, NULL, NULL);
+            layout->addWidget(childwidget[i]);
+            children[i]->setEnabled(children[i]->isEnabled());
+        }
+    }
+
+    if (cg)
+    {
+        connect(this, SIGNAL(changeHelpText(QString)),
+                cg,   SIGNAL(changeHelpText(QString)));
+        confgrp = cg;
+    }
+
+    if (uselabel)
+    {
+        MythGroupBox *groupbox = new MythGroupBox(parent);
+        groupbox->setObjectName(QString("VCG(%1)_groupbox").arg(widgetName));
+        groupbox->setTitle(getLabel());
+        widget = groupbox;
+    }
+    else if (useframe)
+    {
+        QFrame *frame = new QFrame(parent);
+        frame->setFrameStyle(QFrame::Box);
+        frame->setObjectName(QString("VCG(%1)_frame").arg(widgetName));
+        widget = frame;
+    }
+    else
+    {
+        widget = new QWidget(parent);
+        widget->setObjectName(QString("VCG(%1)_widget").arg(widgetName));
+    }
+
+    widget->setLayout(layout);
+    connect(widget, SIGNAL(destroyed(QObject*)),
+            this,   SLOT(widgetDeleted(QObject*)));
+    return widget;
+}
+
+void VerticalConfigurationGroup::widgetInvalid(QObject *obj)
+{
+    widget = (widget == obj) ? NULL : widget;
+}
+
+void VerticalConfigurationGroup::deleteLater(void)
+{
+    clear_widgets(children, childwidget);
+    ConfigurationGroup::deleteLater();
+}
+
+bool VerticalConfigurationGroup::replaceChild(
+    Configurable *old_child, Configurable *new_child)
+{
+    childList::iterator it = children.begin();
+    for (uint i = 0; it != children.end(); ++it, ++i)
+    {
+        if (*it != old_child)
+            continue;
+
+        *it = new_child;
+
+        if (!widget)
+        {
+            old_child->deleteLater();
+            return true;
+        }
+
+        if (childwidget[i])
+        {
+            old_child->widgetInvalid(childwidget[i]);
+            layout->removeWidget(childwidget[i]);
+            childwidget[i]->deleteLater();
+            childwidget[i] = NULL;
+        }
+
+        bool was_visible = old_child->isVisible();
+        bool was_enabled = old_child->isEnabled();
+
+        old_child->deleteLater();
+
+        if (was_visible)
+        {
+            childwidget[i] = new_child->configWidget(confgrp, widget, NULL);
+            layout->addWidget(childwidget[i]);
+            new_child->setEnabled(was_enabled);
+            childwidget[i]->resize(1,1);
+            childwidget[i]->show();
+        }
+
+        return true;
+    }
+
+    return false;
+}
+
+void VerticalConfigurationGroup::repaint(void)
+{
+    if (widget)
+        widget->repaint();
+}
+
+QWidget *HorizontalConfigurationGroup::configWidget(
+    ConfigurationGroup *cg,
+    QWidget            *parent,
+    const char         *widgetName)
+{
+    QHBoxLayout *layout = new QHBoxLayout();
+    layout->setMargin(margin);
+    layout->setSpacing((space<0) ? margin : space);
+
+    for (uint i = 0 ; i < children.size() ; ++i)
+    {
+        if (children[i] && children[i]->isVisible())
+        {
+            QWidget *child = children[i]->configWidget(cg, NULL, NULL);
+            layout->addWidget(child);
+            children[i]->setEnabled(children[i]->isEnabled());
+        }
+    }
+
+    if (cg)
+    {
+        connect(this, SIGNAL(changeHelpText(QString)),
+                cg,   SIGNAL(changeHelpText(QString)));
+    }
+
+    QWidget *widget = NULL;
+    if (uselabel)
+    {
+        MythGroupBox *groupbox = new MythGroupBox(parent);
+        groupbox->setObjectName(QString("HCG(%1)_groupbox").arg(widgetName));
+        groupbox->setTitle(getLabel());
+        widget = groupbox;
+    }
+    else if (useframe)
+    {
+        QFrame *frame = new QFrame(parent);
+        frame->setFrameStyle(QFrame::Box);
+        frame->setObjectName(QString("HCG(%1)_frame").arg(widgetName));
+        widget = frame;
+    }
+    else
+    {
+        widget = new QWidget(parent);
+        widget->setObjectName(QString("HCG(%1)_widget").arg(widgetName));
+    }
+
+    widget->setLayout(layout);
+    return widget;
+}
+
+QWidget* GridConfigurationGroup::configWidget(
+    ConfigurationGroup *cg,
+    QWidget            *parent,
+    const char         *widgetName)
+{
+    QGridLayout *layout = new QGridLayout();
+    layout->setMargin(margin);
+    layout->setSpacing(space < 0 ? margin : space);
+
+    for (uint i = 0; i < children.size(); i++)
+    {
+        if (children[i] && children[i]->isVisible())
+        {
+            QWidget *child = children[i]->configWidget(cg, NULL, NULL);
+            layout->addWidget(child, i / columns, i % columns);
+            children[i]->setEnabled(children[i]->isEnabled());
+        }
+    }
+
+    if (cg)
+    {
+        connect(this, SIGNAL(changeHelpText(QString)),
+                cg,   SIGNAL(changeHelpText(QString)));
+    }
+
+    QWidget *widget = NULL;
+    if (uselabel)
+    {
+        MythGroupBox *groupbox = new MythGroupBox(parent);
+        groupbox->setObjectName(QString("GCG(%1)_groupbox").arg(widgetName));
+        groupbox->setTitle(getLabel());
+        widget = groupbox;
+    }
+    else if (useframe)
+    {
+        QFrame *frame = new QFrame(parent);
+        frame->setFrameStyle(QFrame::Box);
+        frame->setObjectName(QString("GCG(%1)_frame").arg(widgetName));
+        widget = frame;
+    }
+    else
+    {
+        widget = new QWidget(parent);
+        widget->setObjectName(QString("GCG(%1)_widget").arg(widgetName));
+    }
+
+    widget->setLayout(layout);
+
+    return widget;
+}
+
+StackedConfigurationGroup::~StackedConfigurationGroup()
+{
+    clear_widgets(children, childwidget);
+    ConfigurationGroup::deleteLater();
+}
+
+void StackedConfigurationGroup::deleteLater(void)
+{
+    clear_widgets(children, childwidget);
+    ConfigurationGroup::deleteLater();
+}
+
+QWidget* StackedConfigurationGroup::configWidget(ConfigurationGroup *cg,
+                                                 QWidget* parent,
+                                                 const char* widgetName)
+{
+    widget = new QStackedWidget(parent);
+    widget->setObjectName(widgetName);
+
+    connect(widget, SIGNAL(destroyed(QObject*)),
+            this,   SLOT(  widgetDeleted(QObject*)));
+
+    for (uint i = 0 ; i < children.size() ; ++i)
+    {
+        if (!children[i]->isVisible())
+            continue;
+
+        childwidget[i] = children[i]->configWidget(cg, widget, NULL);
+        if (!childwidget[i])
+            continue;
+
+        connect(childwidget[i], SIGNAL(destroyed(    QObject*)),
+                this,           SLOT(  widgetInvalid(QObject*)));
+        widget->addWidget(childwidget[i]);
+        children[i]->setEnabled(children[i]->isEnabled());
+    }
+
+    if (childwidget[top])
+        widget->setCurrentWidget(childwidget[top]);
+
+    if (cg)
+    {
+        connect(this, SIGNAL(changeHelpText(QString)), cg,
+                SIGNAL(changeHelpText(QString)));
+    }
+    confgrp = cg;
+
+    return widget;
+}
+
+void StackedConfigurationGroup::widgetInvalid(QObject *obj)
+{
+    widget = (widget == obj) ? NULL : widget;
+    for (uint i = 0; i < childwidget.size(); i++)
+    {
+        if ((QObject*)childwidget[i] == obj)
+            childwidget[i] = NULL;
+    }
+}
+
+void StackedConfigurationGroup::addChild(Configurable *child)
+{
+    ConfigurationGroup::addChild(child);
+    childwidget.resize(childwidget.size() + 1);
+    if (!widget)
+        return;
+
+    uint i = children.size() - 1;
+    if ((i < children.size()) && children[i]->isVisible())
+    {
+        childwidget[i] = children[i]->configWidget(confgrp, widget, NULL);
+        widget->addWidget(childwidget[i]);
+        childwidget[i]->resize(1,1);
+        childwidget[i]->show();
+    }
+}
+
+void StackedConfigurationGroup::removeChild(Configurable *child)
+{
+    childList::iterator it = find(children.begin(), children.end(), child);
+    if (it == children.end())
+        return;
+
+    uint i = it - children.begin();
+    if ((i >= children.size()) || (i >= childwidget.size()))
+        return;
+
+    children.erase(it);
+
+    vector<QWidget*>::iterator cit = childwidget.begin() + i;
+    QWidget *cw = *cit;
+    childwidget.erase(cit);
+
+    if (widget && cw)
+    {
+        child->widgetInvalid(cw);
+        widget->removeWidget(cw);
+    }
+}
+
+void StackedConfigurationGroup::raise(Configurable* child)
+{
+    for (uint i = 0 ; i < children.size() ; i++)
+    {
+        if (children[i] == child)
+        {
+            top = i;
+            if (widget && childwidget[top])
+                widget->setCurrentWidget(childwidget[top]);
+            return;
+        }
+    }
+
+    LOG(VB_GENERAL, LOG_ALERT,
+             QString("BUG: StackedConfigurationGroup::raise(): "
+                     "unrecognized child 0x%1 on setting %2/%3")
+                 .arg((uint64_t)child,0,16).arg(getName()).arg(getLabel()));
+}
+
+void StackedConfigurationGroup::Save(void)
+{
+    if (saveAll)
+        ConfigurationGroup::Save();
+    else if (top < children.size())
+        children[top]->GetStorage()->Save();
+}
+
+void StackedConfigurationGroup::Save(QString destination)
+{
+    if (saveAll)
+        ConfigurationGroup::Save(destination);
+    else if (top < children.size())
+        children[top]->GetStorage()->Save(destination);
+}
+
+void TriggeredConfigurationGroup::addChild(Configurable* child)
+{
+    VerifyLayout();
+    configLayout->addChild(child);
+}
+
+void TriggeredConfigurationGroup::addTarget(QString triggerValue,
+                                            Configurable *target)
+{
+    VerifyLayout();
+    triggerMap[triggerValue] = target;
+
+    if (!configStack)
+    {
+        configStack = new StackedConfigurationGroup(
+            stackUseLabel, stackUseFrame, stackZeroMargin, stackZeroSpace);
+        configStack->setSaveAll(isSaveAll);
+    }
+
+    configStack->addChild(target);
+}
+
+Setting *TriggeredConfigurationGroup::byName(const QString &settingName)
+{
+    VerifyLayout();
+    Setting *setting = ConfigurationGroup::byName(settingName);
+
+    if (!setting)
+        setting = configLayout->byName(settingName);
+
+    if (!setting && !widget)
+        setting = configStack->byName(settingName);
+
+    return setting;
+}
+
+void TriggeredConfigurationGroup::Load(void)
+{
+    VerifyLayout();
+
+    configLayout->Load();
+
+    if (!widget && configStack)
+        configStack->Load();
+}
+
+void TriggeredConfigurationGroup::Save(void)
+{
+    VerifyLayout();
+
+    configLayout->Save();
+
+    if (!widget)
+        configStack->Save();
+}
+
+void TriggeredConfigurationGroup::Save(QString destination)
+{
+    VerifyLayout();
+
+    configLayout->Save(destination);
+
+    if (!widget)
+        configStack->Save(destination);
+}
+
+void TriggeredConfigurationGroup::repaint(void)
+{
+    VerifyLayout();
+
+    if (widget)
+        widget->repaint();
+}
+
+void TriggeredConfigurationGroup::setTrigger(Configurable *_trigger)
+{
+    if (trigger)
+    {
+        trigger->disconnect();
+    }
+
+    trigger = _trigger;
+
+    if (trigger)
+    {
+        connect(trigger, SIGNAL(valueChanged(  const QString&)),
+                this,    SLOT(  triggerChanged(const QString&)));
+    }
+}
+
+void TriggeredConfigurationGroup::triggerChanged(const QString &value)
+{
+    if (!configStack)
+        return;
+
+    QMap<QString,Configurable*>::iterator it = triggerMap.find(value);
+
+    if (it == triggerMap.end())
+    {
+        LOG(VB_GENERAL, LOG_ALERT,
+                "TriggeredConfigurationGroup::" +
+                QString("triggerChanged(%1) Error:").arg(value) +
+                "Failed to locate value in triggerMap");
+    }
+    else
+    {
+        configStack->raise(*it);
+    }
+}
+
+/** \fn TriggeredConfigurationGroup::SetVertical(bool)
+ *  \brief By default we use a vertical layout, but you can call this
+ *         with a false value to use a horizontal layout instead.
+ *
+ *  NOTE: This must be called before this addChild() is first called.
+ */
+void TriggeredConfigurationGroup::SetVertical(bool vert)
+{
+    if (configLayout)
+    {
+        LOG(VB_GENERAL, LOG_ALERT,
+                 "TriggeredConfigurationGroup::setVertical(): "
+                 "Sorry, this must be called before any children are added "
+                 "to the group.");
+        return;
+    }
+
+    isVertical = vert;
+}
+
+void TriggeredConfigurationGroup::removeTarget(QString triggerValue)
+{
+    ComboBoxSetting *combobox = dynamic_cast<ComboBoxSetting*>(trigger);
+    if (!combobox)
+    {
+        LOG(VB_GENERAL, LOG_ALERT,
+                 "TriggeredConfigurationGroup::removeTarget(): "
+                 "Failed to cast trigger to ComboBoxSetting -- aborting");
+        return;
+    }
+
+    QMap<QString,Configurable*>::iterator cit = triggerMap.find(triggerValue);
+    if (cit == triggerMap.end())
+    {
+        LOG(VB_GENERAL, LOG_ALERT,
+                 QString("TriggeredConfigurationGroup::removeTarget(): "
+                        "Failed to find desired value(%1) -- aborting")
+                     .arg(triggerValue));
+        return;
+    }
+
+    // remove trigger value from trigger combobox
+    bool ok = false;
+    for (uint i = 0; i < combobox->size(); i++)
+    {
+        if (combobox->GetValue(i) == triggerValue)
+        {
+            ok = combobox->removeSelection(
+                combobox->GetLabel(i), combobox->GetValue(i));
+            break;
+        }
+    }
+
+    if (!ok)
+    {
+        LOG(VB_GENERAL, LOG_ALERT,
+                 QString("TriggeredConfigurationGroup::removeTarget(): "
+                         "Failed to remove '%1' from combobox -- aborting")
+                     .arg(triggerValue));
+        return;
+    }
+
+    // actually remove the pane
+    configStack->removeChild(*cit);
+    triggerMap.erase(cit);
+}
+
+void TriggeredConfigurationGroup::VerifyLayout(void)
+{
+    if (configLayout)
+        return;
+
+    if (isVertical)
+    {
+        configLayout = new VerticalConfigurationGroup(
+            uselabel, useframe, zeroMargin, zeroSpace);
+    }
+    else
+    {
+        configLayout = new HorizontalConfigurationGroup(
+            uselabel, useframe, zeroMargin, zeroSpace);
+    }
+
+    ConfigurationGroup::addChild(configLayout);
+}
+
+QWidget *TriggeredConfigurationGroup::configWidget(
+    ConfigurationGroup *cg, QWidget *parent, const char *widgetName)
+{
+    VerifyLayout();
+
+    configLayout->addChild(configStack);
+
+    widget = configLayout->configWidget(cg, parent, widgetName);
+    connect(widget, SIGNAL(destroyed(QObject*)),
+            this,   SLOT(widgetDeleted(QObject*)));
+
+    return widget;
+}
+
+void TriggeredConfigurationGroup::widgetInvalid(QObject *obj)
+{
+    widget = (widget == obj) ? NULL : widget;
+}
+
+JumpPane::JumpPane(const QStringList &labels, const QStringList &helptext) :
+    VerticalConfigurationGroup(true, false, true, true)
+{
+    //setLabel(tr("Jump To Buttons"));
+    for (int i = 0; i < labels.size(); i++)
+    {
+        TransButtonSetting *button =
+            new TransButtonSetting(QString::number(i));
+        button->setLabel(labels[i]);
+        button->setHelpText(helptext[i]);
+        connect(button, SIGNAL(pressed(QString)),
+                this,   SIGNAL(pressed(QString)));
+        addChild(button);
+    }
+}
diff --git a/abs/core/mythinstall/MythVantage-app/mythinstall/mythconfiggroups.h b/abs/core/mythinstall/MythVantage-app/mythinstall/mythconfiggroups.h
new file mode 100644
index 0000000..85a17f8
--- /dev/null
+++ b/abs/core/mythinstall/MythVantage-app/mythinstall/mythconfiggroups.h
@@ -0,0 +1,274 @@
+// -*- Mode: c++ -*-
+
+#ifndef MYTH_CONFIG_GROUPS_H
+#define MYTH_CONFIG_GROUPS_H
+
+#include <QVBoxLayout>
+
+// MythTV headers
+#include "mythexp.h"
+#include "mythstorage.h"
+
+// C++ headers
+#include <vector>
+
+#define MYTHCONFIG
+#include "settings.h"
+#undef MYTHCONFIG
+
+class QStackedWidget;
+class MythGroupBox;
+
+class MPUBLIC ConfigurationGroup : public Setting, public Storage
+{
+    Q_OBJECT
+
+  public:
+    ConfigurationGroup(bool luselabel   = true,  bool luseframe  = true,
+                       bool lzeroMargin = false, bool lzeroSpace = false);
+
+    virtual void deleteLater(void);
+
+    void addChild(Configurable *child)
+    {
+        children.push_back(child);
+    };
+
+    virtual Setting *byName(const QString &name);
+
+    void setUseLabel(bool useit) { uselabel = useit; }
+    void setUseFrame(bool useit) { useframe = useit; }
+
+    void setOptions(bool luselabel   = true,  bool luseframe  = true,
+                    bool lzeroMargin = false, bool lzeroSpace = false)
+    {
+        uselabel = luselabel; useframe = luseframe;
+        zeroMargin = lzeroMargin; zeroSpace = lzeroSpace;
+    }
+
+    // Storage
+    virtual void Load(void);
+    virtual void Save(void);
+    virtual void Save(QString destination);
+    virtual void SetSaveRequired(void);
+
+  signals:
+    void changeHelpText(QString);
+
+  protected:
+    virtual ~ConfigurationGroup();
+
+  protected:
+    typedef std::vector<Configurable*> childList;
+    childList children;
+    bool uselabel;
+    bool useframe;
+    bool zeroMargin;
+    bool zeroSpace;
+    int margin;
+    int space;
+};
+
+class MPUBLIC VerticalConfigurationGroup : public ConfigurationGroup
+{
+  public:
+    VerticalConfigurationGroup(
+        bool luselabel   = true,  bool luseframe  = true,
+        bool lzeroMargin = false, bool lzeroSpace = false) :
+        ConfigurationGroup(luselabel, luseframe, lzeroMargin, lzeroSpace),
+        widget(NULL), confgrp(NULL), layout(NULL)
+    {
+    }
+
+    virtual void deleteLater(void);
+
+    virtual QWidget *configWidget(ConfigurationGroup *cg,
+                                  QWidget            *parent,
+                                  const char         *widgetName);
+    virtual void widgetInvalid(QObject *obj);
+
+    bool replaceChild(Configurable *old_child, Configurable *new_child);
+    void repaint(void);
+
+  protected:
+    /// You need to call deleteLater to delete QObject
+    virtual ~VerticalConfigurationGroup() { }
+
+  private:
+    std::vector<QWidget*>    childwidget;
+    QWidget            *widget;
+    ConfigurationGroup *confgrp;
+    QVBoxLayout        *layout;
+};
+
+class MPUBLIC HorizontalConfigurationGroup : public ConfigurationGroup
+{
+  public:
+    HorizontalConfigurationGroup(
+        bool luselabel   = true,  bool luseframe  = true,
+        bool lzeroMargin = false, bool lzeroSpace = false) :
+        ConfigurationGroup(luselabel, luseframe, lzeroMargin, lzeroSpace)
+    {
+    }
+
+    virtual QWidget *configWidget(ConfigurationGroup *cg,
+                                  QWidget            *parent,
+                                  const char         *widgetName);
+
+  protected:
+    /// You need to call deleteLater to delete QObject
+    virtual ~HorizontalConfigurationGroup() { }
+};
+
+class MPUBLIC GridConfigurationGroup : public ConfigurationGroup
+{
+  public:
+    GridConfigurationGroup(uint col,
+                           bool uselabel   = true,  bool useframe  = true,
+                           bool zeroMargin = false, bool zeroSpace = false) :
+        ConfigurationGroup(uselabel, useframe, zeroMargin, zeroSpace),
+        columns(col)
+    {
+    }
+
+    virtual QWidget *configWidget(ConfigurationGroup *cg,
+                                  QWidget            *parent,
+                                  const char         *widgetName);
+
+  protected:
+    /// You need to call deleteLater to delete QObject
+    virtual ~GridConfigurationGroup() { }
+
+  private:
+    uint columns;
+};
+
+class MPUBLIC StackedConfigurationGroup : public ConfigurationGroup
+{
+    Q_OBJECT
+
+  public:
+    StackedConfigurationGroup(
+        bool uselabel   = true,  bool useframe  = true,
+        bool zeroMargin = false, bool zeroSpace = false) :
+        ConfigurationGroup(uselabel, useframe, zeroMargin, zeroSpace),
+        widget(NULL), confgrp(NULL), top(0), saveAll(true)
+    {
+    }
+
+    virtual void deleteLater(void);
+
+    virtual QWidget *configWidget(ConfigurationGroup *cg, QWidget *parent,
+                                  const char *widgetName = 0);
+
+    void raise(Configurable *child);
+    virtual void Save(void);
+    virtual void Save(QString destination);
+
+    // save all children, or only the top?
+    void setSaveAll(bool b) { saveAll = b; };
+
+    void addChild(Configurable*);
+    void removeChild(Configurable*);
+
+  public slots:
+    virtual void widgetInvalid(QObject *obj);
+
+  protected:
+    /// You need to call deleteLater to delete QObject
+    virtual ~StackedConfigurationGroup();
+
+  protected:
+    std::vector<QWidget*>    childwidget;
+    QStackedWidget     *widget;
+    ConfigurationGroup *confgrp;
+    uint                top;
+    bool                saveAll;
+};
+
+class MPUBLIC TriggeredConfigurationGroup : public ConfigurationGroup
+{
+    Q_OBJECT
+
+  public:
+    TriggeredConfigurationGroup(
+        bool uselabel         = true,  bool useframe        = true,
+        bool zeroMargin       = false, bool zeroSpace       = false,
+        bool stack_uselabel   = true,  bool stack_useframe  = true,
+        bool stack_zeroMargin = false, bool stack_zeroSpace = false) :
+        ConfigurationGroup(uselabel, useframe, zeroMargin, zeroSpace),
+        stackUseLabel(stack_uselabel),     stackUseFrame(stack_useframe),
+        stackZeroMargin(stack_zeroMargin), stackZeroSpace(stack_zeroSpace),
+        isVertical(true),                  isSaveAll(true),
+        configLayout(NULL),                configStack(NULL),
+        trigger(NULL),                     widget(NULL)
+    {
+    }
+
+    // Commands
+
+    virtual void addChild(Configurable *child);
+
+    void addTarget(QString triggerValue, Configurable *target);
+    void removeTarget(QString triggerValue);
+
+    virtual QWidget *configWidget(ConfigurationGroup *cg,
+                                  QWidget            *parent,
+                                  const char         *widgetName);
+    virtual void widgetInvalid(QObject *obj);
+
+    virtual Setting *byName(const QString &settingName);
+
+    virtual void Load(void);
+    virtual void Save(void);
+    virtual void Save(QString destination);
+
+    void repaint(void);
+
+    // Sets
+
+    void SetVertical(bool vert);
+
+    virtual void setSaveAll(bool b)
+    {
+        if (configStack)
+            configStack->setSaveAll(b);
+        isSaveAll = b;
+    }
+
+    void setTrigger(Configurable *_trigger);
+
+  protected slots:
+    virtual void triggerChanged(const QString &value);
+
+  protected:
+    /// You need to call deleteLater to delete QObject
+    virtual ~TriggeredConfigurationGroup() { }
+    void VerifyLayout(void);
+
+  protected:
+    bool stackUseLabel;
+    bool stackUseFrame;
+    bool stackZeroMargin;
+    bool stackZeroSpace;
+    bool isVertical;
+    bool isSaveAll;
+    ConfigurationGroup          *configLayout;
+    StackedConfigurationGroup   *configStack;
+    Configurable                *trigger;
+    QMap<QString,Configurable*>  triggerMap;
+    QWidget                     *widget;
+};
+
+class MPUBLIC JumpPane : public VerticalConfigurationGroup
+{
+    Q_OBJECT
+
+  public:
+    JumpPane(const QStringList &labels, const QStringList &helptext);
+
+  signals:
+    void pressed(QString);
+};
+
+#endif // MYTH_CONFIG_GROUPS_H
diff --git a/abs/core/mythinstall/MythVantage-app/mythinstall/mythinstall.pro b/abs/core/mythinstall/MythVantage-app/mythinstall/mythinstall.pro
index 6405b52..099d0f0 100755
--- a/abs/core/mythinstall/MythVantage-app/mythinstall/mythinstall.pro
+++ b/abs/core/mythinstall/MythVantage-app/mythinstall/mythinstall.pro
@@ -1,8 +1,8 @@
 #This is the path to the mythtv src
 
 PREFIX = /usr/include/mythtv
-LIBVERSION = 29
-VERSION = 29.0
+LIBVERSION = 30
+VERSION = 30.0
 
 INCLUDEPATH += $$PREFIX
 INCLUDEPATH += $$PREFIX/libmyth
@@ -41,7 +41,18 @@ QMAKE_CLEAN += $(TARGET)
 //HEADERS += commandlineparser.h
 //SOURCES += main.cpp commandlineparser.cpp
 
-HEADERS += installdialog.h commandlineparser.h installsettings.h settemplate.h installationtype.h xorgsettings.h password_manage.h misc_settings.h mv_common.h infrared.h compat-mv.h supplemental.h vnc.h fileshare.h questionnotice.h
-SOURCES += main.cpp commandlineparser.cpp installdialog.cpp installsettings.cpp settemplate.cpp installationtype.cpp xorgsettings.cpp password_manage.cpp misc_settings.cpp infrared.cpp compat-mv.cpp supplemental.cpp vnc.cpp fileshare.cpp questionnotice.cpp
+HEADERS += installdialog.h commandlineparser.h installsettings.h
+HEADERS += settemplate.h installationtype.h xorgsettings.h password_manage.h
+HEADERS += misc_settings.h mv_common.h infrared.h compat-mv.h supplemental.h
+HEADERS += vnc.h fileshare.h questionnotice.h
+HEADERS += mythconfigdialogs.h mythconfiggroups.h
+HEADERS += settings.h
+
+SOURCES += main.cpp commandlineparser.cpp installdialog.cpp installsettings.cpp
+SOURCES += settemplate.cpp installationtype.cpp xorgsettings.cpp
+SOURCES += password_manage.cpp misc_settings.cpp infrared.cpp compat-mv.cpp
+SOURCES += supplemental.cpp vnc.cpp fileshare.cpp questionnotice.cpp
+SOURCES += mythconfigdialogs.cpp mythconfiggroups.cpp
+SOURCES += settings.cpp
 
 QT += sql xml network widgets
diff --git a/abs/core/mythinstall/MythVantage-app/mythinstall/settings.cpp b/abs/core/mythinstall/MythVantage-app/mythinstall/settings.cpp
new file mode 100644
index 0000000..41c3cf8
--- /dev/null
+++ b/abs/core/mythinstall/MythVantage-app/mythinstall/settings.cpp
@@ -0,0 +1,1236 @@
+// C++ headers
+#include <algorithm>
+#include <cmath>
+using namespace std;
+
+// POSIX headers
+#include <unistd.h>
+
+// Qt widgets
+#include <QLineEdit>
+#include <QSlider>
+#include <QLCDNumber>
+#include <QButtonGroup>
+#include <QRadioButton>
+#include <QProgressBar>
+
+// Qt utils
+#include <QFile>
+#include <QDateTime>
+#include <QDir>
+
+// MythTV headers
+#define MYTHCONFIG
+#include "settings.h"
+#include "mythconfiggroups.h"
+#undef MYTHCONFIG
+
+#include "mythwidgets.h"
+#include "mythcontext.h"
+#include "mythdb.h"
+#include "mythlogging.h"
+//#include "DisplayRes.h"
+#include "mythuihelper.h"
+
+/** \class Configurable
+ *  \brief Configurable is the root of all the database aware widgets.
+ *
+ *   This is an abstract class and some methods must be implemented
+ *   in children. byName(const &QString) is abstract. While
+ *   configWidget(ConfigurationGroup *, QWidget*, const char*)
+ *   has an implementation, all it does is print an error message
+ *   and return a NULL pointer.
+ */
+
+QWidget* Configurable::configWidget(ConfigurationGroup *cg, QWidget* parent,
+                                    const char* widgetName)
+{
+    (void)cg;
+    (void)parent;
+    (void)widgetName;
+    LOG(VB_GENERAL, LOG_ALERT,
+             "BUG: Configurable is visible, but has no configWidget");
+    return NULL;
+}
+
+/** \brief This slot calls the virtual widgetInvalid(QObject*) method.
+ *
+ *  This should not be needed, anyone calling configWidget() should
+ *  also be calling widgetInvalid() directly before configWidget()
+ *  is called again on the Configurable. If widgetInvalid() is not
+ *  called directly before the Configurable's configWidget() is
+ *  called the Configurable may not update properly on screen, but
+ *  if this is connected to from the widget's destroyed(QObject*)
+ *  signal this will prevent a segfault from occurring.
+ */
+void Configurable::widgetDeleted(QObject *obj)
+{
+    widgetInvalid(obj);
+}
+
+/** \fn Configurable::enableOnSet(const QString &val)
+ *  \brief This slot allows you to enable this configurable when a
+ *         binary configurable is set to true.
+ *  \param val signal value, should be "0" to disable, other to disable.
+ */
+void Configurable::enableOnSet(const QString &val)
+{
+    setEnabled( val != "0" );
+}
+
+/** \fn Configurable::enableOnUnset(const QString &val)
+ *  \brief This slot allows you to enable this configurable when a
+ *         binary configurable is set to false.
+ *  \param val signal value, should be "0" to enable, other to disable.
+ */
+void Configurable::enableOnUnset(const QString &val)
+{
+    setEnabled( val == "0" );
+}
+
+QString Setting::getValue(void) const
+{
+    return settingValue;
+}
+
+void Setting::setValue(const QString &newValue)
+{
+    settingValue = newValue;
+    emit valueChanged(settingValue);
+}
+
+int SelectSetting::findSelection(const QString &label, QString value) const
+{
+    value = (value.isEmpty()) ? label : value;
+
+    for (uint i = 0; i < values.size(); i++)
+    {
+        if ((values[i] == value) && (labels[i] == label))
+            return i;
+    }
+
+    return -1;
+}
+
+void SelectSetting::addSelection(const QString &label, QString value,
+                                 bool select)
+{
+    value = (value.isEmpty()) ? label : value;
+
+    int found = findSelection(label, value);
+    if (found < 0)
+    {
+        labels.push_back(label);
+        values.push_back(value);
+        emit selectionAdded( label, value);
+    }
+
+    if (select || !isSet)
+        setValue(value);
+}
+
+bool SelectSetting::removeSelection(const QString &label, QString value)
+{
+    value = (value.isEmpty()) ? label : value;
+
+    int found = findSelection(label, value);
+    if (found < 0)
+        return false;
+
+    bool wasSet = isSet;
+    isSet = false;
+
+    labels.erase(labels.begin() + found);
+    values.erase(values.begin() + found);
+
+    isSet = wasSet && labels.size();
+    if (isSet)
+    {
+        current = (current > (uint)found) ? current - 1 : current;
+        current = min(current, (uint) (labels.size() - 1));
+    }
+
+    emit selectionRemoved(label, value);
+
+    return true;
+}
+
+void SelectSetting::fillSelectionsFromDir(const QDir& dir, bool absPath)
+{
+    QFileInfoList il = dir.entryInfoList();
+
+    for (QFileInfoList::Iterator it = il.begin();
+                                 it != il.end();
+                               ++it )
+    {
+        QFileInfo &fi = *it;
+
+        if (absPath)
+            addSelection( fi.absoluteFilePath() );
+        else
+            addSelection( fi.fileName() );
+    }
+}
+
+void SelectSetting::clearSelections(void) {
+    labels.clear();
+    values.clear();
+    isSet = false;
+    emit selectionsCleared();
+}
+
+void SelectSetting::setValue(const QString &newValue)
+{
+    int found = getValueIndex(newValue);
+    if (found < 0)
+    {
+        addSelection(newValue, newValue, true);
+    }
+    else
+    {
+        current = found;
+        isSet   = true;
+        Setting::setValue(newValue);
+    }
+}
+
+void SelectSetting::setValue(int which)
+{
+    if ((which >= ((int) values.size())) || (which < 0))
+    {
+        LOG(VB_GENERAL, LOG_ERR,
+                 QString("SelectSetting::setValue(): invalid index: %1 size: %2")
+                     .arg(which).arg(values.size()));
+    }
+    else
+    {
+        current = which;
+        isSet   = true;
+        Setting::setValue(values[current]);
+    }
+}
+
+QString SelectSetting::getSelectionLabel(void) const
+{
+    if (!isSet || (current >= values.size()))
+        return QString::null;
+
+    return labels[current];
+}
+
+/** \fn SelectSetting::getValueIndex(QString)
+ *  \brief Returns index of value in SelectSetting, or -1 if not found.
+ */
+int SelectSetting::getValueIndex(QString value)
+{
+    int ret = 0;
+
+    selectionList::const_iterator it = values.begin();
+    for (; it != values.end(); ++it, ++ret)
+    {
+        if (*it == value)
+            return ret;
+    }
+
+    return -1;
+}
+
+bool SelectSetting::ReplaceLabel(const QString &new_label, const QString &value)
+{
+    int i = getValueIndex(value);
+
+    if (i >= 0)
+        labels[i] = new_label;
+
+    return (i >= 0);
+}
+
+QWidget* LabelSetting::configWidget(ConfigurationGroup *cg, QWidget* parent,
+                                    const char* widgetName) {
+    (void)cg;
+
+    QWidget *widget = new QWidget(parent);
+    widget->setObjectName(widgetName);
+
+    QHBoxLayout *layout = new QHBoxLayout();
+    layout->setContentsMargins(0,0,0,0);
+    layout->setSpacing(0);
+
+    if (getLabel() != "")
+    {
+        MythLabel *label = new MythLabel();
+        label->setText(getLabel() + ":     ");
+        layout->addWidget(label);
+    }
+
+    MythLabel *value = new MythLabel();
+    value->setText(getValue());
+    layout->addWidget(value);
+
+    connect(this, SIGNAL(valueChanged(const QString&)),
+            value, SLOT(setText(const QString&)));
+
+    widget->setLayout(layout);
+
+    return widget;
+}
+
+QWidget* LineEditSetting::configWidget(ConfigurationGroup *cg, QWidget* parent,
+                                       const char *widgetName)
+{
+    QWidget *widget = new QWidget(parent);
+    widget->setObjectName(widgetName);
+
+    QBoxLayout *layout = NULL;
+    if (labelAboveWidget)
+    {
+        layout = new QVBoxLayout();
+        widget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred,
+                                          QSizePolicy::Maximum));
+    }
+    else
+        layout = new QHBoxLayout();
+
+    layout->setContentsMargins(0,0,0,0);
+    layout->setSpacing(0);
+
+    if (getLabel() != "")
+    {
+        MythLabel *label = new MythLabel();
+        label->setText(getLabel() + ":     ");
+        layout->addWidget(label);
+    }
+
+    bxwidget = widget;
+    connect(bxwidget, SIGNAL(destroyed(QObject*)),
+            this,     SLOT(widgetDeleted(QObject*)));
+
+    edit = new MythLineEdit(
+        settingValue, NULL,
+        QString(QString(widgetName) + "-edit").toLatin1().constData());
+    edit->setHelpText(getHelpText());
+    edit->setText( getValue() );
+    edit->setMinimumHeight(25);
+    layout->addWidget(edit);
+
+    connect(this, SIGNAL(valueChanged(const QString&)),
+            edit, SLOT(setText(const QString&)));
+    connect(edit, SIGNAL(textChanged(const QString&)),
+            this, SLOT(setValue(const QString&)));
+
+    if (cg)
+        connect(edit, SIGNAL(changeHelpText(QString)), cg,
+                SIGNAL(changeHelpText(QString)));
+
+    setRW(rw);
+    SetPasswordEcho(password_echo);
+
+    widget->setLayout(layout);
+
+    return widget;
+}
+
+void LineEditSetting::widgetInvalid(QObject *obj)
+{
+    if (bxwidget == obj)
+    {
+        bxwidget = NULL;
+        edit     = NULL;
+    }
+}
+
+void LineEditSetting::setEnabled(bool b)
+{
+    Configurable::setEnabled(b);
+    if (edit)
+        edit->setEnabled(b);
+}
+
+void LineEditSetting::setVisible(bool b)
+{
+    Configurable::setVisible(b);
+    if (edit)
+    {
+        //QWidget *parent = edit->parentWidget();
+        if (b)
+            edit->show();
+        else
+            edit->hide();
+    }
+}
+
+void LineEditSetting::SetPasswordEcho(bool b)
+{
+    password_echo = b;
+    if (edit)
+        edit->setEchoMode(b ? QLineEdit::Password : [REDACTED]
+}
+
+void LineEditSetting::setHelpText(const QString &str)
+{
+    if (edit)
+        edit->setHelpText(str);
+    Setting::setHelpText(str);
+}
+
+void BoundedIntegerSetting::setValue(int newValue)
+{
+    newValue = std::max(std::min(newValue, max), min);
+    IntegerSetting::setValue(newValue);
+}
+
+QWidget* SliderSetting::configWidget(ConfigurationGroup *cg, QWidget* parent,
+                                     const char* widgetName)
+{
+    QWidget *widget = new QWidget(parent);
+    widget->setObjectName(widgetName);
+
+    QBoxLayout *layout = NULL;
+    if (labelAboveWidget)
+    {
+        layout = new QVBoxLayout();
+        widget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred,
+                                          QSizePolicy::Maximum));
+    }
+    else
+        layout = new QHBoxLayout();
+
+    layout->setContentsMargins(0,0,0,0);
+    layout->setSpacing(0);
+
+    if (getLabel() != "")
+    {
+        MythLabel *label = new MythLabel();
+        label->setObjectName(QString(widgetName) + "-label");
+        label->setText(getLabel() + ":     ");
+        layout->addWidget(label);
+    }
+
+    MythSlider *slider = new MythSlider(
+        NULL, QString(QString(widgetName) + "-slider").toLatin1().constData());
+    slider->setHelpText(getHelpText());
+    slider->setMinimum(min);
+    slider->setMaximum(max);
+    slider->setOrientation( Qt::Horizontal );
+    slider->setSingleStep(step);
+    slider->setValue(intValue());
+    layout->addWidget(slider);
+
+    QLCDNumber *lcd = new QLCDNumber();
+    lcd->setObjectName(QString(QString(widgetName) + "-lcd")
+                       .toLatin1().constData());
+    lcd->setMode(QLCDNumber::Dec);
+    lcd->setSegmentStyle(QLCDNumber::Flat);
+    lcd->display(intValue());
+    layout->addWidget(lcd);
+
+    connect(slider, SIGNAL(valueChanged(int)), lcd, SLOT(display(int)));
+    connect(slider, SIGNAL(valueChanged(int)), this, SLOT(setValue(int)));
+    connect(this, SIGNAL(valueChanged(int)), slider, SLOT(setValue(int)));
+
+    if (cg)
+        connect(slider, SIGNAL(changeHelpText(QString)), cg,
+                SIGNAL(changeHelpText(QString)));
+
+    widget->setLayout(layout);
+
+    return widget;
+}
+
+SpinBoxSetting::SpinBoxSetting(
+    Storage *_storage, int _min, int _max, int _step,
+    bool _allow_single_step, QString _special_value_text) :
+    BoundedIntegerSetting(_storage, _min, _max, _step),
+    bxwidget(NULL), spinbox(NULL), relayEnabled(true),
+    sstep(_allow_single_step), svtext("")
+{
+    if (!_special_value_text.isEmpty())
+        svtext = _special_value_text;
+
+    IntegerSetting *iset = (IntegerSetting *) this;
+    connect(iset, SIGNAL(valueChanged(     int)),
+            this, SLOT(  relayValueChanged(int)));
+}
+
+QWidget* SpinBoxSetting::configWidget(ConfigurationGroup *cg, QWidget* parent,
+                                      const char* widgetName)
+{
+    QWidget *widget = new QWidget(parent);
+    widget->setObjectName(widgetName);
+
+    QBoxLayout *layout = NULL;
+    if (labelAboveWidget)
+    {
+        layout = new QVBoxLayout();
+        widget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred,
+                                          QSizePolicy::Maximum));
+    }
+    else
+        layout = new QHBoxLayout();
+
+    layout->setContentsMargins(0,0,0,0);
+    layout->setSpacing(0);
+
+    if (getLabel() != "")
+    {
+        MythLabel *label = new MythLabel();
+        label->setText(getLabel() + ":     ");
+        layout->addWidget(label);
+    }
+
+    bxwidget = widget;
+    connect(bxwidget, SIGNAL(destroyed(QObject*)),
+            this,     SLOT(widgetDeleted(QObject*)));
+
+    QString sbname = QString(widgetName) + "MythSpinBox";
+    spinbox = new MythSpinBox(NULL, sbname.toLatin1().constData(), sstep);
+    spinbox->setHelpText(getHelpText());
+    spinbox->setMinimum(min);
+    spinbox->setMaximum(max);
+    spinbox->setMinimumHeight(25);
+    layout->addWidget(spinbox);
+
+    // only set step size if greater than default (1), otherwise
+    // this will screw up the single-step/jump behavior of the MythSpinBox
+    if (1 < step)
+        spinbox->setSingleStep(step);
+    spinbox->setValue(intValue());
+    if (!svtext.isEmpty())
+        spinbox->setSpecialValueText(svtext);
+
+    connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(setValue(int)));
+
+    if (cg)
+        connect(spinbox, SIGNAL(changeHelpText(QString)), cg,
+                SIGNAL(changeHelpText(QString)));
+
+    widget->setLayout(layout);
+
+    return widget;
+}
+
+void SpinBoxSetting::widgetInvalid(QObject *obj)
+{
+    if (bxwidget == obj)
+    {
+        bxwidget = NULL;
+        spinbox  = NULL;
+    }
+}
+
+void SpinBoxSetting::setValue(int newValue)
+{
+    newValue = std::max(std::min(newValue, max), min);
+    if (spinbox && (spinbox->value() != newValue))
+    {
+        //int old = intValue();
+        spinbox->setValue(newValue);
+    }
+    else if (intValue() != newValue)
+    {
+        BoundedIntegerSetting::setValue(newValue);
+    }
+}
+
+void SpinBoxSetting::setFocus(void)
+{
+    if (spinbox)
+        spinbox->setFocus();
+}
+
+void SpinBoxSetting::clearFocus(void)
+{
+    if (spinbox)
+        spinbox->clearFocus();
+}
+
+bool SpinBoxSetting::hasFocus(void) const
+{
+    if (spinbox)
+        return spinbox->hasFocus();
+
+    return false;
+}
+
+void SpinBoxSetting::relayValueChanged(int newValue)
+{
+    if (relayEnabled)
+        emit valueChanged(configName, newValue);
+}
+
+void SpinBoxSetting::setHelpText(const QString &str)
+{
+    if (spinbox)
+        spinbox->setHelpText(str);
+    BoundedIntegerSetting::setHelpText(str);
+}
+
+QWidget* SelectLabelSetting::configWidget(ConfigurationGroup *cg,
+                                          QWidget    *parent,
+                                          const char *widgetName)
+{
+    (void)cg;
+
+    QWidget *widget = new QWidget(parent);
+    widget->setObjectName(widgetName);
+
+    QBoxLayout *layout = NULL;
+    if (labelAboveWidget)
+    {
+        layout = new QVBoxLayout();
+        widget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred,
+                                          QSizePolicy::Maximum));
+    }
+    else
+        layout = new QHBoxLayout();
+
+    layout->setContentsMargins(0,0,0,0);
+    layout->setSpacing(0);
+
+    if (getLabel() != "")
+    {
+        MythLabel *label = new MythLabel();
+        label->setText(getLabel() + ":     ");
+        layout->addWidget(label);
+    }
+
+
+    MythLabel *value = new MythLabel();
+    value->setText(labels[current]);
+    layout->addWidget(value);
+
+    connect(this, SIGNAL(valueChanged(const QString&)),
+            value, SLOT(setText(const QString&)));
+
+    widget->setLayout(layout);
+
+    return widget;
+}
+
+QWidget* ComboBoxSetting::configWidget(ConfigurationGroup *cg, QWidget* parent,
+                                       const char* widgetName)
+{
+    QWidget *widget = new QWidget(parent);
+    widget->setObjectName(widgetName);
+
+    QBoxLayout *layout = NULL;
+    if (labelAboveWidget)
+    {
+        layout = new QVBoxLayout();
+        widget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred,
+                                          QSizePolicy::Maximum));
+    }
+    else
+        layout = new QHBoxLayout();
+
+    layout->setContentsMargins(0,0,0,0);
+    layout->setSpacing(0);
+
+    if (getLabel() != "")
+    {
+        MythLabel *label = new MythLabel();
+        label->setText(getLabel() + ":     ");
+        layout->addWidget(label);
+    }
+
+    bxwidget = widget;
+    connect(bxwidget, SIGNAL(destroyed(QObject*)),
+            this,     SLOT(widgetDeleted(QObject*)));
+
+    cbwidget = new MythComboBox(rw);
+    cbwidget->setHelpText(getHelpText());
+
+    for(unsigned int i = 0 ; i < labels.size() ; ++i)
+        cbwidget->insertItem(labels[i]);
+
+    resetMaxCount(cbwidget->count());
+
+    if (isSet)
+        cbwidget->setCurrentIndex(current);
+
+    if (1 < step)
+        cbwidget->setStep(step);
+
+    connect(cbwidget, SIGNAL(highlighted(int)),
+            this, SLOT(setValue(int)));
+    connect(cbwidget, SIGNAL(activated(int)),
+            this, SLOT(setValue(int)));
+    connect(this, SIGNAL(selectionsCleared()),
+            cbwidget, SLOT(clear()));
+
+    if (rw)
+        connect(cbwidget, SIGNAL(editTextChanged(const QString &)),
+                this, SLOT(editTextChanged(const QString &)));
+
+    if (cg)
+        connect(cbwidget, SIGNAL(changeHelpText(QString)), cg,
+                SIGNAL(changeHelpText(QString)));
+
+    cbwidget->setMinimumHeight(25);
+
+    layout->addWidget(cbwidget);
+    layout->setStretchFactor(cbwidget, 1);
+
+    widget->setLayout(layout);
+
+    return widget;
+}
+
+void ComboBoxSetting::widgetInvalid(QObject *obj)
+{
+    if (bxwidget == obj)
+    {
+        bxwidget = NULL;
+        cbwidget = NULL;
+    }
+}
+
+void ComboBoxSetting::setEnabled(bool b)
+{
+    Configurable::setEnabled(b);
+    if (cbwidget)
+        cbwidget->setEnabled(b);
+}
+
+void ComboBoxSetting::setVisible(bool b)
+{
+    Configurable::setVisible(b);
+    if (cbwidget)
+    {
+        if (b)
+            cbwidget->show();
+        else
+            cbwidget->hide();
+    }
+}
+
+void ComboBoxSetting::setValue(const QString &newValue)
+{
+    for (uint i = 0; i < values.size(); i++)
+    {
+        if (values[i] == newValue)
+        {
+            setValue(i);
+            break;
+        }
+    }
+
+    if (rw)
+    {
+        Setting::setValue(newValue);
+        if (cbwidget)
+            cbwidget->setCurrentIndex(current);
+    }
+}
+
+void ComboBoxSetting::setValue(int which)
+{
+    if (cbwidget)
+        cbwidget->setCurrentIndex(which);
+    SelectSetting::setValue(which);
+}
+
+void ComboBoxSetting::addSelection(
+    const QString &label, QString value, bool select)
+{
+    if ((findSelection(label, value) < 0) && cbwidget)
+    {
+        resetMaxCount(cbwidget->count()+1);
+        cbwidget->insertItem(label);
+    }
+
+    SelectSetting::addSelection(label, value, select);
+
+    if (cbwidget && isSet)
+        cbwidget->setCurrentIndex(current);
+}
+
+bool ComboBoxSetting::removeSelection(const QString &label, QString value)
+{
+    SelectSetting::removeSelection(label, value);
+    if (!cbwidget)
+        return true;
+
+    for (uint i = 0; ((int) i) < cbwidget->count(); i++)
+    {
+        if (cbwidget->itemText(i) == label)
+        {
+            cbwidget->removeItem(i);
+            if (isSet)
+                cbwidget->setCurrentIndex(current);
+            resetMaxCount(cbwidget->count());
+            return true;
+        }
+    }
+
+    return false;
+}
+
+void ComboBoxSetting::editTextChanged(const QString &newText)
+{
+    if (cbwidget)
+    {
+        for (uint i = 0; i < labels.size(); i++)
+            if (labels[i] == newText)
+                return;
+
+        if (labels.size() == static_cast<size_t>(cbwidget->maxCount()))
+        {
+            SelectSetting::removeSelection(labels[cbwidget->maxCount() - 1],
+                                           values[cbwidget->maxCount() - 1]);
+            cbwidget->setItemText(cbwidget->maxCount() - 1, newText);
+        }
+        else
+        {
+            cbwidget->insertItem(newText);
+        }
+
+        SelectSetting::addSelection(newText, newText, true);
+        cbwidget->setCurrentIndex(cbwidget->maxCount() - 1);
+    }
+}
+
+void ComboBoxSetting::setHelpText(const QString &str)
+{
+    if (cbwidget)
+        cbwidget->setHelpText(str);
+    SelectSetting::setHelpText(str);
+}
+
+void HostRefreshRateComboBox::ChangeResolution(const QString& resolution)
+{
+    clearSelections();
+
+    const vector<double> list = GetRefreshRates(resolution);
+    addSelection(QObject::tr("Auto"), "0");
+    int hz50 = -1, hz60 = -1;
+    for (uint i=0; i<list.size(); ++i)
+    {
+        QString sel = QString::number((double) list[i],'f', 3);
+        addSelection(sel+" Hz", sel);
+        hz50 = (fabs(50.0 - list[i]) < 0.01) ? i : hz50;
+        hz60 = (fabs(60.0 - list[i]) < 0.01) ? i : hz60;
+    }
+
+    setValue(0);
+    if ("640x480" == resolution || "720x480" == resolution)
+        setValue(hz60+1);
+    if ("640x576" == resolution || "720x576" == resolution)
+        setValue(hz50+1);
+
+    setEnabled(list.size());
+}
+
+const vector<double> HostRefreshRateComboBox::GetRefreshRates(const QString &res)
+{
+    QStringList slist = res.split("x");
+    int w = 0, h = 0;
+    bool ok0 = false, ok1 = false;
+    if (2 == slist.size())
+    {
+        w = slist[0].toInt(&ok0);
+        h = slist[1].toInt(&ok1);
+    }
+
+//    DisplayRes *display_res = DisplayRes::GetDisplayRes();
+//    if (display_res && ok0 && ok1)
+//        return display_res->GetRefreshRates(w, h);
+
+    vector<double> list;
+    return list;
+}
+
+void PathSetting::addSelection(const QString& label,
+                               QString value,
+                               bool select) {
+    QString pathname = label;
+    if (value != QString::null)
+        pathname = value;
+
+    if (mustexist && !QFile(pathname).exists())
+        return;
+
+    ComboBoxSetting::addSelection(label, value, select);
+}
+
+QTime TimeSetting::timeValue(void) const {
+    return QTime::fromString(getValue(), Qt::ISODate);
+}
+
+void TimeSetting::setValue(const QTime& newValue) {
+    Setting::setValue(newValue.toString(Qt::ISODate));
+}
+
+QString DateSetting::getValue(void) const
+{
+    return settingValue;
+}
+
+QDate DateSetting::dateValue(void) const {
+    return QDate::fromString(getValue(), Qt::ISODate);
+}
+
+void DateSetting::setValue(const QDate& newValue) {
+    Setting::setValue(newValue.toString(Qt::ISODate));
+}
+
+void DateSetting::setValue(const QString &newValue)
+{
+    QDate date = QDate::fromString(newValue, Qt::ISODate);
+    if (date.isValid())
+        setValue(date);
+}
+
+void TimeSetting::setValue(const QString &newValue)
+{
+    QTime time = QTime::fromString(newValue, Qt::ISODate);
+    if (time.isValid())
+        setValue(time);
+}
+
+QWidget* CheckBoxSetting::configWidget(ConfigurationGroup *cg, QWidget* parent,
+                                       const char* widgetName) {
+    widget = new MythCheckBox(parent, widgetName);
+    connect(widget, SIGNAL(destroyed(QObject*)),
+            this,   SLOT(widgetDeleted(QObject*)));
+
+    widget->setHelpText(getHelpText());
+    widget->setText(getLabel());
+    widget->setChecked(boolValue());
+
+    connect(widget, SIGNAL(toggled(bool)),
+            this, SLOT(setValue(bool)));
+    connect(this, SIGNAL(valueChanged(bool)),
+            widget, SLOT(setChecked(bool)));
+
+    if (cg)
+        connect(widget, SIGNAL(changeHelpText(QString)), cg,
+                SIGNAL(changeHelpText(QString)));
+
+    return widget;
+}
+
+void CheckBoxSetting::widgetInvalid(QObject *obj)
+{
+    widget = (widget == obj) ? NULL : widget;
+}
+
+void CheckBoxSetting::setVisible(bool b)
+{
+    BooleanSetting::setVisible(b);
+    if (widget)
+    {
+        if (b)
+            widget->show();
+        else
+            widget->hide();
+    }
+}
+
+void CheckBoxSetting::setLabel(QString str)
+{
+    // QT treats a single ampersand as special,
+    // we must double up ampersands to display them
+    str = str.replace(" & ", " && ");
+    BooleanSetting::setLabel(str);
+    if (widget)
+        widget->setText(str);
+}
+
+void CheckBoxSetting::setEnabled(bool fEnabled)
+{
+    BooleanSetting::setEnabled(fEnabled);
+    if (widget)
+        widget->setEnabled(fEnabled);
+}
+
+void CheckBoxSetting::setHelpText(const QString &str)
+{
+    if (widget)
+        widget->setHelpText(str);
+    BooleanSetting::setHelpText(str);
+}
+
+void AutoIncrementDBSetting::Save(QString table)
+{
+    if (intValue() == 0)
+    {
+        // Generate a new, unique ID
+        QString querystr = QString("INSERT INTO " + table + " ("
+                + GetColumnName() + ") VALUES (0);");
+
+        MSqlQuery query(MSqlQuery::InitCon());
+
+        if (!query.exec(querystr))
+        {
+            MythDB::DBError("inserting row", query);
+            return;
+        }
+        // XXX -- HACK BEGIN:
+        // lastInsertID fails with "QSqlQuery::value: not positioned on a valid record"
+        // if we get a invalid QVariant we workaround the problem by taking advantage
+        // of mysql always incrementing the auto increment pointer
+        // this breaks if someone modifies the auto increment pointer
+        //setValue(query.lastInsertId().toInt());
+
+        QVariant var = query.lastInsertId();
+
+        if (var.type())
+            setValue(var.toInt());
+        else
+        {
+            querystr = QString("SELECT MAX(" + GetColumnName() + ") FROM " + table + ";");
+            if (query.exec(querystr) && query.next())
+            {
+                int lii = query.value(0).toInt();
+                lii = lii ? lii : 1;
+                setValue(lii);
+            }
+            else
+                LOG(VB_GENERAL, LOG_EMERG,
+                         "Can't determine the Id of the last insert "
+                         "QSqlQuery.lastInsertId() failed, the workaround "
+                         "failed too!");
+        }
+        // XXX -- HACK END:
+    }
+}
+
+void AutoIncrementDBSetting::Save(void)
+{
+    Save(GetTableName());
+}
+
+void ListBoxSetting::setEnabled(bool b)
+{
+    Configurable::setEnabled(b);
+    if (lbwidget)
+        lbwidget->setEnabled(b);
+}
+
+void ListBoxSetting::clearSelections(void)
+{
+    SelectSetting::clearSelections();
+    if (lbwidget)
+        lbwidget->clear();
+}
+
+void ListBoxSetting::addSelection(
+    const QString &label, QString value, bool select)
+{
+    SelectSetting::addSelection(label, value, select);
+    if (lbwidget)
+    {
+        lbwidget->insertItem(label);
+        //lbwidget->triggerUpdate(true);
+    }
+};
+
+bool ListBoxSetting::ReplaceLabel(
+    const QString &new_label, const QString &value)
+{
+    int i = getValueIndex(value);
+
+    if ((i >= 0) && SelectSetting::ReplaceLabel(label, value) && lbwidget)
+    {
+        lbwidget->changeItem(new_label, i);
+        return true;
+    }
+
+    return false;
+}
+
+QWidget* ListBoxSetting::configWidget(ConfigurationGroup *cg, QWidget* parent,
+                                      const char* widgetName)
+{
+    QWidget *widget = new QWidget(parent);
+    widget->setObjectName(widgetName);
+
+    QVBoxLayout *layout = new QVBoxLayout();
+
+    if (getLabel() != "")
+    {
+        MythLabel *label = new MythLabel();
+        label->setText(getLabel());
+        layout->addWidget(label);
+    }
+
+    layout->setContentsMargins(0,0,0,0);
+    layout->setSpacing(0);
+
+    bxwidget = widget;
+    connect(bxwidget, SIGNAL(destroyed(QObject*)),
+            this,     SLOT(widgetDeleted(QObject*)));
+
+    lbwidget = new MythListBox(NULL);
+    lbwidget->setHelpText(getHelpText());
+    if (eventFilter)
+        lbwidget->installEventFilter(eventFilter);
+
+    for(unsigned int i = 0 ; i < labels.size() ; ++i) {
+        lbwidget->insertItem(labels[i]);
+        if (isSet && current == i)
+            lbwidget->setCurrentRow(i);
+    }
+
+    connect(this,     SIGNAL(selectionsCleared()),
+            lbwidget, SLOT(  clear()));
+    connect(this,     SIGNAL(valueChanged(const QString&)),
+            lbwidget, SLOT(  setCurrentItem(const QString&)));
+
+    connect(lbwidget, SIGNAL(accepted(int)),
+            this,     SIGNAL(accepted(int)));
+    connect(lbwidget, SIGNAL(menuButtonPressed(int)),
+            this,     SIGNAL(menuButtonPressed(int)));
+    connect(lbwidget, SIGNAL(editButtonPressed(int)),
+            this,     SIGNAL(editButtonPressed(int)));
+    connect(lbwidget, SIGNAL(deleteButtonPressed(int)),
+            this,     SIGNAL(deleteButtonPressed(int)));
+
+    connect(lbwidget, SIGNAL(highlighted(int)),
+            this,     SLOT(  setValueByIndex(int)));
+
+    if (cg)
+        connect(lbwidget, SIGNAL(changeHelpText(QString)), cg,
+                SIGNAL(changeHelpText(QString)));
+
+    lbwidget->setFocus();
+    lbwidget->setSelectionMode(selectionMode);
+    layout->addWidget(lbwidget);
+
+    widget->setLayout(layout);
+
+    return widget;
+}
+
+void ListBoxSetting::widgetInvalid(QObject *obj)
+{
+    if (bxwidget == obj)
+    {
+        bxwidget = NULL;
+        lbwidget = NULL;
+    }
+}
+
+void ListBoxSetting::setSelectionMode(MythListBox::SelectionMode mode)
+{
+   selectionMode = mode;
+   if (lbwidget)
+       lbwidget->setSelectionMode(selectionMode);
+}
+
+void ListBoxSetting::setValueByIndex(int index)
+{
+    if (((uint)index) < values.size())
+        setValue(values[index]);
+}
+
+void ListBoxSetting::setHelpText(const QString &str)
+{
+    if (lbwidget)
+        lbwidget->setHelpText(str);
+    SelectSetting::setHelpText(str);
+}
+
+HostnameSetting::HostnameSetting(Storage *storage) : Setting(storage)
+{
+    setVisible(false);
+
+    setValue(gCoreContext->GetHostName());
+}
+
+void ChannelSetting::fillSelections(SelectSetting* setting) {
+
+    // this should go somewhere else, in something that knows about
+    // channels and how they're stored in the database.  We're just a
+    // selector.
+
+    MSqlQuery query(MSqlQuery::InitCon());
+    query.prepare("SELECT name, chanid FROM channel;");
+    if (query.exec() && query.isActive() && query.size() > 0)
+        while (query.next())
+            setting->addSelection(query.value(0).toString(),
+                                  QString::number(query.value(1).toInt()));
+}
+
+QWidget* ButtonSetting::configWidget(ConfigurationGroup* cg, QWidget* parent,
+                                     const char* widgetName)
+{
+    (void) cg;
+    button = new MythPushButton(parent, widgetName);
+    connect(button, SIGNAL(destroyed(QObject*)),
+            this,   SLOT(widgetDeleted(QObject*)));
+
+    button->setText(getLabel());
+    button->setHelpText(getHelpText());
+
+    connect(button, SIGNAL(pressed()), this, SIGNAL(pressed()));
+    connect(button, SIGNAL(pressed()), this, SLOT(SendPressedString()));
+
+    if (cg)
+        connect(button, SIGNAL(changeHelpText(QString)),
+                cg, SIGNAL(changeHelpText(QString)));
+
+    return button;
+}
+
+void ButtonSetting::widgetInvalid(QObject *obj)
+{
+    button = (button == obj) ? NULL : button;
+}
+
+void ButtonSetting::SendPressedString(void)
+{
+    emit pressed(name);
+}
+
+void ButtonSetting::setEnabled(bool fEnabled)
+{
+    Configurable::setEnabled(fEnabled);
+    if (button)
+        button->setEnabled(fEnabled);
+}
+
+void ButtonSetting::setLabel(QString str)
+{
+    if (button)
+        button->setText(str);
+    Setting::setLabel(str);
+}
+
+void ButtonSetting::setHelpText(const QString &str)
+{
+    if (button)
+        button->setHelpText(str);
+    Setting::setHelpText(str);
+}
+
+QWidget* ProgressSetting::configWidget(ConfigurationGroup* cg, QWidget* parent,
+                                       const char* widgetName) {
+    (void)cg;
+    QWidget *widget = new QWidget(parent);
+    widget->setObjectName(widgetName);
+    QBoxLayout *layout = new QHBoxLayout();
+    layout->setContentsMargins(0,0,0,0);
+    layout->setSpacing(0);
+
+    if (getLabel() != "")
+    {
+        MythLabel* label = new MythLabel();
+        label->setObjectName(QString(widgetName) + "_label");
+        label->setText(getLabel() + ":     ");
+        layout->addWidget(label);
+    }
+
+    QProgressBar *progress = new QProgressBar(NULL);
+    progress->setObjectName(widgetName);
+    progress->setRange(0,totalSteps);
+    layout->addWidget(progress);
+
+    connect(this, SIGNAL(valueChanged(int)), progress, SLOT(setValue(int)));
+    progress->setValue(intValue());
+
+    widget->setLayout(layout);
+
+    return widget;
+}
diff --git a/abs/core/mythinstall/MythVantage-app/mythinstall/settings.h b/abs/core/mythinstall/MythVantage-app/mythinstall/settings.h
new file mode 100644
index 0000000..2df5dcd
--- /dev/null
+++ b/abs/core/mythinstall/MythVantage-app/mythinstall/settings.h
@@ -0,0 +1,835 @@
+// -*- Mode: c++ -*-
+
+#ifndef SETTINGS_H
+#define SETTINGS_H
+
+// C++ headers
+#include <vector>
+
+// Qt headers
+#include <QObject>
+#include <QDate>
+#include <QTime>
+
+// MythTV headers
+#include "mythexp.h"
+#include "mythwidgets.h"
+#include "mythstorage.h"
+
+class QWidget;
+class ConfigurationGroup;
+class QDir;
+class Setting;
+
+class MPUBLIC Configurable : public QObject
+{
+    Q_OBJECT
+
+  public:
+    /// Create and return a QWidget for configuring this entity
+    /// Note: Any class calling this should call widgetInvalid()
+    ///       before configWidget() is called on the class again,
+    ///       and before the class is deleted; just before removing
+    ///       the instance from a layout or scheduling the delete
+    ///       of a parent container is a good time. Some UI classes
+    ///       depend on this for properly updating the UI.
+    virtual QWidget *configWidget(ConfigurationGroup *cg, QWidget *parent,
+                                  const char *widgetName = NULL);
+    /// Tell any Configurable keeping a pointer to a widget,
+    /// that the pointer returned by an earlier configWidget
+    /// call is invalid.
+    /// Note: It is possible that this may be called after
+    ///       configWidget() has been called another time
+    ///       so you must check the pointer param.
+    virtual void widgetInvalid(QObject*) { }
+
+    // A name for looking up the setting
+    void setName(const QString &str)
+    {
+        configName = str;
+        if (label.isEmpty())
+            setLabel(str);
+    }
+    QString getName(void) const { return configName; }
+    virtual Setting *byName(const QString &name) = 0;
+
+    // A label displayed to the user
+    virtual void setLabel(QString str) { label = str; }
+    QString getLabel(void) const { return label; }
+    void setLabelAboveWidget(bool l = true) { labelAboveWidget = l; }
+
+    virtual void setHelpText(const QString &str)
+        { helptext = str; }
+    QString getHelpText(void) const { return helptext; }
+
+    void setVisible(bool b) { visible = b; };
+    bool isVisible(void) const { return visible; };
+
+    virtual void setEnabled(bool b) { enabled = b; }
+    bool isEnabled() { return enabled; }
+
+    Storage *GetStorage(void) { return storage; }
+
+  public slots:
+    virtual void enableOnSet(const QString &val);
+    virtual void enableOnUnset(const QString &val);
+    virtual void widgetDeleted(QObject *obj);
+
+  protected:
+    explicit Configurable(Storage *_storage) :
+        labelAboveWidget(false), enabled(true), storage(_storage),
+        configName(""), label(""), helptext(""), visible(true) { }
+    virtual ~Configurable() { }
+
+  protected:
+    bool labelAboveWidget;
+    bool enabled;
+    Storage *storage;
+    QString configName;
+    QString label;
+    QString helptext;
+    bool visible;
+};
+
+class MPUBLIC Setting : public Configurable, public StorageUser
+{
+    Q_OBJECT
+
+  public:
+    // Gets
+    virtual QString getValue(void) const;
+
+    // non-const Gets
+    virtual Setting *byName(const QString &name)
+        { return (name == configName) ? this : NULL; }
+
+    // StorageUser
+    void SetDBValue(const QString &val) { setValue(val); }
+    QString GetDBValue(void) const { return getValue(); }
+  public slots:
+    virtual void setValue(const QString &newValue);
+
+  signals:
+    void valueChanged(const QString&);
+
+  protected:
+    explicit Setting(Storage *_storage) : Configurable(_storage) {};
+    virtual ~Setting() {};
+
+  protected:
+    QString settingValue;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+// Read-only display of a setting
+class MPUBLIC LabelSetting : public Setting
+{
+  protected:
+    explicit LabelSetting(Storage *_storage) : Setting(_storage) { }
+  public:
+    virtual QWidget *configWidget(ConfigurationGroup *cg, QWidget *parent,
+                                  const char *widgetName = NULL);
+};
+
+class MPUBLIC LineEditSetting : public Setting
+{
+  protected:
+    LineEditSetting(Storage *_storage, bool readwrite = true) :
+        Setting(_storage), bxwidget(NULL), edit(NULL),
+        rw(readwrite), password_echo(false) { }
+
+  public:
+    virtual QWidget *configWidget(ConfigurationGroup *cg, QWidget *parent,
+                                  const char *widgetName = NULL);
+    virtual void widgetInvalid(QObject *obj);
+
+    void setRW(bool readwrite = true)
+    {
+        rw = readwrite;
+        if (edit)
+            edit->setRW(rw);
+    }
+
+    void setRO(void) { setRW(false); }
+
+    virtual void setEnabled(bool b);
+    virtual void setVisible(bool b);
+    virtual void SetPasswordEcho(bool b);
+
+    virtual void setHelpText(const QString &str);
+
+  private:
+    QWidget      *bxwidget;
+    MythLineEdit *edit;
+    bool rw;
+    bool password_echo;
+};
+
+// TODO: set things up so that setting the value as a string emits
+// the int signal also
+class MPUBLIC IntegerSetting : public Setting
+{
+    Q_OBJECT
+
+  protected:
+    explicit IntegerSetting(Storage *_storage) : Setting(_storage)
+    {
+        settingValue = QString::number(0);
+    }
+
+  public:
+    int intValue(void) const { return settingValue.toInt(); }
+
+  public slots:
+    virtual void setValue(int newValue)
+    {
+        Setting::setValue(QString::number(newValue));
+        emit valueChanged(newValue);
+    }
+    virtual void setValue(const QString &nv) { setValue(nv.toInt()); }
+
+  signals:
+    void valueChanged(int newValue);
+};
+
+class MPUBLIC BoundedIntegerSetting : public IntegerSetting
+{
+  protected:
+    BoundedIntegerSetting(Storage *_storage, int _min, int _max, int _step) :
+        IntegerSetting(_storage), min(_min), max(_max), step(_step) { }
+
+  public:
+    virtual void setValue(int newValue);
+    virtual void setValue(const QString &nv) { setValue(nv.toInt()); }
+
+  protected:
+    int min;
+    int max;
+    int step;
+};
+
+class MPUBLIC SliderSetting: public BoundedIntegerSetting
+{
+    Q_OBJECT
+
+  protected:
+    SliderSetting(Storage *_storage, int min, int max, int step) :
+        BoundedIntegerSetting(_storage, min, max, step) { }
+  public:
+    virtual QWidget *configWidget(ConfigurationGroup *cg, QWidget *parent,
+                                  const char *widgetName = NULL);
+};
+
+class MPUBLIC SpinBoxSetting: public BoundedIntegerSetting
+{
+    Q_OBJECT
+
+  public:
+    SpinBoxSetting(Storage *_storage, int min, int max, int step,
+                   bool allow_single_step = false,
+                   QString special_value_text = "");
+
+    virtual QWidget *configWidget(ConfigurationGroup *cg, QWidget *parent,
+                                  const char *widgetName = NULL);
+    virtual void widgetInvalid(QObject *obj);
+
+    void setFocus(void);
+    void clearFocus(void);
+    bool hasFocus(void) const;
+
+    void SetRelayEnabled(bool enabled) { relayEnabled = enabled; }
+    bool IsRelayEnabled(void) const { return relayEnabled; }
+
+    virtual void setHelpText(const QString &str);
+
+  public slots:
+    virtual void setValue(int newValue);
+    virtual void setValue(const QString &nv) { setValue(nv.toInt()); }
+
+  signals:
+    void valueChanged(const QString &name, int newValue);
+
+  private slots:
+    void relayValueChanged(int newValue);
+
+  private:
+    QWidget     *bxwidget;
+    MythSpinBox *spinbox;
+    bool         relayEnabled;
+    bool         sstep;
+    QString      svtext;
+};
+
+class MPUBLIC SelectSetting : public Setting
+{
+    Q_OBJECT
+
+  protected:
+    explicit SelectSetting(Storage *_storage) :
+        Setting(_storage), current(0), isSet(false) { }
+
+  public:
+    virtual int  findSelection(  const QString &label,
+                                 QString        value  = QString::null) const;
+    virtual void addSelection(   const QString &label,
+                                 QString        value  = QString::null,
+                                 bool           select = false);
+    virtual bool removeSelection(const QString &label,
+                                 QString        value  = QString::null);
+
+    virtual void clearSelections(void);
+
+    virtual void fillSelectionsFromDir(const QDir &dir, bool absPath=true);
+
+    virtual uint size(void) const { return labels.size(); }
+
+    virtual QString GetLabel(uint i) const
+        { return (i < labels.size()) ? labels[i] : QString::null; }
+    virtual QString GetValue(uint i) const
+        { return (i < values.size()) ? values[i] : QString::null; }
+
+  signals:
+    void selectionAdded(const QString &label, QString value);
+    void selectionRemoved(const QString &label, const QString &value);
+    void selectionsCleared(void);
+
+  public slots:
+    virtual void setValue(const QString &newValue);
+    virtual void setValue(int which);
+
+    virtual QString getSelectionLabel(void) const;
+    virtual int getValueIndex(QString value);
+
+  protected:
+    virtual bool ReplaceLabel(
+        const QString &new_label, const QString &value);
+
+    typedef std::vector<QString> selectionList;
+    selectionList labels;
+    selectionList values;
+    unsigned current;
+    bool isSet;
+};
+
+class MPUBLIC SelectLabelSetting : public SelectSetting
+{
+  protected:
+    explicit SelectLabelSetting(Storage *_storage) : SelectSetting(_storage) { }
+
+  public:
+    virtual QWidget *configWidget(ConfigurationGroup *cg, QWidget *parent,
+                                  const char *widgetName = NULL);
+};
+
+class MPUBLIC ComboBoxSetting: public SelectSetting
+{
+    Q_OBJECT
+
+  protected:
+    ComboBoxSetting(Storage *_storage, bool _rw = false, int _step = 1) :
+        SelectSetting(_storage), rw(_rw),
+        bxwidget(NULL), cbwidget(NULL), step(_step) { }
+
+  public:
+    virtual QWidget *configWidget(ConfigurationGroup *cg, QWidget *parent,
+                                  const char *widgetName = NULL);
+    virtual void widgetInvalid(QObject *obj);
+
+    void setFocus(void) { if (cbwidget) cbwidget->setFocus(); }
+    void resetMaxCount(int count)
+        { if (cbwidget) cbwidget->setMaxCount(count + rw); }
+
+    virtual void setEnabled(bool b);
+    virtual void setVisible(bool b);
+
+    virtual void setHelpText(const QString &str);
+
+  public slots:
+    virtual void SetDBValue(const QString &newValue)
+        { SelectSetting::setValue(newValue); }
+    virtual void setValue(const QString &newValue);
+    virtual void setValue(int which);
+
+    void addSelection(const QString &label,
+                      QString value = QString::null,
+                      bool select = false);
+    bool removeSelection(const QString &label,
+                         QString value = QString::null);
+    void editTextChanged(const QString &newText);
+
+  private:
+    bool rw;
+    QWidget      *bxwidget;
+    MythComboBox *cbwidget;
+
+  protected:
+    int step;
+};
+
+class MPUBLIC ListBoxSetting: public SelectSetting
+{
+    Q_OBJECT
+
+  public:
+    explicit ListBoxSetting(Storage *_storage) :
+        SelectSetting(_storage),
+        bxwidget(NULL), lbwidget(NULL), eventFilter(NULL),
+        selectionMode(MythListBox::SingleSelection) { }
+
+    virtual QWidget *configWidget(ConfigurationGroup *cg, QWidget *parent,
+                                  const char *widgetName = NULL);
+    virtual void widgetInvalid(QObject *obj);
+
+    void setFocus(void)
+        { if (lbwidget) lbwidget->setFocus(); }
+    void setSelectionMode(MythListBox::SelectionMode mode);
+    void setCurrentItem(int i)
+        { if (lbwidget) lbwidget->setCurrentRow(i); }
+    void setCurrentItem(const QString &str)
+        { if (lbwidget) lbwidget->setCurrentItem(str, true, false); }
+    int currentItem(void)
+        { return (lbwidget) ? lbwidget->currentRow() : -1; }
+
+    virtual void setEnabled(bool b);
+
+    virtual void clearSelections(void);
+
+    virtual void setHelpText(const QString &str);
+
+    virtual void SetEventFilter(QObject *filter) { eventFilter = filter; }
+    virtual bool ReplaceLabel(
+        const QString &new_label, const QString &value);
+
+  signals:
+    void accepted(int);
+    void menuButtonPressed(int);
+    void editButtonPressed(int);
+    void deleteButtonPressed(int);
+
+  public slots:
+    void addSelection(const QString &label,
+                      QString        value  = QString::null,
+                      bool           select = false);
+
+    void setValueByIndex(int index);
+
+  protected:
+    QWidget     *bxwidget;
+    MythListBox *lbwidget;
+    QObject     *eventFilter;
+    MythListBox::SelectionMode selectionMode;
+};
+
+class MPUBLIC BooleanSetting : public Setting
+{
+    Q_OBJECT
+
+  public:
+    explicit BooleanSetting(Storage *_storage) : Setting(_storage) {}
+
+    bool boolValue(void) const { return getValue().toInt(); }
+
+  public slots:
+    virtual void setValue(bool check)
+    {
+        if (check)
+            Setting::setValue("1");
+        else
+            Setting::setValue("0");
+        emit valueChanged(check);
+    };
+
+    virtual void setValue(const QString &newValue)
+    {
+        setValue((newValue=="1" ||
+                  newValue.toLower().startsWith("y") ||
+                  newValue.toLower().startsWith("t")));
+    }
+
+  signals:
+    void valueChanged(bool);
+};
+
+class MPUBLIC CheckBoxSetting: public BooleanSetting
+{
+    Q_OBJECT
+
+  public:
+    explicit CheckBoxSetting(Storage *_storage) :
+        BooleanSetting(_storage), widget(NULL) { }
+
+    virtual QWidget *configWidget(ConfigurationGroup *cg, QWidget *parent,
+                                  const char *widgetName = NULL);
+
+    virtual void widgetInvalid(QObject*);
+
+    virtual void setVisible(bool b);
+    virtual void setLabel(QString str);
+    virtual void setEnabled(bool b);
+
+    virtual void setHelpText(const QString &str);
+
+  protected:
+    MythCheckBox *widget;
+};
+
+class MPUBLIC PathSetting : public ComboBoxSetting
+{
+    Q_OBJECT
+
+  public:
+    PathSetting(Storage *_storage, bool _mustexist):
+        ComboBoxSetting(_storage, true), mustexist(_mustexist) { }
+
+    // TODO: this should support globbing of some sort
+    virtual void addSelection(const QString &label,
+                              QString value=QString::null,
+                              bool select=false);
+
+    // Use a combobox for now, maybe a modified file dialog later
+    //virtual QWidget *configWidget(ConfigurationGroup *cg, QWidget *parent,
+    //                              const char *widgetName = NULL);
+
+  protected:
+    bool mustexist;
+};
+
+class MPUBLIC HostnameSetting : public Setting
+{
+    Q_OBJECT
+  public:
+    explicit HostnameSetting(Storage *_storage);
+};
+
+class MPUBLIC ChannelSetting : public SelectSetting
+{
+    Q_OBJECT
+  public:
+    explicit ChannelSetting(Storage *_storage) : SelectSetting(_storage)
+    {
+        setLabel("Channel");
+    };
+
+    static void fillSelections(SelectSetting *setting);
+    virtual void fillSelections(void) { fillSelections(this); }
+};
+
+class MPUBLIC DateSetting : public Setting
+{
+    Q_OBJECT
+
+  public:
+    explicit DateSetting(Storage *_storage) : Setting(_storage) { }
+
+    QString getValue(void) const;
+
+    QDate dateValue(void) const;
+
+  public slots:
+    void setValue(const QDate &newValue);
+    void setValue(const QString &newValue);
+};
+
+class MPUBLIC TimeSetting : public Setting
+{
+    Q_OBJECT
+
+  public:
+    explicit TimeSetting(Storage *_storage) : Setting(_storage) { }
+    QTime timeValue(void) const;
+
+  public slots:
+    void setValue(const QTime &newValue);
+    void setValue(const QString &newValue);
+};
+
+class MPUBLIC AutoIncrementDBSetting :
+    public IntegerSetting, public DBStorage
+{
+    Q_OBJECT
+
+  public:
+    AutoIncrementDBSetting(QString _table, QString _column) :
+        IntegerSetting(this), DBStorage(this, _table, _column)
+    {
+        setValue(0);
+    }
+
+    virtual void Load(void) { }
+    virtual void Save(void);
+    virtual void Save(QString destination);
+};
+
+class MPUBLIC ButtonSetting: public Setting
+{
+    Q_OBJECT
+
+  public:
+    ButtonSetting(Storage *_storage, QString _name = "button") :
+        Setting(_storage), name(_name), button(NULL) { }
+
+    virtual QWidget *configWidget(ConfigurationGroup *cg, QWidget *parent,
+                                  const char *widgetName=0);
+    virtual void widgetInvalid(QObject *obj);
+
+    virtual void setEnabled(bool b);
+
+    virtual void setLabel(QString);
+
+    virtual void setHelpText(const QString &);
+
+  signals:
+    void pressed(void);
+    void pressed(QString name);
+
+  protected slots:
+    void SendPressedString();
+
+  protected:
+    QString name;
+    MythPushButton *button;
+};
+
+class MPUBLIC ProgressSetting : public IntegerSetting
+{
+    Q_OBJECT
+  public:
+    ProgressSetting(Storage *_storage, int _totalSteps) :
+        IntegerSetting(_storage), totalSteps(_totalSteps) { }
+
+    QWidget *configWidget(ConfigurationGroup *cg, QWidget *parent,
+                          const char *widgetName = NULL);
+
+  private:
+    int totalSteps;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class MPUBLIC TransButtonSetting :
+    public ButtonSetting, public TransientStorage
+{
+    Q_OBJECT
+  public:
+    explicit TransButtonSetting(QString name = "button") :
+        ButtonSetting(this, name), TransientStorage() { }
+};
+
+class MPUBLIC TransLabelSetting :
+    public LabelSetting, public TransientStorage
+{
+    Q_OBJECT
+  public:
+    TransLabelSetting() : LabelSetting(this), TransientStorage() { }
+};
+
+class MPUBLIC TransLineEditSetting :
+    public LineEditSetting, public TransientStorage
+{
+    Q_OBJECT
+  public:
+    explicit TransLineEditSetting(bool rw = true) :
+        LineEditSetting(this, rw), TransientStorage() { }
+};
+
+class MPUBLIC TransCheckBoxSetting :
+    public CheckBoxSetting, public TransientStorage
+{
+    Q_OBJECT
+  public:
+    TransCheckBoxSetting() : CheckBoxSetting(this), TransientStorage() { }
+};
+
+class MPUBLIC TransComboBoxSetting :
+    public ComboBoxSetting, public TransientStorage
+{
+    Q_OBJECT
+  public:
+    TransComboBoxSetting(bool rw = false, int _step = 1) :
+        ComboBoxSetting(this, rw, _step), TransientStorage() { }
+};
+
+class MPUBLIC TransSpinBoxSetting :
+    public SpinBoxSetting, public TransientStorage
+{
+    Q_OBJECT
+  public:
+    TransSpinBoxSetting(int minv, int maxv, int step,
+                        bool allow_single_step = false,
+                        QString special_value_text = "") :
+        SpinBoxSetting(this, minv, maxv, step,
+                       allow_single_step, special_value_text) { }
+};
+
+class MPUBLIC TransListBoxSetting :
+    public ListBoxSetting, public TransientStorage
+{
+    Q_OBJECT
+  public:
+    TransListBoxSetting() : ListBoxSetting(this), TransientStorage() { }
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+
+class MPUBLIC HostSlider : public SliderSetting, public HostDBStorage
+{
+    Q_OBJECT
+  public:
+    HostSlider(const QString &name, int min, int max, int step) :
+        SliderSetting(this, min, max, step),
+        HostDBStorage(this, name) { }
+};
+
+class MPUBLIC HostSpinBox: public SpinBoxSetting, public HostDBStorage
+{
+    Q_OBJECT
+  public:
+    HostSpinBox(const QString &name, int min, int max, int step,
+                bool allow_single_step = false) :
+        SpinBoxSetting(this, min, max, step, allow_single_step),
+        HostDBStorage(this, name) { }
+};
+
+class MPUBLIC HostCheckBox : public CheckBoxSetting, public HostDBStorage
+{
+    Q_OBJECT
+  public:
+    explicit HostCheckBox(const QString &name) :
+        CheckBoxSetting(this), HostDBStorage(this, name) { }
+    virtual ~HostCheckBox() { ; }
+};
+
+class MPUBLIC HostComboBox : public ComboBoxSetting, public HostDBStorage
+{
+    Q_OBJECT
+  public:
+    HostComboBox(const QString &name, bool rw = false) :
+        ComboBoxSetting(this, rw), HostDBStorage(this, name) { }
+    virtual ~HostComboBox() { ; }
+};
+
+class MPUBLIC HostRefreshRateComboBox : public HostComboBox
+{
+    Q_OBJECT
+  public:
+    HostRefreshRateComboBox(const QString &name, bool rw = false) :
+        HostComboBox(name, rw) { }
+    virtual ~HostRefreshRateComboBox() { ; }
+
+  public slots:
+    virtual void ChangeResolution(const QString &resolution);
+
+  private:
+    static const std::vector<double> GetRefreshRates(const QString &resolution);
+};
+
+class MPUBLIC HostTimeBox : public ComboBoxSetting, public HostDBStorage
+{
+    Q_OBJECT
+  public:
+    HostTimeBox(const QString &name, const QString &defaultTime = "00:00",
+                const int interval = 1) :
+        ComboBoxSetting(this, false, 30 / interval),
+        HostDBStorage(this, name)
+    {
+        int hour;
+        int minute;
+        QString timeStr;
+
+        for (hour = 0; hour < 24; hour++)
+        {
+            for (minute = 0; minute < 60; minute += interval)
+            {
+                timeStr = timeStr.sprintf("%02d:%02d", hour, minute);
+                addSelection(timeStr, timeStr,
+                             timeStr == defaultTime);
+            }
+        }
+    }
+};
+
+class MPUBLIC HostLineEdit: public LineEditSetting, public HostDBStorage
+{
+    Q_OBJECT
+  public:
+    HostLineEdit(const QString &name, bool rw = true) :
+        LineEditSetting(this, rw), HostDBStorage(this, name) { }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class MPUBLIC GlobalSlider : public SliderSetting, public GlobalDBStorage
+{
+    Q_OBJECT
+  public:
+    GlobalSlider(const QString &name, int min, int max, int step) :
+        SliderSetting(this, min, max, step), GlobalDBStorage(this, name) { }
+};
+
+class MPUBLIC GlobalSpinBox : public SpinBoxSetting, public GlobalDBStorage
+{
+    Q_OBJECT
+  public:
+    GlobalSpinBox(const QString &name, int min, int max, int step,
+                  bool allow_single_step = false) :
+        SpinBoxSetting(this, min, max, step, allow_single_step),
+        GlobalDBStorage(this, name) { }
+};
+
+class MPUBLIC GlobalCheckBox : public CheckBoxSetting, public GlobalDBStorage
+{
+    Q_OBJECT
+  public:
+    explicit GlobalCheckBox(const QString &name) :
+        CheckBoxSetting(this), GlobalDBStorage(this, name) { }
+};
+
+class MPUBLIC GlobalComboBox : public ComboBoxSetting, public GlobalDBStorage
+{
+    Q_OBJECT
+  public:
+    GlobalComboBox(const QString &name, bool rw = false) :
+        ComboBoxSetting(this, rw), GlobalDBStorage(this, name) { }
+};
+
+class MPUBLIC GlobalLineEdit : public LineEditSetting, public GlobalDBStorage
+{
+    Q_OBJECT
+  public:
+    GlobalLineEdit(const QString &name, bool rw = true) :
+        LineEditSetting(this, rw), GlobalDBStorage(this, name) { }
+};
+
+class MPUBLIC GlobalTimeBox : public ComboBoxSetting, public GlobalDBStorage
+{
+    Q_OBJECT
+  public:
+    GlobalTimeBox(const QString &name, const QString &defaultTime = "00:00",
+                  const int interval = 1) :
+        ComboBoxSetting(this, false, 30 / interval),
+        GlobalDBStorage(this, name)
+    {
+        int hour;
+        int minute;
+        QString timeStr;
+
+        for (hour = 0; hour < 24; hour++)
+        {
+            for (minute = 0; minute < 60; minute += interval)
+            {
+                timeStr = timeStr.sprintf("%02d:%02d", hour, minute);
+                addSelection(timeStr, timeStr,
+                             timeStr == defaultTime);
+            }
+        }
+    }
+};
+
+#ifndef MYTHCONFIG
+#include "mythconfigdialogs.h"
+#include "mythconfiggroups.h"
+#endif // MYTHCONFIG
+
+#endif // SETTINGS_H
diff --git a/abs/core/mythinstall/PKGBUILD b/abs/core/mythinstall/PKGBUILD
index 75ffe99..24a8235 100644
--- a/abs/core/mythinstall/PKGBUILD
+++ b/abs/core/mythinstall/PKGBUILD
@@ -1,11 +1,11 @@
 # Maintainer: Jams
 pkgname=mythinstall
-pkgver=8.5.1
-pkgrel=4
+pkgver=8.6
+pkgrel=1
 pkgdesc="LinHES installer/systemconfig GUI."
-arch=('i686' 'x86_64')
-depends=('mythtv>=29' 'LinHES-config')
-makedepends=('mythtv>=29')
+arch=('x86_64')
+depends=('mythtv>=30.0' 'LinHES-config')
+makedepends=('mythtv>=30.0')
 logofiles=`ls logo*.png`
 source=('install-ui.xml' $logofiles)
 
-- 
cgit v0.12

