Ticket #3334: importicons-libmythtv-29092007.diff

File importicons-libmythtv-29092007.diff, 33.7 KB (added by Matthew Wire <devel@…>, 17 years ago)

libmythtv changes for import icons

  • libs/libmythtv/channeleditor.cpp

     
    1919#include "sourceutil.h"
    2020
    2121#include "scanwizard.h"
     22#include "importicons.h"
    2223
    2324ChannelWizard::ChannelWizard(int id, int default_sourceid)
    2425    : ConfigurationWizard()
     
    110111        return 0;
    111112}
    112113
    113 void ChannelListSetting::fillSelections(void)
     114int ChannelListSetting::fillSelections(void)
    114115{
    115116    QString currentValue = getValue();
    116117    clearSelections();
    117118    addSelection(QObject::tr("(New Channel)"));
    118119    bool fAllSources = true;
     120    int nCount = 0;
    119121
    120122    QString querystr = "SELECT channel.name,channum,chanid ";
    121123
     
    184186                name += " (" + sourceid  + ")";
    185187
    186188            addSelection(name, chanid, (chanid == currentValue) ? true : false);
     189            nCount++;
    187190        }
    188191    }
     192    return nCount;
    189193}
    190194
    191195class SourceSetting : public ComboBoxSetting, public Storage
     
    266270    buttonScan->setLabel(QObject::tr("Channel Scanner"));
    267271    buttonScan->setHelpText(QObject::tr("Starts the channel scanner."));
    268272    buttonScan->setEnabled(SourceUtil::IsAnySourceScanable());
     273   
     274    buttonImportIcon = new TransButtonSetting();
     275    buttonImportIcon->setLabel(QObject::tr("Icon Import"));
     276    buttonImportIcon->setHelpText(QObject::tr("Starts the icon importer"));
    269277
    270278    buttonTransportEditor = new TransButtonSetting();
    271279    buttonTransportEditor->setLabel(QObject::tr("Transport Editor"));
     
    278286    HorizontalConfigurationGroup *h =
    279287        new HorizontalConfigurationGroup(false, false);
    280288    h->addChild(buttonScan);
     289    h->addChild(buttonImportIcon);
    281290    h->addChild(buttonTransportEditor);
    282291    addChild(h);
    283292
     
    293302            this, SLOT(menu(int)));
    294303    connect(buttonScan, SIGNAL(pressed()),
    295304            this, SLOT(scan()));
     305    connect(buttonImportIcon,  SIGNAL(pressed()),
     306            this, SLOT(channelIconImport()));
    296307    connect(buttonTransportEditor, SIGNAL(pressed()),
    297308            this, SLOT(transportEditor()));
    298309    connect(del,  SIGNAL(pressed()),
     
    354365    if (!query.exec())
    355366        MythContext::DBError("ChannelEditor Delete Channels", query);
    356367
    357     list->fillSelections();
     368    buttonImportIcon->setEnabled(list->fillSelections()==0 ? false:true);
    358369}
    359370
    360371MythDialog* ChannelEditor::dialogWidget(MythMainWindow* parent,
     
    378389    ChannelWizard cw(id, source->getValue().toUInt());
    379390    cw.exec();
    380391
    381     list->fillSelections();
     392    buttonImportIcon->setEnabled(list->fillSelections()==0 ? false:true);
    382393    list->setFocus();
    383394}
    384395
     
    405416        if (!query.exec() || !query.isActive())
    406417            MythContext::DBError("ChannelEditor Delete Channel", query);
    407418
    408         list->fillSelections();
     419    buttonImportIcon->setEnabled(list->fillSelections()==0 ? false:true);
    409420    }
    410421}
    411422
     
    440451    scanwizard->exec(false, true);
    441452    scanwizard->deleteLater();
    442453
    443     list->fillSelections();
     454    buttonImportIcon->setEnabled(list->fillSelections()==0 ? false:true);
    444455    list->setFocus();
    445456#else
    446457    VERBOSE(VB_IMPORTANT,  "You must compile the backend "
     
    456467    editor->exec();
    457468    editor->deleteLater();
    458469
    459     list->fillSelections();
     470    buttonImportIcon->setEnabled(list->fillSelections()==0 ? false:true);
    460471    list->setFocus();
    461472}
     473
     474void ChannelEditor::channelIconImport(void)
     475{
     476    VERBOSE(VB_CHANNEL, "channelIconImport");
     477    int val = MythPopupBox::show2ButtonPopup(gContext->GetMainWindow(),
     478                                             "",
     479                                             tr("Channel Icon Import"),
     480                                             tr("Import all icons.."),
     481                                             tr("Rescan for missing icons.."),
     482                                             0);
     483
     484    if (val == 0)
     485        emit iconImportFull();
     486    else if (val == 1)
     487        emit iconImportRescan();
     488    else
     489        list->setFocus();
     490}
     491
     492void ChannelEditor::iconImportFull(void)
     493{
     494    VERBOSE(VB_CHANNEL, "iconImportFull");
     495    ImportIconsWizard *box = new ImportIconsWizard(false);
     496    box->exec();
     497//    box->deleteLayer();
     498}
     499
     500void ChannelEditor::iconImportRescan(void)
     501{
     502    VERBOSE(VB_CHANNEL, "iconImportRescan");
     503    ImportIconsWizard *box = new ImportIconsWizard(true);
     504    box->exec();
     505//    box->deleteLayer();
     506}
  • libs/libmythtv/libmythtv.pro

     
    148148HEADERS += playgroup.h              progdetails.h
    149149HEADERS += channeleditor.h          channelsettings.h
    150150HEADERS += previewgenerator.h       transporteditor.h
     151HEADERS += importicons.h
    151152
    152153SOURCES += programinfo.cpp          proglist.cpp
    153154SOURCES += storagegroup.cpp
     
    170171SOURCES += progdetails.cpp
    171172SOURCES += channeleditor.cpp        channelsettings.cpp
    172173SOURCES += previewgenerator.cpp     transporteditor.cpp
     174SOURCES += importicons.cpp
    173175
    174176# DiSEqC
    175177HEADERS += diseqc.h                 diseqcsettings.h
  • libs/libmythtv/importicons.h

     
     1/* -*- Mode: c++ -*-
     2 * vim: set expandtab tabstop=4 shiftwidth=4:
     3 *
     4 * Original Project
     5 *      MythTV      http://www.mythtv.org
     6 *
     7 * Author(s):
     8 *      John Pullan 
     9 *
     10 * Description:
     11 */
     12
     13#ifndef _IMPORTICONS_H
     14#define _IMPORTICONS_H
     15
     16#include <qsqldatabase.h>
     17#include <qurl.h>
     18#include "settings.h"
     19
     20/** \class ImportIconsWizard
     21 *  \brief class which constructs an ImportIconsWizard, with an appropriate
     22 *         ImportIcons child in it.
     23 */
     24
     25class ImportIconsWizard : public QObject, public ConfigurationWizard
     26{
     27    Q_OBJECT
     28public:
     29    ImportIconsWizard(bool fRefresh); //!< constructs an ImportIconWizard
     30
     31    bool initialise();             //!< returns true if the net is pingable etc.
     32
     33protected:
     34
     35    enum dialogState
     36    {
     37        STATE_NORMAL,
     38        STATE_SEARCHING
     39    };
     40   
     41    struct CSVEntry                  //! describes the TV channel name
     42    {
     43        QString strChanId;           //!< local channel id
     44        QString strName;             //!< channel name
     45        QString strXmlTvId;          //!< the xmltvid
     46        QString strCallsign;         //!< callsign
     47        QString strTransportId;      //!< transport id
     48        QString strAtscMajorChan;    //!< ATSC major number
     49        QString strAtscMinorChan;    //!< ATSC minor number
     50        QString strNetworkId;        //!< network id
     51        QString strServiceId;        //!< service id
     52        QString strIconCSV;          //!< icon name (csv form)
     53        QString strNameCSV;          //!< name (csv form)
     54    }; 
     55    //! List of CSV entries
     56    typedef QValueList<CSVEntry> ListEntries;     
     57    //! iterator over list of CSV entries
     58    typedef QValueListIterator<CSVEntry> ListEntriesIter;
     59
     60    ListEntries m_listEntries;       //!< list of TV channels to search for
     61    ListEntries m_missingEntries;    //!< list of TV channels with no unique icon
     62    ListEntriesIter m_iter;          //!< the current iterator
     63    ListEntriesIter m_missingIter;
     64
     65    struct SearchEntry               //! search entry results
     66    {
     67        QString strID;               //!< the remote channel id
     68        QString strName;             //!< the remote name
     69        QString strLogo;             //!< the actual logo
     70    };
     71    //! List of SearchEntry entries
     72    typedef QValueList<SearchEntry> ListSearchEntries;
     73    //! iterator over list of SearchEntry entries
     74    typedef QValueListIterator<SearchEntry> ListSearchEntriesIter;
     75
     76    ListSearchEntries m_listSearch;  //!< the list of SearchEntry
     77    QString m_strMatches;            //!< the string for the submit() call
     78
     79    static const QString url;        //!< the default url
     80    QString m_strChannelDir;         //!< the location of the channel icon dir
     81
     82    bool m_fRefresh;                 //!< are we doing a refresh or not
     83    int m_nMaxCount;                 //!< the maximum number of TV channels
     84    int m_nCount;                    //!< the current search point (0..m_nMaxCount)
     85    int m_missingMaxCount;           //!< the total number of missing icons
     86    int m_missingCount;              //!< the current search point (0..m_missingCount)
     87
     88    /*! \brief changes a string into csv format
     89     * \param str the string to change
     90     * \return the actual string
     91     */
     92    QString escape_csv(const QString& str);
     93
     94    /*! \brief extracts the csv values out of a string
     95     * \param str the string to work on
     96     * \return the actual QStringList
     97     */
     98    QStringList extract_csv(const QString& strLine);
     99
     100    /*! \brief use the equivalent of wget to fetch the POST command
     101     * \param url the url to send this to
     102     * \param strParam the string to send
     103     * \return the actual string
     104     */
     105    QString wget(QUrl& url,const QString& strParam);
     106 
     107    TransLineEditSetting *m_editName;    //!< name field for the icon
     108    TransListBoxSetting *m_listIcons;    //!< list of potential icons
     109    TransLineEditSetting *m_editManual;  //!< manual edit field
     110    TransButtonSetting *m_buttonManual;  //!< manual button field
     111    TransButtonSetting *m_buttonSkip;    //!< button skip
     112    TransButtonSetting *m_buttonSelect;    //!< button skip
     113
     114    /*! \brief determines if a particular icon is blocked
     115     * \param str the string to work on
     116     * \return true/false
     117     */
     118    bool isBlocked(const QString& strParam);
     119
     120    /*! \brief looks up the string to determine the caller/xmltvid
     121     * \param str the string to work on
     122     * \return true/false
     123     */
     124    bool lookup(const QString& strParam);
     125
     126    /*! \brief search the remote db for icons etc
     127     * \param str the string to work on
     128     * \return true/false
     129     */
     130    bool search(const QString& strParam);
     131
     132    /*! \brief submit the icon information back to the remote db
     133     * \param str the string to work on
     134     * \return true/false
     135     */
     136    bool submit(const QString& strParam);
     137
     138    /*! \brief retrieve the actual logo for the TV channel
     139     * \param str the string to work on
     140     * \return true/false
     141     */
     142    bool findmissing(const QString& strParam);
     143
     144    /*! \brief checks and attempts to download the logo file to the appropriate
     145     *   place
     146     * \param str the string of the downloaded url
     147     * \return true/false
     148     */
     149    bool checkAndDownload(const QString& str);
     150
     151    /*! \brief attempt the inital load of the TV channel information
     152     * \return the number of TV channels
     153     */
     154    unsigned initialLoad();
     155
     156    /*! \brief attempts to move the itaration on one/more than one
     157     * \return true if we can go again or false if we can not
     158     */
     159    bool doLoad();
     160   
     161    bool m_cancelled;
     162   
     163protected slots:
     164    void enableControls(dialogState state=STATE_NORMAL);         //!< enable/disable the controls
     165    void manualSearch();           //!< process the manual search
     166    void menuSelect();
     167    void menuSelection(int nIndex);//!< process the icon selection
     168    void skip();                   //!< skip this icon
     169    void cancelPressed();
     170
     171};
     172
     173#endif // _IMPORTICONS_H
  • libs/libmythtv/channeleditor.h

     
    2222    void edit();
    2323    void edit(int);
    2424    void scan(void);
    25     void transportEditor();
    26     void deleteChannels();
     25    void transportEditor(void);
     26    void channelIconImport(void);
     27    void deleteChannels(void);
     28    void iconImportFull(void);
     29    void iconImportRescan(void);
    2730
    2831private:
    2932    int                 id;
    3033    SourceSetting      *source;
    3134    ChannelListSetting *list;
    3235    TransButtonSetting *buttonScan;
     36    TransButtonSetting *buttonImportIcon;
    3337    TransButtonSetting *buttonTransportEditor;
    3438};
    3539
     
    6872    bool getHideMode() { return currentHideMode; };
    6973
    7074public slots:
    71     void fillSelections(void);
     75    int fillSelections(void);
    7276    void setSortMode(const QString& sort) {
    7377        if (currentSortMode != sort) {
    7478            currentSortMode = sort;
  • libs/libmythtv/importicons.cpp

     
     1extern "C"
     2{
     3#include <stdlib.h>
     4#include <sys/stat.h>
     5#include <sys/types.h>
     6};
     7
     8#include <httpcomms.h>
     9#include "mythcontext.h"
     10#include "mythdbcon.h"
     11#include "mythwidgets.h"
     12#include "util.h"
     13
     14#include <qapplication.h>
     15#include <qregexp.h>
     16#include <qlayout.h>
     17#include <qdialog.h>
     18#include <qcursor.h>
     19#include <qbuffer.h>
     20#include <qfileinfo.h>
     21
     22#include <mythwidgets.h>
     23#include <mythdialogs.h>
     24#include <mythwizard.h>
     25
     26#include "importicons.h"
     27
     28const QString ImportIconsWizard::url="http://services.mythtv.org/channel-icon/";
     29
     30ImportIconsWizard::ImportIconsWizard(bool fRefresh)
     31{
     32    VERBOSE(VB_CHANNEL, "ImportIconsWizard");
     33    m_fRefresh = fRefresh;
     34
     35    VerticalConfigurationGroup *manSearch =
     36        new VerticalConfigurationGroup(false,false,true,true);
     37   
     38    manSearch->addChild(m_editName = new TransLineEditSetting(false));
     39    m_editName->setLabel(QObject::tr("Name"));
     40    m_editName->setHelpText(QObject::tr("Name of the icon file"));
     41
     42    manSearch->addChild(m_listIcons = new TransListBoxSetting());
     43    m_listIcons->setHelpText(QObject::tr("List of possible icon files"));
     44
     45    m_editManual = new TransLineEditSetting();
     46    m_editManual->setHelpText(QObject::tr("Enter text here for the manual search"));
     47
     48    m_buttonManual = new TransButtonSetting();
     49    m_buttonManual->setLabel(QObject::tr("&Search"));
     50    m_buttonManual->setHelpText(QObject::tr("Manually search for the text"));
     51
     52    m_buttonSkip = new TransButtonSetting();
     53    m_buttonSkip->setLabel(QObject::tr("S&kip"));
     54    m_buttonSkip->setHelpText(QObject::tr("Skip this icon"));
     55
     56    m_buttonSelect = new TransButtonSetting();
     57    m_buttonSelect->setLabel(QObject::tr("S&elect"));
     58    m_buttonSelect->setHelpText(QObject::tr("Select this icon"));
     59
     60    HorizontalConfigurationGroup *hrz1 =
     61        new HorizontalConfigurationGroup(false, false, true, true);
     62
     63    hrz1->addChild(m_editManual);
     64    hrz1->addChild(m_buttonManual);
     65    hrz1->addChild(m_buttonSkip);
     66    hrz1->addChild(m_buttonSelect);
     67    manSearch->addChild(hrz1);
     68   
     69    addChild(manSearch);
     70
     71    connect(m_editManual, SIGNAL(valueChanged( const QString&)),
     72            this, SLOT(  enableControls()));
     73    connect(m_buttonManual, SIGNAL(pressed()), this, SLOT(manualSearch()));
     74    connect(m_buttonSkip, SIGNAL(pressed()), this, SLOT(skip()));
     75    connect(m_listIcons,SIGNAL(accepted(int)),this,
     76             SLOT(menuSelection(int)));
     77    connect(m_buttonSelect,SIGNAL(pressed()),this,
     78             SLOT(menuSelect()));
     79
     80    enableControls();
     81   
     82    initialise();
     83}
     84
     85bool ImportIconsWizard::initialise()
     86{
     87    VERBOSE(VB_CHANNEL, "ImportIconsWizard::initialise");
     88    m_strChannelDir =  MythContext::GetConfDir()+ "/channels";
     89    mkdir(MythContext::GetConfDir(),0776);
     90    mkdir(m_strChannelDir,0776);
     91    m_strChannelDir+="/";
     92    m_cancelled=false;
     93
     94    if (initialLoad() > 0)
     95    {
     96        VERBOSE(VB_CHANNEL, "initialLoad complete");
     97        m_missingIter=m_missingEntries.begin();
     98        m_missingCount=0;
     99        enableControls();
     100        doLoad();
     101        return true;
     102    }
     103    else
     104        return false;
     105    //FIXME This should exit here
     106}
     107
     108void ImportIconsWizard::enableControls(dialogState state)
     109{
     110    switch (state)
     111    {
     112        case STATE_NORMAL:
     113            if (m_editManual->getValue())
     114                m_buttonManual->setEnabled(true);
     115           else
     116           m_buttonManual->setEnabled(false);
     117           if (m_missingCount < m_missingMaxCount)
     118           {
     119               m_buttonSkip->setEnabled(true);
     120               m_editName->setEnabled(true);
     121               m_listIcons->setEnabled(true);
     122               m_editManual->setEnabled(true);
     123//               m_editManual->setValue("");
     124           }
     125           else
     126           {
     127               m_buttonSkip->setEnabled(false);
     128               m_editName->setEnabled(false);
     129               m_listIcons->setEnabled(false);
     130               m_editManual->setEnabled(false);
     131               m_buttonManual->setEnabled(false);
     132               m_buttonSelect->setEnabled(false);
     133           }
     134           break;
     135        case STATE_SEARCHING:
     136               m_buttonSkip->setEnabled(false);
     137               m_buttonSelect->setEnabled(false);
     138               m_buttonManual->setEnabled(false);
     139               m_listIcons->setEnabled(false);
     140               m_listIcons->clearSelections();
     141               m_listIcons->addSelection("Please wait...");
     142        break;
     143    }       
     144}
     145
     146void ImportIconsWizard::manualSearch()
     147{
     148    enableControls(STATE_SEARCHING);
     149    QString str = m_editManual->getValue();
     150    search(escape_csv(str));   
     151    enableControls(STATE_NORMAL);
     152}
     153
     154void ImportIconsWizard::skip()
     155{
     156    enableControls(STATE_SEARCHING);
     157    m_missingCount++;
     158    VERBOSE(VB_CHANNEL, QString("%1").arg(m_missingCount));
     159    m_missingIter++;   
     160    doLoad();
     161    enableControls(STATE_NORMAL);
     162}
     163
     164void ImportIconsWizard::menuSelect()
     165{
     166    menuSelection(m_listIcons->currentItem());   
     167}
     168
     169void ImportIconsWizard::menuSelection(int nIndex)
     170{
     171    enableControls(STATE_SEARCHING);
     172    SearchEntry entry = *(m_listSearch.at(nIndex));
     173    if (!isBlocked((*m_iter).strIconCSV) &&
     174         checkAndDownload(entry.strLogo))
     175    {
     176        CSVEntry entry2 = (*m_iter);
     177        m_strMatches += QString("%1,%2,%3,%4,%5,%6,%7,%8,%9\n").
     178                              arg(escape_csv(entry.strID)).
     179                              arg(escape_csv(entry2.strName)).
     180                              arg(escape_csv(entry2.strXmlTvId)).
     181                              arg(escape_csv(entry2.strCallsign)).
     182                              arg(escape_csv(entry2.strTransportId)).
     183                              arg(escape_csv(entry2.strAtscMajorChan)).
     184                              arg(escape_csv(entry2.strAtscMinorChan)).
     185                              arg(escape_csv(entry2.strNetworkId)).
     186                              arg(escape_csv(entry2.strServiceId));
     187        m_missingCount++;
     188        m_missingIter++;
     189        doLoad();
     190        enableControls(STATE_NORMAL);
     191    }
     192    else
     193    {
     194        MythPopupBox::showOkPopup(gContext->GetMainWindow(),
     195                            QObject::tr("Error downloading"),
     196                            QObject::tr("Failed to download the icon file"));       
     197        enableControls(STATE_NORMAL);
     198    }
     199   
     200}
     201
     202unsigned ImportIconsWizard::initialLoad()
     203{
     204    VERBOSE(VB_CHANNEL, "initialLoad");
     205    MSqlQuery query(MSqlQuery::InitCon());
     206    query.prepare("SELECT chanid,name,xmltvid,callsign,"
     207                  "dtv_multiplex.transportid, "
     208                  "atsc_major_chan,atsc_minor_chan,dtv_multiplex.networkid,"
     209                  "channel.serviceid, "
     210                  "channel.mplexid, dtv_multiplex.mplexid,"
     211                  "channel.icon, channel.visible FROM "
     212                  "channel, dtv_multiplex WHERE "
     213                  "channel.visible && "
     214                  "channel.mplexid=dtv_multiplex.mplexid ORDER BY name");
     215       
     216    m_listEntries.clear();           
     217    m_nCount=0;
     218    m_nMaxCount=0;
     219    m_missingMaxCount=0;
     220
     221    if (query.exec() && query.isActive() && query.size() > 0)
     222    {
     223        MythProgressDialog *progressDialog = new MythProgressDialog("Initialising, please wait...", query.size());
     224       
     225        if (!ping("services.mythtv.org", 3))
     226        {
     227            progressDialog->Close();
     228            MythPopupBox::showOkPopup(gContext->GetMainWindow(),
     229                                  tr("Bad Host"),
     230                                  tr("Failed to connect to the remote server"));
     231            return 0;
     232        }
     233
     234        while(query.next())
     235        {
     236            CSVEntry entry;
     237
     238            if (m_fRefresh)
     239            {
     240                QFileInfo file(query.value(11).toString());
     241                if (file.exists())
     242                    continue;
     243            }
     244           
     245            entry.strChanId=query.value(0).toString();
     246            entry.strName=query.value(1).toString();
     247            entry.strXmlTvId=query.value(2).toString();
     248            entry.strCallsign=query.value(3).toString();
     249            entry.strTransportId=query.value(4).toString();
     250            entry.strAtscMajorChan=query.value(5).toString();
     251            entry.strAtscMinorChan=query.value(6).toString();
     252            entry.strNetworkId=query.value(7).toString();
     253            entry.strServiceId=query.value(8).toString();
     254            entry.strIconCSV= QString("%1,%2,%3,%4,%5,%6,%7,%8,%9\n").
     255                              arg(escape_csv(entry.strChanId)).
     256                              arg(escape_csv(entry.strName)).
     257                              arg(escape_csv(entry.strXmlTvId)).
     258                              arg(escape_csv(entry.strCallsign)).
     259                              arg(escape_csv(entry.strTransportId)).
     260                              arg(escape_csv(entry.strAtscMajorChan)).
     261                              arg(escape_csv(entry.strAtscMinorChan)).
     262                              arg(escape_csv(entry.strNetworkId)).
     263                              arg(escape_csv(entry.strServiceId));
     264            entry.strNameCSV=escape_csv(entry.strName);
     265            VERBOSE(VB_IMPORTANT,QString("chanid %1").arg(entry.strIconCSV));
     266
     267            m_listEntries.append(entry);
     268            m_nMaxCount++;
     269            progressDialog->setProgress(m_nMaxCount);
     270        }
     271        progressDialog->Close();
     272    }
     273   
     274    m_listIcons->clearSelections();
     275    m_editName->setValue("");
     276    m_iter = m_listEntries.begin();
     277   
     278    MythProgressDialog *progressDialog = new MythProgressDialog("Downloading, please wait...",
     279                                m_listEntries.size()+1, true, this, SLOT(cancelPressed()));
     280    while (!m_cancelled && (m_iter != m_listEntries.end()))
     281    {
     282        progressDialog->setLabel(QString("Downloading %1 / %2 : ").arg(m_nCount+1)
     283                                 .arg(m_listEntries.size()+1) + (*m_iter).strName +
     284                                 QString("\nCould not find %1 icons.").arg(m_missingEntries.size()+1));
     285        if (!findmissing((*m_iter).strIconCSV))
     286            m_missingEntries.append((*m_iter));
     287        m_nCount++;
     288        m_iter++;
     289        m_missingMaxCount++;
     290        progressDialog->setProgress(m_nCount);
     291    }
     292    progressDialog->Close();
     293   
     294    //Comment below for debugging - cancel button will continue to dialog
     295//    if (m_cancelled)
     296//        m_nMaxCount=0;
     297    return m_nMaxCount;
     298}
     299
     300bool ImportIconsWizard::doLoad()
     301{
     302    VERBOSE(VB_CHANNEL, QString("%1 / %2").arg(m_missingCount).arg(m_missingMaxCount));
     303    if (m_missingCount >= m_missingMaxCount)
     304    {
     305        VERBOSE(VB_CHANNEL, "doLoad Icon search complete");
     306        if (!m_strMatches.isEmpty())
     307        {
     308            int nVal = MythPopupBox::showOkCancelPopup(
     309                            gContext->GetMainWindow(),
     310                            QObject::tr("Submit information"),
     311                            QObject::tr("You now have the opportunity to "
     312                                        "transmit your choices  back to "
     313                                        "mythtv.org so that others can "
     314                                        "benefit from your selections."),
     315                          true);       
     316             if (nVal == 1)
     317                 submit(m_strMatches);
     318        }
     319        //FIXME: Exit dialog here
     320        return false;
     321    }
     322    else
     323    {
     324        // Look for the next missing icon
     325        m_editName->setValue((*m_missingIter).strName);
     326        m_buttonSelect->setEnabled(search((*m_missingIter).strNameCSV));
     327        return true;
     328    }
     329}
     330
     331QString ImportIconsWizard::escape_csv(const QString& str)
     332{
     333    VERBOSE(VB_CHANNEL, "escape_csv");
     334    QRegExp rxDblForEscape("\"");
     335    QString str2 = str;
     336    str2.replace(rxDblForEscape,"\\\"");
     337    return "\""+str2+"\"";
     338}
     339
     340QStringList ImportIconsWizard::extract_csv(const QString& strLine)
     341{
     342    VERBOSE(VB_CHANNEL, "extract_csv");
     343    QStringList ret;
     344    //Clean up the line and split out the fields
     345    QString str = strLine;
     346
     347    unsigned int pos = 0;
     348    bool fFinish = false;
     349    while(!fFinish)
     350    {
     351        str=str.stripWhiteSpace();
     352        while(!fFinish)
     353        {
     354            QString strLeft;
     355            switch (str.at(pos).unicode())
     356            {
     357            case '\\':
     358                if (pos>=1)
     359                    str.left(pos-1)+str.mid(pos+1);
     360                else
     361                    str=str.mid(pos+1);
     362                pos+=2;
     363                if (pos > str.length())
     364                {
     365                    strLeft = str.left(pos);
     366                    if (strLeft.startsWith("\"") && strLeft.endsWith("\""))
     367                        strLeft=strLeft.mid(1,strLeft.length()-2);
     368                    ret.append(strLeft);
     369                    fFinish = true;
     370                }
     371                break;
     372            case ',':
     373                strLeft = str.left(pos);
     374                if (strLeft.startsWith("\"") && strLeft.endsWith("\""))
     375                    strLeft=strLeft.mid(1,strLeft.length()-2);
     376                ret.append(strLeft);
     377                if ((pos+1) > str.length())
     378                   fFinish = true;
     379                str=str.mid(pos+1);
     380                pos=0;
     381                break;
     382            default:
     383                pos++;
     384                if (pos > str.length())
     385                {
     386                    strLeft = str.left(pos);
     387                    if (strLeft.startsWith("\"") && strLeft.endsWith("\""))
     388                        strLeft=strLeft.mid(1,strLeft.length()-2);
     389                    ret.append(strLeft);
     390                    fFinish = true;
     391                }
     392            }
     393        }
     394    }
     395    return ret;
     396}
     397
     398
     399QString ImportIconsWizard::wget(QUrl& url,const QString& strParam )
     400{
     401    VERBOSE(VB_CHANNEL, "wget");
     402    QByteArray raw;
     403    QTextStream rawStream(raw,IO_WriteOnly);
     404    rawStream << strParam;
     405
     406    QBuffer data(raw);
     407    QHttpRequestHeader header;
     408
     409    header.setContentType(QString("application/x-www-form-urlencoded"));
     410    header.setContentLength(raw.size());
     411
     412    header.setValue("User-Agent", "MythTV Channel Icon lookup bot");
     413
     414    QString str = HttpComms::postHttp(url,&header,&data);
     415
     416    return str;
     417}
     418
     419bool ImportIconsWizard::checkAndDownload(const QString& str)
     420{
     421    VERBOSE(VB_CHANNEL, "checkAndDownload");
     422    int iIndex = str.findRev('/');
     423    QString str2;
     424    if (iIndex < 0)
     425        str2=str;
     426    else
     427        str2=str.mid(iIndex+1);
     428
     429    QString str3 = str;
     430    QFileInfo file(m_strChannelDir+str2);
     431
     432    bool fRet;
     433    if (!file.exists())
     434        fRet = HttpComms::getHttpFile(m_strChannelDir+str2,str3);   
     435    else
     436        fRet = true;
     437
     438    if (fRet)
     439    {
     440        MSqlQuery query(MSqlQuery::InitCon());
     441        QString  qstr = "UPDATE channel SET icon = :ICON "
     442                        "WHERE chanid = :CHANID";
     443
     444        query.prepare(qstr);
     445        query.bindValue(":ICON", m_strChannelDir+str2);
     446        query.bindValue(":CHANID", (*m_iter).strChanId);
     447
     448        if (!query.exec())
     449        {
     450            MythContext::DBError("Error inserting channel icon", query);
     451            return false;
     452        }
     453 
     454    }
     455    return fRet;
     456}
     457
     458bool ImportIconsWizard::isBlocked(const QString& strParam)
     459{
     460    VERBOSE(VB_CHANNEL, "isBlocked");
     461    QString strParam1 = strParam;
     462    QUrl::encode(strParam1);
     463    QUrl url(ImportIconsWizard::url+"/checkblock");
     464    QString str = wget(url,"csv="+strParam1);
     465    if (str.startsWith("Error",false))
     466    {
     467        VERBOSE(VB_IMPORTANT, QString("Error from isBlocked : %1").arg(str));
     468        return true;
     469    }
     470    else if (str.isEmpty() || str.startsWith("\r\n"))
     471        return false;
     472    else
     473    {
     474        VERBOSE(VB_IMPORTANT, QString("Working isBlocked"));
     475        int nVal = MythPopupBox::showOkCancelPopup(gContext->GetMainWindow(),
     476                            QObject::tr("Icon is blocked"),
     477                            QObject::tr("This combination of channel and icon "
     478                                        "has been blocked by the MythTV "
     479                                        "admins. The most common reason for "
     480                                        "this is that there is a better match "
     481                                        "available.\n "
     482                                        "Are you still sure that you want to "
     483                                        "use this icon?"),
     484                          true);       
     485        if (nVal == 0)
     486            return false;
     487        else
     488            return true;
     489    }
     490}
     491
     492
     493bool ImportIconsWizard::lookup(const QString& strParam)
     494{
     495    VERBOSE(VB_CHANNEL, "lookup");
     496    HttpComms http;
     497    QString strParam1 = "callsign="+strParam;
     498    QUrl::encode(strParam1);
     499    QUrl url(ImportIconsWizard::url+"/lookup");
     500
     501    QString str = wget(url,strParam1);
     502    if (str.isEmpty() || str.startsWith("Error",false))
     503    {
     504        VERBOSE(VB_IMPORTANT, QString("Error from lookup : %1").arg(str));
     505        return true;
     506    }
     507    else
     508    {
     509        VERBOSE(VB_IMPORTANT, QString("Working lookup : %1").arg(str));
     510        return false;
     511    }
     512}
     513
     514bool ImportIconsWizard::search(const QString& strParam)
     515{
     516    VERBOSE(VB_CHANNEL, "search");
     517    HttpComms http;
     518    QString strParam1 = strParam;
     519    QUrl::encode(strParam1);
     520    QUrl url(ImportIconsWizard::url+"/search");
     521
     522    QString str = wget(url,"s="+strParam1);
     523   
     524    m_listSearch.clear();
     525    m_listIcons->clearSelections();
     526
     527    if (str.isEmpty() || str.startsWith("#") || str.startsWith("Error",false))
     528    {
     529        VERBOSE(VB_IMPORTANT, QString("Error from search : %1").arg(str));
     530        return false;
     531    }
     532    else
     533    {
     534        VERBOSE(VB_IMPORTANT, QString("Working search : %1").arg(str));
     535        QStringList strSplit=QStringList::split("\n",str);
     536
     537        for (QStringList::iterator begin=strSplit.begin();
     538             begin!=strSplit.end();begin++)
     539        {
     540            if (*begin != "#" )
     541            {
     542                QStringList ret = extract_csv(*begin);
     543                VERBOSE(VB_IMPORTANT, QString(" search : %1 %2 %3").arg(ret[0]).arg(ret[1]).arg(ret[2]));
     544                SearchEntry entry;
     545                entry.strID=ret[0];
     546                entry.strName=ret[1];
     547                entry.strLogo=ret[2];
     548                m_listSearch.append(entry);
     549                m_listIcons->addSelection(entry.strName);
     550            }
     551        }
     552
     553        return true;
     554    }
     555}
     556
     557bool ImportIconsWizard::findmissing(const QString& strParam)
     558{
     559    VERBOSE(VB_CHANNEL, "findmissing");
     560    HttpComms http;
     561    QString strParam1 = strParam;
     562    QUrl::encode(strParam1);
     563    QUrl url(ImportIconsWizard::url+"/findmissing");
     564
     565    QString str = wget(url,"csv="+strParam1);
     566    VERBOSE(VB_IMPORTANT, QString("findmissing : strParam1 = %1. str = %2").arg(strParam1).arg(str));   
     567    if (str.isEmpty() || str.startsWith("#") || str.startsWith("Error",false))
     568    {
     569        VERBOSE(VB_IMPORTANT, QString("Error from findmissing : %1").arg(str));
     570        return false;
     571    }
     572    else
     573    {
     574        VERBOSE(VB_IMPORTANT, QString("Working findmissing : %1").arg(str));
     575        QStringList strSplit=QStringList::split("\n",str);
     576        for (QStringList::iterator begin=strSplit.begin();
     577             begin!=strSplit.end();begin++)
     578        {
     579            if (*begin != "#" )
     580            {
     581                QStringList ret = extract_csv(*begin);
     582                VERBOSE(VB_IMPORTANT, QString(" findmissing : %1 %2 %3 %4 %5").arg(ret[0]).arg(ret[1]).arg(ret[2]).arg(ret[3]).arg(ret[4]));
     583                checkAndDownload(ret[4]);
     584            }
     585        }
     586        return true;
     587    }
     588}
     589
     590bool ImportIconsWizard::submit(const QString& strParam)
     591{
     592    VERBOSE(VB_CHANNEL, "submit");
     593    HttpComms http;
     594    QString strParam1 = strParam;
     595    QUrl::encode(strParam1);
     596    QUrl url(ImportIconsWizard::url+"/submit");
     597
     598    QString str = wget(url,"csv="+strParam1);
     599    if (str.isEmpty() || str.startsWith("#") || str.startsWith("Error",false))
     600    {
     601        VERBOSE(VB_IMPORTANT, QString("Error from submit : %1").arg(str));
     602        return false;
     603    }
     604    else
     605    {
     606        VERBOSE(VB_IMPORTANT, QString("Working submit : %1").arg(str));
     607        QStringList strSplit=QStringList::split("\n",str);
     608        unsigned atsc =0, dvb =0, callsign =0, tv =0, xmltvid=0;
     609        for (QStringList::iterator begin=strSplit.begin();
     610             begin!=strSplit.end();begin++)
     611        {
     612            if (*begin != "#" )
     613            {
     614                QStringList strSplit2=QStringList::split(":",*begin);
     615                QString s=strSplit2[0].stripWhiteSpace();
     616                if (s=="a")
     617                     atsc=strSplit2[1].toUInt();
     618                else if (s=="c")
     619                     callsign=strSplit2[1].toUInt();
     620                else if (s=="d")
     621                     dvb=strSplit2[1].toUInt();
     622                else if (s=="t")
     623                     tv=strSplit2[1].toUInt();
     624                else if (s=="x")
     625                     xmltvid=strSplit2[1].toUInt();
     626            }
     627        }
     628        VERBOSE(VB_IMPORTANT, QString("working submit : atsc=%1 callsign=%2 dvb=%3 tv=%4 xmltvid=%5").arg(atsc).arg(callsign).arg(dvb).arg(tv).arg(xmltvid));
     629        return true;
     630    }
     631}
     632
     633void ImportIconsWizard::cancelPressed()
     634{
     635    m_cancelled=true;
     636}