Index: libs/libmythtv/channeleditor.cpp
===================================================================
--- libs/libmythtv/channeleditor.cpp	(revision 14705)
+++ libs/libmythtv/channeleditor.cpp	(working copy)
@@ -19,6 +19,7 @@
 #include "sourceutil.h"
 
 #include "scanwizard.h"
+#include "importicons.h"
 
 ChannelWizard::ChannelWizard(int id, int default_sourceid)
     : ConfigurationWizard()
@@ -110,16 +111,19 @@
         return 0;
 }
 
-void ChannelListSetting::fillSelections(void) 
+int ChannelListSetting::fillSelections(void) 
 {
     QString currentValue = getValue();
+
     clearSelections();
     addSelection(QObject::tr("(New Channel)"));
     bool fAllSources = true;
+    int nCount = 0;
 
     QString querystr = "SELECT channel.name,channum,chanid ";
 
-    if ((currentSourceID == "") || (currentSourceID == "Unassigned"))
+    if ((currentSourceID == "") || (currentSourceID == "Unassigned")
+                                || (currentSourceID == "(All)"))
     {
         querystr += ",videosource.name FROM channel "
                     "LEFT JOIN videosource ON "
@@ -184,8 +188,15 @@
                 name += " (" + sourceid  + ")";
 
             addSelection(name, chanid, (chanid == currentValue) ? true : false);
+
+            nCount++;
+            
+            // nCount increments first since "(New Channel)" offsets list by one
+            if (chanid == currentValue)
+                setCurrentItem(nCount);
         }
     }
+    return nCount;
 }
 
 class SourceSetting : public ComboBoxSetting, public Storage
@@ -194,7 +205,7 @@
     SourceSetting() : ComboBoxSetting(this)
     {
         setLabel(QObject::tr("Video Source"));
-        addSelection(QObject::tr("(All)"),"");
+        addSelection(QObject::tr("(All)"),"(All)");
     };
 
     void load() 
@@ -266,6 +277,11 @@
     buttonScan->setLabel(QObject::tr("Channel Scanner"));
     buttonScan->setHelpText(QObject::tr("Starts the channel scanner."));
     buttonScan->setEnabled(SourceUtil::IsAnySourceScanable());
+    
+    buttonImportIcon = new TransButtonSetting();
+    buttonImportIcon->setLabel(QObject::tr("Icon Download"));
+    buttonImportIcon->setHelpText(QObject::tr("Starts the icon downloader"));
+    buttonImportIcon->setEnabled(SourceUtil::IsAnySourceScanable());
 
     buttonTransportEditor = new TransButtonSetting();
     buttonTransportEditor->setLabel(QObject::tr("Transport Editor"));
@@ -278,6 +294,7 @@
     HorizontalConfigurationGroup *h = 
         new HorizontalConfigurationGroup(false, false);
     h->addChild(buttonScan);
+    h->addChild(buttonImportIcon);
     h->addChild(buttonTransportEditor);
     addChild(h);
 
@@ -293,6 +310,8 @@
             this, SLOT(menu(int)));
     connect(buttonScan, SIGNAL(pressed()),
             this, SLOT(scan()));
+    connect(buttonImportIcon,  SIGNAL(pressed()),
+            this, SLOT(channelIconImport()));
     connect(buttonTransportEditor, SIGNAL(pressed()),
             this, SLOT(transportEditor()));
     connect(del,  SIGNAL(pressed()),
@@ -377,7 +396,7 @@
     id = list->getValue().toInt();
     ChannelWizard cw(id, source->getValue().toUInt());
     cw.exec();
-
+    
     list->fillSelections();
     list->setFocus();
 }
@@ -459,3 +478,50 @@
     list->fillSelections();
     list->setFocus();
 }
+
+void ChannelEditor::channelIconImport(void)
+{
+    if (list->fillSelections() == 0)
+    {
+        MythPopupBox::showOkPopup(gContext->GetMainWindow(), "",
+                                        tr("Add some for channels first!"));
+        return;
+    }
+    
+    // Get selected channel name from database
+    QString querystr = QString("SELECT channel.name FROM channel WHERE chanid='%1' ").arg(list->getValue());
+    QString channelname = "";
+    MSqlQuery query(MSqlQuery::InitCon()); 
+    query.prepare(querystr);
+    
+    if (query.exec() && query.isActive() && query.size() > 0)
+    {
+        query.next();
+        channelname = QString::fromUtf8(query.value(0).toString());
+    }
+    
+    QStringList buttons;
+    buttons.append(tr("Cancel"));
+    buttons.append(tr("Download all icons.."));
+    buttons.append(tr("Rescan for missing icons.."));
+    if (channelname.isEmpty()==false)
+        buttons.append(tr("Download icon for ") + channelname);
+    
+    int val = MythPopupBox::showButtonPopup(gContext->GetMainWindow(),
+                                             "", "Channel Icon Import", buttons, 2);
+    ImportIconsWizard *iconwizard;
+    if (val == 0) // Cancel pressed
+        return;
+    else if (val == 1) // Import all icons pressed
+        iconwizard = new ImportIconsWizard(false);
+    else if (val == 2) // Rescan for missing pressed
+        iconwizard = new ImportIconsWizard(true);
+    else if (val == 3) // Import a single channel icon
+        iconwizard = new ImportIconsWizard(true, channelname);
+
+    iconwizard->exec();
+    iconwizard->deleteLater();
+    
+    list->fillSelections();
+    list->setFocus();
+}
Index: libs/libmythtv/libmythtv.pro
===================================================================
--- libs/libmythtv/libmythtv.pro	(revision 14651)
+++ libs/libmythtv/libmythtv.pro	(working copy)
@@ -148,6 +148,7 @@
 HEADERS += playgroup.h              progdetails.h
 HEADERS += channeleditor.h          channelsettings.h
 HEADERS += previewgenerator.h       transporteditor.h
