diff -Naurp mythtv-0.20.orig/libs/libmyth/dbsettings.cpp mythtv-0.20/libs/libmyth/dbsettings.cpp
--- mythtv-0.20.orig/libs/libmyth/dbsettings.cpp	2006-04-07 15:14:30.000000000 -0400
+++ mythtv-0.20/libs/libmyth/dbsettings.cpp	2007-04-13 11:28:19.000000000 -0400
@@ -4,40 +4,6 @@
 #include <qfile.h>
 #include <qdir.h>
 
-class TransientSetting: public TransientStorage, virtual public Configurable {
-public:
-    TransientSetting() { };
-};
-
-class TransientSpinBox: public SpinBoxSetting, public TransientSetting {
-  public:
-    TransientSpinBox(int min, int max, int step, 
-                   bool allow_single_step = false) :
-        SpinBoxSetting(min, max, step, allow_single_step) { };
-};
-
-class TransientCheckBox: public CheckBoxSetting, public TransientSetting {
-  public:
-    TransientCheckBox() { };
-};
-
-class TransientLineEdit: public LineEditSetting, public TransientSetting {
-  public:
-    TransientLineEdit(bool rw = true) :
-        LineEditSetting(rw) { };
-};
-
-class TransientComboBox: public ComboBoxSetting, public TransientSetting {
-  public:
-    TransientComboBox(bool rw = true) :
-        ComboBoxSetting(rw) { };
-};
-
-class TransientLabel: public LabelSetting, public TransientSetting {
-  public:
-    TransientLabel() { };
-};
-
 class MythDbSettings1: public VerticalConfigurationGroup {
 public:
     MythDbSettings1();
@@ -46,12 +12,12 @@ public:
     void save();
     
 protected:
-    TransientLabel    *info;
-    TransientLineEdit *dbHostName;
-    TransientLineEdit *dbName;
-    TransientLineEdit *dbUserName;
-    TransientLineEdit *dbPassword;
-    TransientComboBox *dbType;
+    TransLabelSetting    *info;
+    TransLineEditSetting *dbHostName;
+    TransLineEditSetting *dbName;
+    TransLineEditSetting *dbUserName;
+    TransLineEditSetting *dbPassword;
+    TransComboBoxSetting *dbType;
 }; 
 
 class MythDbSettings2: public VerticalConfigurationGroup {
@@ -62,12 +28,12 @@ public:
     void save();
     
 protected:
-    TransientCheckBox *localEnabled;
-    TransientLineEdit *localHostName;
-    TransientCheckBox *wolEnabled;
-    TransientSpinBox  *wolReconnect;
-    TransientSpinBox  *wolRetry;
-    TransientLineEdit *wolCommand;
+    TransCheckBoxSetting *localEnabled;
+    TransLineEditSetting *localHostName;
+    TransCheckBoxSetting *wolEnabled;
+    TransSpinBoxSetting  *wolReconnect;
+    TransSpinBoxSetting  *wolRetry;
+    TransLineEditSetting *wolCommand;
 }; 
 
 
@@ -115,7 +81,7 @@ MythDbSettings1::MythDbSettings1() :
     setLabel(QObject::tr("Database Configuration") + " 1/2");
     setUseLabel(false);
     
-    info = new TransientLabel();
+    info = new TransLabelSetting();
 
     MSqlQuery query(MSqlQuery::InitCon());
     if (query.isConnected())
@@ -127,34 +93,33 @@ MythDbSettings1::MythDbSettings1() :
                                    "below."));
     addChild(info);
     
-    dbHostName = new TransientLineEdit(true);
+    dbHostName = new TransLineEditSetting(true);
     dbHostName->setLabel(QObject::tr("Host name"));
     dbHostName->setHelpText(QObject::tr("The host name or IP address of "
                                         "the machine hosting the database. "
                                         "This information is required."));
     addChild(dbHostName);
-    
-    dbName = new TransientLineEdit(true);
+    dbName = new TransLineEditSetting(true);
     dbName->setLabel(QObject::tr("Database"));
     dbName->setHelpText(QObject::tr("The name of the database. "
                                     "This information is required."));
     addChild(dbName);
 
-    dbUserName = new TransientLineEdit(true);
+    dbUserName = new TransLineEditSetting(true);
     dbUserName->setLabel(QObject::tr("User"));
     dbUserName->setHelpText(QObject::tr("The user name to use while "
                                         "connecting to the database. "
                                         "This information is required."));
     addChild(dbUserName);
     
-    dbPassword = new TransientLineEdit(true);
+    dbPassword = new TransLineEditSetting(true);
     dbPassword->setLabel(QObject::tr("Password"));
     dbPassword->setHelpText(QObject::tr("The password to use while "
                                         "connecting to the database. "
                                         "This information is required."));
     addChild(dbPassword);
     
-    dbType = new TransientComboBox(false);
+    dbType = new TransComboBoxSetting(false);
     dbType->setLabel(QObject::tr("Database type"));
     dbType->addSelection(QObject::tr("MySQL"), "QMYSQL3");
     //dbType->addSelection(QObject::tr("PostgreSQL"), "QPSQL7");
@@ -171,7 +136,7 @@ MythDbSettings2::MythDbSettings2(void) :
     setLabel(QObject::tr("Database Configuration") + " 2/2");
     setUseLabel(false);
     
-    localEnabled = new TransientCheckBox();
+    localEnabled = new TransCheckBoxSetting();
     localEnabled->setLabel(QObject::tr("Use custom identifier for frontend "
                                        "preferences"));
     localEnabled->setHelpText(QObject::tr("If this frontend's host name "
@@ -183,7 +148,7 @@ MythDbSettings2::MythDbSettings2(void) :
                                           "be used to save preferences in "
                                           "the database."));
     
