Index: libs/libmythtv/scanwizardhelpers.h
===================================================================
--- libs/libmythtv/scanwizardhelpers.h	(revision 12492)
+++ libs/libmythtv/scanwizardhelpers.h	(working copy)
@@ -50,9 +50,6 @@
 class STPane;
 class DVBUtilsImportPane;
 
-/// Max range of the ScanProgressPopup progress bar
-#define PROGRESS_MAX  1000
-
 class ScanSignalMeter: public ProgressSetting, public TransientStorage
 {
   public:
@@ -63,25 +60,38 @@
 {
     Q_OBJECT
 
-  protected:
+    friend class QObject; // quiet OSX gcc warning
+
+  public:
+    ScanProgressPopup(bool lock, bool strength, bool snr);
+    virtual void deleteLater(void);
+
+    virtual int exec(void);
+
+    void SetStatusSignalToNoise(int value);
+    void SetStatusSignalStrength(int value);
+    void SetStatusLock(int value);
+    void SetScanProgress(double value)
+        { progressBar->setValue((uint)(value * 65535));}
+
+    void SetStatusText(const QString &value);
+    void SetStatusTitleText(const QString &value);
+
+  private slots:
+    void Done(void);
+
+  private:
+    ~ScanProgressPopup();
+
+    bool               done;
+    QWaitCondition     wait;
+
     ScanSignalMeter   *ss;
     ScanSignalMeter   *sn;
     ScanSignalMeter   *progressBar;
 
     TransLabelSetting *sl;
     TransLabelSetting *sta;
-
-  public:
-    ScanProgressPopup(ScanWizardScanner *parent, bool signalmonitors = true);
-    ~ScanProgressPopup();
-    void exec(ScanWizardScanner *parent);
-    void signalToNoise(int value);
-    void signalStrength(int value);
-    void dvbLock(int value);
-    void status(const QString& value);
-
-    void progress(int value) { progressBar->setValue(value);}
-    void incrementProgress() { progress(progressBar->getValue().toInt()+1);}
 };
 
 class ScannerEvent : public QCustomEvent
@@ -91,13 +101,15 @@
   public:
     enum TYPE 
     {
-        ServiceScanComplete,
-        Update,
-        TableLoaded,
-        ServicePct,
-        DVBSNR,
-        DVBSignalStrength,
-        DVBLock,
+        ScanComplete,
+        ScanShutdown,
+        AppendTextToLog,
+        SetStatusText,
+        SetStatusTitleText,
+        SetPercentComplete,
+        SetStatusSignalToNoise,
+        SetStatusSignalStrength,
+        SetStatusSignalLock,
     };
 
     ScannerEvent(TYPE t) : QCustomEvent(t + QEvent::User) { ; }
Index: libs/libmythtv/scanwizardscanner.cpp
===================================================================
--- libs/libmythtv/scanwizardscanner.cpp	(revision 12492)
+++ libs/libmythtv/scanwizardscanner.cpp	(working copy)
@@ -95,11 +95,8 @@
 
 ScanWizardScanner::ScanWizardScanner(void)
     : VerticalConfigurationGroup(false, true, false, false),
-      log(new LogList()),
-      channel(NULL),                popupProgress(NULL),
-      scanner(NULL),                analogScanner(NULL),
-      freeboxScanner(NULL),
-      frequency(0),                 modulation("8vsb")
+      log(new LogList()), channel(NULL), popupProgress(NULL),
+      scanner(NULL), freeboxScanner(NULL), nVideoSource(0)
 {
     init_statics();
 
@@ -107,6 +104,14 @@
     addChild(log);
 }
 
+ScanWizardScanner::~ScanWizardScanner()
+{
+    Teardown();
+
+    QMutexLocker locker(&popupLock);
+    StopPopup();
+}
+
 void ScanWizardScanner::Teardown()
 {
     // Join the thread and close the channel
@@ -130,68 +135,87 @@
         freeboxScanner = NULL;
     }
 #endif
-
-    if (popupProgress)
-    {
-        delete popupProgress; // TODO we should use deleteLater...
-        popupProgress = NULL;
-    }
 }
 
 void ScanWizardScanner::customEvent(QCustomEvent *e)
 {
     ScannerEvent *scanEvent = (ScannerEvent*) e;
-    if ((popupProgress == NULL) &&
-        (scanEvent->eventType() != ScannerEvent::Update))
+
+    switch (scanEvent->eventType())
     {
-        return;
+        case ScannerEvent::ScanComplete:
+        {
+            QMutexLocker locker(&popupLock);
+            if (popupProgress)
+            {
+                popupProgress->SetScanProgress(1.0);
+                popupProgress->accept();
+            }
+        }
+        break;
+
+        case ScannerEvent::ScanShutdown:
+        {
+            Teardown();
+        }
+        break;
+
+        case ScannerEvent::AppendTextToLog:
+        {
+            log->updateText(scanEvent->strValue());
+        }
+        break;
+
+        default:
+            break;
     }
 
+    QMutexLocker locker(&popupLock);
+    if (!popupProgress)
+        return;
+
     switch (scanEvent->eventType())
     {
-        case ScannerEvent::ServiceScanComplete:
-            popupProgress->progress(PROGRESS_MAX);
-            Teardown();
+        case ScannerEvent::SetStatusText:
+            popupProgress->SetStatusText(scanEvent->strValue());
             break;
-        case ScannerEvent::Update:
-            log->updateText(scanEvent->strValue());
+        case ScannerEvent::SetStatusTitleText:
+            popupProgress->SetStatusTitleText(scanEvent->strValue());
             break;
-        case ScannerEvent::TableLoaded:
-            popupProgress->incrementProgress();
+        case ScannerEvent::SetPercentComplete:
+            popupProgress->SetScanProgress(scanEvent->intValue() * 0.01);
             break;
-        case ScannerEvent::ServicePct:
-            popupProgress->progress(
-                (scanEvent->intValue() * PROGRESS_MAX) / 100);
+        case ScannerEvent::SetStatusSignalLock:
+            popupProgress->SetStatusLock(scanEvent->intValue());
             break;
-        case ScannerEvent::DVBLock:
-            popupProgress->dvbLock(scanEvent->intValue());
+        case ScannerEvent::SetStatusSignalToNoise:
+            popupProgress->SetStatusSignalToNoise(scanEvent->intValue());
             break;
-        case ScannerEvent::DVBSNR:
-            popupProgress->signalToNoise(scanEvent->intValue());
+        case ScannerEvent::SetStatusSignalStrength:
+            popupProgress->SetStatusSignalStrength(scanEvent->intValue());
             break;
-        case ScannerEvent::DVBSignalStrength:
-            popupProgress->signalStrength(scanEvent->intValue());
+        default:
             break;
     }
 }
 
 void ScanWizardScanner::scanComplete()
 {
-    ScannerEvent::TYPE se = ScannerEvent::ServiceScanComplete;
+    ScannerEvent::TYPE se = ScannerEvent::ScanComplete;
     QApplication::postEvent(this, new ScannerEvent(se));
 }
 
 void ScanWizardScanner::transportScanComplete()
 {
     scanner->ScanServicesSourceID(nVideoSource);
-    ScannerEvent* e = new ScannerEvent(ScannerEvent::ServicePct);
+    ScannerEvent* e = new ScannerEvent(ScannerEvent::SetPercentComplete);
     e->intValue(TRANSPORT_PCT);
     QApplication::postEvent(this, e);
 }
 
 void ScanWizardScanner::serviceScanPctComplete(int pct)
 {
-    ScannerEvent* e = new ScannerEvent(ScannerEvent::ServicePct);
+    ScannerEvent* e = new ScannerEvent(ScannerEvent::SetPercentComplete);
     int tmp = TRANSPORT_PCT + ((100 - TRANSPORT_PCT) * pct)/100;
     e->intValue(tmp);
     QApplication::postEvent(this, e);
@@ -201,17 +225,20 @@
 {
     if (str.isEmpty())
         return;
-    ScannerEvent* e = new ScannerEvent(ScannerEvent::Update);
+    ScannerEvent* e = new ScannerEvent(ScannerEvent::AppendTextToLog);
     e->strValue(str);
     QApplication::postEvent(this, e);
 }
 
 void ScanWizardScanner::updateStatusText(const QString &str)
 {
-    if (str.isEmpty())
-        return;
-    if (popupProgress)
-        popupProgress->status(tr("Scanning")+" "+str);
+    QString msg = tr("Scanning");
+    if (!str.isEmpty())
+        msg = QString("%1 %2").arg(msg).arg(str);
+
+    ScannerEvent* e = new ScannerEvent(ScannerEvent::SetStatusText);
+    e->strValue(msg);
+    QApplication::postEvent(this, e);
 }
 
 void ScanWizardScanner::dvbLock(const SignalMonitorValue &val)
@@ -231,21 +258,21 @@
 
 void ScanWizardScanner::dvbLock(int locked)
 {
-    ScannerEvent* e = new ScannerEvent(ScannerEvent::DVBLock);
+    ScannerEvent* e = new ScannerEvent(ScannerEvent::SetStatusSignalLock);
     e->intValue(locked);
     QApplication::postEvent(this, e);
 }
 
 void ScanWizardScanner::dvbSNR(int i)
 {
-    ScannerEvent* e = new ScannerEvent(ScannerEvent::DVBSNR);
+    ScannerEvent* e = new ScannerEvent(ScannerEvent::SetStatusSignalToNoise);
     e->intValue(i);
     QApplication::postEvent(this, e);
 }
 
 void ScanWizardScanner::dvbSignalStrength(int i)
 {
-    ScannerEvent* e = new ScannerEvent(ScannerEvent::DVBSignalStrength);
+    ScannerEvent* e = new ScannerEvent(ScannerEvent::SetStatusSignalStrength);
     e->intValue(i);
     QApplication::postEvent(this, e);
 }
@@ -283,10 +310,8 @@
     }
 
     scanner->StartScanner();
