Ticket #158: dvdwizard.patch

File dvdwizard.patch, 39.1 KB (added by Aaron McCarthy <mccarthy.aaron@…>, 15 years ago)

DVD Authoring Wizard

  • mythtv/programs/mythfrontend/dvdwizard.cpp

    diff -urNad mythtv/programs/mythfrontend/dvdwizard.cpp /tmp/dpep.aoKJsg/mythtv/programs/mythfrontend/dvdwizard.cpp
    old new  
     1#include "dvdwizard.h"
     2#include "dvdwizardpage.h"
     3#include "mythcontext.h"
     4
     5DVDWizard::DVDWizard(MythMainWindow* parent, const char* name) : MythWizard(parent, name)
     6{
     7    /* Page 1 - Introduction */
     8    DVDWizardPage *page1 = new DVDWizardPageIntro(&wizardData);
     9    addPage(page1, page1->heading());
     10    connect(page1, SIGNAL(changeHelpText(QString)), this, SLOT(setHelpText(QString)));
     11
     12    /* Page Last - Finish */
     13    /* need to add this to prevent Finish button from appearing */
     14    DVDWizardPage *pageX = new DVDWizardPageLast(&wizardData);
     15    addPage(pageX, pageX->heading());
     16    setBackEnabled(pageX, true);
     17    connect(pageX, SIGNAL(changeHelpText(QString)), this, SLOT(setHelpText(QString)));
     18
     19    /* disconnect next signals */
     20    disconnect( nextButton(), SIGNAL(clicked()), this, SLOT(next()) );
     21
     22    /* reconnect to regeneration methods */
     23    connect( nextButton(), SIGNAL(clicked()), this, SLOT(next()) );
     24}
     25
     26void DVDWizard::next()
     27{
     28    DVDWizardPage *npage = dynamic_cast<DVDWizardPage *>(currentPage())->nextPage();
     29
     30    if (npage && indexOf(npage) == -1)
     31    {
     32        /* new page - add it to the stack */
     33        insertPage(npage, npage->heading(), indexOf(currentPage())+1);
     34        setBackEnabled(npage, true);
     35        connect(npage, SIGNAL(changeHelpText(QString)), this, SLOT(setHelpText(QString)));
     36    }
     37   
     38    if (npage)
     39        showPage(npage);
     40    else
     41        showPage(page(pageCount()-1));
     42}
     43
     44void DVDWizard::back()
     45{
     46    DVDWizardPage *dp = dynamic_cast<DVDWizardPage *>(currentPage());
     47    if (dp)
     48        dp->goingBack();
     49
     50    MythWizard::back();
     51}
     52
     53void DVDWizard::showPage(QWidget *page)
     54{
     55    MythWizard::showPage(page);
     56
     57    DVDWizardPage *dp = dynamic_cast<DVDWizardPage *>(page);
     58    if (dp)
     59        dp->entered();
     60}
  • mythtv/programs/mythfrontend/dvdwizard.h

    diff -urNad mythtv/programs/mythfrontend/dvdwizard.h /tmp/dpep.aoKJsg/mythtv/programs/mythfrontend/dvdwizard.h
    old new  
     1#ifndef DVDWIZARD_H_
     2#define DVDWIZARD_H_
     3
     4#include "mythwizard.h"
     5
     6#include "dvdwizardpage.h"
     7
     8class DVDWizard: virtual public MythWizard
     9{
     10    Q_OBJECT
     11    public:
     12        DVDWizard(MythMainWindow* parent, const char* name = 0);
     13
     14    private:
     15        QWidget *findNext();
     16        virtual void showPage(QWidget *page);
     17
     18        DVDWizardData wizardData;
     19
     20    public slots:
     21        void next();
     22        void back();
     23};
     24
     25#endif
  • mythtv/programs/mythfrontend/dvdwizardpage.cpp

    diff -urNad mythtv/programs/mythfrontend/dvdwizardpage.cpp /tmp/dpep.aoKJsg/mythtv/programs/mythfrontend/dvdwizardpage.cpp
    old new  
     1#include <qhbox.h>
     2#include <qvbox.h>
     3
     4#include "playbackbox.h"
     5#include "dvdwizardpage.h"
     6#include "dvdwizard.h"
     7
     8DVDWizardData::DVDWizardData()
     9{
     10    recordings.clear();
     11    dvdtype = Autoplay;
     12}
     13
     14ProgramInfo *DVDWizardData::getProgramInfo(QString &filename)
     15{
     16    /* iterate over all selected recordings */
     17    QValueVector<ProgramInfo>::iterator it;
     18    for (it = recordings.begin(); it != recordings.end(); it++)
     19    {
     20        if ((*it).GetRecordFilename(gContext->GetFilePrefix()) == filename)
     21            return &(*it);
     22    }
     23
     24    return NULL;
     25}
     26
     27DVDWizardPage::DVDWizardPage(DVDWizardData *data, QWidget * parent,
     28                             const char * name) : QGroupBox(parent, name)
     29{
     30    setHeading(QObject::tr("DVD Authoring Wizard"));
     31    setBackgroundOrigin(QWidget::WindowOrigin);
     32
     33    float wmult = 0, hmult = 0;
     34    gContext->GetScreenSettings(wmult, hmult);
     35
     36    new QVBoxLayout(this, (int)(10 * hmult));
     37
     38    m_data = data;
     39
     40    next_page = NULL;
     41}
     42
     43DVDWizardPage::~DVDWizardPage()
     44{
     45    if (next_page) delete next_page;
     46}
     47
     48QString DVDWizardPage::heading()
     49{
     50    return m_heading;
     51}
     52
     53void DVDWizardPage::setHeading(const QString &h)
     54{
     55    m_heading = h;
     56}
     57
     58DVDWizardPage *DVDWizardPage::nextPage()
     59{
     60    if (modified() || !next_page)
     61    {
     62        if (next_page) delete next_page;
     63        next_page = generateNextPage();
     64    }
     65
     66    return next_page;
     67}
     68
     69DVDWizardPageIntro::DVDWizardPageIntro(DVDWizardData *data)
     70    : DVDWizardPage(data, NULL, "intro")
     71{
     72    MythLabel *intro = new MythLabel(QObject::tr("This wizard will walk you "
     73                                     "through the steps of creating a DVD from "
     74                                     "recordings. The recordings must be in a "
     75                                     "DVD compliant MPEG2 format with NAV "
     76                                     "packets. The MPEG2 profile of the "
     77                                     "mythtranscode program generates compliant "
     78                                     "files."), this);
     79    layout()->add(intro);
     80
     81    if (gContext->GetSetting("DVDWizardDir").isEmpty())
     82    {
     83        MythLabel *warn = new MythLabel(QObject::tr("WARNING: You have not set "
     84                                        "the scratch directory for creating "
     85                                        "DVDs. Go to Setup->General->DVD Wizard "
     86                                        "and set the directory. If you continue "
     87                                        "the files and directories (dvd_dir, "
     88                                        "dvd.xml, dvd.iso will be created and "
     89                                        "subsequently deleted in the current "
     90                                        "working directory. This may "
     91                                        "inadvertently result in data loss."),
     92                                        this);
     93        layout()->add(warn);
     94    }
     95}
     96
     97DVDWizardPageSelectRecordings::DVDWizardPageSelectRecordings(DVDWizardData *data)
     98    : DVDWizardPage(data, NULL, "selrec")
     99{
     100    setHeading(QObject::tr("Select Recordings"));
     101    MythLabel *intro = new MythLabel(QObject::tr("Select all the recordings "
     102                                     "that you want on the DVD. The indicators "
     103                                     "at the bottom of the screen show an "
     104                                     "estimate of the amount of space used on "
     105                                     "the DVD. The selected recordings should "
     106                                     "be in DVD compliant MPEG2 format."), this);
     107    layout()->add(intro);
     108
     109    QHBox *hbox = new QHBox(this);
     110    hbox->setSpacing(layout()->spacing());
     111    hbox->setBackgroundOrigin(QWidget::WindowOrigin);
     112   
     113    rec = new MythListBox(hbox);
     114    rec->setFocusPolicy(QWidget::NoFocus);
     115    rec->setBackgroundOrigin(QWidget::WindowOrigin);
     116    rec->setHelpText(QObject::tr("Select a recording to remove from the list."));
     117
     118    QVBox *vbox = new QVBox(hbox);
     119    vbox->setBackgroundOrigin(QWidget::WindowOrigin);
     120
     121    add = new MythPushButton(QObject::tr("Add"), vbox);
     122    add->setBackgroundOrigin(QWidget::WindowOrigin);
     123    add->setHelpText(QObject::tr("Add a recording to the list."));
     124    remove = new MythPushButton(QObject::tr("Remove"), vbox);
     125    remove->setBackgroundOrigin(QWidget::WindowOrigin);
     126    remove->setHelpText(QObject::tr("Remove a recording from the list."));
     127
     128    layout()->add(hbox);
     129
     130    connect(rec, SIGNAL(changeHelpText(QString)), this, SIGNAL(changeHelpText(QString)));
     131    connect(add, SIGNAL(changeHelpText(QString)), this, SIGNAL(changeHelpText(QString)));
     132    connect(remove, SIGNAL(changeHelpText(QString)), this, SIGNAL(changeHelpText(QString)));
     133
     134    connect(add, SIGNAL(clicked()), this, SLOT(addRecording()));
     135    connect(remove, SIGNAL(clicked()), this, SLOT(removeRecording()));
     136    rec->installEventFilter(this);
     137
     138    dvdSize = 0;
     139    sldvd = new MythLabel("", this);
     140    layout()->add(sldvd);
     141    dldvd = new MythLabel("", this);
     142    layout()->add(dldvd);
     143    adjustSize(0);
     144}
     145
     146DVDWizardPageSelectRecordings::~DVDWizardPageSelectRecordings()
     147{
     148    rec->removeEventFilter(this);
     149}
     150
     151void DVDWizardPageSelectRecordings::entered()
     152{
     153    if (m_data->recordings.count() == 0)
     154    {
     155        MythWizard *w = dynamic_cast<MythWizard *>(parent()->parent());
     156        if (w)
     157            w->setNextEnabled(this, false);
     158    }
     159}
     160
     161void DVDWizardPageSelectRecordings::adjustSize(long long delta)
     162{
     163    dvdSize += delta;
     164   
     165    sldvd->setText(QObject::tr("%1 of 4700MB (%2%) used on Single Layer disc")
     166                   .arg(dvdSize/(1024*1024)).arg(dvdSize/47000000LL));
     167    dldvd->setText(QObject::tr("%1 of 9400MB (%2%) used on Dual Layer disc")
     168                   .arg(dvdSize/(1024*1024)).arg(dvdSize/94000000LL));
     169}
     170
     171void DVDWizardPageSelectRecordings::addRecording()
     172{
     173    PlaybackBox pbb(PlaybackBox::Select, gContext->GetMainWindow(),
     174                    "tvplayselect");
     175
     176    if (pbb.exec() == QDialog::Accepted)
     177    {
     178        adjustSize(pbb.getSelected().filesize);
     179        m_data->recordings.append(pbb.getSelected());
     180        rec->insertItem(m_data->recordings.last().title + " " +
     181                        m_data->recordings.last().subtitle);
     182        dataChanged = true;
     183
     184        MythWizard *w = dynamic_cast<MythWizard *>(parent()->parent());
     185        if (w)
     186            w->setNextEnabled(this, true);
     187    }
     188    /* this doesn't seem to work */
     189    add->setFocus();
     190}
     191
     192void DVDWizardPageSelectRecordings::removeRecording()
     193{
     194    rec->setFocusPolicy(QWidget::WheelFocus);
     195    rec->setFocus();
     196}
     197
     198bool DVDWizardPageSelectRecordings::eventFilter(QObject *obj, QEvent *e)
     199{
     200    bool handled = false;
     201    QStringList actions;
     202    if ((e->type() == QEvent::KeyPress) && (obj == rec))
     203    {
     204        if (gContext->GetMainWindow()->TranslateKeyPress("qt", (QKeyEvent *)e, actions))
     205        {
     206            for (unsigned int i = 0; i < actions.size() && !handled; i++)
     207            {
     208                QString action = actions[i];
     209                handled = true;
     210               
     211                if (action == "SELECT")
     212                {
     213                    adjustSize(-m_data->recordings[rec->currentItem()].filesize);
     214                    m_data->recordings.erase(m_data->recordings.begin() + rec->currentItem());
     215                    rec->removeItem(rec->currentItem());
     216                    rec->setFocusPolicy(QWidget::NoFocus);
     217                    remove->setFocus();
     218                    dataChanged = true;
     219
     220                    if (m_data->recordings.count() == 0)
     221                    {
     222                        MythWizard *w = dynamic_cast<MythWizard *>(parent()->parent());
     223                        if (w)
     224                            w->setNextEnabled(this, false);
     225                    }
     226                }
     227                else if (action == "ESCAPE")
     228                {
     229                    rec->setFocusPolicy(QWidget::NoFocus);
     230                    remove->setFocus();
     231                }
     232                else
     233                    handled = false;
     234            }
     235        }
     236    }
     237    return handled;
     238}
     239
     240DVDWizardPageAutoPlayDVD::DVDWizardPageAutoPlayDVD(DVDWizardData *data) : DVDWizardPage(data, NULL, "autoplay")
     241{
     242    setHeading(QObject::tr("Autoplay DVD"));
     243
     244    MythLabel *text = new MythLabel(QObject::tr("Would you like to create an "
     245                                    "autoplay DVD. Autoplay DVDs do not have "
     246                                    "menus and will start to play automatically "                                    "when inserted into the DVD Player. This "
     247                                    "option is good for movies and discs which "
     248                                    "will be used by children. If you selected "
     249                                    "multiple recordings they will play back to "
     250                                    "back."), this);
     251    layout()->add(text);
     252
     253    QHBox *hbox = new QHBox(this);
     254    hbox->setBackgroundOrigin(QWidget::WindowOrigin);
     255    hbox->setSpacing(layout()->spacing());
     256   
     257    new MythLabel(QObject::tr("What type of DVD do you want to create?"), hbox);
     258    dvd_type = new MythComboBox(false, hbox);
     259    dvd_type->setBackgroundOrigin(QWidget::WindowOrigin);
     260    dvd_type->insertItem(QObject::tr("Autoplay DVD"));
     261    dvd_type->insertItem(QObject::tr("Menu based DVD"));
     262    dvd_type->setHelpText(QObject::tr("Select the type of DVD to create."));
     263    layout()->add(hbox);
     264
     265    connect(dvd_type, SIGNAL(changeHelpText(QString)), this, SIGNAL(changeHelpText(QString)));
     266}
     267
     268DVDWizardPage *DVDWizardPageAutoPlayDVD::generateNextPage()
     269{
     270    m_data->dvdtype = (DVDWizardData::DVDType)dvd_type->currentItem();
     271
     272    if (m_data->dvdtype == DVDWizardData::Autoplay) // Autoplay DVD
     273    {
     274        return new DVDWizardPageGenerateXML(m_data);
     275    }
     276    else if (m_data->dvdtype == DVDWizardData::MenuBased) // Menu based DVD
     277    {
     278        return NULL;
     279    }
     280    else
     281        return NULL;
     282}
     283
     284bool DVDWizardPageAutoPlayDVD::modified()
     285{
     286    return (m_data->dvdtype != dvd_type->currentItem());
     287}
     288
     289DVDWizardPageGenerateXML::DVDWizardPageGenerateXML(DVDWizardData *data) : DVDWizardPage(data, NULL, "generate xml")
     290{
     291    generateXML();
     292
     293    MythLabel *text = new MythLabel(QObject::tr("The DVD structure has been "
     294                                    "defined. Select next to generate the DVD "
     295                                    "filesystem."), this);
     296    layout()->add(text);
     297}
     298
     299void DVDWizardPageGenerateXML::generateXML()
     300{
     301    QDomDocument doc;
     302    QDomElement root = doc.createElement("dvdauthor");
     303    root.setAttribute("dest", "dvd_dir");
     304    doc.appendChild(root);
     305
     306    if (m_data->dvdtype == DVDWizardData::Autoplay)
     307    {
     308        /* empty menu */
     309        root.appendChild(doc.createElement("vmgm"));
     310
     311        QDomElement titleset = doc.createElement("titleset");
     312        root.appendChild(titleset);
     313
     314        QDomElement titles = doc.createElement("titles");
     315        titleset.appendChild(titles);
     316
     317        m_data->titlesetSize.resize(1, 0);
     318        m_data->titlesetSize[0] = 0;
     319
     320        /* iterate over all selected recordings */
     321        int titleCount = 1;
     322        QValueVector<ProgramInfo>::iterator it = m_data->recordings.begin();
     323        while (it != m_data->recordings.end())
     324        {
     325            QDomElement pgc = doc.createElement("pgc");
     326            titles.appendChild(pgc);
     327
     328            QDomElement vob = doc.createElement("vob");
     329            vob.setAttribute("file", (*it).GetRecordFilename(gContext->GetFilePrefix()).ascii());
     330            pgc.appendChild(vob);
     331
     332            m_data->titlesetSize[0] += (*it).filesize;
     333
     334            it++;
     335            titleCount++;
     336
     337            /* add a jump to the next title */
     338            QDomElement post = doc.createElement("post");
     339            pgc.appendChild(post);
     340            if (it != m_data->recordings.end())
     341                post.appendChild(doc.createTextNode("jump title " + QString::number(titleCount) + " chapter 1;"));
     342            else
     343                post.appendChild(doc.createTextNode("exit;"));
     344       
     345        }
     346    }
     347    else
     348    {
     349        cerr << "Not yet defined\n";
     350    }
     351
     352    cout << doc.toString().ascii() << endl;
     353
     354    /* Output XML file for dvdauthor */
     355    QFile file(gContext->GetSetting("DVDWizardDir").append("/dvd.xml"));
     356    if (file.open(IO_WriteOnly))
     357    {
     358        QTextStream stream(&file);
     359        stream << doc.toString();
     360        file.close();
     361    }
     362}
     363
     364DVDWizardPageGenerateFS::DVDWizardPageGenerateFS(DVDWizardData *data)
     365    : DVDWizardPage(data, NULL, "generate fs")
     366{
     367    MythLabel *text = new MythLabel(QObject::tr("Generating the DVD filesystem."), this);
     368    layout()->add(text);
     369
     370    output = new MythListBox(this);
     371    output->setFocusPolicy(QWidget::NoFocus);
     372    output->setBackgroundOrigin(QWidget::WindowOrigin);
     373    layout()->add(output);
     374
     375    status = new MythLabel(QObject::tr("Executing dvdauthor..."), this);
     376    layout()->add(status);
     377
     378    task = new QProgressBar(100, this);
     379    task->setBackgroundOrigin(QWidget::WindowOrigin);
     380    layout()->add(task);
     381
     382    QHBox *hbox = new QHBox(this);
     383    hbox->setBackgroundOrigin(QWidget::WindowOrigin);
     384    hbox->setSpacing(layout()->spacing());
     385
     386    text = new MythLabel(QObject::tr("Overall progress"), hbox);
     387    overall = new QProgressBar(0, hbox);
     388    overall->setBackgroundOrigin(QWidget::WindowOrigin);
     389    layout()->add(hbox);
     390
     391    p = NULL;
     392}
     393
     394DVDWizardPageGenerateFS::~DVDWizardPageGenerateFS()
     395{
     396    if (p)
     397        p->kill();
     398}
     399
     400void DVDWizardPageGenerateFS::goingBack()
     401{
     402    if (p)
     403    {
     404        if (p->isRunning())
     405            p->tryTerminate();
     406    }
     407    task->reset();
     408    overall->reset();
     409}
     410
     411void DVDWizardPageGenerateFS::entered()
     412{
     413    if (p)
     414        cerr << "This shouldn't be\n";
     415
     416    /* disable next button */
     417    MythWizard *w = dynamic_cast<MythWizard *>(parent()->parent());
     418    if (w)
     419        w->setNextEnabled(this, false);
     420       
     421    /* clear list box */
     422    output->clear();
     423
     424    /* make sure that dvd_dir is not there */
     425    QString command = QString("rm -rf ") + gContext->GetSetting("DVDWizardDir") + QString("/dvd_dir");
     426    myth_system(command);
     427
     428    /* calculate the estimated size of the DVD */
     429    /* iterate over all selected recordings */
     430    dvdSize = 0;
     431    QValueVector<long long>::iterator it;
     432    for (it = m_data->titlesetSize.begin(); it != m_data->titlesetSize.end(); it++)
     433    {
     434        dvdSize += ((*it) / (1024*1024));
     435    }
     436
     437    /* calculate the total progress */
     438    /* value is in megabytes of data processed */
     439    // currently counts
     440    //  - dvdauthor VOBU
     441    //  - dvdauthor fixing (NAV packets)
     442    //  - mkisofs
     443    overall->setProgress(-1, 3*dvdSize);
     444
     445    /* base Progress */
     446    /* overall progress = baseProgress + task progress */
     447    baseProgress = 0;
     448
     449    /* start the dvdauthor process */
     450    p = new QProcess(QString("dvdauthor"), this);
     451    p->setCommunication(QProcess::Stderr);
     452    p->setWorkingDirectory(gContext->GetSetting("DVDWizardDir"));
     453    p->addArgument("-x");
     454    p->addArgument("dvd.xml");
     455
     456    connect(p, SIGNAL(readyReadStderr()), this, SLOT(readProcDVDAuthor()));
     457    connect(p, SIGNAL(processExited()), this, SLOT(procExited()));
     458
     459    p->start();
     460}
     461
     462void DVDWizardPageGenerateFS::readProcDVDAuthor()
     463{
     464    int index;
     465
     466    pOutput.append(p->readStderr());
     467
     468    QRegExp sep("[\r\n]");
     469
     470    index = pOutput.find(sep);
     471    while (index != -1)
     472    {
     473        QString s = pOutput.left(index);
     474        pOutput.remove(0, index+1);
     475
     476        if (s.startsWith("STAT: "))
     477        {
     478            s.remove(0, 6);
     479
     480            if (s.startsWith("Picking VTS "))
     481            {
     482               s.remove(0, 12);
     483               currentTitleset = s.toInt();
     484               status->setText(QObject::tr("Generating Titleset %1")
     485                               .arg(currentTitleset));
     486               task->setProgress(0, 2*m_data->titlesetSize[currentTitleset-1] / (1024*1024));
     487            }
     488/*            else if (s.startsWith("Processing "))
     489            {
     490            }*/
     491            else if (s.startsWith("VOBU "))
     492            {
     493                int taskProgress = s.section(' ', 3, 3).remove("MB,").toInt();
     494                task->setProgress(taskProgress);
     495                overall->setProgress(baseProgress + taskProgress);
     496            }
     497            else if (s.startsWith("fixing VOBU at "))
     498            {
     499                int taskProgress = s.section(' ', 3, 3).remove("MB").toInt() + task->totalSteps()/2;
     500                task->setProgress(taskProgress);
     501                overall->setProgress(baseProgress + taskProgress);
     502            }
     503            else if (s.startsWith("fixed "))
     504            {
     505                task->setProgress(task->totalSteps());
     506                baseProgress += task->totalSteps();
     507                overall->setProgress(baseProgress);
     508            }
     509            else
     510            {
     511                cerr << s.ascii() << endl;
     512                output->insertItem(s);
     513            }
     514        }
     515        else if (s.startsWith("ERR: "))
     516        {
     517            s.remove(0, 5);
     518            status->setText(s);
     519        }
     520       
     521        index = pOutput.find(sep);
     522    }
     523}
     524
     525void DVDWizardPageGenerateFS::readProcMkisofs()
     526{
     527    while (p->canReadLineStderr())
     528    {
     529        QString s = p->readLineStderr();
     530
     531        QRegExp rxp("\\d{0,1}\\d{0,1}\\d\\.\\d\\d%");
     532        if (s.contains(rxp))
     533        {
     534            s = s.section(' ', 1, 1);
     535
     536            if (s.endsWith("%"))
     537            {
     538                float percent = s.left(s.length()-1).toFloat();
     539                int taskProgress = (int)(percent * dvdSize / 100);
     540                task->setProgress(taskProgress);
     541                overall->setProgress(baseProgress + taskProgress);
     542            }
     543        }
     544        else if (s.contains("extents written"))
     545        {
     546            task->setProgress(task->totalSteps());
     547            baseProgress += task->totalSteps();
     548            overall->setProgress(baseProgress);
     549        }
     550        else
     551        {
     552            cerr << "Got line \"" << s.ascii() << '"' << endl;
     553            output->insertItem(s);
     554        }
     555    }
     556}
     557
     558void DVDWizardPageGenerateFS::procExited()
     559{
     560    if (p->normalExit())
     561    {
     562        QString progname = p->arguments()[0];
     563
     564        if (progname == "dvdauthor")
     565        {
     566            if (p->exitStatus() == 0)
     567            {
     568                /* dvdauthor finished, start mkisofs */
     569
     570                p->deleteLater();
     571
     572                p = new QProcess(QString("mkisofs"), this);
     573                p->setCommunication(QProcess::Stderr);
     574                p->setWorkingDirectory(gContext->GetSetting("DVDWizardDir"));
     575                p->addArgument("-dvd-video");
     576                p->addArgument("-o");
     577                p->addArgument("dvd.iso");
     578                p->addArgument("dvd_dir");
     579
     580                connect(p, SIGNAL(readyReadStderr()), this, SLOT(readProcMkisofs()));
     581                connect(p, SIGNAL(processExited()), this, SLOT(procExited()));
     582
     583                p->start();
     584
     585                status->setText(QObject::tr("Generating iso image..."));
     586                task->setProgress(0, dvdSize);
     587            }
     588            else
     589            {
     590                /* dvdauthor failed */
     591                cerr << "dvdauthor exited with " << p->exitStatus() << endl;
     592
     593                p->deleteLater();
     594                p = NULL;
     595            }
     596        }
     597        else if (progname == "mkisofs")
     598        {
     599            if (p->exitStatus() == 0)
     600            {
     601                //readProcMkisofs();
     602                task->reset();
     603                status->setText(QObject::tr("DVD finished generating. Select 'Next' "
     604                                "to continue"));
     605
     606                p->deleteLater();
     607                p = NULL;
     608
     609                /* delete dvd_dir */
     610                QString command = QString("rm -rf ") + gContext->GetSetting("DVDWizardDir") + QString("/dvd_dir");
     611                myth_system(command);
     612
     613                /* enable next button */
     614                MythWizard *w = dynamic_cast<MythWizard *>(parent()->parent());
     615                if (w)
     616                {
     617                    w->setNextEnabled(this, true);
     618                    w->nextButton()->setFocus();
     619                }
     620            }
     621            else
     622            {
     623                /* mkisofs failed */
     624                cerr << "mkisofs exited with " << p->exitStatus() << endl;
     625
     626                p->deleteLater();
     627                p = NULL;
     628            }
     629        }
     630        else
     631        {
     632            cerr << "Program " << progname.ascii() << " exited normally.\n";
     633
     634            p->deleteLater();
     635            p = NULL;
     636        }
     637    }
     638    else
     639    {
     640        status->setText(QObject::tr("Child process exit error, check stderr."));
     641        cerr << "Program: " << p->arguments().join(" ").ascii() << endl;
     642        cerr << "Exit code: " << p->exitStatus() << endl;
     643
     644        p->deleteLater();
     645        p = NULL;
     646    }
     647}
     648
     649DVDWizardPageBurnDVD::DVDWizardPageBurnDVD(DVDWizardData *data) : DVDWizardPage(data, NULL, "burn")
     650{
     651    MythLabel *text = new MythLabel(QObject::tr("Burning the DVD."), this);
     652    layout()->add(text);
     653
     654    instructions = new MythLabel(QObject::tr("Ensure that a blank DVD is the "
     655                                 "DVD burner and select 'Burn' to start burning "
     656                                 "the image to disc."), this);
     657
     658    layout()->add(instructions);
     659
     660    progress = new QProgressBar(100, this);
     661    progress->setBackgroundOrigin(QWidget::WindowOrigin);
     662    layout()->add(progress);
     663
     664    burn = new MythPushButton("Burn", this);
     665    layout()->add(burn);
     666
     667    connect(burn, SIGNAL(clicked()), this, SLOT(startBurn()));
     668
     669    p = NULL;
     670}
     671
     672DVDWizardPageBurnDVD::~DVDWizardPageBurnDVD()
     673{
     674    if (p)
     675        p->kill();
     676}
     677
     678void DVDWizardPageBurnDVD::entered()
     679{
     680    progress->reset();
     681}
     682
     683void DVDWizardPageBurnDVD::readProc()
     684{
     685    while (p->canReadLineStderr())
     686    {
     687        QString s = p->readLineStderr();
     688
     689        QRegExp rxp("\\d{0,1}\\d{0,1}\\d\\.\\d%");
     690        if (s.contains(rxp))
     691        {
     692            s.remove(0, s.find(rxp));
     693            s = s.left(s.find('%'));
     694
     695            progress->setProgress((int)s.toFloat());
     696        }
     697        else
     698            cerr << s.ascii() << endl;
     699    }
     700}
     701
     702void DVDWizardPageBurnDVD::procExited()
     703{
     704    if (p->normalExit() && (p->exitStatus() == 0))
     705    {
     706        burn->setEnabled(true);
     707        burn->setFocus();
     708       
     709        instructions->setText(QObject::tr("Burn completed sucessfully. Insert a "
     710                              "new DVD and select 'Burn' to burn another, "
     711                              "otherwise select 'Next' to continue."));
     712
     713        p->deleteLater();
     714        p = NULL;
     715    }
     716    else
     717    {
     718        burn->setEnabled(true);
     719        burn->setFocus();
     720
     721        instructions->setText(QObject::tr("Burn failed. Insert a new DVD and "
     722                              "select 'Burn' to try again, otherwise select "
     723                              "'Next' to continue."));
     724
     725        p->deleteLater();
     726        p = NULL;
     727    }
     728}
     729
     730void DVDWizardPageBurnDVD::startBurn()
     731{
     732    burn->setDisabled(true);
     733
     734    /* reset progress bar */
     735    progress->setProgress(0);
     736   
     737    p = new QProcess(QString("growisofs"), this);
     738    p->setCommunication(QProcess::Stderr);
     739    p->setWorkingDirectory(gContext->GetSetting("DVDWizardDir"));
     740    p->addArgument("-dvd-compat");
     741    p->addArgument("-Z");
     742    p->addArgument(gContext->GetSetting("DVDDevice") + QString("dvd.iso"));
     743    connect(p, SIGNAL(readyReadStderr()), this, SLOT(readProc()));
     744    connect(p, SIGNAL(processExited()), this, SLOT(procExited()));
     745
     746    p->start();
     747}
     748
     749DVDWizardPageLast::DVDWizardPageLast(DVDWizardData *data)
     750    : DVDWizardPage(data, NULL, "last")
     751{
     752    MythLabel *text = new MythLabel(QObject::tr("Congratulations the DVD has "
     753                                    "now been sucessfully authored."), this);
     754    layout()->add(text);
     755}
     756
     757DVDWizardPageLast::~DVDWizardPageLast()
     758{
     759    /* clean up temp files */
     760    /* this deletes everything in the gContext->GetSetting("DVDWizardDir") directory */
     761
     762    QString command = QString("rm -rf ") + gContext->GetSetting("DVDWizardDir");
     763    myth_system(command + QString("/dvd_dir"));
     764    myth_system(command + QString("/dvd.xml"));
     765    myth_system(command + QString("/dvd.iso"));
     766}
     767
     768MythLabel::MythLabel(const QString & text, QWidget * parent, const char * name, WFlags f)
     769            : QLabel(text, parent, name, f)
     770{
     771    setBackgroundOrigin(QWidget::WindowOrigin);
     772    setAlignment(Qt::WordBreak | Qt::AlignLeft | Qt::AlignTop);
     773}
     774
  • mythtv/programs/mythfrontend/dvdwizardpage.h

    diff -urNad mythtv/programs/mythfrontend/dvdwizardpage.h /tmp/dpep.aoKJsg/mythtv/programs/mythfrontend/dvdwizardpage.h
    old new  
     1#ifndef DVDWIZARDPAGE_H_
     2#define DVDWIZARDPAGE_H_
     3
     4#include <qgroupbox.h>
     5#include <qlabel.h>
     6#include <qprocess.h>
     7#include <qprogressbar.h>
     8#include <qvaluevector.h>
     9
     10#include "mythwidgets.h"
     11#include "mythcontext.h"
     12#include "programinfo.h"
     13
     14class DVDWizardData
     15{
     16    public:
     17        DVDWizardData();
     18
     19        ProgramInfo *getProgramInfo(QString &filename);
     20
     21        /* all these data members should probably be private */
     22        enum DVDType { Autoplay = 0, MenuBased = 1 };
     23
     24        QValueVector<ProgramInfo> recordings;
     25        QValueVector<long long> titlesetSize;
     26        DVDType dvdtype;
     27};
     28
     29class MythLabel: public QLabel
     30{
     31    Q_OBJECT
     32    public:
     33        MythLabel(const QString & text, QWidget * parent,
     34                  const char * name = 0, WFlags f = 0);
     35};
     36
     37class DVDWizardPage: public QGroupBox
     38{
     39    Q_OBJECT
     40    public:
     41        DVDWizardPage(DVDWizardData *data, QWidget * parent = 0,
     42                      const char * name = 0);
     43        ~DVDWizardPage();
     44
     45        DVDWizardPage *nextPage();
     46
     47        QString heading();
     48        void setHeading(const QString &h);
     49       
     50        virtual void goingBack() { };
     51        virtual void entered() { };
     52
     53    signals:
     54        void changeHelpText(QString);
     55
     56    private:
     57        virtual DVDWizardPage *generateNextPage() = 0;
     58        virtual bool modified() { return false; };
     59
     60        DVDWizardPage *next_page;
     61        QString m_heading;
     62
     63    protected:
     64        DVDWizardData *m_data;
     65};
     66
     67class DVDWizardPageLast: public DVDWizardPage
     68{
     69    public:
     70        DVDWizardPageLast(DVDWizardData *data);
     71        ~DVDWizardPageLast();
     72
     73    private:
     74        DVDWizardPage *generateNextPage() { return NULL; };
     75};
     76
     77class DVDWizardPageBurnDVD: public DVDWizardPage
     78{
     79    Q_OBJECT
     80    public:
     81        DVDWizardPageBurnDVD(DVDWizardData *data);
     82        ~DVDWizardPageBurnDVD();
     83
     84        virtual void entered();
     85
     86    private:
     87        DVDWizardPage *generateNextPage() { return NULL; };
     88
     89        MythLabel *instructions;
     90        MythPushButton *burn;
     91        QProgressBar *progress;
     92        QProcess *p;
     93
     94    private slots:
     95        void readProc();
     96        void procExited();
     97        void startBurn();
     98};
     99
     100class DVDWizardPageGenerateFS: public DVDWizardPage
     101{
     102    Q_OBJECT
     103    public:
     104        DVDWizardPageGenerateFS(DVDWizardData *data);
     105        ~DVDWizardPageGenerateFS();
     106
     107        virtual void goingBack();
     108        virtual void entered();
     109
     110    private:
     111        DVDWizardPage *generateNextPage() { return new DVDWizardPageBurnDVD(m_data); };
     112
     113        MythListBox *output;
     114        MythLabel *status;
     115        QProgressBar *overall;
     116        QProgressBar *task;
     117        QProcess *p;
     118        QString pOutput;
     119        int baseProgress;
     120        int dvdSize;
     121        int currentTitleset;
     122
     123    private slots:
     124        void readProcDVDAuthor();
     125        void readProcMkisofs();
     126        void procExited();
     127};
     128
     129class DVDWizardPageGenerateXML: public DVDWizardPage
     130{
     131    public:
     132        DVDWizardPageGenerateXML(DVDWizardData *data);
     133
     134    private:
     135        DVDWizardPage *generateNextPage() { return new DVDWizardPageGenerateFS(m_data); };
     136
     137        void generateXML();
     138};
     139
     140class DVDWizardPageMainMenu: public DVDWizardPage
     141{
     142    public:
     143        DVDWizardPageMainMenu(DVDWizardData *data);
     144
     145    private:
     146        DVDWizardPage *generateNextPage() { return NULL; };
     147
     148        MythCheckBox *dvd_main_menu;
     149};
     150
     151class DVDWizardPageAutoPlayDVD: public DVDWizardPage
     152{
     153    public:
     154        DVDWizardPageAutoPlayDVD(DVDWizardData *data);
     155
     156    private:
     157        DVDWizardPage *generateNextPage();
     158        bool modified();
     159
     160        MythComboBox *dvd_type;
     161};
     162
     163class DVDWizardPageSelectRecordings: public DVDWizardPage
     164{
     165    Q_OBJECT
     166    public:
     167        DVDWizardPageSelectRecordings(DVDWizardData *data);
     168        ~DVDWizardPageSelectRecordings();
     169
     170        virtual void entered();
     171
     172    private:
     173        DVDWizardPage *generateNextPage() { return new DVDWizardPageAutoPlayDVD(m_data); };
     174        bool modified() { return dataChanged; };
     175        void adjustSize(long long delta);
     176
     177        MythListBox *rec;
     178        MythPushButton *add;
     179        MythPushButton *remove;
     180        MythLabel *sldvd;
     181        MythLabel *dldvd;
     182
     183        bool dataChanged;
     184        int dvdSize;
     185
     186    protected:
     187        bool eventFilter(QObject *obj, QEvent *e);
     188
     189    private slots:
     190        void addRecording();
     191        void removeRecording();
     192};
     193
     194class DVDWizardPageIntro: public DVDWizardPage
     195{
     196    public:
     197        DVDWizardPageIntro(DVDWizardData *data);
     198
     199    private:
     200        DVDWizardPage *generateNextPage() { return new DVDWizardPageSelectRecordings(m_data); };
     201};
     202
     203#endif
  • mythtv/programs/mythfrontend/globalsettings.cpp

    diff -urNad mythtv/programs/mythfrontend/globalsettings.cpp /tmp/dpep.aoKJsg/mythtv/programs/mythfrontend/globalsettings.cpp
    old new  
    22192219    };
    22202220};
    22212221
     2222static HostLineEdit *DVDWizardDir()
     2223{
     2224    HostLineEdit *l = new HostLineEdit("DVDWizardDir");
     2225    l->setLabel(QObject::tr("Scratch Dir"));
     2226    l->setValue("");
     2227    l->setHelpText(QObject::tr("This directory will be used to store temporary "
     2228                   "files when generating DVDs."));
     2229    return l;
     2230}
     2231
     2232static HostComboBox *DVDWizardDevice()
     2233{
     2234    HostComboBox *gc = new HostComboBox("DVDDevice", true);
     2235    gc->setLabel(QObject::tr("DVD-Writer device"));
     2236
     2237    QDir dev("/dev", "cdrom*", QDir::Name, QDir::System);
     2238    gc->fillSelectionsFromDir(dev);
     2239    dev.setNameFilter("scd*");
     2240    gc->fillSelectionsFromDir(dev);
     2241    dev.setNameFilter("hd*");
     2242    gc->fillSelectionsFromDir(dev);
     2243    dev.setNameFilter("cdrom*");
     2244    dev.setPath("/dev/cdroms");
     2245    gc->fillSelectionsFromDir(dev);
     2246
     2247    gc->setHelpText(QObject::tr("DVD Writer device used for burning DVDs."));
     2248    return gc;
     2249}
     2250
    22222251static GlobalCheckBox *LogEnabled()
    22232252{
    22242253    GlobalCheckBox *bc = new GlobalCheckBox("LogEnabled");
     
    28692898
    28702899    MythFillSettings *mythfill = new MythFillSettings();
    28712900    addChild(mythfill);
     2901
     2902    VerticalConfigurationGroup* dvdwizard = new VerticalConfigurationGroup(false);
     2903    dvdwizard->setLabel(QObject::tr("DVD Wizard"));
     2904    dvdwizard->addChild(DVDWizardDir());
     2905    dvdwizard->addChild(DVDWizardDevice());
     2906    addChild(dvdwizard);
    28722907}
    28732908
    28742909PlaybackSettings::PlaybackSettings()
  • mythtv/programs/mythfrontend/main.cpp

    diff -urNad mythtv/programs/mythfrontend/main.cpp /tmp/dpep.aoKJsg/mythtv/programs/mythfrontend/main.cpp
    old new  
    2626#include "channelrecpriority.h"
    2727#include "globalsettings.h"
    2828#include "profilegroup.h"
     29#include "dvdwizard.h"
    2930
    3031#include "exitcodes.h"
    3132#include "themedmenu.h"
     
    210211    qApp->lock();
    211212}
    212213
     214void startDVDWizard(void)
     215{
     216    DVDWizard wizard(gContext->GetMainWindow(), "dvd wizard");
     217
     218    qApp->unlock();
     219    wizard.exec();
     220    qApp->lock();
     221}
     222
    213223void startCustomRecord(void)
    214224{
    215225    CustomRecord custom(gContext->GetMainWindow(), "custom record");
     
    397407        startSearchTime();
    398408    else if (sel == "tv_previous")
    399409        startPrevious();
     410    else if (sel == "tv_dvd_wizard")
     411        startDVDWizard();
    400412    else if (sel == "settings appearance")
    401413    {
    402414        AppearanceSettings settings;
  • mythtv/programs/mythfrontend/mainmenu.xml

    diff -urNad mythtv/programs/mythfrontend/mainmenu.xml /tmp/dpep.aoKJsg/mythtv/programs/mythfrontend/mainmenu.xml
    old new  
    9191     <text lang="SI">CD/DVD</text>
    9292     <text lang="ET">DVD ja CD</text>
    9393     <action>MENU optical_menu.xml</action>
    94      <depends>mythmusic mythdvd</depends>
    9594   </button>
    9695   
    9796   <button>
  • mythtv/programs/mythfrontend/mythfrontend.pro

    diff -urNad mythtv/programs/mythfrontend/mythfrontend.pro /tmp/dpep.aoKJsg/mythtv/programs/mythfrontend/mythfrontend.pro
    old new  
    4343HEADERS += manualbox.h playbackbox.h viewscheduled.h globalsettings.h
    4444HEADERS += manualschedule.h programrecpriority.h channelrecpriority.h
    4545HEADERS += statusbox.h previousbox.h customrecord.h
     46HEADERS += dvdwizard.h dvdwizardpage.h
    4647
    4748SOURCES += main.cpp manualbox.cpp playbackbox.cpp viewscheduled.cpp
    4849SOURCES += globalsettings.cpp manualschedule.cpp programrecpriority.cpp
    4950SOURCES += channelrecpriority.cpp statusbox.cpp previousbox.cpp
    5051SOURCES += customrecord.cpp
     52SOURCES += dvdwizard.cpp dvdwizardpage.cpp
    5153
    5254macx {
    5355    RC_FILE += mythfrontend.icns
  • mythtv/programs/mythfrontend/optical_menu.xml

    diff -urNad mythtv/programs/mythfrontend/optical_menu.xml /tmp/dpep.aoKJsg/mythtv/programs/mythfrontend/optical_menu.xml
    old new  
    11<mythmenu name="OPTICAL_DISK">
    22
    33   <button>
     4      <type>DVD_WIZARD</type>
     5      <text>Author DVD</text>
     6      <action>TV_DVD_WIZARD</action>
     7   </button>
     8
     9   <button>
    410      <type>DVD_PLAY</type>
    511      <text>Play DVD</text>
    612      <text lang="DK">Afspil DVD</text>
  • mythtv/programs/mythfrontend/playbackbox.cpp

    diff -urNad mythtv/programs/mythfrontend/playbackbox.cpp /tmp/dpep.aoKJsg/mythtv/programs/mythfrontend/playbackbox.cpp
    old new  
    431431void PlaybackBox::exitWin()
    432432{
    433433    killPlayerSafe();
    434     accept();
     434    reject();
    435435}
    436436
    437437void PlaybackBox::updateBackground(void)
     
    15671567        play(curitem);
    15681568}
    15691569
     1570void PlaybackBox::selectSelected()
     1571{
     1572    killPlayerSafe();
     1573    accept();
     1574}
     1575
    15701576void PlaybackBox::stopSelected()
    15711577{
    15721578    state = kStopping;
     
    16641670    {
    16651671        case Play: playSelected(); break;
    16661672        case Delete: deleteSelected(); break;
     1673        case Select: selectSelected(); break;
    16671674    }
    16681675}
    16691676
  • mythtv/programs/mythfrontend/playbackbox.h

    diff -urNad mythtv/programs/mythfrontend/playbackbox.h /tmp/dpep.aoKJsg/mythtv/programs/mythfrontend/playbackbox.h
    old new  
    2626{
    2727    Q_OBJECT
    2828  public:
    29     typedef enum { Play, Delete } BoxType;
     29    typedef enum { Play, Delete, Select } BoxType;
    3030    typedef enum { TitlesOnly, TitlesCategories, TitlesCategoriesRecGroups,
    3131                   TitlesRecGroups, Categories, CategoriesRecGroups, RecGroups} ViewType;
    3232
     
    3535   ~PlaybackBox(void);
    3636   
    3737    void customEvent(QCustomEvent *e);
     38
     39    ProgramInfo getSelected() { return *curitem; };
    3840 
    3941  protected slots:
    4042    void timeout(void);
     
    6567    void showPlaylistPopup();
    6668    void showPlaylistJobPopup();
    6769
     70    void selectSelected();
     71
    6872    void doPlay();
    6973    void doPlayFromBeg();
    7074    void doPlayListRandom();