-    localHostName = new TransientLineEdit(true);
+    localHostName = new TransLineEditSetting(true);
     localHostName->setLabel(QObject::tr("Custom identifier"));
     localHostName->setHelpText(QObject::tr("An identifier to use while "
                                            "saving the settings for this "
@@ -197,24 +162,24 @@ MythDbSettings2::MythDbSettings2(void) :
         new LocalHostNameSettings(localEnabled, group1);
     addChild(sub3);
     
-    wolEnabled = new TransientCheckBox();
+    wolEnabled = new TransCheckBoxSetting();
     wolEnabled->setLabel(QObject::tr("Use Wake-On-LAN to wake database"));
     wolEnabled->setHelpText(QObject::tr("If checked, the frontend will use "
                                         "Wake-On-LAN parameters to "
                                         "reconnect to the database server."));
     
-    wolReconnect = new TransientSpinBox(0, 60, 1, true);
+    wolReconnect = new TransSpinBoxSetting(0, 60, 1, true);
     wolReconnect->setLabel(QObject::tr("Reconnect time"));
     wolReconnect->setHelpText(QObject::tr("The time in seconds to wait for "
                                           "the server to wake up."));
     
-    wolRetry = new TransientSpinBox(1, 10, 1, true);
+    wolRetry = new TransSpinBoxSetting(1, 10, 1, true);
     wolRetry->setLabel(QObject::tr("Retry attempts"));
     wolRetry->setHelpText(QObject::tr("The number of retries to wake the "
                                       "server before the frontend gives "
                                       "up."));
     
-    wolCommand = new TransientLineEdit(true);
+    wolCommand = new TransLineEditSetting(true);
     wolCommand->setLabel(QObject::tr("Wake command"));
     wolCommand->setHelpText(QObject::tr("The command executed on this "
                                         "frontend to wake up the database "
diff -Naurp mythtv-0.20.orig/libs/libmyth/mythcontext.h mythtv-0.20/libs/libmyth/mythcontext.h
--- mythtv-0.20.orig/libs/libmyth/mythcontext.h	2007-04-13 11:26:47.000000000 -0400
+++ mythtv-0.20/libs/libmyth/mythcontext.h	2007-04-13 11:28:19.000000000 -0400
@@ -224,7 +224,7 @@ class MythPrivRequest
 
 /// Update this whenever the plug-in API changes.
 /// Including changes in the libmythtv class methods used by plug-ins.
-#define MYTH_BINARY_VERSION "0.20.20060828-3"
+#define MYTH_BINARY_VERSION "0.20.20060828-4"
 
 /** \brief Increment this whenever the MythTV network protocol changes.
  *
diff -Naurp mythtv-0.20.orig/libs/libmyth/settings.h mythtv-0.20/libs/libmyth/settings.h
--- mythtv-0.20.orig/libs/libmyth/settings.h	2006-09-04 17:01:06.000000000 -0400
+++ mythtv-0.20/libs/libmyth/settings.h	2007-04-13 11:28:19.000000000 -0400
@@ -719,11 +719,6 @@ protected:
     MythPushButton *button;
 };
 
-class TransButtonSetting: public ButtonSetting, public TransientStorage {
-public:
-    TransButtonSetting(QString name = "button") : ButtonSetting(name) {}
-};
-
 class ConfigPopupDialogWidget: public MythPopupBox {
     Q_OBJECT
 public:
@@ -767,16 +762,6 @@ private:
     int totalSteps;
 };
 
-class TransLabelSetting: public LabelSetting, public TransientStorage {
-public:
-    TransLabelSetting() {};
-};
-
-class TransCheckBoxSetting: public CheckBoxSetting, public TransientStorage {
-public:
-    TransCheckBoxSetting() {};
-};
-
 class HostSetting: public SimpleDBStorage, virtual public Configurable {
 public:
     HostSetting(QString name):
@@ -802,6 +787,57 @@ protected:
     virtual QString setClause(MSqlBindings& bindings);
 };
 
+///////////////////////////////////////////////////////////////////////////////
+
+class TransButtonSetting :
+    public ButtonSetting, public TransientStorage
+{
+  public:
+    TransButtonSetting(QString name = "button") : ButtonSetting(name) { }
+};
+
+class TransLabelSetting :
+    public LabelSetting, public TransientStorage
+{
+  public:
+    TransLabelSetting() { }
+};
+
+class TransLineEditSetting :
+    public LineEditSetting, public TransientStorage
+{
+  public:
+    TransLineEditSetting(bool rw = true) : LineEditSetting(rw) { }
+};
+
+class TransCheckBoxSetting :
+    public CheckBoxSetting, public TransientStorage
+{
+  public:
+    TransCheckBoxSetting() { }
+};
+
+class TransComboBoxSetting :
+    public ComboBoxSetting, public TransientStorage
+{
+  public:
+    TransComboBoxSetting(bool rw = true, int _step = 1) :
+        ComboBoxSetting(rw, _step) { }
+};
+
+class TransSpinBoxSetting :
+    public SpinBoxSetting, public TransientStorage
+{
+  public:
+    TransSpinBoxSetting(int min, int max, int step,
+                        bool allow_single_step = false,
+                        QString special_value_text = "") :
+        SpinBoxSetting(min, max, step, allow_single_step,
+                       special_value_text) { }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
 class HostSlider: public SliderSetting, public HostSetting {
   public:
     HostSlider(const QString &name, int min, int max, int step) :
diff -Naurp mythtv-0.20.orig/libs/libmythtv/dtvconfparserhelpers.cpp mythtv-0.20/libs/libmythtv/dtvconfparserhelpers.cpp
--- mythtv-0.20.orig/libs/libmythtv/dtvconfparserhelpers.cpp	1969-12-31 19:00:00.000000000 -0500
+++ mythtv-0.20/libs/libmythtv/dtvconfparserhelpers.cpp	2007-04-13 11:28:23.000000000 -0400
@@ -0,0 +1,351 @@
+#include "mythcontext.h"
+#include "dtvconfparserhelpers.h"
+
+bool DTVParamHelper::ParseParam(const QString &symbol, int &value,
+                                const DTVParamHelperStruct *table)
+{
+    const DTVParamHelperStruct *p = table;
+
+    while (p->symbol != NULL)
+    {
+        if (p->symbol == symbol.left(p->symbol.length()))
+        {
+            //symbol = symbol.mid(p->symbol.length());
+            value = p->value;
+            return true;
+        }
+        p++;
+    }
+
+    return false;
+}
+
+QString DTVParamHelper::toString(const char *strings[], int index,
+                                 uint strings_size)
+{
+    if ((index < 0) || ((uint)index >= strings_size))
+    {
+        VERBOSE(VB_IMPORTANT,
+                "DTVParamHelper::toString() index out of bounds");
+
+        return QString::null;
+    }
+
+    return strings[index];
+}
+
+const DTVParamHelperStruct DTVInversion::confTable[] =
+{
+   { "INVERSION_AUTO", kInversionAuto },
+   { "INVERSION_OFF",  kInversionOff  },
+   { "INVERSION_ON",   kInversionOn   },
+   { NULL,             kInversionAuto },
+};
+
+const DTVParamHelperStruct DTVInversion::vdrTable[] =
+{
+   { "999", kInversionAuto },
+   { "0",   kInversionOff  },
+   { "1",   kInversionOn   },
+   { NULL,  kInversionAuto },
+};
+
+const DTVParamHelperStruct DTVInversion::parseTable[] =
+{
+   { "a",  kInversionAuto },
+   { "0",  kInversionOff  },
+   { "1",  kInversionOn   },
+   { NULL, kInversionAuto },
+};
+
+const char *DTVInversion::dbStr[DTVInversion::kDBStrCnt] =
+{
+    "0", ///< kInversionOff
+    "1", ///< kInversionOn
+    "a"  ///< kInversionAuto
+};
+
+const DTVParamHelperStruct DTVBandwidth::confTable[] =
+{
+   { "BANDWIDTH_AUTO",  kBandwidthAuto },
+   { "BANDWIDTH_8_MHZ", kBandwidth8Mhz },
+   { "BANDWIDTH_7_MHZ", kBandwidth7Mhz },
+   { "BANDWIDTH_6_MHZ", kBandwidth6Mhz },
+   { NULL,              kBandwidthAuto },
+};
+
+const DTVParamHelperStruct DTVBandwidth::vdrTable[] =
+{
+   { "999", kBandwidthAuto },
+   { "8",   kBandwidth8Mhz },
+   { "7",   kBandwidth7Mhz },
+   { "6",   kBandwidth6Mhz },
+   { NULL,  kBandwidthAuto },
+};
+
+const DTVParamHelperStruct DTVBandwidth::parseTable[] =
+{
+   { "auto", kBandwidthAuto },
+   { "8",    kBandwidth8Mhz },
+   { "7",    kBandwidth7Mhz },
+   { "6",    kBandwidth6Mhz },
+   { NULL,   kBandwidthAuto },
+};
+
+const char *DTVBandwidth::dbStr[DTVBandwidth::kDBStrCnt] =
+{
+    "8",   ///< kBandwidth8Mhz
+    "7",   ///< kBandwidth7Mhz
+    "6",   ///< kBandwidth6Mhz
+    "auto" ///< kBandwidthAUTO
+};
+
+const DTVParamHelperStruct DTVCodeRate::confTable[] =
+{
+    { "FEC_AUTO", kFECAuto },
+    { "FEC_1_2",  kFEC_1_2  },
+    { "FEC_2_3",  kFEC_2_3  },
+    { "FEC_3_4",  kFEC_3_4  },
+    { "FEC_4_5",  kFEC_4_5  },
+    { "FEC_5_6",  kFEC_5_6  },
+    { "FEC_6_7",  kFEC_6_7  },
+    { "FEC_7_8",  kFEC_7_8  },
+    { "FEC_8_9",  kFEC_8_9  },
+    { "FEC_NONE", kFECNone },
+    { NULL,       kFECAuto },
+};
+
+const DTVParamHelperStruct DTVCodeRate::vdrTable[] =
+{
+    { "999", kFECAuto },
+    { "12",  kFEC_1_2 },
+    { "23",  kFEC_2_3 },
+    { "34",  kFEC_3_4 },
+    { "45",  kFEC_4_5 },
+    { "56",  kFEC_5_6 },
+    { "67",  kFEC_6_7 },
+    { "78",  kFEC_7_8 },
+    { "89",  kFEC_8_9 },
+    { "0",   kFECNone },
+    { NULL,  kFECAuto }
+};
+
+const DTVParamHelperStruct DTVCodeRate::parseTable[] =
+{
+    { "auto", kFECAuto },
+    { "1/2",  kFEC_1_2 },
+    { "2/3",  kFEC_2_3 },
+    { "3/4",  kFEC_3_4 },
+    { "4/5",  kFEC_4_5 },
+    { "5/6",  kFEC_5_6 },
+    { "6/7",  kFEC_6_7 },
+    { "7/8",  kFEC_7_8 },
+    { "8/9",  kFEC_8_9 },
+    { "none", kFECNone },
+    { NULL,   kFECAuto }
+};
+
+const char *DTVCodeRate::dbStr[DTVCodeRate::kDBStrCnt] =
+{
+     "none", ///< kFECNone
+     "1/2",  ///< kFEC_1_2
+     "2/3",  ///< kFEC_2_3
+     "3/4",  ///< kFEC_3_4
+     "4/5",  ///< kFEC_4_5
+     "5/6",  ///< kFEC_5_6
+     "6/7",  ///< kFEC_6_7
+     "7/8",  ///< kFEC_7_8
+     "8/9",  ///< kFEC_8_9
+     "auto"  ///< kFECAuto
+};
+
+const DTVParamHelperStruct DTVModulation::confTable[] =
+{
+   { "QAM_AUTO", kModulationQAMAuto },
+   { "QAM_16",   kModulationQAM16   },
+   { "QAM_32",   kModulationQAM32   },
+   { "QAM_64",   kModulationQAM64   },
+   { "QAM_128",  kModulationQAM128  },
+   { "QAM_256",  kModulationQAM256  },
+   { "QPSK",     kModulationQPSK    },
+   { "8PSK",     kModulation8PSK    },
+   { NULL,       kModulationQAMAuto },
+};
+
+const DTVParamHelperStruct DTVModulation::vdrTable[] =
+{
+   { "999", kModulationQAMAuto },
+   { "16",  kModulationQAM16   },
+   { "32",  kModulationQAM32   },
+   { "64",  kModulationQAM64   },
+   { "128", kModulationQAM128  },
+   { "256", kModulationQAM256  },
+   { "0",   kModulationQPSK    },
+   { NULL,  kModulationQAMAuto },
+};
+
+const DTVParamHelperStruct DTVModulation::parseTable[] =
+{
+   { "auto",     kModulationQAMAuto },
+   { "qam_16",   kModulationQAM16   },
+   { "qam_32",   kModulationQAM32   },
+   { "qam_64",   kModulationQAM64   },
+   { "qam_128",  kModulationQAM128  },
+   { "qam_256",  kModulationQAM256  },
+   { "qpsk",     kModulationQPSK    },
+   { "8vsb",     kModulation8VSB    },
+   { "16vsb",    kModulation16VSB   },
+   { "8psk",     kModulation8PSK    },
+   // alternates from dvbtypes
+   { "a",        kModulationQAMAuto },
+   { "qam_auto", kModulationQAMAuto },
+   { "qam-16",   kModulationQAM16   },
+   { "qam-32",   kModulationQAM32   },
+   { "qam-64",   kModulationQAM64   },
+   { "qam-128",  kModulationQAM128  },
+   { "qam-256",  kModulationQAM256  },
+   { "8-vsb",    kModulation8VSB    },
+   { "16-vsb",   kModulation16VSB   },
+   { "8-psk",    kModulation8PSK    },
+   { NULL,       kModulationQAMAuto },
+};
+
+const char *DTVModulation::dbStr[DTVModulation::kDBStrCnt] =
+{
+    "qpsk",    ///< kModulationQPSK,
+    "qam_16",  ///< kModulationQAM16
+    "qam_32",  ///< kModulationQAM32
+    "qam_64",  ///< kModulationQAM64
+    "qam_128", ///< kModulationQAM128
+    "qam_256", ///< kModulationQAM256
+    "auto",    ///< kModulationQAMAuto
+    "8vsb",    ///< kModulation8VSB
+    "16vsb",   ///< kModulation16VSB
+    "8psk",    ///< kModulation8PSK
+};
+
+const DTVParamHelperStruct DTVTransmitMode::confTable[] =
+{
+   { "TRANSMISSION_MODE_AUTO", kTransmissionModeAuto },
+   { "TRANSMISSION_MODE_2K",   kTransmissionMode2K   },
+   { "TRANSMISSION_MODE_8K",   kTransmissionMode8K   },
+   { NULL,                     kTransmissionModeAuto },
+};
+
+const DTVParamHelperStruct DTVTransmitMode::vdrTable[] =
+{
+   { "999", kTransmissionModeAuto },
+   { "2",   kTransmissionMode2K   },
+   { "8",   kTransmissionMode8K   },
+   { NULL,  kTransmissionModeAuto },
+};
+
+const DTVParamHelperStruct DTVTransmitMode::parseTable[] =
+{
+   { "auto", kTransmissionModeAuto },
+   { "2",    kTransmissionMode2K   },
+   { "8",    kTransmissionMode8K   },
+   { NULL,   kTransmissionModeAuto },
+};
+
+const char *DTVTransmitMode::dbStr[DTVTransmitMode::kDBStrCnt] =
+{
+    "2",   ///< kTransmissionMode2K
+    "8",   ///< kTransmissionMode8K
+    "auto" ///< kTransmissionModeAuto
+};
+
+const DTVParamHelperStruct DTVGuardInterval::confTable[] =
+{
+   { "GUARD_INTERVAL_AUTO", kGuardIntervalAuto  },
+   { "GUARD_INTERVAL_1_32", kGuardInterval_1_32 },
+   { "GUARD_INTERVAL_1_16", kGuardInterval_1_16 },
+   { "GUARD_INTERVAL_1_8",  kGuardInterval_1_8  },
+   { "GUARD_INTERVAL_1_4",  kGuardInterval_1_4  },
+   { NULL,                  kGuardIntervalAuto  },
+};
+
+const DTVParamHelperStruct DTVGuardInterval::vdrTable[] =
+{
+   { "999", kGuardIntervalAuto  },
+   { "32",  kGuardInterval_1_32 },
+   { "16",  kGuardInterval_1_16 },
+   { "8",   kGuardInterval_1_8  },
+   { "4",   kGuardInterval_1_4  },
+   { NULL,  kGuardIntervalAuto  },
+};
+
+const DTVParamHelperStruct DTVGuardInterval::parseTable[] =
+{
+   { "auto", kGuardIntervalAuto  },
+   { "1/32", kGuardInterval_1_32 },
+   { "1/16", kGuardInterval_1_16 },
+   { "1/8",  kGuardInterval_1_8  },
+   { "1/4",  kGuardInterval_1_4  },
+   { NULL,   kGuardIntervalAuto  },
+};
+
+const char *DTVGuardInterval::dbStr[DTVGuardInterval::kDBStrCnt] =
+{
+    "1/32", ///< kGuardInterval_1_32
+    "1/16", ///< kGuardInterval_1_16
+    "1/8",  ///< kGuardInterval_1_8
+    "1/4",  ///< kGuardInterval_1_4
+    "auto"  ///< kGuardIntervalAuto
+};
+
+const DTVParamHelperStruct DTVHierarchy::confTable[] =
+{
+   { "HIERARCHY_NONE", kHierarchyNone },
+   { "HIERARCHY_1",    kHierarchy1    },
+   { "HIERARCHY_2",    kHierarchy2    },
+   { "HIERARCHY_4",    kHierarchy4    },
+   { "HIERARCHY_AUTO", kHierarchyAuto },
+   { NULL,             kHierarchyAuto },
+};
+
+const DTVParamHelperStruct DTVHierarchy::vdrTable[] =
+{
+   { "0",   kHierarchyNone },
+   { "1",   kHierarchy1    },
+   { "2",   kHierarchy2    },
+   { "4",   kHierarchy4    },
+   { "999", kHierarchyAuto },
+   { NULL,  kHierarchyAuto },
+};
+
+const DTVParamHelperStruct DTVHierarchy::parseTable[] =
+{
+   { "n",  kHierarchyNone },
+   { "1",  kHierarchy1    },
+   { "2",  kHierarchy2    },
+   { "4",  kHierarchy4    },
+   { "a",  kHierarchyAuto },
+   { NULL, kHierarchyAuto },
+};
+
+const char *DTVHierarchy::dbStr[DTVHierarchy::kDBStrCnt] =
+{
+    "n", ///< kHierarchyNone
+    "1", ///< kHierarchy1
+    "2", ///< kHierarchy2
+    "4", ///< kHierarchy4
+    "a"  ///< kHierarchyAuto
+};
+
+const DTVParamHelperStruct DTVPolarity::parseTable[] =
+{
+    { "v",  kPolarityVertical   },
+    { "h",  kPolarityHorizontal },
+    { "r",  kPolarityRight      },
+    { "l",  kPolarityLeft       },
+    { NULL, kPolarityVertical   },
+};
+
+const char *DTVPolarity::dbStr[DTVPolarity::kDBStrCnt] =
+{
+   "v", ///< kPolarityVertical
+   "h", ///< kPolarityHorizontal
+   "r", ///< kPolarityRight
+   "l"  ///< kPolarityLeft
+};
diff -Naurp mythtv-0.20.orig/libs/libmythtv/dtvconfparserhelpers.h mythtv-0.20/libs/libmythtv/dtvconfparserhelpers.h
--- mythtv-0.20.orig/libs/libmythtv/dtvconfparserhelpers.h	1969-12-31 19:00:00.000000000 -0500
+++ mythtv-0.20/libs/libmythtv/dtvconfparserhelpers.h	2007-04-13 11:28:23.000000000 -0400
@@ -0,0 +1,348 @@
+/* -*- Mode: c++ -*-
+ * vim: set expandtab tabstop=4 shiftwidth=4:
+ *
+ * Original Project
+ *      MythTV      http://www.mythtv.org
+ *
+ * Author(s):
+ *      John Pullan  (john@pullan.org)
+ *
+ * Description:
+ *     Collection of classes to provide dvb channel scanning
+ *     functionallity
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
+ *
+ */
+
+#ifndef _DTVCONFPARSERHELPERS_H_
+#define _DTVCONFPARSERHELPERS_H_
+
+#include <qstring.h>
+
+// The following are a set of helper classes to allow easy translation
+// between the different string representations of various tuning params.
+
+struct DTVParamHelperStruct
+{
+    QString symbol;
+    int     value;
+};
+
+/** \class DTVParamHelper
+ *  \brief Helper abstract template to do some of the mundane portions
+ *         of translating and comparing the paramater strings.
+ */
+class DTVParamHelper
+{
+  public:
+    DTVParamHelper(int _value) : value(_value) { }
+
+    operator int()                const { return value;          }
+    int operator=(int _value)           { return value = _value; }
+    bool operator==(const int& v) const { return value == v;     }
+
+  protected:
+    static bool ParseParam(const QString &symbol, int &value,
+                           const DTVParamHelperStruct *table);
+
+    static QString toString(const char *strings[], int index,
+                            uint strings_size);
+
+  protected:
+    int value;
+};
+
+class DTVInversion : public DTVParamHelper
+{
+  protected:
+    static const DTVParamHelperStruct confTable[];
+    static const DTVParamHelperStruct vdrTable[];
+    static const DTVParamHelperStruct parseTable[];
+    static const uint kDBStrCnt = 3;
+    static const char *dbStr[kDBStrCnt];
+
+  public:
+    enum
+    {
+        kInversionOff,
+        kInversionOn,
+        kInversionAuto,
+    };
+
+    DTVInversion(int _default = kInversionAuto)
+        : DTVParamHelper(_default) { }
+
+    bool ParseConf(const QString &_value)
+       { return ParseParam(_value, value, confTable); }
+    bool ParseVDR(const QString &_value)
+       { return ParseParam(_value, value, vdrTable); }
+    bool Parse(const QString &_value)
+       { return ParseParam(_value, value, parseTable); }
+
+    QString toString() const { return toString(value); }
+
+    static QString toString(int _value)
+        { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); }
+};
+
+class DTVBandwidth : public DTVParamHelper
+{
+  protected:
+    static const DTVParamHelperStruct confTable[];
+    static const DTVParamHelperStruct vdrTable[];
+    static const DTVParamHelperStruct parseTable[];
+    static const uint kDBStrCnt = 4;
+    static const char *dbStr[kDBStrCnt];
+
+  public:
+    enum
+    {
+        kBandwidth8Mhz,
+        kBandwidth7Mhz,
+        kBandwidth6Mhz,
+        kBandwidthAuto,
+    };
+
+    DTVBandwidth(int _default = kBandwidthAuto) : DTVParamHelper(_default) { }
+
+    bool ParseConf(const QString &_value)
+       { return ParseParam(_value, value, confTable); }
+    bool ParseVDR(const QString &_value)
+       { return ParseParam(_value, value, vdrTable); }
+    bool Parse(const QString &_value)
+       { return ParseParam(_value, value, parseTable); }
+
+    QString toString() const { return toString(value); }
+
+    static QString toString(int _value)
+        { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); }
+};
+
+class DTVCodeRate : public DTVParamHelper
+{
+  protected:
+    static const DTVParamHelperStruct confTable[];
+    static const DTVParamHelperStruct vdrTable[];
+    static const DTVParamHelperStruct parseTable[];
+    static const uint kDBStrCnt = 10;
+    static const char *dbStr[kDBStrCnt];
+
+  public:
+    enum
+    {
+        kFECNone,
+        kFEC_1_2,
+        kFEC_2_3,
+        kFEC_3_4,
+        kFEC_4_5,
+        kFEC_5_6,
+        kFEC_6_7,
+        kFEC_7_8,
+        kFEC_8_9,
+        kFECAuto,
+    };
+
+    DTVCodeRate(int _default = kFECAuto) : DTVParamHelper(_default) { }
+
+    bool ParseConf(const QString &_value)
+       { return ParseParam(_value, value, confTable); }
+    bool ParseVDR(const QString &_value)
+       { return ParseParam(_value, value, vdrTable); }
+    bool Parse(const QString &_value)
+       { return ParseParam(_value, value, parseTable); }
+
+    QString toString() const { return toString(value); }
+
+    static QString toString(int _value)
+        { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); }
+};
+
+class DTVModulation : public DTVParamHelper
+{
+  protected:
+    static const DTVParamHelperStruct confTable[];
+    static const DTVParamHelperStruct vdrTable[];
+    static const DTVParamHelperStruct parseTable[];
+    static const uint kDBStrCnt = 10;
+    static const char *dbStr[kDBStrCnt];
+
+  public:
+    enum
+    {
+        kModulationQPSK,
+        kModulationQAM16,
+        kModulationQAM32, 
+        kModulationQAM64, 
+        kModulationQAM128,
+        kModulationQAM256,
+        kModulationQAMAuto,
+        kModulation8VSB,
+        kModulation16VSB,
+        kModulation8PSK, 
+    };
+
+    DTVModulation(int _default = kModulationQAMAuto)
+        : DTVParamHelper(_default) { }
+
+    bool ParseConf(const QString &_value)
+       { return ParseParam(_value, value, confTable); }
+    bool ParseVDR(const QString &_value)
+       { return ParseParam(_value, value, vdrTable); }
+    bool Parse(const QString &_value)
+       { return ParseParam(_value, value, parseTable); }
+
+    QString toString() const { return toString(value); }
+
+    static QString toString(int _value)
+        { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); }
+};
+
+class DTVTransmitMode : public DTVParamHelper
+{
+  protected:
+    static const DTVParamHelperStruct confTable[];
+    static const DTVParamHelperStruct vdrTable[];
+    static const DTVParamHelperStruct parseTable[];
+    static const uint kDBStrCnt = 3;
+    static const char *dbStr[kDBStrCnt];
+
+  public:
+    enum
+    {
+        kTransmissionMode2K,
+        kTransmissionMode8K,
+        kTransmissionModeAuto,
+    };
+
+    DTVTransmitMode(int _default = kTransmissionModeAuto)
+        : DTVParamHelper(_default) { }
+
+    bool ParseConf(const QString &_value)
+       { return ParseParam(_value, value, confTable); }
+    bool ParseVDR(const QString &_value)
+       { return ParseParam(_value, value, vdrTable); }
+    bool Parse(const QString &_value)
+       { return ParseParam(_value, value, parseTable); }
+
+    QString toString() const { return toString(value); }
+    static QString toString(int _value)
+        { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); }
+};
+
+class DTVGuardInterval : public DTVParamHelper
+{
+  protected:
+    static const DTVParamHelperStruct confTable[];
+    static const DTVParamHelperStruct vdrTable[];
+    static const DTVParamHelperStruct parseTable[];
+    static const uint kDBStrCnt = 5;
+    static const char *dbStr[kDBStrCnt];
+
+  public:
+    enum
+    {
+        kGuardInterval_1_32,
+        kGuardInterval_1_16,
+        kGuardInterval_1_8,
+        kGuardInterval_1_4,
+        kGuardIntervalAuto,
+    };
+
+    DTVGuardInterval(int _default = kGuardIntervalAuto)
+        : DTVParamHelper(_default) { }
+
+    bool ParseConf(const QString &_value)
+       { return ParseParam(_value, value, confTable); }
+    bool ParseVDR(const QString &_value)
+       { return ParseParam(_value, value, vdrTable); }
+    bool Parse(const QString &_value)
+       { return ParseParam(_value, value, parseTable); }
+
+    QString toString() const { return toString(value); }
+
+    static QString toString(int _value)
+        { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); }
+};
+
+class DTVHierarchy : public DTVParamHelper
+{
+  protected:
+    static const DTVParamHelperStruct confTable[];
+    static const DTVParamHelperStruct vdrTable[];
+    static const DTVParamHelperStruct parseTable[];
+    static const uint kDBStrCnt = 5;
+    static const char *dbStr[kDBStrCnt];
+
+  public:
+    enum
+    {
+        kHierarchyNone,
+        kHierarchy1,
+        kHierarchy2,
+        kHierarchy4,
+        kHierarchyAuto,
+    };
+
+    DTVHierarchy(int _default = kHierarchyAuto) : DTVParamHelper(_default) { }
+
+    bool ParseConf(const QString &_value)
+       { return ParseParam(_value, value, confTable); }
+    bool ParseVDR(const QString &_value)
+       { return ParseParam(_value, value, vdrTable); }
+    bool Parse(const QString &_value)
+       { return ParseParam(_value, value, parseTable); }
+
+    QString toString() const { return toString(value); }
+
+    static QString toString(int _value)
+        { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); }
+};
+
+class DTVPolarity : public DTVParamHelper
+{
+  protected:
+    static const DTVParamHelperStruct parseTable[];
+    static const uint kDBStrCnt = 4;
+    static const char *dbStr[kDBStrCnt];
+
+  public:
+    enum PolarityValues
+    {
+        kPolarityVertical,
+        kPolarityHorizontal,
+        kPolarityRight,
+        kPolarityLeft
+    };
+
+    DTVPolarity(int _default = kPolarityVertical)
+        : DTVParamHelper(_default) { }
+
+    bool ParseConf(const QString &_value)
+       { return ParseParam(_value, value, parseTable); }
+    bool ParseVDR(const QString &_value)
+       { return ParseParam(_value, value, parseTable); }
+    bool Parse(const QString &_value)
+       { return ParseParam(_value, value, parseTable); }
+
+    QString toString() const { return toString(value); }
+
+    static QString toString(int _value)
+        { return DTVParamHelper::toString(dbStr, _value, kDBStrCnt); }
+};
+
+#endif // _DTVCONFPARSERHELPERS_H_
diff -Naurp mythtv-0.20.orig/libs/libmythtv/dvbconfparser.cpp mythtv-0.20/libs/libmythtv/dvbconfparser.cpp
--- mythtv-0.20.orig/libs/libmythtv/dvbconfparser.cpp	2006-03-11 23:31:03.000000000 -0500
+++ mythtv-0.20/libs/libmythtv/dvbconfparser.cpp	2007-04-13 11:28:23.000000000 -0400
@@ -29,558 +29,308 @@
  * Or, point your browser to http://www.gnu.org/copyleft/gpl.html
  *
  */