+    updateStatusText("");
 
-    popupProgress->status(tr("Scanning"));
-    popupProgress->progress( (TUNED_PCT * PROGRESS_MAX) / 100 );
-
     bool ok = false;
 
     if (do_delete_channels && (ScanTypeSetting::TransportScan == scantype))
@@ -354,8 +379,7 @@
         ok = scanner->ScanServicesSourceID(sourceid);
         if (ok)
         {
-            post_event(this, ScannerEvent::ServicePct,
-                       TRANSPORT_PCT);
+            serviceScanPctComplete(0);
         }
         else
         {
@@ -390,8 +414,7 @@
         }
         if (ok)
         {
-            post_event(this, ScannerEvent::ServicePct,
-                       TRANSPORT_PCT);
+            serviceScanPctComplete(0);
         }
         else
         {
@@ -570,9 +593,7 @@
     }
 #endif // USING_DVB
 
-    popupProgress = new ScanProgressPopup(this);
-    popupProgress->progress(0);
-    popupProgress->exec(this);
+    MonitorProgress(monitor, monitor, dvbm);
 }
 
 void ScanWizardScanner::ImportM3U(uint cardid, const QString &inputname,
@@ -581,7 +602,6 @@
 #ifdef USING_IPTV
     //Create an analog scan object
     freeboxScanner = new IPTVChannelFetcher(cardid, inputname, sourceid);
-    popupProgress  = new ScanProgressPopup(this, false);
 
     connect(freeboxScanner, SIGNAL(ServiceScanComplete(void)),
             this,           SLOT(  scanComplete(void)));
@@ -590,15 +610,54 @@
     connect(freeboxScanner, SIGNAL(ServiceScanPercentComplete(int)),
             this,           SLOT(  serviceScanPctComplete(int)));
 
-    popupProgress->progress(0);
-    popupProgress->exec(this);
+    MonitorProgress(false, false, false);
 
     if (!freeboxScanner->Scan())
     {
         MythPopupBox::showOkPopup(gContext->GetMainWindow(),
                                   tr("ScanWizard"),
                                   tr("Error starting scan"));
-        Teardown();
     }
 #endif // USING_IPTV
 }