+HEADERS += importicons.h
 
 SOURCES += programinfo.cpp          proglist.cpp
 SOURCES += storagegroup.cpp
@@ -170,6 +171,7 @@
 SOURCES += progdetails.cpp
 SOURCES += channeleditor.cpp        channelsettings.cpp
 SOURCES += previewgenerator.cpp     transporteditor.cpp
+SOURCES += importicons.cpp
 
 # DiSEqC
 HEADERS += diseqc.h                 diseqcsettings.h
Index: libs/libmythtv/importicons.h
===================================================================
--- libs/libmythtv/importicons.h	(revision 0)
+++ libs/libmythtv/importicons.h	(revision 0)
@@ -0,0 +1,178 @@
+/* -*- Mode: c++ -*-
+ * vim: set expandtab tabstop=4 shiftwidth=4:
+ *
+ * Original Project
+ *      MythTV      http://www.mythtv.org
+ *
+ * Author(s):
+ *      John Pullan, Matthew Wire  
+ *
+ * Description:
+ */
+
+#ifndef IMPORTICONS_H
+#define IMPORTICONS_H
+
+#include <qsqldatabase.h>
+#include <qurl.h>
+
+#include "settings.h"
+
+class ImportIconsWizard : public QObject, public ConfigurationWizard
+{
+    Q_OBJECT
+public:
+    ImportIconsWizard(bool fRefresh, QString channelname=""); //!< constructs an ImportIconWizard
+    MythDialog *dialogWidget(MythMainWindow *parent, const char *widgetName);
+
+    int exec();
+
+private:
+
+    enum dialogState
+    {
+        STATE_NORMAL,
+        STATE_SEARCHING,
+        STATE_DISABLED
+    };
+    
+    struct CSVEntry                  //! describes the TV channel name
+    {
+        QString strChanId;           //!< local channel id
+        QString strName;             //!< channel name
+        QString strXmlTvId;          //!< the xmltvid 
+        QString strCallsign;         //!< callsign
+        QString strTransportId;      //!< transport id
+        QString strAtscMajorChan;    //!< ATSC major number
+        QString strAtscMinorChan;    //!< ATSC minor number
+        QString strNetworkId;        //!< network id
+        QString strServiceId;        //!< service id
+        QString strIconCSV;          //!< icon name (csv form) 
+        QString strNameCSV;          //!< name (csv form)
+    };  
+    //! List of CSV entries
+    typedef QValueList<CSVEntry> ListEntries;     
+    //! iterator over list of CSV entries
+    typedef QValueListIterator<CSVEntry> ListEntriesIter; 
+
+    ListEntries m_listEntries;       //!< list of TV channels to search for
+    ListEntries m_missingEntries;    //!< list of TV channels with no unique icon
+    ListEntriesIter m_iter;          //!< the current iterator
+    ListEntriesIter m_missingIter;
+
+    struct SearchEntry               //! search entry results
+    {
+        QString strID;               //!< the remote channel id 
+        QString strName;             //!< the remote name
+        QString strLogo;             //!< the actual logo
+    };
+    //! List of SearchEntry entries
+    typedef QValueList<SearchEntry> ListSearchEntries;
+    //! iterator over list of SearchEntry entries
+    typedef QValueListIterator<SearchEntry> ListSearchEntriesIter;
+
+    ListSearchEntries m_listSearch;  //!< the list of SearchEntry
+    QString m_strMatches;            //!< the string for the submit() call
+
+    static const QString url;        //!< the default url
+    QString m_strChannelDir;         //!< the location of the channel icon dir
+    QString m_strChannelname;        //!< the channel name if searching for a single channel icon
+
+    bool m_fRefresh;                 //!< are we doing a refresh or not
+    int m_nMaxCount;                 //!< the maximum number of TV channels
+    int m_nCount;                    //!< the current search point (0..m_nMaxCount)
+    int m_missingMaxCount;           //!< the total number of missing icons
+    int m_missingCount;              //!< the current search point (0..m_missingCount)
+
+    void startDialog();
+    bool importSingleIcon(const QString& channelname);
+
+    /*! \brief changes a string into csv format 
+     * \param str the string to change
+     * \return the actual string
+     */ 
+    QString escape_csv(const QString& str); 
+
+    /*! \brief extracts the csv values out of a string
+     * \param str the string to work on
+     * \return the actual QStringList
+     */ 
+    QStringList extract_csv(const QString& strLine);
+
+    /*! \brief use the equivalent of wget to fetch the POST command
+     * \param url the url to send this to
+     * \param strParam the string to send
+     * \return the actual string
+     */ 
+    QString wget(QUrl& url,const QString& strParam);
+ 
+    TransLineEditSetting *m_editName;    //!< name field for the icon 
+    TransListBoxSetting *m_listIcons;    //!< list of potential icons
+    TransLineEditSetting *m_editManual;  //!< manual edit field
+    TransButtonSetting *m_buttonManual;  //!< manual button field
+    TransButtonSetting *m_buttonSkip;    //!< button skip
+    TransButtonSetting *m_buttonSelect;    //!< button skip
+
+    /*! \brief determines if a particular icon is blocked
+     * \param str the string to work on
+     * \return true/false
+     */ 
+    bool isBlocked(const QString& strParam);
+
+    /*! \brief looks up the string to determine the caller/xmltvid
+     * \param str the string to work on
+     * \return true/false
+     */ 
+    bool lookup(const QString& strParam);
+
+    /*! \brief search the remote db for icons etc
+     * \param str the string to work on
+     * \return true/false
+     */ 
+    bool search(const QString& strParam);
+
+    /*! \brief submit the icon information back to the remote db
+     * \param str the string to work on
+     * \return true/false
+     */ 
+    bool submit(const QString& strParam);
+
+    /*! \brief retrieve the actual logo for the TV channel
+     * \param str the string to work on
+     * \return true/false
+     */ 
+    bool findmissing(const QString& strParam);
+
+    /*! \brief checks and attempts to download the logo file to the appropriate
+     *   place
+     * \param str the string of the downloaded url
+     * \return true/false
+     */ 
+    bool checkAndDownload(const QString& str);
+
+    /*! \brief attempt the inital load of the TV channel information
+     * \return the number of TV channels
+     */ 
+    unsigned initialLoad(QString name="");
+
+    /*! \brief attempts to move the itaration on one/more than one
+     * \return true if we can go again or false if we can not
+     */ 
+    bool doLoad();
+    
+    bool m_closeDialog;
+    
+    ~ImportIconsWizard() { };
+    
+protected slots:
+    void enableControls(dialogState state=STATE_NORMAL, bool selectEnabled=true);         //!< enable/disable the controls
+    void manualSearch();           //!< process the manual search
+    void menuSelect();
+    void menuSelection(int nIndex);//!< process the icon selection
+    void skip();                   //!< skip this icon
+    void cancelPressed();
+    void finishButtonPressed();
+
+};
+
+#endif // IMPORTICONS_H
Index: libs/libmythtv/channeleditor.h
===================================================================
--- libs/libmythtv/channeleditor.h	(revision 14651)
+++ libs/libmythtv/channeleditor.h	(working copy)
@@ -22,14 +22,16 @@
     void edit();
     void edit(int);
     void scan(void);