-#include <qobject.h>
+
+// Qt headers
+#include <qstringlist.h>
+#include <qdeepcopy.h>
 #include <qfile.h>
-#include <qapplication.h>
+
+// MythTV headers
 #include "mythcontext.h"
-#include "dvbtypes.h"
-#include "dvbconfparser.h"
 #include "mythdbcon.h"
+#include "dvbconfparser.h"
 #include "channelutil.h"
 
-void DVBConfParser::Multiplex::dump()
+#define PARSE_SKIP(VAR) do { \
+    if (it == tokens.end()) return false; else it++; } while(0)
+
+#define PARSE_CONF(VAR) do { \
+    if (it == tokens.end() || !VAR.ParseConf(*it++)) \
+        return false; } while(0)
+
+#define PARSE_STR(VAR) do { \
+    if (it != tokens.end()) VAR = *it++; else return false; } while(0)
+
+#define PARSE_UINT(VAR) do { \
+    if (it != tokens.end()) \
+         VAR = (*it++).toUInt(); else return false; } while(0)
+
+#define PARSE_UINT_1000(VAR) do { \
+    if (it != tokens.end()) \
+         VAR = (*it++).toUInt() * 1000ULL; else return false; } while(0)
+
+
+QString DTVMultiplex::toString() const
 {
-    cerr << frequency<<" "<<inversion.toString()<<" "<<bandwidth.toString()<<" "<<coderate_hp.toString()<<" "<<coderate_lp.toString()<<" "<<constellation.toString()<<" "<<modulation.toString()<<" "<<transmit_mode.toString()<<" "<<guard_interval.toString()<<" "<<hierarchy.toString()<<" "<<polarity.toString()<<" "<<mplexid<<endl;
+    QString ret = QString("%1 %2 %3 ")
+        .arg(frequency).arg(modulation.toString()).arg(inversion.toString());
+
+    ret += QString("%1 %2 %3 %4 %5 %6 %7 %8")
+        .arg(hp_code_rate.toString()).arg(lp_code_rate.toString())
+        .arg(constellation.toString()).arg(bandwidth.toString())
+        .arg(trans_mode.toString()).arg(guard_interval.toString())
+        .arg(hierarchy.toString()).arg(polarity.toString());
+
+    return ret;
 }
- 
-void DVBConfParser::Channel::dump()
+
+bool DTVMultiplex::operator==(const DTVMultiplex &m) const
 {
-    cerr<<lcn<<" "<<mplexnumber<<" "<<name<<" "<<frequency<<" "<<inversion.toString()<<" "<<bandwidth.toString()<<" "<<coderate_hp.toString()<<" "<<coderate_lp.toString()<<" "<<constellation.toString()<<" "<<transmit_mode.toString()<<" "<<guard_interval.toString()<<" "<<hierarchy.toString()<<" "<<polarity.toString()<<" "<<serviceid<<endl;
+    return ((frequency == m.frequency) &&
+            (modulation == m.modulation) &&
+            (inversion == m.inversion) &&
+            (bandwidth == m.bandwidth) &&
+            (hp_code_rate == m.hp_code_rate) &&
+            (lp_code_rate == m.lp_code_rate) &&
+            (constellation == m.constellation) &&
+            (trans_mode == m.trans_mode) &&
+            (guard_interval == m.guard_interval) &&
+            (fec == m.fec) &&
+            (polarity == m.polarity) &&
+            (hierarchy == m.hierarchy));
 }
 