+
+void *spawn_popup(void *tmp)
+{
+    ((ScanWizardScanner*)(tmp))->RunPopup();
+    return NULL;
+}
+
+void ScanWizardScanner::RunPopup(void)
+{
+    int ret = popupProgress->exec();
+
+    popupLock.lock();
+    popupProgress->deleteLater();
+    popupProgress = NULL;
+    popupLock.unlock();
+
+    post_event(this, ScannerEvent::ScanShutdown, ret);
+}
+
+void ScanWizardScanner::StopPopup(void)
+{
+    if (popupProgress)
+    {
+        popupProgress->reject();
+        popupLock.unlock();
+        pthread_join(popup_thread, NULL);
+        popupLock.lock();
+    }
+}
+
+void ScanWizardScanner::MonitorProgress(bool lock, bool strength, bool snr)
+{
+    QMutexLocker locker(&popupLock);
+    StopPopup();
+    popupProgress = new ScanProgressPopup(lock, strength, snr);
+    if (pthread_create(&popup_thread, NULL, spawn_popup, this) != 0)
+    {
+        popupProgress->deleteLater();
+        popupProgress = NULL;
+    }
+}
Index: libs/libmythtv/scanwizardscanner.h
===================================================================
--- libs/libmythtv/scanwizardscanner.h	(revision 12492)
+++ libs/libmythtv/scanwizardscanner.h	(working copy)
@@ -58,6 +58,8 @@
 {
     Q_OBJECT
 
+    friend void *spawn_popup(void*);
+
   public:
     ScanWizardScanner(void);
     virtual void deleteLater(void)
@@ -96,7 +98,7 @@
     void serviceScanPctComplete(int pct);
 
   protected:
-    ~ScanWizardScanner() { Teardown(); }
+    ~ScanWizardScanner();
     void Teardown(void);
 
     void PreScanCommon(int scantype, uint parent_cardid, uint child_cardid,
@@ -108,24 +110,26 @@
     void dvbSignalStrength(int);
     void customEvent(QCustomEvent *e);
 
+    void MonitorProgress(bool lock, bool strength, bool snr);
+    void RunPopup(void);
+    void StopPopup(void);
+
   public:
     static QString kTitle;
 
   private:
     LogList           *log;
     ChannelBase       *channel;
-    ScanProgressPopup *popupProgress;
 
-    SIScan            *scanner;
-    AnalogScan        *analogScanner;
+    ScanProgressPopup  *popupProgress;
+    pthread_t           popup_thread;
+    mutable QMutex      popupLock;
+
+    SIScan             *scanner;
     IPTVChannelFetcher *freeboxScanner;
 
     uint               nVideoSource;
 
-    // tranport info
-    uint               frequency;
-    QString            modulation;
-
     // dvb-utils imported channels
     DTVChannelList channels;
 };
Index: libs/libmythtv/scanwizardhelpers.cpp
===================================================================
--- libs/libmythtv/scanwizardhelpers.cpp	(revision 12492)
+++ libs/libmythtv/scanwizardhelpers.cpp	(working copy)
@@ -78,43 +78,46 @@
     return QString("(%1)").arg(cardTypes);
 }
 
