Index: programs/mythfrontend/playbackbox.cpp
===================================================================
--- programs/mythfrontend/playbackbox.cpp	(revision 6963)
+++ programs/mythfrontend/playbackbox.cpp	(working copy)
@@ -431,7 +431,7 @@
 void PlaybackBox::exitWin()
 {
     killPlayerSafe();
-    accept();
+    reject();
 }
 
 void PlaybackBox::updateBackground(void)
@@ -1572,6 +1572,12 @@
         play(curitem);
 }
 
+void PlaybackBox::selectSelected()
+{
+    killPlayerSafe();
+    accept();
+}
+
 void PlaybackBox::stopSelected()
 {
     state = kStopping;
@@ -1669,6 +1675,7 @@
     {
         case Play: playSelected(); break;
         case Delete: deleteSelected(); break;
+        case Select: selectSelected(); break;
     }
 }
 
Index: programs/mythfrontend/dvdwizardpage.h
===================================================================
--- programs/mythfrontend/dvdwizardpage.h	(revision 0)
+++ programs/mythfrontend/dvdwizardpage.h	(revision 0)
@@ -0,0 +1,202 @@
+#ifndef DVDWIZARDPAGE_H_
+#define DVDWIZARDPAGE_H_
+
+#include <qgroupbox.h>
+#include <qlabel.h>
+#include <qprocess.h>
+#include <qprogressbar.h>
+#include <qvaluevector.h>
+
+#include "programinfo.h"
+#include "mythwidgets.h"
+
+class DVDWizardData
+{
+    public:
+        DVDWizardData();
+
+        ProgramInfo *getProgramInfo(QString &filename);
+
+        /* all these data members should probably be private */
+        enum DVDType { Autoplay = 0, MenuBased = 1 };
+
+        QValueVector<ProgramInfo> recordings;
+        QValueVector<long long> titlesetSize;
+        DVDType dvdtype;
+};
+
+class MythLabel: public QLabel
+{
+    Q_OBJECT
+    public:
+        MythLabel(const QString & text, QWidget * parent,
+                  const char * name = 0, WFlags f = 0);
+};
+
+class DVDWizardPage: public QGroupBox
+{
+    Q_OBJECT
+    public:
+        DVDWizardPage(DVDWizardData *data, QWidget * parent = 0,
+                      const char * name = 0);
+        ~DVDWizardPage();
+
+        DVDWizardPage *nextPage();
+
+        QString heading();
+        void setHeading(const QString &h);
+        
+        virtual void goingBack() { };
+        virtual void entered() { };
+
+    signals:
+        void changeHelpText(QString);
+
+    private:
+        virtual DVDWizardPage *generateNextPage() = 0;
+        virtual bool modified() { return false; };
+
+        DVDWizardPage *next_page;
+        QString m_heading;
+
+    protected:
+        DVDWizardData *m_data;
+};
+
+class DVDWizardPageLast: public DVDWizardPage
+{
+    public:
+        DVDWizardPageLast(DVDWizardData *data);
+        ~DVDWizardPageLast();
+
+    private:
+        DVDWizardPage *generateNextPage() { return NULL; };
+};
+
+class DVDWizardPageBurnDVD: public DVDWizardPage
+{
+    Q_OBJECT
+    public:
+        DVDWizardPageBurnDVD(DVDWizardData *data);
+        ~DVDWizardPageBurnDVD();
+
+        virtual void entered();
+
+    private:
+        DVDWizardPage *generateNextPage() { return NULL; };
+
+        MythLabel *instructions;
+        MythPushButton *burn;
+        QProgressBar *progress;
+        QProcess *p;
+
+    private slots:
+        void readProc();
+        void procExited();
+        void startBurn();
+};
+
+class DVDWizardPageGenerateFS: public DVDWizardPage
+{
+    Q_OBJECT
+    public:
+        DVDWizardPageGenerateFS(DVDWizardData *data);
+        ~DVDWizardPageGenerateFS();
+
+        virtual void goingBack();
+        virtual void entered();
+
+    private:
+        DVDWizardPage *generateNextPage() { return new DVDWizardPageBurnDVD(m_data); };
+
+        MythListBox *output;
+        MythLabel *status;
+        QProgressBar *overall;
+        QProgressBar *task;
+        QProcess *p;
+        QString pOutput;
+        int baseProgress;
+        int dvdSize;
+        int currentTitleset;
+
+    private slots:
+        void readProcDVDAuthor();
+        void readProcMkisofs();
+        void procExited();
+};
+
+class DVDWizardPageGenerateXML: public DVDWizardPage
+{
+    public:
+        DVDWizardPageGenerateXML(DVDWizardData *data);
+
+    private:
+        DVDWizardPage *generateNextPage() { return new DVDWizardPageGenerateFS(m_data); };
+
+        void generateXML();
+};
+
+class DVDWizardPageMainMenu: public DVDWizardPage
+{
+    public:
+        DVDWizardPageMainMenu(DVDWizardData *data);
+
+    private:
+        DVDWizardPage *generateNextPage() { return NULL; };
+
+        MythCheckBox *dvd_main_menu;
+};
+
+class DVDWizardPageAutoPlayDVD: public DVDWizardPage
+{
+    public:
+        DVDWizardPageAutoPlayDVD(DVDWizardData *data);
+
+    private:
+        DVDWizardPage *generateNextPage();
+        bool modified();
+
+        MythComboBox *dvd_type;
+};
+
+class DVDWizardPageSelectRecordings: public DVDWizardPage
+{
+    Q_OBJECT
+    public:
+        DVDWizardPageSelectRecordings(DVDWizardData *data);
+        ~DVDWizardPageSelectRecordings();
+
+        virtual void entered();
+
+    private:
+        DVDWizardPage *generateNextPage() { return new DVDWizardPageAutoPlayDVD(m_data); };
+        bool modified() { return dataChanged; };
+        void adjustSize(long long delta);
+
+        MythListBox *rec;
+        MythPushButton *add;
+        MythPushButton *remove;
+        MythLabel *sldvd;
+        MythLabel *dldvd;
+
+        bool dataChanged;
+        int dvdSize;
+
+    protected:
+        bool eventFilter(QObject *obj, QEvent *e);
+
+    private slots:
+        void addRecording();
+        void removeRecording();
+};
+
+class DVDWizardPageIntro: public DVDWizardPage
+{
+    public:
+        DVDWizardPageIntro(DVDWizardData *data);
+
+    private:
+        DVDWizardPage *generateNextPage() { return new DVDWizardPageSelectRecordings(m_data); };
+};
+
+#endif
Index: programs/mythfrontend/dvdwizard.h
===================================================================
--- programs/mythfrontend/dvdwizard.h	(revision 0)
+++ programs/mythfrontend/dvdwizard.h	(revision 0)
@@ -0,0 +1,25 @@
+#ifndef DVDWIZARD_H_
+#define DVDWIZARD_H_
+
+#include "mythwizard.h"
+
+#include "dvdwizardpage.h"
+
+class DVDWizard: virtual public MythWizard
+{
+    Q_OBJECT
+    public:
+        DVDWizard(MythMainWindow* parent, const char* name = 0);
+
+    private:
+        QWidget *findNext();
+        virtual void showPage(QWidget *page);
+
+        DVDWizardData wizardData;
+
+    public slots:
+        void next();
+        void back();
+};
+
+#endif
Index: programs/mythfrontend/globalsettings.cpp
===================================================================
--- programs/mythfrontend/globalsettings.cpp	(revision 6963)
+++ programs/mythfrontend/globalsettings.cpp	(working copy)
@@ -2244,6 +2244,35 @@
     };
 };
 