-bool DVBConfParser::Multiplex::operator==(const Multiplex& m) const
-{
-    if ((frequency == m.frequency) &&
-        (inversion == m.inversion) &&
-        (bandwidth == m.bandwidth) &&
-        (coderate_hp == m.coderate_hp) &&
-        (coderate_lp == m.coderate_lp) &&
-        (constellation == m.constellation) &&
-        (transmit_mode == m.transmit_mode) &&
-        (guard_interval == m.guard_interval) &&
-        (fec == m.fec) &&
-        (polarity == m.polarity) &&
-        (hierarchy == m.hierarchy))
-        return true;
-    else
-        return false;
+QString DTVChannelInfo::toString() const
+{
+    return QString("%1 %2 %3 ").arg(name).arg(serviceid).arg(lcn);
 }
 
-DVBConfParser::DVBConfParser(enum TYPE _type,unsigned _sourceid,
-                             const QString& _file)
+DTVConfParser::DTVConfParser(enum cardtype_t _type, uint _sourceid,
+                             const QString &_file)
+    : type(_type), sourceid(_sourceid), filename(QDeepCopy<QString>(_file))
 {
-    type=_type;
-    filename = _file;
-    sourceid=_sourceid;
 }
 
-int DVBConfParser::parse()
+DTVConfParser::return_t DTVConfParser::Parse(void)
 {
-    QFile file( filename );
-    if (file.open( IO_ReadOnly ) ) 
+    channels.clear();
+
+    QFile file(filename);
+    if (!file.open(IO_ReadOnly))
+        return ERROR_OPEN;
+
+    bool ok = true;
+    QTextStream stream(&file);
+    QString line;
+    while (!stream.atEnd())
     {
-        QTextStream stream( &file );
-        QString line;
-        while ( !stream.atEnd() ) 
+        line = stream.readLine(); // line of text excluding '\n'
+        line.stripWhiteSpace();
+        if (line.startsWith("#"))
+            continue;
+
+        QStringList list = QStringList::split(":", line);
+        QString str = *list.at(0);
+        int channelNo = -1;
+
+        if (str.at(0) == '@')
         {
-            line = stream.readLine(); // line of text excluding '\n'
-            line.stripWhiteSpace();
-            if (line.startsWith("#"))
-                continue;
-            QStringList list=QStringList::split(":",line);
-            QString str = *list.at(0);
-            int channelNo = -1;
-            if (str.at(0)=='@')
-            {
-                channelNo=str.mid(1).toInt();
-                line = stream.readLine(); 
-                list=QStringList::split(":",line);
-            }
-            str = *list.at(3);
-            if ((str == "T") || (str == "C") || (str=="S"))
-            {
-                if ((type == OFDM) && (str=="T"))
-                    parseVDR(list,channelNo);
-                else if ((type == QPSK) && (str=="S"))
-                    parseVDR(list,channelNo);
-                else if ((type == QAM) && (str=="C"))
-                    parseVDR(list,channelNo);
-            }
-            else if (type==OFDM)
-                parseConfOFDM(list);
-            else if (type==ATSC)
-                parseConfATSC(list);
-            else if (type==QPSK)
-                parseConfQPSK(list);
-            else if (type==QAM)
-                parseConfQAM(list);
+            channelNo = str.mid(1).toInt();
+            line = stream.readLine();
+            list = QStringList::split(":", line);
         }
-        file.close();
 
-        processChannels();
-        return OK;
+        str = *list.at(3);
+
+        if ((str == "T") || (str == "C") || (str == "S"))
+        {
+            if ((type == OFDM) && (str == "T"))
+                ok &= ParseVDR(list, channelNo);
+            else if ((type == QPSK) && (str == "S"))
+                ok &= ParseVDR(list, channelNo);
+            else if ((type == QAM) && (str == "C"))
+                ok &= ParseVDR(list, channelNo);
+        }
+        else if (type == OFDM)
+            ok &= ParseConfOFDM(list);
+        else if (type == ATSC)
+            ok &= ParseConfATSC(list);
+        else if (type == QPSK)
+            ok &= ParseConfQPSK(list);
+        else if (type == QAM)
+            ok &= ParseConfQAM(list);
     }
-    return ERROR_OPEN;
+    file.close();
+
+    return (ok) ? OK : ERROR_PARSE;
 }
 
-bool DVBConfParser::parseConfOFDM(QStringList& tokens)
+bool DTVConfParser::ParseConfOFDM(const QStringList &tokens)
 {
-    Channel c;
-    QStringList::Iterator i = tokens.begin();
-    QStringList::Iterator end = tokens.end();
-    if (i != end) c.name = *i++; else return false;
-    if (i != end) c.frequency = (*i++).toInt(); else return false;
-    if (i == end || !c.inversion.parseConf(*i++)) return false;
-    if (i == end || !c.bandwidth.parseConf(*i++)) return false;
-    if (i == end || !c.coderate_hp.parseConf(*i++)) return false;
-    if (i == end || !c.coderate_lp.parseConf(*i++)) return false;
-    if (i == end || !c.constellation.parseConf(*i++)) return false;
-    if (i == end || !c.transmit_mode.parseConf(*i++)) return false;
-    if (i == end || !c.guard_interval.parseConf(*i++)) return false;
-    if (i == end || !c.hierarchy.parseConf(*i++)) return false;
-    if (i == end ) return false; else i++;
-    if (i == end ) return false; else i++;
-    if (i != end) c.serviceid = (*i++).toInt(); else return false;
+    DTVChannelInfo chan;
+    DTVMultiplex   mux;
+
+    QStringList::const_iterator it = tokens.begin();
+
+    PARSE_SKIP(unknown);
+    PARSE_UINT(mux.frequency);
+    PARSE_CONF(mux.inversion);
+    PARSE_CONF(mux.bandwidth);
+    PARSE_CONF(mux.hp_code_rate);
+    PARSE_CONF(mux.lp_code_rate);
+    PARSE_CONF(mux.constellation);
+    PARSE_CONF(mux.trans_mode);
+    PARSE_CONF(mux.guard_interval);
+    PARSE_CONF(mux.hierarchy);
+    PARSE_SKIP(unknown);
+    PARSE_SKIP(unknown);
+    PARSE_UINT(chan.serviceid);
 
-    channels.append(c);
+    AddChannel(mux, chan);
 
     return true;
 }
 
-bool DVBConfParser::parseConfATSC(QStringList& tokens)
+bool DTVConfParser::ParseConfATSC(const QStringList &tokens)
 {
-    Channel c;
-    QStringList::Iterator i = tokens.begin();
-    QStringList::Iterator end = tokens.end();
-    if (i != end) c.name = *i++; else return false;
-    if (i != end) c.frequency = (*i++).toInt(); else return false;
-    if (i == end || !c.modulation.parseConf(*i++)) return false;
-    // We need the program number in the transport stream,
-    // otherwise we cannot "tune" to the program.
-    if (i == end ) return false; else i++;   // Ignore video pid
-    if (i == end ) return false; else i++;   // Ignore audio pid
-    if (i != end) c.serviceid = (*i++).toInt(); else return false;
+    DTVChannelInfo chan;
+    DTVMultiplex   mux;
 
-    channels.append(c);
+    QStringList::const_iterator it = tokens.begin();
 
-    return true;
-}
+    PARSE_STR(chan.name);
+    PARSE_UINT(mux.frequency);
+    PARSE_CONF(mux.modulation);
+    PARSE_SKIP(Ignore_Video_PID);
+    PARSE_SKIP(Ignore_Audio_PID);
+    PARSE_UINT(chan.serviceid);
+
+    AddChannel(mux, chan);
 
-bool DVBConfParser::parseConfQAM(QStringList& tokens)
-{
-    Channel c;
-    QStringList::Iterator i = tokens.begin();
-    QStringList::Iterator end = tokens.end();
-
-    if (i != end) c.name = *i++; else return false;
-    if (i != end) c.frequency = (*i++).toInt(); else return false;
-    if (i == end || !c.inversion.parseConf(*i++)) return false;
-    if (i != end) c.symbolrate = (*i++).toInt(); else return false;
-    if (i == end || !c.fec.parseConf(*i++)) return false;
-    if (i == end || !c.modulation.parseConf(*i++)) return false;
-    if (i == end ) return false; else i++;
-    if (i == end ) return false; else i++;
-    if (i != end) c.serviceid = (*i++).toInt(); else return false;
-    
-    channels.append(c);
     return true;
 }
 
-bool DVBConfParser::parseConfQPSK(QStringList& tokens)
+bool DTVConfParser::ParseConfQAM(const QStringList &tokens)
 {
-    Channel c;
-    QStringList::iterator it = tokens.begin();
-
-    if (it != tokens.end())
-        c.name = *it++;
-    else
-        return false;
-
-    if (it != tokens.end())
-        c.frequency = (*it++).toUInt() * 1000;
-    else
-        return false;
-
-    if (it == tokens.end() || !c.polarity.parseConf(*it++))
-        return false;
+    DTVChannelInfo chan;
+    DTVMultiplex   mux;
 
-    if (it == tokens.end())
-        return false;
-    else
-        it++; //Sat num
+    QStringList::const_iterator it = tokens.begin();
 
-    if (it != tokens.end())
-        c.symbolrate = (*it++).toUInt() * 1000;
-    else
-        return false;
+    PARSE_SKIP(unknown);
+    PARSE_UINT(mux.frequency);
+    PARSE_CONF(mux.inversion);
+    PARSE_UINT(mux.symbolrate);
+    PARSE_CONF(mux.fec);
+    PARSE_CONF(mux.modulation);
+    PARSE_SKIP(unknown);
+    PARSE_SKIP(unknown);
+    PARSE_UINT(chan.serviceid);
 
-    if (it == tokens.end())
-        return false;
-    else
-        it++;
+    AddChannel(mux, chan);
 
-    if (it == tokens.end())
-        return false;
-    else
-        it++;
-
-    if (it != tokens.end())
-        c.serviceid = (*it++).toInt();
-    else
-        return false;
-    
-    channels.append(c);
     return true;
 }
 
-bool DVBConfParser::parseVDR(QStringList& tokens, int channelNo)
+bool DTVConfParser::ParseConfQPSK(const QStringList &tokens)
 {
-    Channel c;
-    QStringList::Iterator i = tokens.begin();
-    QStringList::Iterator end = tokens.end();
-    c.lcn = channelNo;
-
-//BBC ONE:754166:I999B8C34D34M16T2G32Y0:T:27500:600:601,602:0:0:4168:0:0:0
-    if (i != end) c.name = *i++; else return false;
-    if (i != end) c.frequency = (*i++).toInt()*1000; else return false;
-    if (i == end) return false;
-    QString params = (*i++);
-    while (!params.isEmpty())
-    {
-        QString ori = params;
-        int s = *(const char*)params;
-        params=params.mid(1);
-        switch(s)
-        {
-        case 'I':
-            c.inversion.parseVDR(params);
-            break;
-        case 'B':
-            c.bandwidth.parseVDR(params);
-            break;
-        case 'C':
-            c.coderate_hp.parseVDR(params);
-            break;
-        case 'D':
-            c.coderate_lp.parseVDR(params);
-            break;
-        case 'M':
-            c.constellation.parseVDR(params);
-            break;
-        case 'T':
-            c.transmit_mode.parseVDR(params);
-            break;
-        case 'G':
-            c.guard_interval.parseVDR(params);
-            break;
-        case 'Y':
-            c.hierarchy.parseVDR(params);
-            break;
-        case 'V':
-        case 'H':
-        case 'R':
-        case 'L':
-            c.polarity.parseVDR(ori);
-            break;
-        default:
-            return false;
-        }
-    }
-     
-    if (i == end ) return false; else i++;
-    if (i == end ) return false; else i++;
-    if (i == end ) return false; else i++;
-    if (i == end ) return false; else i++;
-    if (i == end ) return false; else i++;
-    if (i == end ) return false; else i++;
-    if (i != end) c.serviceid = (*i++).toInt(); else return false;
+    DTVChannelInfo chan;
+    DTVMultiplex   mux;
+
+    QStringList::const_iterator it = tokens.begin();
+
+    PARSE_STR(chan.name);
+    PARSE_UINT_1000(mux.frequency);
+    PARSE_CONF(mux.polarity);
+    PARSE_SKIP(Satelite_Number);
+    PARSE_UINT_1000(mux.symbolrate);
+    PARSE_SKIP(unknown);
+    PARSE_SKIP(unknown);
+    PARSE_UINT(chan.serviceid);
+
+    AddChannel(mux, chan);
 
-    channels.append(c);
     return true;
 }
 
-int DVBConfParser::generateNewChanID(int sourceID)
+bool DTVConfParser::ParseVDR(const QStringList &tokens, int channelNo)
 {
-    MSqlQuery query(MSqlQuery::InitCon());
-
-    QString theQuery =
-        QString("SELECT max(chanid) as maxchan "
-                "FROM channel WHERE sourceid=%1").arg(sourceID);
-    query.prepare(theQuery);
+    DTVChannelInfo chan;
+    DTVMultiplex   mux;
 
-    if (!query.exec())
-        MythContext::DBError("Calculating new ChanID", query);
+    QStringList::const_iterator it = tokens.begin();
 
-    if (!query.isActive())
-        MythContext::DBError("Calculating new ChanID for Analog Channel",query);
+    chan.lcn = channelNo;
 
-    query.next();
+// BBC ONE:754166:I999B8C34D34M16T2G32Y0:T:27500:600:601, 602:0:0:4168:0:0:0
 
-    // If transport not present add it, and move on to the next
-    if (query.size() <= 0)
-        return sourceID * 1000;
+    PARSE_SKIP(unknown);
 
-    int MaxChanID = query.value(0).toInt();
+    PARSE_UINT_1000(mux.frequency);
 
-    if (MaxChanID == 0)
-        return sourceID * 1000;
-    else
-        return MaxChanID + 1;
-}
-
-int DVBConfParser::findMultiplex(const DVBConfParser::Multiplex& m)
-{
-    MSqlQuery query(MSqlQuery::InitCon());
-    QString queryStr=QString("SELECT mplexid FROM dtv_multiplex WHERE "
-             "sourceid= %1 AND frequency=%2 AND inversion=\"%3\" AND ")
-             .arg(sourceid).arg(m.frequency).arg(m.inversion.toString());
+    if (it == tokens.end())
+        return false;
 
-    switch (type)
-    {
-    case OFDM:
-        queryStr+=QString("sistandard=\"dvb\" AND bandwidth=\"%1\" AND "
-                     "hp_code_rate=\"%2\" AND "
-                     "lp_code_rate=\"%3\" AND constellation=\"%4\" AND "
-                     "transmission_mode=\"%5\" AND guard_interval=\"%6\" AND "
-                     "hierarchy=\"%7\";")
-                      .arg(m.bandwidth.toString())
-                      .arg(m.coderate_hp.toString())
-                      .arg(m.coderate_lp.toString())
-                      .arg(m.constellation.toString())
-                      .arg(m.transmit_mode.toString())
-                      .arg(m.guard_interval.toString())
-                      .arg(m.hierarchy.toString());
-        break;
-    case QPSK:
-        queryStr+=QString("sistandard=\"dvb\" AND symbolrate=%1 AND "
-                          "polarity=\"%2\";").arg(m.symbolrate)
-                         .arg(m.polarity.toString());
-        break; 
-    case QAM:
-        queryStr+=QString("symbolrate=%1 AND modulation=\"%2\" AND fec=\"%3\";")
-                         .arg(m.symbolrate)
-                         .arg(m.modulation.toString())
-                         .arg(m.fec.toString());
-        break;
-    case ATSC:
-        queryStr+=QString("modulation=\"%1\";")
-                         .arg(m.modulation.toString());
-        break;
-    } 
-    query.prepare(queryStr);
-    if (!query.exec())
-        MythContext::DBError("searching for transport", query);
-    if (!query.isActive())
-        MythContext::DBError("searching for transport.", query);
-    if (query.size() > 0)
+    QString params = (*it++);
+    while (!params.isEmpty())
     {
-       query.next();
-       return query.value(0).toInt();
+        QString ori = params;
+        int s = *((const char*)params);
+        params = params.mid(1);
+        switch (s)
+        {
+            case 'I':
+                mux.inversion.ParseVDR(params);
+                break;
+            case 'B':
+                mux.bandwidth.ParseVDR(params);
+                break;
+            case 'C':
+                mux.hp_code_rate.ParseVDR(params);
+                break;
+            case 'D':
+                mux.lp_code_rate.ParseVDR(params);
+                break;
+            case 'M':
+                mux.constellation.ParseVDR(params);
+                break;
+            case 'T':
+                mux.trans_mode.ParseVDR(params);
+                break;
+            case 'G':
+                mux.guard_interval.ParseVDR(params);
+                break;
+            case 'Y':
+                mux.hierarchy.ParseVDR(params);
+                break;
+            case 'V':
+            case 'H':
+            case 'R':
+            case 'L':
+                mux.polarity.ParseVDR(ori);
+                break;
+            default:
+                return false;
+        }
     }
-    return -1;
-}
 
-int DVBConfParser::findChannel(const DVBConfParser::Channel &c, int &mplexid)
-{
-    MSqlQuery query(MSqlQuery::InitCon());
+    for (uint i = 0; i < 6; i++)
+        PARSE_SKIP(unknown);
 
-    // try to find exact match first
-    query.prepare("SELECT chanid "
-                  "FROM channel "
-                  "WHERE callsign = :CALLSIGN AND "
-                  "      mplexid  = :MPLEXID  AND "
-                  "      sourceid = :SOURCEID");
-    query.bindValue(":MPLEXID",  multiplexes[c.mplexnumber].mplexid);
-    query.bindValue(":SOURCEID", sourceid);
-    query.bindValue(":CALLSIGN", c.name.utf8());
-
-    if (!query.exec() || !query.isActive())
-        MythContext::DBError("searching for channel", query);
-    else if (query.next())
-    {
-        mplexid = multiplexes[c.mplexnumber].mplexid;
-        return query.value(0).toInt();
-    }
+    PARSE_UINT(chan.serviceid);
 
-    // if we didn't find exact match, try to match just the source & callsign
-    query.prepare("SELECT chanid, mplexid "
-                  "FROM channel "
-                  "WHERE callsign = :CALLSIGN AND "
-                  "      sourceid = :SOURCEID");
-    query.bindValue(":SOURCEID", sourceid);
-    query.bindValue(":CALLSIGN", c.name.utf8());
-
-    if (!query.exec() || !query.isActive())
-        MythContext::DBError("searching for channel", query);
-    else if (query.next())
-    {
-        mplexid = query.value(1).toInt();
-        return query.value(0).toInt();
-    }
+    AddChannel(mux, chan);
 
-    return -1;
-} 
+    return true;
+}
 
-void DVBConfParser::processChannels()
+void DTVConfParser::AddChannel(const DTVMultiplex &mux, DTVChannelInfo &chan)
 {
-    ListChannels::iterator iter;
-    for (iter=channels.begin();iter!=channels.end();iter++)
+    for (uint i = 0; i < channels.size(); i++)
     {
-        bool fFound = false;
-        for (unsigned i=0;i<multiplexes.size() && !fFound;i++ )
+        if (channels[i] == mux)
         {
-            if (multiplexes[i] == (Multiplex)(*iter))
-            {
-                (*iter).mplexnumber = i;
-                fFound = true;
-            }
-        } 
-        if (!fFound)
-        {
-            (*iter).mplexnumber = multiplexes.size();
-            multiplexes.append((Multiplex)(*iter));
+            channels[i].channels.push_back(chan);
+
+            VERBOSE(VB_IMPORTANT, "Imported channel: "<<chan.toString()
+                    <<" on "<<mux.toString());
+            return;
         }
-    } 
-/*
-    for (iter=channels.begin();iter!=channels.end();iter++)
-        (*iter).dump();
-    for (unsigned i=0;i<multiplexes.size() ;i++ )
-        multiplexes[i].dump();
-*/
-    QString standard = (type == ATSC) ? "atsc" : "dvb"; 
-    //create the multiplexes
-    MSqlQuery query(MSqlQuery::InitCon());
-    for (unsigned i=0;i<multiplexes.size() ;i++ )
-    {
-        int mplexid = findMultiplex(multiplexes[i]);
-        if (mplexid < 0)
-        {
-            query.prepare("INSERT into dtv_multiplex (frequency, "
-                "sistandard, sourceid,inversion,bandwidth,hp_code_rate,"
-                "lp_code_rate,constellation,transmission_mode,guard_interval,"
-                "hierarchy,modulation,symbolrate,fec,polarity) "
-                "VALUES (:FREQUENCY,:STANDARD,:SOURCEID,:INVERSION,:BANDWIDTH,"
-                ":CODERATE_HP,:CODERATE_LP,:CONSTELLATION,:TRANS_MODE,"
-                ":GUARD_INTERVAL,:HIERARCHY,:MODULATION,:SYMBOLRATE,"
-                ":FEC,:POLARITY);");
-            query.bindValue(":STANDARD",standard);
-            query.bindValue(":SOURCEID",sourceid);
-            query.bindValue(":FREQUENCY",multiplexes[i].frequency);
-            query.bindValue(":INVERSION",multiplexes[i].inversion.toString());
-            query.bindValue(":BANDWIDTH",multiplexes[i].bandwidth.toString());
-            query.bindValue(":CODERATE_HP",multiplexes[i].coderate_hp.toString());
-            query.bindValue(":CODERATE_LP",multiplexes[i].coderate_lp.toString());
-            query.bindValue(":CONSTELLATION",multiplexes[i].constellation.toString());
-            query.bindValue(":TRANS_MODE",multiplexes[i].transmit_mode.toString());
-            query.bindValue(":GUARD_INTERVAL",multiplexes[i].guard_interval.toString());
-            query.bindValue(":HIERARCHY",multiplexes[i].hierarchy.toString());
-            query.bindValue(":MODULATION",multiplexes[i].modulation.toString());
-            query.bindValue(":SYMBOLRATE",multiplexes[i].symbolrate);
-            query.bindValue(":FEC",multiplexes[i].fec.toString());
-            query.bindValue(":POLARITY",multiplexes[i].polarity.toString());
-
-            if (!query.exec())
-                MythContext::DBError("Inserting new transport", query);
-            if (!query.isActive())
-                MythContext::DBError("Adding transport to Database.", query);
-            query.prepare("select max(mplexid) from dtv_multiplex;");
-            if (!query.exec())
-                MythContext::DBError("Getting ID of new Transport", query);
-            if (!query.isActive())
-                MythContext::DBError("Getting ID of new Transport.", query);
-            if (query.size() > 0)
-            {
-               query.next();
-               multiplexes[i].mplexid = query.value(0).toInt();
-            }
-       }
-       else
-           multiplexes[i].mplexid = mplexid;
     }
 
-    // If the channel number cannot be determined from the config
-    // file, assign temporary unique numbers. First determine the
-    // highest channel number already assigned. This will likely
-    // fail if there are any ATSC channels, since channum is not
-    // really an integer. But in that case 501 is a generally safe
-    // offset for the first unknown channel.
-    int maxchannum = 500;
-    query.prepare("SELECT MAX(channum) FROM channel");
-    if (!query.exec() || !query.isActive())
-        MythContext::DBError("Getting highest channel number.", query);
-    else if (query.next())
-        maxchannum = max(maxchannum, query.value(0).toInt());
-    for (iter = channels.begin(); iter != channels.end(); ++iter)
-        maxchannum = max(maxchannum, (*iter).lcn);
+    channels.push_back(mux);
+    channels.back().channels.push_back(chan);
 
-    // Now insert the channels
-    for (iter=channels.begin();iter!=channels.end();iter++)
-    {
-        int mplexid    = multiplexes[(*iter).mplexnumber].mplexid;
-        int db_mplexid = 0;
-        int chanid     = findChannel(*iter, db_mplexid);
-        if (chanid < 0)
-        {
-            // The channel does not exist in the DB at all, insert it.
-            query.prepare("INSERT INTO channel (chanid, channum, "
-                  "sourceid, callsign, name,  mplexid, "
-                  "serviceid) "
-                  "VALUES (:CHANID,:CHANNUM,:SOURCEID,:CALLSIGN,"
-                  ":NAME,:MPLEXID,:SERVICEID);");
-
-            // If the channel number is unknown, get next unique number
-            int channum = (*iter).lcn;
-            if (-1 == channum)
-                channum = ++maxchannum;
-
-            int chanid = ChannelUtil::CreateChanID(
-                sourceid, QString::number(channum));
-
-            query.bindValue(":CHANID",    chanid);
-            query.bindValue(":CHANNUM",   channum);
-            query.bindValue(":SOURCEID",  sourceid);
-            query.bindValue(":CALLSIGN",  (*iter).name.utf8());
-            query.bindValue(":NAME",      (*iter).name.utf8());
-            query.bindValue(":MPLEXID",   mplexid);
-            query.bindValue(":SERVICEID", (*iter).serviceid);
-            if (!query.exec() || !query.isActive())
-            {
-                MythContext::DBError("Adding new DVB Channel", query);
-                emit updateText(QObject::tr("Failed to add %1: DB error")
-                                .arg((*iter).name));
-            }
-            else
-            {
-                emit updateText(QObject::tr("Adding %1").arg((*iter).name));
-            }
-        }
-        else if (db_mplexid == 32767)
-        {
-            // The channel in the database if from the listings provider amd
-            // does not have tuning information. Just fill in the tuning info.
-            query.prepare("UPDATE channel "
-                          "SET mplexid   = :MPLEXID,  "
-                          "    serviceid = :SERVICEID "
-                          "WHERE chanid   = :CHANID   AND "
-                          "      sourceid = :SOURCEID     ");
-
-            query.bindValue(":MPLEXID",   mplexid);
-            query.bindValue(":SERVICEID", (*iter).serviceid);
-            query.bindValue(":CHANID",    chanid);
-            query.bindValue(":SOURCEID",  sourceid);
-
-            if (!query.exec() || !query.isActive())
-            {
-                MythContext::DBError("Updating DVB Channel", query);
-                emit updateText(QObject::tr("Failed to add %1: DB error")
-                                .arg((*iter).name));
-            }
-            else
-            {
-                emit updateText(QObject::tr("Updating %1").arg((*iter).name));
-            }
-        }
-        else
-            emit updateText(QObject::tr("Skipping %1").arg((*iter).name));
-    }
+    VERBOSE(VB_IMPORTANT, "Imported channel: "<<chan.toString()
+            <<" on "<<mux.toString());
 }