-ScanProgressPopup::ScanProgressPopup(
-    ScanWizardScanner *parent, bool signalmonitors) :
-    ConfigurationPopupDialog()
+ScanProgressPopup::ScanProgressPopup(bool lock, bool strength, bool snr) :
+    ConfigurationPopupDialog(),
+    done(false), ss(NULL), sn(NULL), progressBar(NULL), sl(NULL), sta(NULL)
 {
     setLabel(tr("Scan Progress"));
 
-    if (signalmonitors)
+    addChild(sta = new TransLabelSetting());
+    sta->setLabel(tr("Status"));
+    sta->setValue(tr("Tuning"));
+
+    if (lock)
     {
-        VerticalConfigurationGroup *box = new VerticalConfigurationGroup();
-        box->addChild(sta = new TransLabelSetting());
-        box->addChild(sl = new TransLabelSetting());
-        sta->setLabel(tr("Status"));
-        sta->setValue(tr("Tuning"));
+        addChild(sl = new TransLabelSetting());
         sl->setValue("                                  "
                      "                                  ");
-        box->setUseFrame(false);
-        addChild(box);
     }
 
-    addChild(progressBar = new ScanSignalMeter(PROGRESS_MAX));
-    progressBar->setValue(0);
-    progressBar->setLabel(tr("Scan"));
+    if (strength)
+    {
+        addChild(ss = new ScanSignalMeter(65535));
+        ss->setLabel(tr("Signal Strength"));
+    }
 
-    if (signalmonitors)
+    if (snr)
     {
-        addChild(ss = new ScanSignalMeter(65535));
         addChild(sn = new ScanSignalMeter(65535));
-        ss->setLabel(tr("Signal Strength"));
         sn->setLabel(tr("Signal/Noise"));
     }
 
+    addChild(progressBar = new ScanSignalMeter(65535));
+    progressBar->setValue(0);
+    progressBar->setLabel(tr("Scan"));
+
+
     TransButtonSetting *cancel = new TransButtonSetting();
     cancel->setLabel(tr("Cancel"));
     addChild(cancel);
 
     connect(cancel, SIGNAL(pressed(void)),
-            parent, SLOT(  CancelScan(void)));
+            this,   SLOT(  reject(void)));
 
     //Seem to need to do this as the constructor doesn't seem enough
     setUseLabel(false);