+static HostLineEdit *DVDWizardDir()
+{
+    HostLineEdit *l = new HostLineEdit("DVDWizardDir");
+    l->setLabel(QObject::tr("Scratch Dir"));
+    l->setValue("");
+    l->setHelpText(QObject::tr("This directory will be used to store temporary "
+                   "files when generating DVDs."));
+    return l;
+}
+
+static HostComboBox *DVDWizardDevice()
+{
+    HostComboBox *gc = new HostComboBox("DVDDevice", true);
+    gc->setLabel(QObject::tr("DVD-Writer device"));
+
+    QDir dev("/dev", "cdrom*", QDir::Name, QDir::System);
+    gc->fillSelectionsFromDir(dev);
+    dev.setNameFilter("scd*");
+    gc->fillSelectionsFromDir(dev);
+    dev.setNameFilter("hd*");
+    gc->fillSelectionsFromDir(dev);
+    dev.setNameFilter("cdrom*");
+    dev.setPath("/dev/cdroms");
+    gc->fillSelectionsFromDir(dev);
+
+    gc->setHelpText(QObject::tr("DVD Writer device used for burning DVDs."));
+    return gc;
+}
+
 static GlobalCheckBox *LogEnabled()
 {
     GlobalCheckBox *bc = new GlobalCheckBox("LogEnabled");
@@ -2888,6 +2917,12 @@
 
     MythFillSettings *mythfill = new MythFillSettings();
     addChild(mythfill);
+
+    VerticalConfigurationGroup* dvdwizard = new VerticalConfigurationGroup(false);
+    dvdwizard->setLabel(QObject::tr("DVD Wizard"));
+    dvdwizard->addChild(DVDWizardDir());
+    dvdwizard->addChild(DVDWizardDevice());
+    addChild(dvdwizard);
 }
 
 PlaybackSettings::PlaybackSettings()
Index: programs/mythfrontend/main.cpp
===================================================================
--- programs/mythfrontend/main.cpp	(revision 6963)
+++ programs/mythfrontend/main.cpp	(working copy)
@@ -27,6 +27,7 @@
 #include "channelrecpriority.h"
 #include "globalsettings.h"
 #include "profilegroup.h"
+#include "dvdwizard.h"
 
 #include "exitcodes.h"
 #include "themedmenu.h"
@@ -211,6 +212,15 @@
     qApp->lock();
 }
 