diff -Naurp mythtv-0.20.orig/libs/libmythtv/dvbconfparser.h mythtv-0.20/libs/libmythtv/dvbconfparser.h
--- mythtv-0.20.orig/libs/libmythtv/dvbconfparser.h	2006-02-07 16:56:06.000000000 -0500
+++ mythtv-0.20/libs/libmythtv/dvbconfparser.h	2007-04-13 11:28:23.000000000 -0400
@@ -30,91 +30,107 @@
  *
  */
 
-#ifndef DVBCONFPARSER_H
-#define DVBCONFPARSER_H
+#ifndef _DTVCONFPARSER_H_
+#define _DTVCONFPARSER_H_
 
-#include <qobject.h>
-#include <qvaluevector.h>
+// POSIX headers
+#include <stdint.h>
+#include <unistd.h>
+
+// C++ headers
+#include <vector>
+using namespace std;
+
+// Qt headers
 #include <qstring.h>
-#include <dvbtypes.h>
 
-/**
- * class DVBConfParser
- * @brief parses channels.conf files into the mythtv structure
+// MythTV headers
+#include "dtvconfparserhelpers.h"
+
+class QStringList;
+
+class DTVMultiplex
+{
+  public:
+    DTVMultiplex() : frequency(0), symbolrate(0) { }
+
+    bool operator==(const DTVMultiplex &m) const;
+ 
+    QString toString() const;
+
+ public:
+    uint64_t         frequency;
+    uint             symbolrate;
+    DTVInversion     inversion;
+    DTVBandwidth     bandwidth;
+    DTVCodeRate      hp_code_rate;
+    DTVCodeRate      lp_code_rate;
+    DTVModulation    constellation;
+    DTVModulation    modulation;
+    DTVTransmitMode  trans_mode;
+    DTVGuardInterval guard_interval;
+    DTVHierarchy     hierarchy;
+    DTVPolarity      polarity;
+    DTVCodeRate      fec;
+};
+
+class DTVChannelInfo
+{
+  public:
+    DTVChannelInfo() :
+        name(QString::null), serviceid(0), lcn(-1) {}
+
+    QString toString() const;
+
+ public:
+    QString name;
+    uint    serviceid;
+    int     lcn;
+};
+typedef vector<DTVChannelInfo> DTVChannelInfoList;
+
+class DTVTransport : public DTVMultiplex
+{
+  public:
+    DTVTransport(const DTVMultiplex &other) : DTVMultiplex(other) { }
+
+  public:
+    DTVChannelInfoList channels;
+};
+typedef vector<DTVTransport> DTVChannelList;
+
+/** \class DTVConfParser
+ *  \brief Parses dvb-utils channel scanner output files.
  */
-class DVBConfParser : public QObject
+class DTVConfParser
 {
-    Q_OBJECT
-protected:
-    class Multiplex
-    {
-    public:
-        Multiplex() : frequency(0),symbolrate(0),mplexid(0) {}
-        bool operator==(const Multiplex& m) const;
-
-        unsigned frequency;
-        unsigned symbolrate;
-        DVBInversion inversion;
-        DVBBandwidth bandwidth;
-        DVBCodeRate coderate_hp;
-        DVBCodeRate coderate_lp;
-        DVBModulation constellation;
-        DVBModulation modulation;
-        DVBTransmitMode transmit_mode;
-        DVBGuardInterval guard_interval;
-        DVBHierarchy  hierarchy;
-        DVBPolarity  polarity;
-        DVBCodeRate fec;
-        unsigned mplexid;
-
-        void dump();
-    };
-
-    class Channel : public Multiplex
-    {
-    public:
-        Channel() : serviceid(0),mplexnumber(0), lcn(-1) {}
-
-        QString name;
-        unsigned serviceid;
-        unsigned mplexnumber;
-        int lcn;
-
-        void dump();
-    };
-
-    typedef QValueList<Channel> ListChannels;
-
-    ListChannels  channels;
-    QValueVector<Multiplex> multiplexes;
-
-public:
-    enum RETURN {ERROR_OPEN,ERROR_PARSE,OK};
-    enum TYPE {ATSC,OFDM,QPSK,QAM};
-
-    DVBConfParser(enum TYPE _type,unsigned sourceid, const QString& _file);
-    virtual ~DVBConfParser() {};
-    int parse(); 
-
-signals:
-    /** @brief Status message from the scan engine
-        @param status the message
-    */ 
-    void updateText(const QString& status);
-protected:
-    QString filename;
-    TYPE type;
-    unsigned sourceid;
-    bool parseVDR(QStringList& tokens, int channelNo = -1);
-    bool parseConf(QStringList& tokens);
-    bool parseConfOFDM(QStringList& tokens);
-    bool parseConfQPSK(QStringList& tokens);
-    bool parseConfQAM(QStringList& tokens);
-    bool parseConfATSC(QStringList& tokens);
-    void processChannels();
-    int findMultiplex(const Multiplex& m);
-    int findChannel(const Channel& c, int& mplexid);
-    int generateNewChanID(int sourceID);
+  public:
+    enum return_t   { ERROR_OPEN, ERROR_PARSE, OK };
+    enum cardtype_t { ATSC, OFDM, QPSK, QAM, UNKNOWN };
+
+    DTVConfParser(enum cardtype_t _type, uint sourceid, const QString &_file);
+    virtual ~DTVConfParser() { }
+
+    return_t Parse(void);
+
+    DTVChannelList GetChannels(void) const { return channels; }
+
+  private:
+    bool ParseVDR(     const QStringList &tokens, int channelNo = -1);
+    bool ParseConf(    const QStringList &tokens);
+    bool ParseConfOFDM(const QStringList &tokens);
+    bool ParseConfQPSK(const QStringList &tokens);
+    bool ParseConfQAM( const QStringList &tokens);
+    bool ParseConfATSC(const QStringList &tokens);
+
+  private:
+    cardtype_t type;
+    uint       sourceid;
+    QString    filename;
+
+    void AddChannel(const DTVMultiplex &mux, DTVChannelInfo &chan);
+
+    DTVChannelList channels;
 };
 