@@ -126,35 +129,72 @@
     VERBOSE(VB_IMPORTANT, "~ScanProgressPopup()");
 }
 
-void ScanProgressPopup::signalToNoise(int value)
+void ScanProgressPopup::SetStatusSignalToNoise(int value)
 {
-    sn->setValue(value);
+    if (sn)
+        sn->setValue(value);
 }
 
-void ScanProgressPopup::signalStrength(int value)
+void ScanProgressPopup::SetStatusSignalStrength(int value)
 {
-    ss->setValue(value);
+    if (ss)
+        ss->setValue(value);
 }
 
-void ScanProgressPopup::dvbLock(int value)
+void ScanProgressPopup::SetStatusLock(int value)
 {
-    sl->setValue((value) ? tr("Locked") : tr("No Lock"));
+    if (sl)
+        sl->setValue((value) ? tr("Locked") : tr("No Lock"));
 }
 
-void ScanProgressPopup::status(const QString& value)
+void ScanProgressPopup::SetStatusText(const QString &value)
 {
-    sta->setValue(value);
+    if (sta)
+        sta->setValue(value);
 }
 
-void ScanProgressPopup::exec(ScanWizardScanner *parent)
+void ScanProgressPopup::SetStatusTitleText(const QString &value)
 {
-    dialog = (ConfigPopupDialogWidget*)
-        dialogWidget(gContext->GetMainWindow(), "ScanProgressPopup");
-    connect(dialog, SIGNAL(popupDone(void)),
-            parent, SLOT(  CancelScan(void)));
-    dialog->ShowPopup(this);
+    QString msg = tr("Scan Progress") + QString(" %1").arg(value);
+    setLabel(msg);
 }
 
+void ScanProgressPopup::deleteLater(void)
+{
+    disconnect();
+    if (dialog)
+    {
+        dialog->deleteLater();
+        dialog = NULL;
+    }
+    ConfigurationPopupDialog::deleteLater();
+}
+
+int ScanProgressPopup::exec(void)
+{
+    if (!dialog)
+    {
+        dialog = (ConfigPopupDialogWidget*)
+            dialogWidget(gContext->GetMainWindow(),
+                         "ConfigurationPopupDialog");
+    }
+    dialog->setResult(0);
+
+    done = false;
+    dialog->ShowPopup(this, SLOT(Done(void)));
+
+    while (!done)
+        wait.wait(100);
+
+    return dialog->result();
+}
+
+void ScanProgressPopup::Done(void)
+{
+    done = true;
+    wait.wakeAll();
+}
+
 void MultiplexSetting::load(void)
 {
     clearSelections();
Index: libs/libmyth/settings.cpp
===================================================================
--- libs/libmyth/settings.cpp	(revision 12492)
+++ libs/libmyth/settings.cpp	(working copy)
@@ -1547,6 +1547,19 @@
     }
 }
 
+void ConfigurationPopupDialog::deleteLater(void)
+{
+    disconnect();
+    if (dialog)
+    {
+        dialog->disconnect();
+        dialog->deleteLater();
+        dialog = NULL;
+        label = NULL;
+    }
+    VerticalConfigurationGroup::deleteLater();
+}
+
 MythDialog* ConfigurationPopupDialog::dialogWidget(MythMainWindow* parent,
                                                    const char* widgetName)
 {
@@ -1559,7 +1572,7 @@
         box->setSizePolicy(QSizePolicy(QSizePolicy::Minimum, 
                                        QSizePolicy::Maximum));
 
-        QLabel* label = new QLabel(box);
+        label = new QLabel(box);
         label->setText(getLabel());
         label->setBackgroundOrigin(QWidget::WindowOrigin);
         label->setAlignment(Qt::AlignHCenter);
@@ -1576,10 +1589,16 @@
     return dialog;
 }
 