+void startDVDWizard(void)
+{
+    DVDWizard wizard(gContext->GetMainWindow(), "dvd wizard");
+
+    qApp->unlock();
+    wizard.exec();
+    qApp->lock();
+}
+
 void startCustomRecord(void)
 {
     CustomRecord custom(gContext->GetMainWindow(), "custom record");
@@ -406,6 +416,8 @@
         startSearchTime();
     else if (sel == "tv_previous")
         startPrevious();
+    else if (sel == "tv_dvd_wizard")
+        startDVDWizard();
     else if (sel == "settings appearance") 
     {
         AppearanceSettings settings;
Index: programs/mythfrontend/mainmenu.xml
===================================================================
--- programs/mythfrontend/mainmenu.xml	(revision 6963)
+++ programs/mythfrontend/mainmenu.xml	(working copy)
@@ -96,7 +96,6 @@
      <text lang="ET">DVD ja CD</text>
      <text lang="NB">CD-/DVD-stasjoner</text>
      <action>MENU optical_menu.xml</action>
-     <depends>mythmusic mythdvd</depends>
    </button>
     
    
Index: programs/mythfrontend/dvdwizardpage.cpp
===================================================================
--- programs/mythfrontend/dvdwizardpage.cpp	(revision 0)
+++ programs/mythfrontend/dvdwizardpage.cpp	(revision 0)
@@ -0,0 +1,777 @@
+#include <qlayout.h>
+#include <qhbox.h>
+#include <qvbox.h>
+
+#include "mythcontext.h"
+#include "mythwizard.h"
+
+#include "dvdwizardpage.h"
+#include "playbackbox.h"
+
+DVDWizardData::DVDWizardData()
+{
+    recordings.clear();
+    dvdtype = Autoplay;
+}
+
+ProgramInfo *DVDWizardData::getProgramInfo(QString &filename)
+{
+    /* iterate over all selected recordings */
+    QValueVector<ProgramInfo>::iterator it;
+    for (it = recordings.begin(); it != recordings.end(); it++)
+    {
+        if ((*it).GetRecordFilename(gContext->GetFilePrefix()) == filename)
+            return &(*it);
+    }
+
+    return NULL;
+}
+
+DVDWizardPage::DVDWizardPage(DVDWizardData *data, QWidget * parent,
+                             const char * name) : QGroupBox(parent, name)
+{
+    setHeading(QObject::tr("DVD Authoring Wizard"));
+    setBackgroundOrigin(QWidget::WindowOrigin);
+
+    float wmult = 0, hmult = 0;
+    gContext->GetScreenSettings(wmult, hmult);
+
+    new QVBoxLayout(this, (int)(10 * hmult));
+
+    m_data = data;
+
+    next_page = NULL;
+}
+
+DVDWizardPage::~DVDWizardPage()
+{
+    if (next_page) delete next_page;
+}
+
+QString DVDWizardPage::heading()
+{
+    return m_heading;
+}
+
+void DVDWizardPage::setHeading(const QString &h)
+{
+    m_heading = h;
+}
+
+DVDWizardPage *DVDWizardPage::nextPage()
+{
+    if (modified() || !next_page)
+    {
+        if (next_page) delete next_page;
+        next_page = generateNextPage();
+    }
+
+    return next_page;
+}
+
+DVDWizardPageIntro::DVDWizardPageIntro(DVDWizardData *data)
+    : DVDWizardPage(data, NULL, "intro")
+{
+    MythLabel *intro = new MythLabel(QObject::tr("This wizard will walk you "
+                                     "through the steps of creating a DVD from "
+                                     "recordings. The recordings must be in a "
+                                     "DVD compliant MPEG2 format with NAV "
+                                     "packets. The MPEG2 profile of the "
+                                     "mythtranscode program generates compliant "
+                                     "files."), this);
+    layout()->add(intro);
+
+    if (gContext->GetSetting("DVDWizardDir").isEmpty())
+    {
+        MythLabel *warn = new MythLabel(QObject::tr("WARNING: You have not set "
+                                        "the scratch directory for creating "
+                                        "DVDs. Go to Setup->General->DVD Wizard "
+                                        "and set the directory. If you continue "
+                                        "the files and directories (dvd_dir, "
+                                        "dvd.xml, dvd.iso will be created and "
+                                        "subsequently deleted in the current "
+                                        "working directory. This may "
+                                        "inadvertently result in data loss."),
+                                        this);
+        layout()->add(warn);
+    }
+}
+
+DVDWizardPageSelectRecordings::DVDWizardPageSelectRecordings(DVDWizardData *data)
+    : DVDWizardPage(data, NULL, "selrec")
+{
+    setHeading(QObject::tr("Select Recordings"));
+    MythLabel *intro = new MythLabel(QObject::tr("Select all the recordings "
+                                     "that you want on the DVD. The indicators "
+                                     "at the bottom of the screen show an "
+                                     "estimate of the amount of space used on "
+                                     "the DVD. The selected recordings should "
+                                     "be in DVD compliant MPEG2 format."), this);
+    layout()->add(intro);
+
+    QHBox *hbox = new QHBox(this);
+    hbox->setSpacing(layout()->spacing());
+    hbox->setBackgroundOrigin(QWidget::WindowOrigin);
+    
+    rec = new MythListBox(hbox);
+    rec->setFocusPolicy(QWidget::NoFocus);
+    rec->setBackgroundOrigin(QWidget::WindowOrigin);
+    rec->setHelpText(QObject::tr("Select a recording to remove from the list."));
+
+    QVBox *vbox = new QVBox(hbox);
+    vbox->setBackgroundOrigin(QWidget::WindowOrigin);
+
+    add = new MythPushButton(QObject::tr("Add"), vbox);
+    add->setBackgroundOrigin(QWidget::WindowOrigin);
+    add->setHelpText(QObject::tr("Add a recording to the list."));
+    remove = new MythPushButton(QObject::tr("Remove"), vbox);
+    remove->setBackgroundOrigin(QWidget::WindowOrigin);
+    remove->setHelpText(QObject::tr("Remove a recording from the list."));
+
+    layout()->add(hbox);
+
+    connect(rec, SIGNAL(changeHelpText(QString)), this, SIGNAL(changeHelpText(QString)));
+    connect(add, SIGNAL(changeHelpText(QString)), this, SIGNAL(changeHelpText(QString)));
+    connect(remove, SIGNAL(changeHelpText(QString)), this, SIGNAL(changeHelpText(QString)));
+
+    connect(add, SIGNAL(clicked()), this, SLOT(addRecording()));
+    connect(remove, SIGNAL(clicked()), this, SLOT(removeRecording()));
+    rec->installEventFilter(this);
+
+    dvdSize = 0;
+    sldvd = new MythLabel("", this);
+    layout()->add(sldvd);
+    dldvd = new MythLabel("", this);
+    layout()->add(dldvd);
+    adjustSize(0);
+}
+
+DVDWizardPageSelectRecordings::~DVDWizardPageSelectRecordings()
+{
+    rec->removeEventFilter(this);
+}
+
+void DVDWizardPageSelectRecordings::entered()
+{
+    if (m_data->recordings.count() == 0)
+    {
+        MythWizard *w = dynamic_cast<MythWizard *>(parent()->parent());
+        if (w)
+            w->setNextEnabled(this, false);
+    }
+}
+
+void DVDWizardPageSelectRecordings::adjustSize(long long delta)
+{
+    dvdSize += delta;
+    
+    sldvd->setText(QObject::tr("%1 of 4700MB (%2%) used on Single Layer disc")
+                   .arg(dvdSize/(1024*1024)).arg(dvdSize/47000000LL));
+    dldvd->setText(QObject::tr("%1 of 9400MB (%2%) used on Dual Layer disc")
+                   .arg(dvdSize/(1024*1024)).arg(dvdSize/94000000LL));
+}
+
+void DVDWizardPageSelectRecordings::addRecording()
+{
+    PlaybackBox pbb(PlaybackBox::Select, gContext->GetMainWindow(),
+                    "tvplayselect");
+
+    if (pbb.exec() == QDialog::Accepted)
+    {
+        adjustSize(pbb.getSelected().filesize);
+        m_data->recordings.append(pbb.getSelected());
+        rec->insertItem(m_data->recordings.last().title + " " +
+                        m_data->recordings.last().subtitle);
+        dataChanged = true;
+
+        MythWizard *w = dynamic_cast<MythWizard *>(parent()->parent());
+        if (w)
+            w->setNextEnabled(this, true);
+    }
+    /* this doesn't seem to work */
+    add->setFocus();
+}
+
+void DVDWizardPageSelectRecordings::removeRecording()
+{
+    rec->setFocusPolicy(QWidget::WheelFocus);
+    rec->setFocus();
+}
+
+bool DVDWizardPageSelectRecordings::eventFilter(QObject *obj, QEvent *e)
+{
+    bool handled = false;
+    QStringList actions;
+    if ((e->type() == QEvent::KeyPress) && (obj == rec))
+    {
+        if (gContext->GetMainWindow()->TranslateKeyPress("qt", (QKeyEvent *)e, actions))
+        {
+            for (unsigned int i = 0; i < actions.size() && !handled; i++)
+            {
+                QString action = actions[i];
+                handled = true;
+                
+                if (action == "SELECT")
+                {
+                    adjustSize(-m_data->recordings[rec->currentItem()].filesize);
+                    m_data->recordings.erase(m_data->recordings.begin() + rec->currentItem());
+                    rec->removeItem(rec->currentItem());
+                    rec->setFocusPolicy(QWidget::NoFocus);
+                    remove->setFocus();
+                    dataChanged = true;
+
+                    if (m_data->recordings.count() == 0)
+                    {
+                        MythWizard *w = dynamic_cast<MythWizard *>(parent()->parent());
+                        if (w)
+                            w->setNextEnabled(this, false);
+                    }
+                }
+                else if (action == "ESCAPE")
+                {
+                    rec->setFocusPolicy(QWidget::NoFocus);
+                    remove->setFocus();
+                }
+                else
+                    handled = false;
+            }
+        }
+    }
+    return handled;
+}
+
+DVDWizardPageAutoPlayDVD::DVDWizardPageAutoPlayDVD(DVDWizardData *data) : DVDWizardPage(data, NULL, "autoplay")
+{
+    setHeading(QObject::tr("Autoplay DVD"));
+
+    MythLabel *text = new MythLabel(QObject::tr("Would you like to create an "
+                                    "autoplay DVD. Autoplay DVDs do not have "
+                                    "menus and will start to play automatically "                                    "when inserted into the DVD Player. This "
+                                    "option is good for movies and discs which "
+                                    "will be used by children. If you selected "
+                                    "multiple recordings they will play back to "
+                                    "back."), this);
+    layout()->add(text);
+
+    QHBox *hbox = new QHBox(this);
+    hbox->setBackgroundOrigin(QWidget::WindowOrigin);
+    hbox->setSpacing(layout()->spacing());
+    
+    new MythLabel(QObject::tr("What type of DVD do you want to create?"), hbox);
+    dvd_type = new MythComboBox(false, hbox);
+    dvd_type->setBackgroundOrigin(QWidget::WindowOrigin);
+    dvd_type->insertItem(QObject::tr("Autoplay DVD"));
+    dvd_type->insertItem(QObject::tr("Menu based DVD"));
+    dvd_type->setHelpText(QObject::tr("Select the type of DVD to create."));
+    layout()->add(hbox);
+
+    connect(dvd_type, SIGNAL(changeHelpText(QString)), this, SIGNAL(changeHelpText(QString)));
+}
+
+DVDWizardPage *DVDWizardPageAutoPlayDVD::generateNextPage()
+{
+    m_data->dvdtype = (DVDWizardData::DVDType)dvd_type->currentItem();
+
+    if (m_data->dvdtype == DVDWizardData::Autoplay) // Autoplay DVD
+    {
+        return new DVDWizardPageGenerateXML(m_data);
+    }
+    else if (m_data->dvdtype == DVDWizardData::MenuBased) // Menu based DVD
+    {
+        return NULL;
+    }
+    else
+        return NULL;
+}
+
+bool DVDWizardPageAutoPlayDVD::modified()
+{
+    return (m_data->dvdtype != dvd_type->currentItem());
+}
+
+DVDWizardPageGenerateXML::DVDWizardPageGenerateXML(DVDWizardData *data) : DVDWizardPage(data, NULL, "generate xml")
+{
+    generateXML();
+
+    MythLabel *text = new MythLabel(QObject::tr("The DVD structure has been "
+                                    "defined. Select next to generate the DVD "
+                                    "filesystem."), this);
+    layout()->add(text);
+}
+
+void DVDWizardPageGenerateXML::generateXML()
+{
+    QDomDocument doc;
+    QDomElement root = doc.createElement("dvdauthor");
+    root.setAttribute("dest", "dvd_dir");
+    doc.appendChild(root);
+
+    if (m_data->dvdtype == DVDWizardData::Autoplay)
+    {
+        /* empty menu */
+        root.appendChild(doc.createElement("vmgm"));
+
+        QDomElement titleset = doc.createElement("titleset");
+        root.appendChild(titleset);
+
+        QDomElement titles = doc.createElement("titles");
+        titleset.appendChild(titles);
+
+        m_data->titlesetSize.resize(1, 0);
+        m_data->titlesetSize[0] = 0;
+
+        /* iterate over all selected recordings */
+        int titleCount = 1;
+        QValueVector<ProgramInfo>::iterator it = m_data->recordings.begin();
+        while (it != m_data->recordings.end())
+        {
+            QDomElement pgc = doc.createElement("pgc");
+            titles.appendChild(pgc);
+
+            QDomElement vob = doc.createElement("vob");
+            vob.setAttribute("file", (*it).GetRecordFilename(gContext->GetFilePrefix()).ascii());
+            pgc.appendChild(vob);
+
+            m_data->titlesetSize[0] += (*it).filesize;
+
+            it++;
+            titleCount++;
+
+            /* add a jump to the next title */
+            QDomElement post = doc.createElement("post");
+            pgc.appendChild(post);
+            if (it != m_data->recordings.end())
+                post.appendChild(doc.createTextNode("jump title " + QString::number(titleCount) + " chapter 1;"));
+            else
+                post.appendChild(doc.createTextNode("exit;"));
+        
+        }
+    }
+    else
+    {
+        cerr << "Not yet defined\n";
+    }
+
+    cout << doc.toString().ascii() << endl;
+
+    /* Output XML file for dvdauthor */
+    QFile file(gContext->GetSetting("DVDWizardDir").append("/dvd.xml"));
+    if (file.open(IO_WriteOnly))
+    {
+        QTextStream stream(&file);
+        stream << doc.toString();
+        file.close();
+    }
+}
+
+DVDWizardPageGenerateFS::DVDWizardPageGenerateFS(DVDWizardData *data)
+    : DVDWizardPage(data, NULL, "generate fs")
+{
+    MythLabel *text = new MythLabel(QObject::tr("Generating the DVD filesystem."), this);
+    layout()->add(text);
+
+    output = new MythListBox(this);
+    output->setFocusPolicy(QWidget::NoFocus);
+    output->setBackgroundOrigin(QWidget::WindowOrigin);
+    layout()->add(output);
+
+    status = new MythLabel(QObject::tr("Executing dvdauthor..."), this);
+    layout()->add(status);
+
+    task = new QProgressBar(100, this);
+    task->setBackgroundOrigin(QWidget::WindowOrigin);
+    layout()->add(task);
+
+    QHBox *hbox = new QHBox(this);
+    hbox->setBackgroundOrigin(QWidget::WindowOrigin);
+    hbox->setSpacing(layout()->spacing());
+
+    text = new MythLabel(QObject::tr("Overall progress"), hbox);
+    overall = new QProgressBar(0, hbox);
+    overall->setBackgroundOrigin(QWidget::WindowOrigin);
+    layout()->add(hbox);
+
+    p = NULL;
+}
+
+DVDWizardPageGenerateFS::~DVDWizardPageGenerateFS()
+{
+    if (p)
+        p->kill();
+}
+
+void DVDWizardPageGenerateFS::goingBack()
+{
+    if (p)
+    {
+        if (p->isRunning())
+            p->tryTerminate();
+    }
+    task->reset();
+    overall->reset();
+}
+
+void DVDWizardPageGenerateFS::entered()
+{
+    if (p)
+        cerr << "This shouldn't be\n";
+
+    /* disable next button */
+    MythWizard *w = dynamic_cast<MythWizard *>(parent()->parent());
+    if (w)
+        w->setNextEnabled(this, false);
+        
+    /* clear list box */
+    output->clear();
+
+    /* make sure that dvd_dir is not there */
+    QString command = QString("rm -rf ") + gContext->GetSetting("DVDWizardDir") + QString("/dvd_dir");
+    myth_system(command);
+
+    /* calculate the estimated size of the DVD */
+    /* iterate over all selected recordings */
+    dvdSize = 0;
+    QValueVector<long long>::iterator it;
+    for (it = m_data->titlesetSize.begin(); it != m_data->titlesetSize.end(); it++)
+    {
+        dvdSize += ((*it) / (1024*1024));
+    }
+
+    /* calculate the total progress */
+    /* value is in megabytes of data processed */
+    // currently counts
+    //  - dvdauthor VOBU
+    //  - dvdauthor fixing (NAV packets)
+    //  - mkisofs
+    overall->setProgress(-1, 3*dvdSize);
+
+    /* base Progress */
+    /* overall progress = baseProgress + task progress */
+    baseProgress = 0;
+
+    /* start the dvdauthor process */
+    p = new QProcess(QString("dvdauthor"), this);
+    p->setCommunication(QProcess::Stderr);
+    p->setWorkingDirectory(gContext->GetSetting("DVDWizardDir"));
+    p->addArgument("-x");
+    p->addArgument("dvd.xml");
+
+    connect(p, SIGNAL(readyReadStderr()), this, SLOT(readProcDVDAuthor()));
+    connect(p, SIGNAL(processExited()), this, SLOT(procExited()));
+
+    p->start();
+}
+
+void DVDWizardPageGenerateFS::readProcDVDAuthor()
+{
+    int index;
+
+    pOutput.append(p->readStderr());
+
+    QRegExp sep("[\r\n]");
+
+    index = pOutput.find(sep);
+    while (index != -1)
+    {
+        QString s = pOutput.left(index);
+        pOutput.remove(0, index+1);
+
+        if (s.startsWith("STAT: "))
+        {
+            s.remove(0, 6);
+
+            if (s.startsWith("Picking VTS "))
+            {
+               s.remove(0, 12);
+               currentTitleset = s.toInt();
+               status->setText(QObject::tr("Generating Titleset %1")
+                               .arg(currentTitleset));
+               task->setProgress(0, 2*m_data->titlesetSize[currentTitleset-1] / (1024*1024));
+            }
+/*            else if (s.startsWith("Processing "))
+            {
+            }*/
+            else if (s.startsWith("VOBU "))
+            {
+                int taskProgress = s.section(' ', 3, 3).remove("MB,").toInt();
+                task->setProgress(taskProgress);
+                overall->setProgress(baseProgress + taskProgress);
+            }
+            else if (s.startsWith("fixing VOBU at "))
+            {
+                int taskProgress = s.section(' ', 3, 3).remove("MB").toInt() + task->totalSteps()/2;
+                task->setProgress(taskProgress);
+                overall->setProgress(baseProgress + taskProgress);
+            }
+            else if (s.startsWith("fixed "))
+            {
+                task->setProgress(task->totalSteps());
+                baseProgress += task->totalSteps();
+                overall->setProgress(baseProgress);
+            }
+            else
+            {
+                cerr << s.ascii() << endl;
+                output->insertItem(s);
+            }
+        }
+        else if (s.startsWith("ERR: "))
+        {
+            s.remove(0, 5);
+            status->setText(s);
+        }
+        
+        index = pOutput.find(sep);
+    }
+}
+
+void DVDWizardPageGenerateFS::readProcMkisofs()
+{
+    while (p->canReadLineStderr())
+    {
+        QString s = p->readLineStderr();
+
+        QRegExp rxp("\\d{0,1}\\d{0,1}\\d\\.\\d\\d%");
+        if (s.contains(rxp))
+        {
+            s = s.section(' ', 1, 1);
+
+            if (s.endsWith("%"))
+            {
+                float percent = s.left(s.length()-1).toFloat();
+                int taskProgress = (int)(percent * dvdSize / 100);
+                task->setProgress(taskProgress);
+                overall->setProgress(baseProgress + taskProgress);
+            }
+        }
+        else if (s.contains("extents written"))
+        {
+            task->setProgress(task->totalSteps());
+            baseProgress += task->totalSteps();
+            overall->setProgress(baseProgress);
+        }
+        else
+        {
+            cerr << "Got line \"" << s.ascii() << '"' << endl;
+            output->insertItem(s);
+        }
+    }
+}
+
+void DVDWizardPageGenerateFS::procExited()
+{
+    if (p->normalExit())
+    {
+        QString progname = p->arguments()[0];
+
+        if (progname == "dvdauthor")
+        {
+            if (p->exitStatus() == 0)
+            {
+                /* dvdauthor finished, start mkisofs */
+
+                p->deleteLater();
+
+                p = new QProcess(QString("mkisofs"), this);
+                p->setCommunication(QProcess::Stderr);
+                p->setWorkingDirectory(gContext->GetSetting("DVDWizardDir"));
+                p->addArgument("-dvd-video");
+                p->addArgument("-o");
+                p->addArgument("dvd.iso");
+                p->addArgument("dvd_dir");
+
+                connect(p, SIGNAL(readyReadStderr()), this, SLOT(readProcMkisofs()));
+                connect(p, SIGNAL(processExited()), this, SLOT(procExited()));
+
+                p->start();
+
+                status->setText(QObject::tr("Generating iso image..."));
+                task->setProgress(0, dvdSize);
+            }
+            else
+            {
+                /* dvdauthor failed */
+                cerr << "dvdauthor exited with " << p->exitStatus() << endl;
+
+                p->deleteLater();
+                p = NULL;
+            }
+        }
+        else if (progname == "mkisofs")
+        {
+            if (p->exitStatus() == 0)
+            {
+                //readProcMkisofs();
+                task->reset();
+                status->setText(QObject::tr("DVD finished generating. Select 'Next' "
+                                "to continue"));
+
+                p->deleteLater();
+                p = NULL;
+
+                /* delete dvd_dir */
+                QString command = QString("rm -rf ") + gContext->GetSetting("DVDWizardDir") + QString("/dvd_dir");
+                myth_system(command);
+
+                /* enable next button */
+                MythWizard *w = dynamic_cast<MythWizard *>(parent()->parent());
+                if (w)
+                {
+                    w->setNextEnabled(this, true);
+                    w->nextButton()->setFocus();
+                }
+            }
+            else
+            {
+                /* mkisofs failed */
+                cerr << "mkisofs exited with " << p->exitStatus() << endl;
+
+                p->deleteLater();
+                p = NULL;
+            }
+        }
+        else
+        {
+            cerr << "Program " << progname.ascii() << " exited normally.\n";
+
+            p->deleteLater();
+            p = NULL;
+        }
+    }
+    else
+    {
+        status->setText(QObject::tr("Child process exit error, check stderr."));
+        cerr << "Program: " << p->arguments().join(" ").ascii() << endl;
+        cerr << "Exit code: " << p->exitStatus() << endl;
+
+        p->deleteLater();
+        p = NULL;
+    }
+}
+
+DVDWizardPageBurnDVD::DVDWizardPageBurnDVD(DVDWizardData *data) : DVDWizardPage(data, NULL, "burn")
+{
+    MythLabel *text = new MythLabel(QObject::tr("Burning the DVD."), this);
+    layout()->add(text);
+
+    instructions = new MythLabel(QObject::tr("Ensure that a blank DVD is the "
+                                 "DVD burner and select 'Burn' to start burning "
+                                 "the image to disc."), this);
+
+    layout()->add(instructions);
+
+    progress = new QProgressBar(100, this);
+    progress->setBackgroundOrigin(QWidget::WindowOrigin);
+    layout()->add(progress);
+
+    burn = new MythPushButton("Burn", this);
+    layout()->add(burn);
+
+    connect(burn, SIGNAL(clicked()), this, SLOT(startBurn()));
+
+    p = NULL;
+}
+
+DVDWizardPageBurnDVD::~DVDWizardPageBurnDVD()
+{
+    if (p)
+        p->kill();
+}
+
+void DVDWizardPageBurnDVD::entered()
+{
+    progress->reset();
+}
+
+void DVDWizardPageBurnDVD::readProc()
+{
+    while (p->canReadLineStderr())
+    {
+        QString s = p->readLineStderr();
+
+        QRegExp rxp("\\d{0,1}\\d{0,1}\\d\\.\\d%");
+        if (s.contains(rxp))
+        {
+            s.remove(0, s.find(rxp));
+            s = s.left(s.find('%'));
+
+            progress->setProgress((int)s.toFloat());
+        }
+        else
+            cerr << s.ascii() << endl;
+    }
+}
+
+void DVDWizardPageBurnDVD::procExited()
+{
+    if (p->normalExit() && (p->exitStatus() == 0))
+    {
+        burn->setEnabled(true);
+        burn->setFocus();
+        
+        instructions->setText(QObject::tr("Burn completed sucessfully. Insert a "
+                              "new DVD and select 'Burn' to burn another, "
+                              "otherwise select 'Next' to continue."));
+
+        p->deleteLater();
+        p = NULL;
+    }
+    else
+    {
+        burn->setEnabled(true);
+        burn->setFocus();
+
+        instructions->setText(QObject::tr("Burn failed. Insert a new DVD and "
+                              "select 'Burn' to try again, otherwise select "
+                              "'Next' to continue."));
+
+        p->deleteLater();
+        p = NULL;
+    }
+}
+
+void DVDWizardPageBurnDVD::startBurn()
+{
+    burn->setDisabled(true);
+
+    /* reset progress bar */
+    progress->setProgress(0);
+    
+    p = new QProcess(QString("growisofs"), this);
+    p->setCommunication(QProcess::Stderr);
+    p->setWorkingDirectory(gContext->GetSetting("DVDWizardDir"));
+    p->addArgument("-dvd-compat");
+    p->addArgument("-Z");
+    p->addArgument(gContext->GetSetting("DVDDevice") + QString("dvd.iso"));
+    connect(p, SIGNAL(readyReadStderr()), this, SLOT(readProc()));
+    connect(p, SIGNAL(processExited()), this, SLOT(procExited()));
+
+    p->start();
+}
+
+DVDWizardPageLast::DVDWizardPageLast(DVDWizardData *data)
+    : DVDWizardPage(data, NULL, "last")
+{
+    MythLabel *text = new MythLabel(QObject::tr("Congratulations the DVD has "
+                                    "now been sucessfully authored."), this);
+    layout()->add(text);
+}
+
+DVDWizardPageLast::~DVDWizardPageLast()
+{
+    /* clean up temp files */
+    /* this deletes everything in the gContext->GetSetting("DVDWizardDir") directory */
+
+    QString command = QString("rm -rf ") + gContext->GetSetting("DVDWizardDir");
+    myth_system(command + QString("/dvd_dir"));
+    myth_system(command + QString("/dvd.xml"));
+    myth_system(command + QString("/dvd.iso"));
+}
+
+MythLabel::MythLabel(const QString & text, QWidget * parent, const char * name, WFlags f)
+            : QLabel(text, parent, name, f)
+{
+    setBackgroundOrigin(QWidget::WindowOrigin);
+    setAlignment(Qt::WordBreak | Qt::AlignLeft | Qt::AlignTop);
+}
+
Index: programs/mythfrontend/dvdwizard.cpp
===================================================================
--- programs/mythfrontend/dvdwizard.cpp	(revision 0)
+++ programs/mythfrontend/dvdwizard.cpp	(revision 0)
@@ -0,0 +1,58 @@
+#include "dvdwizard.h"
+
+DVDWizard::DVDWizard(MythMainWindow* parent, const char* name) : MythWizard(parent, name)
+{
+    /* Page 1 - Introduction */
+    DVDWizardPage *page1 = new DVDWizardPageIntro(&wizardData);
+    addPage(page1, page1->heading());
+    connect(page1, SIGNAL(changeHelpText(QString)), this, SLOT(setHelpText(QString)));
+
+    /* Page Last - Finish */
+    /* need to add this to prevent Finish button from appearing */
+    DVDWizardPage *pageX = new DVDWizardPageLast(&wizardData);
+    addPage(pageX, pageX->heading());
+    setBackEnabled(pageX, true);
+    connect(pageX, SIGNAL(changeHelpText(QString)), this, SLOT(setHelpText(QString)));
+
+    /* disconnect next signals */
+    disconnect( nextButton(), SIGNAL(clicked()), this, SLOT(next()) );
+
+    /* reconnect to regeneration methods */
+    connect( nextButton(), SIGNAL(clicked()), this, SLOT(next()) );
+}
+
+void DVDWizard::next()
+{
+    DVDWizardPage *npage = dynamic_cast<DVDWizardPage *>(currentPage())->nextPage();
+
+    if (npage && indexOf(npage) == -1)
+    {
+        /* new page - add it to the stack */
+        insertPage(npage, npage->heading(), indexOf(currentPage())+1);
+        setBackEnabled(npage, true);
+        connect(npage, SIGNAL(changeHelpText(QString)), this, SLOT(setHelpText(QString)));
+    }
+    
+    if (npage)
+        showPage(npage);
+    else
+        showPage(page(pageCount()-1));
+}
+
+void DVDWizard::back()
+{
+    DVDWizardPage *dp = dynamic_cast<DVDWizardPage *>(currentPage());
+    if (dp)
+        dp->goingBack();
+
+    MythWizard::back();
+}
+
+void DVDWizard::showPage(QWidget *page)
+{
+    MythWizard::showPage(page);
+
+    DVDWizardPage *dp = dynamic_cast<DVDWizardPage *>(page);
+    if (dp)
+        dp->entered();
+}
Index: programs/mythfrontend/mythfrontend.pro
===================================================================
--- programs/mythfrontend/mythfrontend.pro	(revision 6963)
+++ programs/mythfrontend/mythfrontend.pro	(working copy)
@@ -45,11 +45,13 @@
 HEADERS += manualbox.h playbackbox.h viewscheduled.h globalsettings.h
 HEADERS += manualschedule.h programrecpriority.h channelrecpriority.h
 HEADERS += statusbox.h previousbox.h customrecord.h
+HEADERS += dvdwizard.h dvdwizardpage.h
 
 SOURCES += main.cpp manualbox.cpp playbackbox.cpp viewscheduled.cpp
 SOURCES += globalsettings.cpp manualschedule.cpp programrecpriority.cpp 
 SOURCES += channelrecpriority.cpp statusbox.cpp previousbox.cpp
 SOURCES += customrecord.cpp
+SOURCES += dvdwizard.cpp dvdwizardpage.cpp
 
 macx {
     RC_FILE += mythfrontend.icns
Index: programs/mythfrontend/playbackbox.h
===================================================================
--- programs/mythfrontend/playbackbox.h	(revision 6963)
+++ programs/mythfrontend/playbackbox.h	(working copy)
@@ -26,7 +26,7 @@
 {
     Q_OBJECT
   public:
-    typedef enum { Play, Delete } BoxType;
+    typedef enum { Play, Delete, Select } BoxType;
     typedef enum { TitlesOnly, TitlesCategories, TitlesCategoriesRecGroups,
                    TitlesRecGroups, Categories, CategoriesRecGroups, RecGroups} ViewType;
 
@@ -35,6 +35,8 @@
    ~PlaybackBox(void);
    
     void customEvent(QCustomEvent *e);
+
+    ProgramInfo getSelected() { return *curitem; };
   
   protected slots:
     void timeout(void);
@@ -64,6 +66,8 @@
     void showPlaylistPopup();
     void showPlaylistJobPopup();
 
+    void selectSelected();
+
     void doPlay();
     void doPlayFromBeg();
     void doPlayListRandom();
Index: programs/mythfrontend/optical_menu.xml
===================================================================
--- programs/mythfrontend/optical_menu.xml	(revision 6963)
+++ programs/mythfrontend/optical_menu.xml	(working copy)
@@ -1,6 +1,12 @@
 <mythmenu name="OPTICAL_DISK">
 
    <button>
+      <type>DVD_WIZARD</type>
+      <text>Author DVD</text>
+      <action>TV_DVD_WIZARD</action>
+   </button>
+
+   <button>
       <type>DVD_PLAY</type>
       <text>Play DVD</text>
       <text lang="DK">Afspil DVD</text>