-#endif
+#endif // _DTVCONFPARSER_H_
diff -Naurp mythtv-0.20.orig/libs/libmythtv/dvbtypes.cpp mythtv-0.20/libs/libmythtv/dvbtypes.cpp
--- mythtv-0.20.orig/libs/libmythtv/dvbtypes.cpp	2006-07-18 08:35:04.000000000 -0400
+++ mythtv-0.20/libs/libmythtv/dvbtypes.cpp	2007-04-13 11:28:23.000000000 -0400
@@ -8,317 +8,6 @@ static QString mod2str(fe_modulation mod
 static QString mod2dbstr(fe_modulation mod);
 static QString coderate(fe_code_rate_t coderate);
 
-DVBParamHelper<PolarityValues>::Table DVBPolarity::parseTable[] =
-{
-    {"v",Vertical},
-    {"h",Horizontal},
-    {"r",Right},
-    {"l",Left},
-    {NULL,Vertical}
-};
-
-char *DVBPolarity::stringLookup[] =
-{
-   "v",   // Vertical
-   "h",   // Horizontal
-   "r",   // Right
-   "l"    // Left
-};
-
-DVBParamHelper<fe_spectral_inversion_t>::Table DVBInversion::confTable[] =
-{
-   {"INVERSION_AUTO",INVERSION_AUTO},
-   {"INVERSION_OFF",INVERSION_OFF},
-   {"INVERSION_ON",INVERSION_ON},
-   {NULL,INVERSION_AUTO}
-};
-
-DVBParamHelper<fe_spectral_inversion_t>::Table DVBInversion::vdrTable[] =
-{
-   {"999",INVERSION_AUTO},
-   {"0",INVERSION_OFF},
-   {"1",INVERSION_ON},
-   {NULL,INVERSION_AUTO}
-};
-
-DVBParamHelper<fe_spectral_inversion_t>::Table DVBInversion::parseTable[] =
-{
-   {"a",INVERSION_AUTO},
-   {"0",INVERSION_OFF},
-   {"1",INVERSION_ON},
-   {NULL,INVERSION_AUTO}
-};
-
-char* DVBInversion::stringLookup[] =
-{
-    "0", // INVERSION_OFF,
-    "1", // INVERSION_ON,
-    "a"  //INVERSION_AUTO
-};
-
-DVBParamHelper<fe_bandwidth_t>::Table DVBBandwidth::confTable[] =
-{
-   {"BANDWIDTH_AUTO",BANDWIDTH_AUTO},
-   {"BANDWIDTH_8_MHZ",BANDWIDTH_8_MHZ},
-   {"BANDWIDTH_7_MHZ",BANDWIDTH_7_MHZ},
-   {"BANDWIDTH_6_MHZ",BANDWIDTH_6_MHZ},
-   {NULL,BANDWIDTH_AUTO}
-};
-
-DVBParamHelper<fe_bandwidth_t>::Table DVBBandwidth::vdrTable[] =
-{
-   {"999",BANDWIDTH_AUTO},
-   {"8",BANDWIDTH_8_MHZ},
-   {"7",BANDWIDTH_7_MHZ},
-   {"6",BANDWIDTH_6_MHZ},
-   {NULL,BANDWIDTH_AUTO},
-};
-
-DVBParamHelper<fe_bandwidth_t>::Table DVBBandwidth::parseTable[] =
-{
-   {"auto",BANDWIDTH_AUTO},
-   {"8",BANDWIDTH_8_MHZ},
-   {"7",BANDWIDTH_7_MHZ},
-   {"6",BANDWIDTH_6_MHZ},
-   {NULL,BANDWIDTH_AUTO}
-};
-
-char *DVBBandwidth::stringLookup[]=
-{
-    "8",   //BANDWIDTH_8_MHZ,
-    "7",   //BANDWIDTH_7_MHZ,
-    "6",   //BANDWIDTH_6_MHZ,
-    "auto" //BANDWIDTH_AUTO
-};
-
-DVBParamHelper<fe_code_rate_t>::Table DVBCodeRate::confTable[] =
-{
-    {"FEC_AUTO",FEC_AUTO},
-    {"FEC_1_2",FEC_1_2},
-    {"FEC_2_3",FEC_2_3},
-    {"FEC_3_4",FEC_3_4},
-    {"FEC_4_5",FEC_4_5},
-    {"FEC_5_6",FEC_5_6},
-    {"FEC_6_7",FEC_6_7},
-    {"FEC_7_8",FEC_7_8},
-    {"FEC_8_9",FEC_8_9},
-    {"FEC_NONE",FEC_NONE},
-    {NULL,FEC_AUTO}
-};
-
-DVBParamHelper<fe_code_rate_t>::Table DVBCodeRate::vdrTable[] =
-{
-    {"999",FEC_AUTO},
-    {"12",FEC_1_2},
-    {"23",FEC_2_3},
-    {"34",FEC_3_4},
-    {"45",FEC_4_5},
-    {"56",FEC_5_6},
-    {"67",FEC_6_7},
-    {"78",FEC_7_8},
-    {"89",FEC_8_9},
-    {"0",FEC_NONE},
-    {NULL,FEC_AUTO}
-};
-
-DVBParamHelper<fe_code_rate_t>::Table DVBCodeRate::parseTable[] =
-{
-    {"auto",FEC_AUTO},
-    {"1/2",FEC_1_2},
-    {"2/3",FEC_2_3},
-    {"3/4",FEC_3_4},
-    {"4/5",FEC_4_5},
-    {"5/6",FEC_5_6},
-    {"6/7",FEC_6_7},
-    {"7/8",FEC_7_8},
-    {"8/9",FEC_8_9},
-    {"none",FEC_NONE},
-    {NULL,FEC_AUTO}
-};
-
-char *DVBCodeRate::stringLookup[] =
-{
-     "none", //FEC_NONE,
-     "1/2",  //FEC_1_2,
-     "2/3",  //FEC_2_3,
-     "3/4",  //FEC_3_4,
-     "4/5",  //FEC_4_5,
-     "5/6",  //FEC_5_6,
-     "6/7",  //FEC_6_7,
-     "7/8",  //FEC_7_8,
-     "8/9",  //FEC_8_9,
-     "auto"  //FEC_AUTO
-};
-
-DVBParamHelper<fe_modulation_t>::Table DVBModulation::confTable[] =
-{
-   {"QAM_AUTO",QAM_AUTO},
-   {"QAM_16",QAM_16},
-   {"QAM_32",QAM_32},
-   {"QAM_64",QAM_64},
-   {"QAM_128",QAM_128},
-   {"QAM_256",QAM_256},
-   {"QPSK",QPSK},
-#ifdef FE_GET_EXTENDED_INFO
-   {"8PSK", MOD_8PSK},
-#endif
-   {NULL,QAM_AUTO},
-};
-
-DVBParamHelper<fe_modulation_t>::Table DVBModulation::vdrTable[] =
-{
-   {"999",QAM_AUTO},
-   {"16",QAM_16},
-   {"32",QAM_32},
-   {"64",QAM_64},
-   {"128",QAM_128},
-   {"256",QAM_256},
-   {"0",QPSK},
-   {NULL,QAM_AUTO},
-};
-
-DVBParamHelper<fe_modulation_t>::Table DVBModulation::parseTable[] =
-{
-   {"auto",QAM_AUTO},
-   {"qam_16",QAM_16},
-   {"qam_32",QAM_32},
-   {"qam_64",QAM_64},
-   {"qam_128",QAM_128},
-   {"qam_256",QAM_256},
-   {"qpsk",QPSK},
-   {"8vsb",VSB_8},
-   {"16vsb",VSB_16},
-#ifdef FE_GET_EXTENDED_INFO
-   {"8psk", MOD_8PSK},
-#endif
-   {NULL,QAM_AUTO},
-};
-
-char *DVBModulation::stringLookup[] =
-{
-    "qpsk",    //QPSK,
-    "qam_16",  //QAM_16,
-    "qam_32",  //QAM_32,
-    "qam_64",  //QAM_64,
-    "qam_128", //QAM_128,
-    "qam_256", //QAM_256,
-    "auto",    //QAM_AUTO,
-    "8vsb",    //VSB_8,
-    "16vsb",   //VSB_16
-#ifdef FE_GET_EXTENDED_INFO
-    "8psk",    //MOD_8PSK
-#endif
-};
-
-DVBParamHelper<fe_transmit_mode_t>::Table DVBTransmitMode::confTable[] =
-{
-   {"TRANSMISSION_MODE_AUTO",TRANSMISSION_MODE_AUTO},
-   {"TRANSMISSION_MODE_2K",TRANSMISSION_MODE_2K},
-   {"TRANSMISSION_MODE_8K",TRANSMISSION_MODE_8K},
-   {NULL,TRANSMISSION_MODE_AUTO},
-};
-
-DVBParamHelper<fe_transmit_mode_t>::Table DVBTransmitMode::vdrTable[] =
-{
-   {"999",TRANSMISSION_MODE_AUTO},
-   {"2",TRANSMISSION_MODE_2K},
-   {"8",TRANSMISSION_MODE_8K},
-   {NULL,TRANSMISSION_MODE_AUTO},
-};
-
-DVBParamHelper<fe_transmit_mode_t>::Table DVBTransmitMode::parseTable[] =
-{
-   {"auto",TRANSMISSION_MODE_AUTO},
-   {"2",TRANSMISSION_MODE_2K},
-   {"8",TRANSMISSION_MODE_8K},
-   {NULL,TRANSMISSION_MODE_AUTO},
-};
-
-char *DVBTransmitMode::stringLookup[] =
-{
-    "2",   //TRANSMISSION_MODE_2K,
-    "8",   //TRANSMISSION_MODE_8K,
-    "auto" //TRANSMISSION_MODE_AUTO
-};
-
-DVBParamHelper<fe_guard_interval_t>::Table DVBGuardInterval::confTable[] =
-{
-   {"GUARD_INTERVAL_AUTO",GUARD_INTERVAL_AUTO},
-   {"GUARD_INTERVAL_1_32",GUARD_INTERVAL_1_32},
-   {"GUARD_INTERVAL_1_16",GUARD_INTERVAL_1_16},
-   {"GUARD_INTERVAL_1_8",GUARD_INTERVAL_1_8},
-   {"GUARD_INTERVAL_1_4",GUARD_INTERVAL_1_4},
-   {NULL,GUARD_INTERVAL_AUTO},
-};
-
-DVBParamHelper<fe_guard_interval_t>::Table DVBGuardInterval::vdrTable[] =
-{
-   {"999",GUARD_INTERVAL_AUTO},
-   {"32",GUARD_INTERVAL_1_32},
-   {"16",GUARD_INTERVAL_1_16},
-   {"8",GUARD_INTERVAL_1_8},
-   {"4",GUARD_INTERVAL_1_4},
-   {NULL,GUARD_INTERVAL_AUTO},
-};
-
-DVBParamHelper<fe_guard_interval_t>::Table DVBGuardInterval::parseTable[] =
-{
-   {"auto",GUARD_INTERVAL_AUTO},
-   {"1/32",GUARD_INTERVAL_1_32},
-   {"1/16",GUARD_INTERVAL_1_16},
-   {"1/8",GUARD_INTERVAL_1_8},
-   {"1/4",GUARD_INTERVAL_1_4},
-   {NULL,GUARD_INTERVAL_AUTO},
-};
-
-char *DVBGuardInterval::stringLookup[] =
-{
-    "1/32", // GUARD_INTERVAL_1_32,
-    "1/16", // GUARD_INTERVAL_1_16,
-    "1/8",  // GUARD_INTERVAL_1_8,
-    "1/4",  // GUARD_INTERVAL_1_4,
-    "auto"  // GUARD_INTERVAL_AUTO
-};
-
-DVBParamHelper<fe_hierarchy_t>::Table DVBHierarchy::confTable[] =
-{
-   {"HIERARCHY_NONE",HIERARCHY_NONE},
-   {"HIERARCHY_1",HIERARCHY_1},
-   {"HIERARCHY_2",HIERARCHY_2},
-   {"HIERARCHY_4",HIERARCHY_4},
-   {"HIERARCHY_AUTO",HIERARCHY_AUTO},
-   {NULL,HIERARCHY_AUTO},
-};
-
-DVBParamHelper<fe_hierarchy_t>::Table DVBHierarchy::vdrTable[] =
-{
-   {"0",HIERARCHY_NONE},
-   {"1",HIERARCHY_1},
-   {"2",HIERARCHY_2},
-   {"4",HIERARCHY_4},
-   {"999",HIERARCHY_AUTO},
-   {NULL,HIERARCHY_AUTO},
-};
-
-DVBParamHelper<fe_hierarchy_t>::Table DVBHierarchy::parseTable[] =
-{
-   {"n",HIERARCHY_NONE},
-   {"1",HIERARCHY_1},
-   {"2",HIERARCHY_2},
-   {"4",HIERARCHY_4},
-   {"a",HIERARCHY_AUTO},
-   {NULL,HIERARCHY_AUTO},
-};
-
-char *DVBHierarchy::stringLookup[] =
-{
-    "n", //HIERARCHY_NONE,
-    "1", //HIERARCHY_1,
-    "2", //HIERARCHY_2,
-    "4", //HIERARCHY_4,
-    "a"  //HIERARCHY_AUTO
-};
-
 bool equal_qpsk(const struct dvb_fe_params &p,
                 const struct dvb_fe_params &op, uint range)
 {
diff -Naurp mythtv-0.20.orig/libs/libmythtv/dvbtypes.h mythtv-0.20/libs/libmythtv/dvbtypes.h
--- mythtv-0.20.orig/libs/libmythtv/dvbtypes.h	2006-07-18 08:35:04.000000000 -0400
+++ mythtv-0.20/libs/libmythtv/dvbtypes.h	2007-04-13 11:28:26.000000000 -0400
@@ -67,225 +67,6 @@ QString toString(const struct dvb_fe_par
 QString toString(fe_status);
 QString toString(const struct dvb_frontend_event&, const fe_type_t);
 
-//The following are a set of helper classes to allow easy translation
-//between the actual dvb enums and db strings.
-
-//Helper abstract template to do some of the mundain bits
-//of translating the DVBParamHelpers
-template <typename V> class DVBParamHelper 
-{
-protected:
-    V value;
-
-    struct Table
-    {
-        QString symbol;
-        V value;
-    };
-
-    static bool parseParam(QString& symbol, V& value, Table *table)
-    {
-        Table *p = table;
-        while (p->symbol!=NULL)
-        {
-            if (p->symbol==symbol.left(p->symbol.length()))
-            {
-                 symbol=symbol.mid(p->symbol.length());
-                 value = p->value;
-                 return true;
-            }
-            p++;
-        }
-        return false;
-    }
-
-public:
-    DVBParamHelper(V _value) : value(_value) {}
-
-    operator V() const { return value; }
-    V operator=(V _value) {return value = _value;}
-    bool operator==(const V& v) const {return value == v;}
-};
-
-class DVBInversion : public DVBParamHelper<fe_spectral_inversion_t>
-{
-protected:
-    static Table confTable[];
-    static Table vdrTable[];
-    static Table parseTable[];
-    static char* stringLookup[];
-
-public:
-    DVBInversion() : DVBParamHelper<fe_spectral_inversion_t>(INVERSION_AUTO) {}
-    bool parseConf(QString& _value) 
-           {return parseParam(_value,value,confTable);}
-    bool parseVDR(QString& _value)
-           {return parseParam(_value,value,vdrTable);}
-    bool parse(QString& _value)
-           {return parseParam(_value,value,parseTable);}
-
-    QString toString() const {return toString(value);}
-    static QString toString(fe_spectral_inversion_t _value)
-           {return stringLookup[_value];}
-};
-
-class DVBBandwidth : public DVBParamHelper<fe_bandwidth_t>
-{
-protected:
-    static Table confTable[];
-    static Table vdrTable[];
-    static Table parseTable[];
-    static char* stringLookup[];
-
-public:
-    DVBBandwidth() : DVBParamHelper<fe_bandwidth_t>(BANDWIDTH_AUTO) {}
-    bool parseConf(QString& _value) 
-           {return parseParam(_value,value,confTable);}
-    bool parseVDR(QString& _value)
-           {return parseParam(_value,value,vdrTable);}
-    bool parse(QString& _value)
-           {return parseParam(_value,value,parseTable);}
-
-    QString toString() const {return toString(value);}
-    static QString toString(fe_bandwidth_t _value)
-           {return stringLookup[_value];}
-};
-
-class DVBCodeRate : public DVBParamHelper<fe_code_rate_t>
-{
-protected:
-    static Table confTable[];
-    static Table vdrTable[];
-    static Table parseTable[];
-    static char* stringLookup[];
-
-public:
-    DVBCodeRate() : DVBParamHelper<fe_code_rate_t>(FEC_AUTO) {}
-
-    bool parseConf(QString& _value) 
-           {return parseParam(_value,value,confTable);}
-    bool parseVDR(QString& _value)
-           {return parseParam(_value,value,vdrTable);}
-    bool parse(QString& _value)
-           {return parseParam(_value,value,parseTable);}
-
-    QString toString() const {return toString(value);}
-    static QString toString(fe_code_rate_t _value)
-           {return stringLookup[_value];}
-};
-
-class DVBModulation : public DVBParamHelper<fe_modulation_t>
-{
-protected:
-    static Table confTable[];
-    static Table vdrTable[];
-    static Table parseTable[];
-    static char* stringLookup[];
-
-public:
-    DVBModulation() : DVBParamHelper<fe_modulation_t>(QAM_AUTO) {}
-
-    bool parseConf(QString& _value) 
-           {return parseParam(_value,value,confTable);}
-    bool parseVDR(QString& _value)
-           {return parseParam(_value,value,vdrTable);}
-    bool parse(QString& _value)
-           {return parseParam(_value,value,parseTable);}
-
-    QString toString() const {return toString(value);}
-    static QString toString(fe_modulation_t _value)
-           {return stringLookup[_value];}
-};
-
-class DVBTransmitMode : public DVBParamHelper<fe_transmit_mode_t>
-{
-protected:
-    static Table confTable[];
-    static Table vdrTable[];
-    static Table parseTable[];
-    static char* stringLookup[];
-
-public:
-    DVBTransmitMode() : DVBParamHelper<fe_transmit_mode_t>(TRANSMISSION_MODE_AUTO) {}
-
-    bool parseConf(QString& _value) 
-           {return parseParam(_value,value,confTable);}
-    bool parseVDR(QString& _value)
-           {return parseParam(_value,value,vdrTable);}
-    bool parse(QString& _value)
-           {return parseParam(_value,value,parseTable);}
-
-    QString toString() const {return toString(value);}
-    static QString toString(fe_transmit_mode_t _value)
-           {return stringLookup[_value];}
-};
-
-class DVBGuardInterval : public DVBParamHelper<fe_guard_interval_t>
-{
-protected:
-    static Table confTable[];
-    static Table vdrTable[];
-    static Table parseTable[];
-    static char* stringLookup[];
-
-public:
-    DVBGuardInterval() : DVBParamHelper<fe_guard_interval_t>(GUARD_INTERVAL_AUTO) {}
-
-    bool parseConf(QString& _value) 
-           {return parseParam(_value,value,confTable);}
-    bool parseVDR(QString& _value)
-           {return parseParam(_value,value,vdrTable);}
-    bool parse(QString& _value)
-           {return parseParam(_value,value,parseTable);}
-
-    QString toString() const {return toString(value);}
-    static QString toString(fe_guard_interval_t _value)
-           {return stringLookup[_value];}
-};
-
-class DVBHierarchy : public DVBParamHelper<fe_hierarchy_t>
-{
-protected:
-    static Table confTable[];
-    static Table vdrTable[];
-    static Table parseTable[];
-    static char* stringLookup[];
-
-public:
-    DVBHierarchy() : DVBParamHelper<fe_hierarchy_t>(HIERARCHY_AUTO) {}
-
-    bool parseConf(QString& _value) 
-           {return parseParam(_value,value,confTable);}
-    bool parseVDR(QString& _value)
-           {return parseParam(_value,value,vdrTable);}
-    bool parse(QString& _value)
-           {return parseParam(_value,value,parseTable);}
-
-    QString toString() const {return toString(value);}
-    static QString toString(fe_hierarchy_t _value)
-           {return stringLookup[_value];}
-};
-
-enum PolarityValues {Vertical,Horizontal,Right,Left};
-class DVBPolarity : public DVBParamHelper<PolarityValues>
-{
-protected:
-    static Table parseTable[];
-    static char* stringLookup[];
-public:
-    DVBPolarity() :  DVBParamHelper<PolarityValues>(Vertical) { }
-
-    bool parseConf(QString& _value) 
-           {return parseParam(_value,value,parseTable);}
-    bool parseVDR(QString& _value)
-           {return parseParam(_value,value,parseTable);}
-    bool parse(QString& _value)
-           {return parseParam(_value,value,parseTable);}
-
-    QString toString() const {return toString(value);}
-    static QString toString(PolarityValues _value) 
-           {return stringLookup[_value];}
-};
 
 typedef vector<uint16_t> dvb_pid_t;
 // needs to add provider id so dvbcam doesnt require parsing
@@ -398,7 +179,6 @@ class DVBTuning
                     const QString& pol,            const QString& modulation);
 #endif
 
-  private:
     bool ParseTuningParams(
         fe_type_t type,
         QString frequency,    QString inversion,      QString symbolrate,
diff -Naurp mythtv-0.20.orig/libs/libmythtv/frequencytables.cpp mythtv-0.20/libs/libmythtv/frequencytables.cpp
--- mythtv-0.20.orig/libs/libmythtv/frequencytables.cpp	2007-04-13 11:26:47.000000000 -0400
+++ mythtv-0.20/libs/libmythtv/frequencytables.cpp	2007-04-13 11:28:26.000000000 -0400
@@ -55,6 +55,51 @@ TransportScanItem::TransportScanItem(int
 }
 #endif // USING_DVB
 
+
+TransportScanItem::TransportScanItem(int                 _sourceid,
+                                     const QString      &_std,
+                                     const QString      &_name,
+                                     const QString      &_cardtype,
+                                     const DTVTransport &_tuning,
+                                     uint                _timeoutTune)
+    : mplexid(-1),         standard(_std),
+      FriendlyName(_name), friendlyNum(0),
+      SourceID(_sourceid), UseTimer(false),
+      scanning(false),     timeoutTune(_timeoutTune)
+{
+    (void) _cardtype;
+
+    bzero(freq_offsets, sizeof(int) * 3);
+    expectedChannels = _tuning.channels;
+
+#ifdef USING_DVB
+    bzero(&tuning, sizeof(DVBTuning));
+
+    fe_type type = FE_QPSK;
+
+    type = (_cardtype.upper() == "QAM")    ? FE_QAM    : type;
+    type = (_cardtype.upper() == "OFDM")   ? FE_OFDM   : type;
+    type = (_cardtype.upper() == "ATSC")   ? FE_ATSC   : type;
+#ifdef FE_GET_EXTENDED_INFO
+    type = (_cardtype.upper() == "DVB_S2") ? FE_DVB_S2 : type;
+#endif
+
+    tuning.ParseTuningParams(
+        type,
+        QString::number(_tuning.frequency),  _tuning.inversion.toString(),
+        QString::number(_tuning.symbolrate), _tuning.fec.toString(),
+        _tuning.polarity.toString(),         _tuning.hp_code_rate.toString(),
+        _tuning.lp_code_rate.toString(),     _tuning.constellation.toString(),
+        _tuning.trans_mode.toString(),       _tuning.guard_interval.toString(),
+        _tuning.hierarchy.toString(),        _tuning.modulation.toString(),
+        _tuning.bandwidth.toString());
+
+#else
+    frequency  = _tuning.frequency;
+    modulation = _tuning.modulation;
+#endif
+}
+
 TransportScanItem::TransportScanItem(int sourceid,
                                      const QString &std,
                                      const QString &fn,
diff -Naurp mythtv-0.20.orig/libs/libmythtv/frequencytables.h mythtv-0.20/libs/libmythtv/frequencytables.h
--- mythtv-0.20.orig/libs/libmythtv/frequencytables.h	2006-05-01 12:40:46.000000000 -0400
+++ mythtv-0.20/libs/libmythtv/frequencytables.h	2007-04-13 11:28:23.000000000 -0400
@@ -29,6 +29,7 @@ using namespace std;
 #endif // USING_DVB
 
 class FrequencyTable;
+#include "dvbconfparser.h"
 class TransportScanItem;
 
 typedef QMap<QString, const FrequencyTable*> freq_table_map_t;
@@ -130,6 +131,13 @@ class TransportScanItem
                       uint           _timeoutTune);
 #endif // USING_DVB
 
+    TransportScanItem(int                 _sourceid,
+                      const QString      &_std,
+                      const QString      &_name,
+                      const QString      &_cardtype,
+                      const DTVTransport &_tuning,
+                      uint                _timeoutTune);
+
     TransportScanItem(int sourceid,           /* source id in DB */
                       const QString &std,     /* atsc/dvb */
                       const QString &strFmt,  /* fmt for info shown to user  */
@@ -144,6 +152,7 @@ class TransportScanItem
     uint freq_offset(uint i) const;
 
     QString ModulationDB(void) const;
+    QString toString() const;
 
   private:
     int GetMultiplexIdFromDB() const;
@@ -168,7 +177,8 @@ class TransportScanItem
     uint      frequency;        ///< Tuning frequency if mplexid == -1
     uint      modulation;       ///< Tuning frequency if mplexid == -1
 #endif
-    QString toString() const;
+
+    DTVChannelInfoList expectedChannels;
 };
 
 class transport_scan_items_it_t
diff -Naurp mythtv-0.20.orig/libs/libmythtv/libmythtv.pro mythtv-0.20/libs/libmythtv/libmythtv.pro
--- mythtv-0.20.orig/libs/libmythtv/libmythtv.pro	2006-07-18 08:35:04.000000000 -0400
+++ mythtv-0.20/libs/libmythtv/libmythtv.pro	2007-04-13 11:28:23.000000000 -0400
@@ -322,10 +322,12 @@ using_backend {
 
     # Channel scanner stuff
     HEADERS += scanwizard.h                scanwizardhelpers.h
+    HEADERS += dvbconfparser.h             dtvconfparserhelpers.h
     HEADERS += siscan.h
     HEADERS += scanwizardscanner.h
     SOURCES += scanwizard.cpp              scanwizardhelpers.cpp
     SOURCES += siscan.cpp
+    SOURCES += dvbconfparser.cpp           dtvconfparserhelpers.cpp
     SOURCES += scanwizardscanner.cpp
 
     # EIT stuff
@@ -449,8 +451,8 @@ using_backend {
         SOURCES += dvbrecorder.cpp
 
         # Misc
-        HEADERS += dvbconfparser.h        dvbdev/dvbci.h
-        SOURCES += dvbconfparser.cpp      dvbdev/dvbci.cpp
+        HEADERS += dvbdev/dvbci.h
+        SOURCES += dvbdev/dvbci.cpp
 
         DEFINES += USING_DVB
     }
diff -Naurp mythtv-0.20.orig/libs/libmythtv/scanwizard.cpp mythtv-0.20/libs/libmythtv/scanwizard.cpp
--- mythtv-0.20.orig/libs/libmythtv/scanwizard.cpp	2006-05-22 18:51:16.000000000 -0400
+++ mythtv-0.20/libs/libmythtv/scanwizard.cpp	2007-04-13 11:28:23.000000000 -0400
@@ -39,6 +39,7 @@ ScanWizard::ScanWizard(int sourceid)
     : paneOFDM(new OFDMPane()),     paneQPSK(new QPSKPane()),
       paneATSC(new ATSCPane()),     paneQAM(new QAMPane()),
       paneSingle(new STPane()),
+      paneDVBUtilsImport(new DVBUtilsImportPane()),
 #ifdef FE_GET_EXTENDED_INFO
       paneDVBS2(new DVBS2Pane()),
 #endif
@@ -111,7 +112,10 @@ bool ScanWizard::ignoreSignalTimeout(voi
     bool vl1 = (configPane->scanConfig->
                 ignoreSignalTimeoutAll->getValue().toInt());
 
-    return (ts0) ? vl0 : ((ts1) ? vl1 : false);
+    bool ts2 = (ScanTypeSetting::DVBUtilsImport == scanType());
+    bool vl2 = paneDVBUtilsImport->DoIgnoreSignalTimeout();
+
+    return (ts0) ? vl0 : ((ts1) ? vl1 : (ts2) ? vl2 : false);
 }
 
 QString ScanWizard::country(void) const
@@ -121,5 +125,5 @@ QString ScanWizard::country(void) const
 
 QString ScanWizard::filename(void) const
 {
-    return configPane->scanConfig->filename->getValue();
+    return paneDVBUtilsImport->GetFilename();
 }
diff -Naurp mythtv-0.20.orig/libs/libmythtv/scanwizard.h mythtv-0.20/libs/libmythtv/scanwizard.h
--- mythtv-0.20.orig/libs/libmythtv/scanwizard.h	2006-03-15 17:21:38.000000000 -0500
+++ mythtv-0.20/libs/libmythtv/scanwizard.h	2007-04-13 11:28:23.000000000 -0400
@@ -42,6 +42,7 @@ class QPSKPane;
 class ATSCPane;
 class QAMPane;
 class STPane;
+class DVBUtilsImportPane;
 class ScanWizardScanType;
 class ScanWizardScanner;
 
@@ -77,6 +78,8 @@ class ScanWizard : public ConfigurationW
     ATSCPane     *paneATSC;
     QAMPane      *paneQAM;
     STPane       *paneSingle;
+    DVBUtilsImportPane *paneDVBUtilsImport;
+
     int           nVideoDev;
     unsigned      nCardType;
     int           nCaptureCard;
diff -Naurp mythtv-0.20.orig/libs/libmythtv/scanwizardhelpers.cpp mythtv-0.20/libs/libmythtv/scanwizardhelpers.cpp
--- mythtv-0.20.orig/libs/libmythtv/scanwizardhelpers.cpp	2006-08-16 17:47:43.000000000 -0400
+++ mythtv-0.20/libs/libmythtv/scanwizardhelpers.cpp	2007-04-13 11:28:23.000000000 -0400
@@ -315,29 +315,27 @@ void ScanTypeSetting::refresh(const QStr
         addSelection(tr("Full Scan (Tuned)"),
                      QString::number(NITAddScan_OFDM));
         addSelection(tr("Import channels.conf"),
-                     QString::number(Import));
+                     QString::number(DVBUtilsImport));
         break;
     case CardUtil::QPSK:
         addSelection(tr("Full Scan (Tuned)"),
                      QString::number(NITAddScan_QPSK));
         addSelection(tr("Import channels.conf"),
-                     QString::number(Import));
+                     QString::number(DVBUtilsImport));
         break;
     case CardUtil::QAM:
         addSelection(tr("Full Scan (Tuned)"),
                      QString::number(NITAddScan_QAM));
         addSelection(tr("Import channels.conf"),
-                     QString::number(Import));
+                     QString::number(DVBUtilsImport));
         break;
     case CardUtil::ATSC:
     case CardUtil::HDTV:
     case CardUtil::HDHOMERUN:
         addSelection(tr("Full Scan"),
                      QString::number(FullScan_ATSC), true);
-#ifdef USING_DVB
         addSelection(tr("Import channels.conf"),
-                     QString::number(Import));
-#endif
+                     QString::number(DVBUtilsImport));
         break;
     case CardUtil::FREEBOX:
         addSelection(tr("M3U Import"),
@@ -393,8 +391,7 @@ ScanOptionalConfig::ScanOptionalConfig(S
     ConfigurationGroup(false, false, true, true),
     VerticalConfigurationGroup(false, false, true, true),
     country(new ScanCountry()),
-    ignoreSignalTimeoutAll(new IgnoreSignalTimeout()),
-    filename(new ScanFileImport())
+    ignoreSignalTimeoutAll(new IgnoreSignalTimeout())
 {
     setTrigger(scanType);
 
@@ -432,8 +429,8 @@ ScanOptionalConfig::ScanOptionalConfig(S
               scanAllTransports);
     addTarget(QString::number(ScanTypeSetting::FreeBoxImport),
               new BlankSetting());
-    addTarget(QString::number(ScanTypeSetting::Import),
-              filename);
+    addTarget(QString::number(ScanTypeSetting::DVBUtilsImport),
+              wizard->paneDVBUtilsImport);
 }
 
 void ScanOptionalConfig::triggerChanged(const QString& value)
diff -Naurp mythtv-0.20.orig/libs/libmythtv/scanwizardhelpers.h mythtv-0.20/libs/libmythtv/scanwizardhelpers.h
--- mythtv-0.20.orig/libs/libmythtv/scanwizardhelpers.h	2006-07-26 09:10:21.000000000 -0400
+++ mythtv-0.20/libs/libmythtv/scanwizardhelpers.h	2007-04-13 11:28:23.000000000 -0400
@@ -188,16 +188,6 @@ class ScanCountry: public ComboBoxSettin
     ScanCountry();
 };
 
-class ScanFileImport : public LineEditSetting, public TransientStorage
-{
-public:
-    ScanFileImport() : LineEditSetting()
-    {
-        setLabel(QObject::tr("File location"));
-        setHelpText(QObject::tr("Location of the channels.conf file."));
-    }
-};
-
 class ScanTypeSetting : public ComboBoxSetting, public TransientStorage
 {
     Q_OBJECT
@@ -222,7 +212,7 @@ class ScanTypeSetting : public ComboBoxS
         // Freebox import of channels from M3U URL
         FreeBoxImport,
         // Imports lists from dvb-utils scanners
-        Import
+        DVBUtilsImport,
     };
     ScanTypeSetting() : nCaptureCard(-1)
     {
@@ -244,7 +234,7 @@ class ScanOptionalConfig: public Vertica
 
     ScanCountry         *country;
     IgnoreSignalTimeout *ignoreSignalTimeoutAll;
-    ScanFileImport      *filename;
+
   protected slots:
     void triggerChanged(const QString&);
 };
@@ -781,6 +771,43 @@ class STPane : public VerticalConfigurat
     IgnoreSignalTimeout     *ignore_signal_timeout;
 };
 
+class DVBUtilsImportPane : public VerticalConfigurationGroup
+{
+  public:
+    DVBUtilsImportPane() :
+        ConfigurationGroup(false,false,true,false),
+        VerticalConfigurationGroup(false,false,true,false),
+        filename(new TransLineEditSetting()),
+        atsc_format(new ScanATSCChannelFormat()),
+        old_channel_treatment(new ScanOldChannelTreatment()),
+        ignore_signal_timeout(new IgnoreSignalTimeout())
+    {
+        filename->setLabel(tr("File location"));
+        filename->setHelpText(tr("Location of the channels.conf file."));
+        addChild(filename);
+
+        addChild(atsc_format);
+        addChild(old_channel_treatment);
+        addChild(ignore_signal_timeout);
+    }
+
+    QString GetFilename(void)   const { return filename->getValue();    }
+    QString GetATSCFormat(void) const { return atsc_format->getValue(); }
+
+    bool DoDeleteChannels(void) const
+        { return old_channel_treatment->getValue() == "delete"; }
+    bool DoRenameChannels(void) const
+        { return old_channel_treatment->getValue() == "rename"; }
+    bool DoIgnoreSignalTimeout(void) const
+        { return ignore_signal_timeout->getValue().toInt(); }
+
+  private:
+    TransLineEditSetting    *filename;
+    ScanATSCChannelFormat   *atsc_format;
+    ScanOldChannelTreatment *old_channel_treatment;
+    IgnoreSignalTimeout     *ignore_signal_timeout;
+};
+
 class ErrorPane : public HorizontalConfigurationGroup
 {
   public:
diff -Naurp mythtv-0.20.orig/libs/libmythtv/scanwizardscanner.cpp mythtv-0.20/libs/libmythtv/scanwizardscanner.cpp
--- mythtv-0.20.orig/libs/libmythtv/scanwizardscanner.cpp	2006-07-18 08:35:04.000000000 -0400
+++ mythtv-0.20/libs/libmythtv/scanwizardscanner.cpp	2007-04-13 11:28:23.000000000 -0400
@@ -43,6 +43,7 @@
 #include "channelbase.h"
 #include "dtvsignalmonitor.h"
 #include "siscan.h"
+#include "dvbconfparser.h"
 
 #ifdef USING_V4L
 #include "channel.h"
@@ -53,7 +54,6 @@
 #ifdef USING_DVB
 #include "dvbchannel.h"
 #include "dvbsignalmonitor.h"
-#include "dvbconfparser.h"
 #endif
 
 #ifdef USING_HDHOMERUN
@@ -302,10 +302,9 @@ void ScanWizardScanner::scan()
         do_scan = false;
         ScanAnalog(cardid, nVideoSource);
     }
-    else if (nScanType == ScanTypeSetting::Import)
+    else if (nScanType == ScanTypeSetting::DVBUtilsImport)
     {
-        do_scan = false;
-        Import(nVideoSource, parent->nCardType, parent->filename());
+        ImportDVBUtils(nVideoSource, parent->nCardType, parent->filename());
     }
     else if ((nScanType == ScanTypeSetting::FullScan_ATSC)     ||
              (nScanType == ScanTypeSetting::FullTransportScan) ||
@@ -416,49 +415,36 @@ void ScanWizardScanner::scan()
     }
 }
 