+void ConfigurationPopupDialog::setLabel(QString str)
+{
+    VerticalConfigurationGroup::setLabel(str);
+    if (label)
+        label->setText(str);
+}
+
 int ConfigurationPopupDialog::exec(bool saveOnAccept)
 {
     storage->load();
-
     dialog = (ConfigPopupDialogWidget*)
         dialogWidget(gContext->GetMainWindow(), "ConfigurationPopupDialog");
     dialog->ShowPopup(this);
@@ -1588,7 +1607,6 @@
 
     if ((QDialog::Accepted == ret) && saveOnAccept)
         storage->save();
-
     return ret;
 }
 
Index: libs/libmyth/mythdialogs.cpp
===================================================================
--- libs/libmyth/mythdialogs.cpp	(revision 12492)
+++ libs/libmyth/mythdialogs.cpp	(working copy)
@@ -447,6 +447,18 @@
         MythDialog::keyPressEvent(e);
 }
 
+void MythPopupBox::accept(void)
+{
+    MythDialog::done(Accepted);
+    emit popupDone();
+}
+
+void MythPopupBox::reject(void)
+{
+    MythDialog::done(Rejected);
+    emit popupDone();
+}
+
 int MythPopupBox::ExecPopup(QObject *target, const char *slot)
 {
     if (!target)
Index: libs/libmyth/mythcontext.h
===================================================================
--- libs/libmyth/mythcontext.h	(revision 12492)
+++ libs/libmyth/mythcontext.h	(working copy)
@@ -201,7 +201,7 @@
 
 /// 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.20070111-1"
+#define MYTH_BINARY_VERSION "0.20.20070112-1"
 
 /** \brief Increment this whenever the MythTV network protocol changes.
  *
Index: libs/libmyth/settings.h
===================================================================
--- libs/libmyth/settings.h	(revision 12492)
+++ libs/libmyth/settings.h	(working copy)
@@ -1075,13 +1075,17 @@
 
   public:
     ConfigurationPopupDialog() :
-        VerticalConfigurationGroup(), dialog(NULL) { }
+        VerticalConfigurationGroup(), dialog(NULL), label(NULL) { }
 
+    virtual void deleteLater(void);
+
     virtual MythDialog *dialogWidget(
         MythMainWindow *parent, const char* widgetName);
 
     int exec(bool saveOnAccept = true);
 
+    virtual void setLabel(QString str);
+
   public slots:
     void accept(void) { if (dialog) dialog->accept(); }
     void reject(void) { if (dialog) dialog->reject(); }
@@ -1091,10 +1095,11 @@
 
   protected:
     /// You need to call deleteLater to delete QObject
-    virtual ~ConfigurationPopupDialog() { dialog->deleteLater(); }
+    virtual ~ConfigurationPopupDialog() { }
 
   protected:
-    ConfigPopupDialogWidget* dialog;
+    ConfigPopupDialogWidget *dialog;
+    QLabel                  *label;
 };
 
 ///////////////////////////////////////////////////////////////////////////////
Index: libs/libmyth/mythdialogs.h
===================================================================
--- libs/libmyth/mythdialogs.h	(revision 12492)
+++ libs/libmyth/mythdialogs.h	(working copy)
@@ -70,6 +70,8 @@
    
     virtual bool onMediaEvent(MythMediaDevice * mediadevice); 
     
+    void setResult(int r) { rescode = r; }
+
   signals:
     void menuButtonPressed();
 
@@ -82,7 +84,6 @@
     virtual void reject();
 
   protected:
-    void setResult(int r) { rescode = r; }
     void keyPressEvent(QKeyEvent *e);
 
     float wmult, hmult;
@@ -139,6 +140,10 @@
 
     static bool showGetTextPopup(MythMainWindow *parent, QString title,
                                  QString message, QString& text);
+
+    virtual void accept(void);
+    virtual void reject(void);
+
   signals:
     void popupDone();
 