-    void transportEditor();
-    void deleteChannels();
+    void transportEditor(void);
+    void channelIconImport(void);
+    void deleteChannels(void);
 
 private:
     int                 id;
     SourceSetting      *source;
     ChannelListSetting *list;
     TransButtonSetting *buttonScan;
+    TransButtonSetting *buttonImportIcon;
     TransButtonSetting *buttonTransportEditor;
 };
 
@@ -68,7 +70,7 @@
     bool getHideMode() { return currentHideMode; };
 
 public slots:
-    void fillSelections(void);
+    int fillSelections(void);
     void setSortMode(const QString& sort) {
         if (currentSortMode != sort) {
             currentSortMode = sort;
Index: libs/libmythtv/importicons.cpp
===================================================================
--- libs/libmythtv/importicons.cpp	(revision 0)
+++ libs/libmythtv/importicons.cpp	(revision 0)
@@ -0,0 +1,697 @@
+#include <sys/stat.h>
+#include <qapplication.h>
+#include <qregexp.h>
+#include <qbuffer.h>
+#include <qfileinfo.h>
+
+#include "mythwizard.h"
+#include "httpcomms.h"
+#include "importicons.h"
+#include "util.h"
+
+ImportIconsWizard::ImportIconsWizard(bool fRefresh, QString channelname)
+{
+    m_fRefresh = fRefresh;   
+    m_strChannelname = channelname;
+    m_closeDialog = false;
+    m_missingCount=0;
+    m_missingMaxCount=0;
+
+}
+
+MythDialog *ImportIconsWizard::dialogWidget(MythMainWindow *parent,
+                                     const char *widgetName)
+{
+    MythWizard *ret = (MythWizard*)ConfigurationWizard::dialogWidget(parent,widgetName);
+    connect(ret->finishButton(), SIGNAL(pressed()), this, SLOT(finishButtonPressed()));
+    return (MythDialog*)ret;
+}
+
+int ImportIconsWizard::exec()
+{
+    m_strChannelDir =  MythContext::GetConfDir()+ "/channels";
+    mkdir(MythContext::GetConfDir(),0776);
+    mkdir(m_strChannelDir,0776);
+    m_strChannelDir+="/";
+
+    if (m_strChannelname.isEmpty()){
+        if (initialLoad() > 0)
+        {
+            startDialog();
+            m_missingIter=m_missingEntries.begin();
+            doLoad();
+        }
+    }
+    else
+    {
+        importSingleIcon(m_strChannelname);
+    }
+
+    if (m_closeDialog==false) // Need this if line to exit if cancel button is pressed
+        while ((ConfigurationDialog::exec() == QDialog::Accepted) && (m_closeDialog == false))  {}
+    
+    return QDialog::Rejected;
+}
+
+bool ImportIconsWizard::importSingleIcon(const QString& channelname)
+{
+    m_fRefresh=false; // Does not apply so make sure it is false or m_iter won't get set
+    initialLoad(channelname);
+    startDialog();
+    m_missingMaxCount=1;
+    m_editName->setValue(channelname);
+    search(channelname);
+}
+
+void ImportIconsWizard::startDialog()
+{
+    VerticalConfigurationGroup *manSearch = 
+        new VerticalConfigurationGroup(false,false,true,true);
+    
+    manSearch->addChild(m_editName = new TransLineEditSetting(false));
+    m_editName->setLabel(QObject::tr("Name"));
+    m_editName->setHelpText(QObject::tr("Name of the icon file"));
+
+    manSearch->addChild(m_listIcons = new TransListBoxSetting());
+    m_listIcons->setHelpText(QObject::tr("List of possible icon files"));
+
+    m_editManual = new TransLineEditSetting();
+    m_editManual->setHelpText(QObject::tr("Enter text here for the manual search"));
+
+    m_buttonManual = new TransButtonSetting();
+    m_buttonManual->setLabel(QObject::tr("&Search"));
+    m_buttonManual->setHelpText(QObject::tr("Manually search for the text"));
+
+    m_buttonSkip = new TransButtonSetting();
+    m_buttonSkip->setLabel(QObject::tr("S&kip"));
+    m_buttonSkip->setHelpText(QObject::tr("Skip this icon"));
+
+    m_buttonSelect = new TransButtonSetting();
+    m_buttonSelect->setLabel(QObject::tr("S&elect"));
+    m_buttonSelect->setHelpText(QObject::tr("Select this icon"));
+
+    HorizontalConfigurationGroup *hrz1 =
+        new HorizontalConfigurationGroup(false, false, true, true);
+
+    hrz1->addChild(m_editManual);
+    hrz1->addChild(m_buttonManual);
+    hrz1->addChild(m_buttonSkip);
+    hrz1->addChild(m_buttonSelect);
+    manSearch->addChild(hrz1);
+    
+    addChild(manSearch);
+
+    connect(m_buttonManual, SIGNAL(pressed()), this, SLOT(manualSearch()));
+    connect(m_buttonSkip, SIGNAL(pressed()), this, SLOT(skip()));
+    connect(m_listIcons,SIGNAL(accepted(int)),this,
+             SLOT(menuSelection(int)));
+    connect(m_buttonSelect,SIGNAL(pressed()),this,
+            SLOT(menuSelect()));
+
+    enableControls(STATE_NORMAL);
+}
+
+const QString ImportIconsWizard::url="http://services.mythtv.org/channel-icon/";
+
+void ImportIconsWizard::enableControls(dialogState state, bool selectEnabled)
+{
+    switch (state)
+    {
+        case STATE_NORMAL:
+            if (m_editManual->getValue())
+                 m_buttonManual->setEnabled(true);
+            else
+            m_buttonManual->setEnabled(false);
+            if (m_missingCount < m_missingMaxCount)
+            {
+                if (m_missingMaxCount < 2) //When there's only one icon, nothing to skip to!
+                    m_buttonSkip->setEnabled(false);
+                else
+                    m_buttonSkip->setEnabled(true);
+                m_editName->setEnabled(true);
+                m_listIcons->setEnabled(true);
+                m_editManual->setEnabled(true);
+                m_buttonSelect->setEnabled(selectEnabled);
+            }
+            else
+            {
+                m_buttonSkip->setEnabled(false);
+                m_editName->setEnabled(false);
+                m_listIcons->setEnabled(false);
+                m_editManual->setEnabled(false);
+                m_buttonManual->setEnabled(false);
+                m_buttonSelect->setEnabled(false);
+            }
+            break;
+        case STATE_SEARCHING:
+            m_buttonSkip->setEnabled(false);
+            m_buttonSelect->setEnabled(false);
+            m_buttonManual->setEnabled(false);
+            m_listIcons->setEnabled(false);
+            m_listIcons->clearSelections();
+            m_listIcons->addSelection("Please wait...");
+            m_editManual->setValue("");
+            break;
+        case STATE_DISABLED:
+            m_buttonSkip->setEnabled(false);
+            m_buttonSelect->setEnabled(false);
+            m_buttonManual->setEnabled(false);
+            m_listIcons->setEnabled(false);
+            m_listIcons->clearSelections();
+            m_editName->setEnabled(false);
+            m_editName->setValue("");
+            m_editManual->setEnabled(false);
+            m_editManual->setValue("");
+            m_listIcons->setFocus();
+            break;    
+    }       
+}
+
+void ImportIconsWizard::manualSearch()
+{
+    QString str = m_editManual->getValue();
+    search(escape_csv(str));    
+}
+
+void ImportIconsWizard::skip()
+{
+    if (m_missingMaxCount > 1)
+    {
+        m_missingCount++;
+        m_missingIter++;    
+        doLoad();
+    }
+}
+
+void ImportIconsWizard::menuSelect()
+{
+    menuSelection(m_listIcons->currentItem());   
+}
+
+void ImportIconsWizard::menuSelection(int nIndex)
+{
+    enableControls(STATE_SEARCHING);
+    SearchEntry entry = *(m_listSearch.at(nIndex));
+
+    if ((!isBlocked((*m_iter).strIconCSV)) &&
+            (checkAndDownload(entry.strLogo)))
+    {
+        CSVEntry entry2 = (*m_iter);
+        m_strMatches += QString("%1,%2,%3,%4,%5,%6,%7,%8,%9\n").
+                              arg(escape_csv(entry.strID)).
+                              arg(escape_csv(entry2.strName)).
+                              arg(escape_csv(entry2.strXmlTvId)).
+                              arg(escape_csv(entry2.strCallsign)).
+                              arg(escape_csv(entry2.strTransportId)).
+                              arg(escape_csv(entry2.strAtscMajorChan)).
+                              arg(escape_csv(entry2.strAtscMinorChan)).
+                              arg(escape_csv(entry2.strNetworkId)).
+                              arg(escape_csv(entry2.strServiceId));
+        if (m_missingMaxCount > 1)
+        {
+            m_missingCount++;
+            m_missingIter++;
+            doLoad();
+        }
+        else
+        {
+            enableControls(STATE_DISABLED);
+            m_listIcons->addSelection(QString("Channel icon for %1 was downloaded successfully.")
+                                      .arg(entry2.strName));
+            m_listIcons->setFocus();
+            if (!m_strMatches.isEmpty())
+                submit(m_strMatches);
+            m_closeDialog=true;
+        }
+    }
+    else
+    {
+        MythPopupBox::showOkPopup(gContext->GetMainWindow(),
+                            QObject::tr("Error downloading"),
+                            QObject::tr("Failed to download the icon file"));
+        enableControls(STATE_DISABLED);
+        m_closeDialog=true;
+    }
+
+}
+
+unsigned ImportIconsWizard::initialLoad(QString name)
+{
+    // Do not try and access dialog within this function
+    VERBOSE(VB_CHANNEL, "initialLoad");
+    
+    QString querystring=("SELECT chanid,name,xmltvid,callsign,"
+                  "dtv_multiplex.transportid, "
+                  "atsc_major_chan,atsc_minor_chan,dtv_multiplex.networkid,"
+                  "channel.serviceid, "
+                  "channel.mplexid, dtv_multiplex.mplexid,"
+                  "channel.icon, channel.visible FROM "
+                  "channel, dtv_multiplex WHERE "
+                  "channel.visible && "
+                  "channel.mplexid=dtv_multiplex.mplexid");
+    if (name.isEmpty()==false)
+        querystring+=" && name=\"" + name + "\"";
+    querystring+=" ORDER BY name";
+
+    MSqlQuery query(MSqlQuery::InitCon());
+    query.prepare(querystring);
+       
+    m_listEntries.clear();           
+    m_nCount=0;
+    m_nMaxCount=0;
+    m_missingMaxCount=0;
+
+    if (query.exec() && query.isActive() && query.size() > 0)
+    {
+        MythProgressDialog *progressDialog = new MythProgressDialog("Initialising, please wait...", query.size());
+        
+        sleep(2); // Ensures dialog is drawn before ping freezes execution
+        
+        if (!ping("services.mythtv.org", 3))
+        {
+            progressDialog->Close();
+            progressDialog->deleteLater();
+            MythPopupBox::showOkPopup(gContext->GetMainWindow(),
+                                  tr("Bad Host"),
+                                  tr("Failed to connect to the remote server"));
+            return 0;
+        }
+
+        while(query.next())
+        {
+            CSVEntry entry;
+
+            if (m_fRefresh)
+            {
+                QFileInfo file(query.value(11).toString());
+                if (file.exists())
+                    continue;
+            }
+           
+            entry.strChanId=query.value(0).toString();
+            entry.strName=query.value(1).toString();
+            entry.strXmlTvId=query.value(2).toString();
+            entry.strCallsign=query.value(3).toString(); 
+            entry.strTransportId=query.value(4).toString();
+            entry.strAtscMajorChan=query.value(5).toString();
+            entry.strAtscMinorChan=query.value(6).toString();
+            entry.strNetworkId=query.value(7).toString();
+            entry.strServiceId=query.value(8).toString();
+            entry.strIconCSV= QString("%1,%2,%3,%4,%5,%6,%7,%8,%9\n").
+                              arg(escape_csv(entry.strChanId)).
+                              arg(escape_csv(entry.strName)).
+                              arg(escape_csv(entry.strXmlTvId)).
+                              arg(escape_csv(entry.strCallsign)).
+                              arg(escape_csv(entry.strTransportId)).
+                              arg(escape_csv(entry.strAtscMajorChan)).
+                              arg(escape_csv(entry.strAtscMinorChan)).
+                              arg(escape_csv(entry.strNetworkId)).
+                              arg(escape_csv(entry.strServiceId));
+            entry.strNameCSV=escape_csv(entry.strName);
+            VERBOSE(VB_CHANNEL,QString("chanid %1").arg(entry.strIconCSV));
+
+            m_listEntries.append(entry);
+            m_nMaxCount++;
+            progressDialog->setProgress(m_nMaxCount);
+        }
+        
+        progressDialog->Close();
+        progressDialog->deleteLater();
+    }
+    
+    m_iter = m_listEntries.begin();
+    
+    if (name.isEmpty()) // Scanning for multiple icons
+    {
+        MythProgressDialog *progressDialog = new MythProgressDialog("Downloading, please wait...",
+                                m_listEntries.size()+1, true, this, SLOT(cancelPressed()));
+        while (!m_closeDialog && (m_iter != m_listEntries.end()))
+        {
+            progressDialog->setLabel(QString("Downloading %1 / %2 : ").arg(m_nCount+1)
+                                     .arg(m_listEntries.size()+1) + (*m_iter).strName + 
+                                     QString("\nCould not find %1 icons.").arg(m_missingEntries.size()+1));
+            if (!findmissing((*m_iter).strIconCSV))
+                m_missingEntries.append((*m_iter));
+            m_nCount++;
+            m_iter++;
+            m_missingMaxCount++;
+            progressDialog->setProgress(m_nCount);
+        }
+        progressDialog->Close();
+        progressDialog->deleteLater();
+    }
+    
+    //Comment below for debugging - cancel button will continue to dialog
+    if (m_closeDialog)
+        m_nMaxCount=0;
+    return m_nMaxCount; 
+}
+
+bool ImportIconsWizard::doLoad()
+{
+    VERBOSE(VB_CHANNEL, QString("%1 / %2").arg(m_missingCount).arg(m_missingMaxCount));
+    if (m_missingCount >= m_missingMaxCount)
+    {
+        VERBOSE(VB_CHANNEL, "doLoad Icon search complete");
+        enableControls(STATE_DISABLED);
+        if (!m_strMatches.isEmpty())
+            submit(m_strMatches);
+        m_closeDialog=true;
+        return false;
+    }
+    else
+    {
+        // Look for the next missing icon
+        m_editName->setValue((*m_missingIter).strName);
+        search((*m_missingIter).strNameCSV);
+        return true;
+    }
+}
+
+QString ImportIconsWizard::escape_csv(const QString& str)
+{
+    VERBOSE(VB_CHANNEL, "escape_csv");
+    QRegExp rxDblForEscape("\"");
+    QString str2 = str;
+    str2.replace(rxDblForEscape,"\\\"");
+    return "\""+str2+"\"";
+}
+
+QStringList ImportIconsWizard::extract_csv(const QString& strLine)
+{
+    VERBOSE(VB_CHANNEL, "extract_csv");
+    QStringList ret;
+    //Clean up the line and split out the fields
+    QString str = strLine;
+
+    unsigned int pos = 0;
+    bool fFinish = false;
+    while(!fFinish)
+    {
+        str=str.stripWhiteSpace();
+        while(!fFinish)
+        {
+            QString strLeft;
+            switch (str.at(pos).unicode())
+            {
+            case '\\':
+                if (pos>=1)
+                    str.left(pos-1)+str.mid(pos+1);
+                else
+                    str=str.mid(pos+1);
+                pos+=2;
+                if (pos > str.length())
+                {
+                    strLeft = str.left(pos); 
+                    if (strLeft.startsWith("\"") && strLeft.endsWith("\""))
+                        strLeft=strLeft.mid(1,strLeft.length()-2);
+                    ret.append(strLeft);
+                    fFinish = true;
+                }
+                break;
+            case ',':
+                strLeft = str.left(pos); 
+                if (strLeft.startsWith("\"") && strLeft.endsWith("\""))
+                    strLeft=strLeft.mid(1,strLeft.length()-2);
+                ret.append(strLeft);
+                if ((pos+1) > str.length())
+                   fFinish = true;
+                str=str.mid(pos+1);
+                pos=0;
+                break;
+            default:
+                pos++;
+                if (pos > str.length())
+                {
+                    strLeft = str.left(pos); 
+                    if (strLeft.startsWith("\"") && strLeft.endsWith("\""))
+                        strLeft=strLeft.mid(1,strLeft.length()-2);
+                    ret.append(strLeft);
+                    fFinish = true;
+                }
+            }
+        }
+    }
+    return ret;
+}
+
+
+QString ImportIconsWizard::wget(QUrl& url,const QString& strParam )
+{
+    VERBOSE(VB_CHANNEL, "wget");
+    QByteArray raw;
+    QTextStream rawStream(raw,IO_WriteOnly);
+    rawStream << strParam;
+
+    QBuffer data(raw);
+    QHttpRequestHeader header;
+
+    header.setContentType(QString("application/x-www-form-urlencoded"));
+    header.setContentLength(raw.size());
+
+    header.setValue("User-Agent", "MythTV Channel Icon lookup bot");
+
+    QString str = HttpComms::postHttp(url,&header,&data);
+
+    return str;
+}
+
+bool ImportIconsWizard::checkAndDownload(const QString& str)
+{
+    // Do not try and access dialog within this function
+    VERBOSE(VB_CHANNEL, "checkAndDownload");
+    
+    int iIndex = str.findRev('/');
+    QString str2;
+    if (iIndex < 0)
+        str2=str;
+    else
+        str2=str.mid(iIndex+1);
+
+    QString str3 = str;
+    QFileInfo file(m_strChannelDir+str2);
+
+    bool fRet;
+    if (!file.exists())
+        fRet = HttpComms::getHttpFile(m_strChannelDir+str2,str3);    
+    else
+        fRet = true;
+
+    if (fRet)
+    {
+        MSqlQuery query(MSqlQuery::InitCon());
+        QString  qstr = "UPDATE channel SET icon = :ICON "
+                        "WHERE chanid = :CHANID";
+
+        query.prepare(qstr);
+        query.bindValue(":ICON", m_strChannelDir+str2);
+        query.bindValue(":CHANID", (*m_iter).strChanId);
+
+        if (!query.exec())
+        {
+            MythContext::DBError("Error inserting channel icon", query);
+            return false;
+        }
+ 
+    }
+
+    return fRet;
+}
+
+bool ImportIconsWizard::isBlocked(const QString& strParam)
+{
+    VERBOSE(VB_CHANNEL, "isBlocked");
+    QString strParam1 = strParam;
+    QUrl::encode(strParam1);
+    QUrl url(ImportIconsWizard::url+"/checkblock");
+    QString str = wget(url,"csv="+strParam1);
+
+    if (str.startsWith("Error",false))
+    {
+        VERBOSE(VB_IMPORTANT, QString("Error from isBlocked : %1").arg(str));
+        return true;
+    }
+    else if (str.isEmpty() || str.startsWith("\r\n"))
+        return false;
+    else
+    {
+        VERBOSE(VB_CHANNEL, QString("Icon Import: Working isBlocked"));
+        int nVal = MythPopupBox::showOkCancelPopup(gContext->GetMainWindow(),
+                            QObject::tr("Icon is blocked"),
+                            QObject::tr("This combination of channel and icon "
+                                        "has been blocked by the MythTV "
+                                        "admins. The most common reason for "
+                                        "this is that there is a better match "
+                                        "available.\n "
+                                        "Are you still sure that you want to "
+                                        "use this icon?"),
+                          true);        
+        if (nVal == 1) // Use the icon
+            return false;
+        else // Don't use the icon
+            return true;
+    }
+}
+
+
+bool ImportIconsWizard::lookup(const QString& strParam)
+{
+    QString strParam1 = "callsign="+strParam;
+    QUrl::encode(strParam1);
+    QUrl url(ImportIconsWizard::url+"/lookup");
+
+    QString str = wget(url,strParam1);
+    if (str.isEmpty() || str.startsWith("Error",false))
+    {
+        VERBOSE(VB_IMPORTANT, QString("Error from lookup : %1").arg(str));
+        return true;
+    }
+    else
+    {
+        VERBOSE(VB_CHANNEL, QString("Icon Import: Working lookup : %1").arg(str));
+        return false;
+    }
+}
+
+bool ImportIconsWizard::search(const QString& strParam)
+{
+    QString strParam1 = strParam;
+    bool retVal = false;
+    enableControls(STATE_SEARCHING);
+    QUrl::encode(strParam1);
+    QUrl url(ImportIconsWizard::url+"/search");
+
+    QString str = wget(url,"s="+strParam1);
+    
+    m_listSearch.clear();
+    m_listIcons->clearSelections();
+
+    if (str.isEmpty() || str.startsWith("#") || str.startsWith("Error",false))
+    {
+        VERBOSE(VB_IMPORTANT, QString("Error from search : %1").arg(str));
+        retVal=false;
+    }
+    else
+    {
+        VERBOSE(VB_CHANNEL, QString("Icon Import: Working search : %1").arg(str));
+        QStringList strSplit=QStringList::split("\n",str);
+
+        for (QStringList::iterator begin=strSplit.begin();
+             begin!=strSplit.end();begin++)
+        {
+            if (*begin != "#" )
+            {
+                QStringList ret = extract_csv(*begin); 
+                VERBOSE(VB_CHANNEL, QString("Icon Import: search : %1 %2 %3").arg(ret[0]).arg(ret[1]).arg(ret[2]));
+                SearchEntry entry;
+                entry.strID=ret[0];
+                entry.strName=ret[1];
+                entry.strLogo=ret[2];
+                m_listSearch.append(entry);
+                m_listIcons->addSelection(entry.strName);
+            }
+        }
+        retVal=true;
+    }
+    enableControls(STATE_NORMAL, retVal);
+    return retVal;
+}
+
+bool ImportIconsWizard::findmissing(const QString& strParam)
+{
+    QString strParam1 = strParam;
+    QUrl::encode(strParam1);
+    QUrl url(ImportIconsWizard::url+"/findmissing");
+
+    QString str = wget(url,"csv="+strParam1);
+    VERBOSE(VB_CHANNEL, QString("Icon Import: findmissing : strParam1 = %1. str = %2").arg(strParam1).arg(str));    
+    if (str.isEmpty() || str.startsWith("#") || str.startsWith("Error",false))
+    {
+        VERBOSE(VB_IMPORTANT, QString("Error from findmissing : %1").arg(str));
+        return false;
+    }
+    else
+    {
+        VERBOSE(VB_CHANNEL, QString("Icon Import: Working findmissing : %1").arg(str));
+        QStringList strSplit=QStringList::split("\n",str);
+        for (QStringList::iterator begin=strSplit.begin();
+             begin!=strSplit.end();begin++)
+        {
+            if (*begin != "#" )
+            {
+                QStringList ret = extract_csv(*begin); 
+                VERBOSE(VB_CHANNEL, QString("Icon Import: findmissing : %1 %2 %3 %4 %5").arg(ret[0]).arg(ret[1]).arg(ret[2]).arg(ret[3]).arg(ret[4]));
+                checkAndDownload(ret[4]);
+            }
+        }
+        return true;
+    }
+}
+
+bool ImportIconsWizard::submit(const QString& strParam)
+{
+    int nVal = MythPopupBox::showOkCancelPopup(
+                            gContext->GetMainWindow(),
+                            QObject::tr("Submit information"),
+                            QObject::tr("You now have the opportunity to "
+                                        "transmit your choices  back to "
+                                        "mythtv.org so that others can "
+                                        "benefit from your selections."),
+                            true);        
+    if (nVal == 0) // If cancel is pressed exit
+    {
+        m_listIcons->addSelection("Icon choices not submitted.");
+        return false;
+    }
+    
+    QString strParam1 = strParam;
+    QUrl::encode(strParam1);
+    QUrl url(ImportIconsWizard::url+"/submit");
+
+    QString str = wget(url,"csv="+strParam1);
+    if (str.isEmpty() || str.startsWith("#") || str.startsWith("Error",false))
+    {
+        VERBOSE(VB_IMPORTANT, QString("Error from submit : %1").arg(str));
+        m_listIcons->addSelection("Failed to submit icon choices.");
+        return false;
+    }
+    else
+    {
+        VERBOSE(VB_CHANNEL, QString("Icon Import: Working submit : %1").arg(str));
+        QStringList strSplit=QStringList::split("\n",str);
+        unsigned atsc =0, dvb =0, callsign =0, tv =0, xmltvid=0;
+        for (QStringList::iterator begin=strSplit.begin();
+             begin!=strSplit.end();begin++)
+        {
+            if (*begin != "#" )
+            {
+                QStringList strSplit2=QStringList::split(":",*begin);
+                QString s=strSplit2[0].stripWhiteSpace();
+                if (s=="a")
+                     atsc=strSplit2[1].toUInt();
+                else if (s=="c")
+                     callsign=strSplit2[1].toUInt();
+                else if (s=="d")
+                     dvb=strSplit2[1].toUInt();
+                else if (s=="t")
+                     tv=strSplit2[1].toUInt();
+                else if (s=="x")
+                     xmltvid=strSplit2[1].toUInt();
+            }
+        }
+        VERBOSE(VB_CHANNEL, QString("Icon Import: working submit : atsc=%1 callsign=%2 dvb=%3 tv=%4 xmltvid=%5")
+                                              .arg(atsc).arg(callsign).arg(dvb).arg(tv).arg(xmltvid));
+        m_listIcons->addSelection("Icon choices submitted successfully.");
+        return true;
+    }
+}
+
+void ImportIconsWizard::cancelPressed()
+{
+    m_closeDialog=true;
+}
+
+void ImportIconsWizard::finishButtonPressed()
+{
+    m_closeDialog = true;
+}