-void ScanWizardScanner::Import(uint sourceid, int cardtype,
-                               const QString &file)
+void ScanWizardScanner::ImportDVBUtils(uint sourceid, int cardtype,
+                                       const QString &file)
 {
-    (void) sourceid;
-    (void) cardtype;
-    (void) file;
+    channels.clear();
 
-#ifdef USING_DVB
-    DVBConfParser *parser = NULL;
-
-    if (CardUtil::OFDM == cardtype)
-        parser = new DVBConfParser(DVBConfParser::OFDM, sourceid, file);
-    else if (CardUtil::QPSK == cardtype)
-        parser = new DVBConfParser(DVBConfParser::QPSK, sourceid, file);
-    else if (CardUtil::QAM == cardtype)
-        parser = new DVBConfParser(DVBConfParser::QAM, sourceid, file);
-    else if ((CardUtil::ATSC == cardtype) ||
-             (CardUtil::HDTV == cardtype))
-        parser = new DVBConfParser(DVBConfParser::ATSC, sourceid, file);
+    DTVConfParser::cardtype_t type = DTVConfParser::UNKNOWN;
+    type = (CardUtil::OFDM == cardtype) ? DTVConfParser::OFDM : type;
+    type = (CardUtil::QPSK == cardtype) ? DTVConfParser::QPSK : type;
+    type = (CardUtil::QAM  == cardtype) ? DTVConfParser::QAM  : type;
+    type = ((CardUtil::ATSC == cardtype) || (CardUtil::HDTV == cardtype) ||
+            (CardUtil::HDHOMERUN == cardtype)) ? DTVConfParser::ATSC : type;
 
-    if (!parser)
+    if (type == DTVConfParser::UNKNOWN)
         return;
 
-    connect(parser, SIGNAL(updateText(const QString&)),
-            this,   SLOT(  updateText(const QString&)));
-
-    int ret = parser->parse();
-    parser->deleteLater();
+    DTVConfParser parser(type, sourceid, file);
 
-    if (DVBConfParser::ERROR_OPEN == ret)
+    DTVConfParser::return_t ret = parser.Parse();
+    if (DTVConfParser::OK != ret)
     {
-        MythPopupBox::showOkPopup(
-            gContext->GetMainWindow(), tr("ScanWizard"),
-            tr("Failed to open '%1'").arg(file));
-    }
+        QString msg = (DTVConfParser::ERROR_PARSE == ret) ?
+            tr("Failed to parse '%1'") : tr("Failed to open '%1'");
 
-    if (DVBConfParser::ERROR_PARSE == ret)
+        MythPopupBox::showOkPopup(gContext->GetMainWindow(),
+                                  tr("ScanWizard"), msg.arg(file));
+    }
+    else
     {
-        MythPopupBox::showOkPopup(
-            gContext->GetMainWindow(), tr("ScanWizard"),
-            tr("Failed to parse '%1'").arg(file));
+        channels = parser.GetChannels();
     }
-#endif // USING_DVB
 }
 
 void ScanWizardScanner::PreScanCommon(uint cardid, uint sourceid)
@@ -734,6 +720,55 @@ void ScanWizardScanner::HandleTuneComple
                        ScannerEvent::ERROR_TUNE);
         }
     }
+    else if (nScanType == ScanTypeSetting::DVBUtilsImport && channels.size())
+    {
+        ok = true;
+
+        VERBOSE(VB_SIPARSER, LOC + "ScanForChannels("<<nVideoSource<<")");
+
+        scanner->SetChannelFormat(parent->paneDVBUtilsImport->GetATSCFormat());
+
+        if (parent->paneDVBUtilsImport->DoDeleteChannels())
+        {
+            MSqlQuery query(MSqlQuery::InitCon());
+            query.prepare("DELETE FROM channel "
+                          "WHERE sourceid = :SOURCEID");
+            query.bindValue(":SOURCEID", nVideoSource);
+            query.exec();
+        }
+
+        scanner->SetRenameChannels(
+            parent->paneDVBUtilsImport->DoRenameChannels());
+
+        int  ccardid = parent->captureCard();
+        int  pcardid = CardUtil::GetParentCardID(ccardid);
+        int  cardid  = (pcardid) ? pcardid : ccardid;
+        QString card_type = CardUtil::GetRawCardType(cardid, nVideoSource);
+        QString sub_type = card_type;
+        if (card_type == "DVB")
+        {
+            QString device = CardUtil::GetVideoDevice(cardid, nVideoSource);
+            ok = !device.isEmpty();
+            if (ok)
+                sub_type = CardUtil::ProbeDVBType(device.toUInt()).upper();
+        }
+
+        if (ok)
+        {
+            ok = scanner->ScanForChannels(nVideoSource, std,
+                                          sub_type, channels);
+        }
+        if (ok)
+        {
+            post_event(this, ScannerEvent::ServicePct,
+                       TRANSPORT_PCT);
+        }
+        else
+        {
+            post_event(this, ScannerEvent::TuneComplete,
+                       ScannerEvent::ERROR_TUNE);
+        }
+    }
     else if (nScanType == ScanTypeSetting::TransportScan)
     {
         VERBOSE(VB_SIPARSER, LOC + "ScanTransport("<<nMultiplexToTuneTo<<")");
diff -Naurp mythtv-0.20.orig/libs/libmythtv/scanwizardscanner.h mythtv-0.20/libs/libmythtv/scanwizardscanner.h
--- mythtv-0.20.orig/libs/libmythtv/scanwizardscanner.h	2006-07-08 13:48:37.000000000 -0400
+++ mythtv-0.20/libs/libmythtv/scanwizardscanner.h	2007-04-13 11:28:23.000000000 -0400
@@ -40,6 +40,7 @@
 
 // MythTV headers
 #include "settings.h"
+#include "dvbconfparser.h"
 
 class ScanWizard;
 class AnalogScan;
@@ -79,7 +80,7 @@ class ScanWizardScanner : public Vertica
     void serviceScanPctComplete(int pct);
 
   protected:
-    void Import(uint sourceid, int cardtype, const QString &file);
+    void ImportDVBUtils(uint sourceid, int cardtype, const QString &file);
     void PreScanCommon(uint cardid, uint sourceid);
     void TunedScanCommon(uint cardid, uint sourceid, bool ok);
     void ScanAnalog(uint cardid, uint sourceid);
@@ -113,6 +114,9 @@ class ScanWizardScanner : public Vertica
     uint               frequency;
     QString            modulation;
     QMap<QString,QString> startChan;
+
+    // dvb-utils imported channels
+    DTVChannelList channels;
 };
 
 #endif // _SCANWIZARDSCANNER_H_
diff -Naurp mythtv-0.20.orig/libs/libmythtv/siscan.cpp mythtv-0.20/libs/libmythtv/siscan.cpp
--- mythtv-0.20.orig/libs/libmythtv/siscan.cpp	2006-08-18 16:37:07.000000000 -0400
+++ mythtv-0.20/libs/libmythtv/siscan.cpp	2007-04-13 11:28:23.000000000 -0400
@@ -322,7 +322,10 @@ void SIScan::HandleMPEGDBInsertion(const
     pat_vec_t pats = sd->GetCachedPATs();
     pmt_map_t pmt_map = sd->GetCachedPMTMap();
     for (uint i = 0; i < pats.size(); i++)
-        UpdatePATinDB(mplexid, fn, freqid, pats[i], pmt_map, true);
+    {
+        UpdatePATinDB(mplexid, fn, freqid, pats[i], pmt_map,
+                      (*current).expectedChannels, true);
+    }
     sd->ReturnCachedPMTTables(pmt_map);
     sd->ReturnCachedPATTables(pats);
 
@@ -354,13 +357,19 @@ void SIScan::HandleATSCDBInsertion(const
     // Insert Terrestrial VCTs
     tvct_vec_t tvcts = sd->GetAllCachedTVCTs();
     for (uint i = 0; i < tvcts.size(); i++)
-        UpdateVCTinDB(mplexid, fn, freqid, tvcts[i], true);
+    {
+        UpdateVCTinDB(mplexid, fn, freqid, tvcts[i],
+                      (*current).expectedChannels, true);
+    }
     sd->ReturnCachedTVCTTables(tvcts);
 
     // Insert Cable VCTs
     cvct_vec_t cvcts = sd->GetAllCachedCVCTs();
     for (uint i = 0; i < cvcts.size(); i++)
-        UpdateVCTinDB(mplexid, fn, freqid, cvcts[i], true);
+    {
+        UpdateVCTinDB(mplexid, fn, freqid, cvcts[i],
+                      (*current).expectedChannels, true);
+    }
     sd->ReturnCachedCVCTTables(cvcts);
 
     // tell UI we are done with these channels
@@ -386,7 +395,10 @@ void SIScan::HandleDVBDBInsertion(const 
 
     vector<const ServiceDescriptionTable*> sdts = sd->GetAllCachedSDTs();
     for (uint i = 0; i < sdts.size(); i++)
-        UpdateSDTinDB((*current).mplexid, sdts[i], forceUpdate);
+    {
+        UpdateSDTinDB((*current).mplexid, sdts[i],
+                      (*current).expectedChannels, forceUpdate);
+    }
     sd->ReturnCachedSDTTables(sdts);
 
     emit ServiceScanUpdateText(tr("Finished processing Services"));
@@ -787,6 +799,41 @@ bool SIScan::ScanTransports(int SourceID
     return true;
 }
 
+bool SIScan::ScanForChannels(uint sourceid,
+                             const QString &std,
+                             const QString &cardtype,
+                             const DTVChannelList &channels)
+{
+    scanTransports.clear();
+    nextIt = scanTransports.end();
+
+    DTVChannelList::const_iterator it = channels.begin();
+    for (uint i = 0; it != channels.end(); ++it, i++)
+    {
+        TransportScanItem item(sourceid, std, QString::number(i),
+                               cardtype, *it, signalTimeout);
+
+        scanTransports += item;
+
+        VERBOSE(VB_SIPARSER, LOC + item.toString());
+    }
+
+    if (scanTransports.empty())
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR + "ScanForChannels() no transports");
+        return false;
+    }
+
+    timer.start();
+    waitingForTables = false;
+
+    nextIt            = scanTransports.begin();
+    transportsScanned = 0;
+    scanMode          = TRANSPORT_LIST;
+
+    return true;
+}
+
 /** \fn SIScan::ScanTransportsStartingOn(int,const QMap<QString,QString>&)
  *  \brief Generates a list of frequencies to scan and adds it to the
  *   scanTransport list, and then sets the scanMode to TRANSPORT_LIST.
@@ -953,6 +1000,52 @@ void SIScan::OptimizeNITFrequencies(Netw
 #endif // USING_DVB
 }
 
+/** \fn SIScan::CheckImportedList(const DTVChannelInfoList&,uint,QString&,QString&,QString&)
+ *  \brief If we as scanning a dvb-utils import verify channel is in list..
+ */
+bool SIScan::CheckImportedList(const DTVChannelInfoList &channels,
+                               uint mpeg_program_num,
+                               QString &service_name,
+                               QString &callsign,
+                               QString &common_status_info)
+{
+    if (channels.empty())
+        return true;
+
+    bool found = false;
+    for (uint i = 0; i < channels.size(); i++)
+    {
+        VERBOSE(VB_IMPORTANT,
+                QString("comparing %1 %2 against %3 %4")
+                .arg(channels[i].serviceid).arg(channels[i].name)
+                .arg(mpeg_program_num).arg(common_status_info));
+
+        if (channels[i].serviceid == mpeg_program_num)
+        {
+            found = true;
+            if (!channels[i].name.isEmpty())
+            {
+                service_name = QDeepCopy<QString>(channels[i].name);
+                callsign     = QDeepCopy<QString>(channels[i].name);
+            }
+        }
+    }
+
+    if (found)
+    {
+        common_status_info += QString(" %1 %2")
+            .arg(tr("as")).arg(service_name);
+    }
+    else
+    {
+        emit ServiceScanUpdateText(
+            tr("Skipping %1, not in imported channel map")
+            .arg(common_status_info));
+    }
+
+    return found;
+}
+
 // ///////////////////// DB STUFF /////////////////////
 // ///////////////////// DB STUFF /////////////////////
 // ///////////////////// DB STUFF /////////////////////
@@ -962,7 +1055,8 @@ void SIScan::OptimizeNITFrequencies(Netw
 void SIScan::UpdatePMTinDB(
     int db_source_id,
     int db_mplexid, const QString &friendlyName, int freqid,
-    int pmt_indx, const ProgramMapTable *pmt, bool /*force_update*/)
+    int pmt_indx, const ProgramMapTable *pmt,
+    const DTVChannelInfoList &channels, bool /*force_update*/)
 {
     // See if service already in database based on program number
     int chanid = ChannelUtil::GetChanID(
@@ -988,10 +1082,16 @@ void SIScan::UpdatePMTinDB(
 
     QString common_status_info = tr("%1%2%3 on %4 (%5)")
         .arg(service_name)
-        .arg(service_name.isEmpty() ? "" : " as ")
+        .arg(service_name.isEmpty() ? "" : QString(" %1 ").arg(tr("as")))
         .arg(chan_num)
         .arg(friendlyName).arg(freqid);
 
+    if (!CheckImportedList(channels, pmt->ProgramNumber(),
+                           service_name, chan_num, common_status_info))
+    {
+        return;
+    }
+
     if (chanid < 0)
     {   // The service is not in database, add it
         emit ServiceScanUpdateText(
@@ -1028,7 +1128,7 @@ void SIScan::UpdatePMTinDB(
 void SIScan::UpdatePATinDB(
     int db_mplexid, const QString &friendlyName, int freqid,
     const ProgramAssociationTable *pat, const pmt_map_t &pmt_map,
-    bool force_update)
+    const DTVChannelInfoList &channels, bool force_update)
 {
     VERBOSE(VB_SIPARSER, LOC +
             QString("UpdatePATinDB(): tsid: 0x%1  mplex: %2")
@@ -1066,7 +1166,7 @@ void SIScan::UpdatePATinDB(
                 continue;
 
             UpdatePMTinDB(db_source_id, db_mplexid, friendlyName, freqid,
-                          i, *vit, force_update);
+                          i, *vit, channels, force_update);
         }
     }    
 }
@@ -1076,6 +1176,7 @@ void SIScan::UpdatePATinDB(
 void SIScan::UpdateVCTinDB(int db_mplexid,
                            const QString &friendlyName, int freqid,
                            const VirtualChannelTable *vct,
+                           const DTVChannelInfoList &channels,
                            bool force_update)
 {
     (void) force_update;
@@ -1142,6 +1243,13 @@ void SIScan::UpdateVCTinDB(int db_mplexi
             .arg(vct->MajorChannel(i)).arg(vct->MinorChannel(i))
             .arg(chan_num).arg(friendlyName).arg(freqid);
 
+        QString callsign = vct->ShortChannelName(i);
+
+        if (!CheckImportedList(channels, vct->ProgramNumber(i),
+                               longName, callsign, common_status_info))
+        {
+            continue;
+        }
         QString msg = "";
         if (chanid < 0)
         {   // The service is not in database, add it
@@ -1153,7 +1261,7 @@ void SIScan::UpdateVCTinDB(int db_mplexi
                     db_mplexid,
                     db_source_id,
                     chanid,
-                    vct->ShortChannelName(i),
+                    callsign,
                     longName,
                     chan_num,
                     vct->ProgramNumber(i),
@@ -1170,7 +1278,7 @@ void SIScan::UpdateVCTinDB(int db_mplexi
                 db_mplexid,
                 db_source_id,
                 chanid,
-                vct->ShortChannelName(i),
+                callsign,
                 longName,
                 chan_num,
                 vct->ProgramNumber(i),
@@ -1186,6 +1294,7 @@ void SIScan::UpdateVCTinDB(int db_mplexi
  *  \brief Inserts channels from service description table.
  */
 void SIScan::UpdateSDTinDB(int /*mplexid*/, const ServiceDescriptionTable *sdt,
+                           const DTVChannelInfoList &channels,
                            bool force_update)
 {
     if (!sdt->ServiceCount())
@@ -1261,6 +1370,14 @@ void SIScan::UpdateSDTinDB(int /*mplexid
             continue;
         }
 
+        QString common_status_info = service_name;
+
+        if (!CheckImportedList(channels, sdt->ServiceID(i),
+                               service_name, service_name, common_status_info))
+        {
+            continue;
+        }
+
         // See if service already in database based on service ID
         int chanid = ChannelUtil::GetChanID(db_mplexid, -1, -1, -1,
                                             sdt->ServiceID(i));
diff -Naurp mythtv-0.20.orig/libs/libmythtv/siscan.h mythtv-0.20/libs/libmythtv/siscan.h
--- mythtv-0.20.orig/libs/libmythtv/siscan.h	2006-08-18 16:37:07.000000000 -0400
+++ mythtv-0.20/libs/libmythtv/siscan.h	2007-04-13 11:28:23.000000000 -0400
@@ -14,6 +14,7 @@
 // MythTV includes
 #include "frequencytables.h"
 #include "streamlisteners.h"
+#include "dvbconfparser.h"
 
 class MSqlQuery;
 
@@ -54,6 +55,9 @@ class SIScan : public QObject,
     bool ScanTransportsStartingOn(
         int sourceid, const QMap<QString,QString> &valueMap);
     bool ScanTransport(int mplexid);
+    bool ScanForChannels(
+        uint sourceid, const QString &std, const QString &cardtype,
+        const DTVChannelList&);
 
     bool ScanServicesSourceID(int SourceID);
 
@@ -119,24 +123,34 @@ class SIScan : public QObject,
     /// \brief Updates Transport Scan progress bar
     inline void UpdateScanPercentCompleted(void);
 
+    bool CheckImportedList(const DTVChannelInfoList&,
+                           uint mpeg_program_num,
+                           QString &service_name,
+                           QString &callsign,
+                           QString &common_status_info);
+
     void HandleMPEGDBInsertion(const ScanStreamData *sd, bool wait);
     void UpdatePATinDB(int mplexid, const QString &friendlyName, int freqid,
                        const ProgramAssociationTable*, const pmt_map_t&,
+                       const DTVChannelInfoList&,
                        bool force_update);
 
     void UpdatePMTinDB(int sourceid,
                        int mplexid, const QString &friendlyName, int freqid,
                        int pmt_indx, const ProgramMapTable*,
+                       const DTVChannelInfoList&,
                        bool force_update);
 
     void HandleATSCDBInsertion(const ScanStreamData *sd, bool wait);
     void UpdateVCTinDB(int mplexid, const QString &friendlyName, int freqid,
                        const VirtualChannelTable*,
+                       const DTVChannelInfoList&,
                        bool force_update);
 
     void HandleDVBDBInsertion(const ScanStreamData *sd, bool wait);
     void UpdateSDTinDB(int mplexid,
                        const ServiceDescriptionTable*,
+                       const DTVChannelInfoList&,
                        bool force_update);
 
     bool HandlePostInsertion(void);
