]> git.sesse.net Git - kdenlive/commitdiff
Final changes to the DVD wizard rewrite. Allow transcoding of non compliant files...
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 2 Nov 2012 00:30:15 +0000 (01:30 +0100)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 2 Nov 2012 00:30:15 +0000 (01:30 +0100)
src/cliptranscode.cpp
src/cliptranscode.h
src/dvdwizardvob.cpp
src/dvdwizardvob.h
src/kdenlivetranscodingrc
src/mainwindow.cpp
src/widgets/dvdwizardvob_ui.ui

index c91ec59826bed8b6acdf6e969ded5268d6b27b64..eace784d2d55003bdfadd277f160bf3ba529b7a4 100644 (file)
@@ -27,8 +27,8 @@
 #include <KFileDialog>
 
 
-ClipTranscode::ClipTranscode(KUrl::List urls, const QString &params, const QString &description, QWidget * parent) :
-        QDialog(parent), m_urls(urls), m_duration(0)
+ClipTranscode::ClipTranscode(KUrl::List urls, const QString &params, const QStringList &postParams, const QString &description, bool automaticMode, QWidget * parent) :
+        QDialog(parent), m_urls(urls), m_duration(0), m_automaticMode(automaticMode), m_postParams(postParams)
 {
     setFont(KGlobalSettings::toolBarFont());
     setupUi(this);
@@ -42,6 +42,9 @@ ClipTranscode::ClipTranscode(KUrl::List urls, const QString &params, const QStri
 #endif
     log_text->setHidden(true);
     setWindowTitle(i18n("Transcode Clip"));
+    if (m_automaticMode) {
+       auto_add->setHidden(true);
+    }
     auto_add->setText(i18np("Add clip to project", "Add clips to project", m_urls.count()));
     auto_add->setChecked(KdenliveSettings::add_new_clip());
 
@@ -98,6 +101,7 @@ ClipTranscode::ClipTranscode(KUrl::List urls, const QString &params, const QStri
     ffmpeg_params->setMaximumHeight(QFontMetrics(font()).lineSpacing() * 5);
 
     adjustSize();
+    if (m_automaticMode) slotStartTransCode();
 }
 
 ClipTranscode::~ClipTranscode()
@@ -143,8 +147,19 @@ void ClipTranscode::slotStartTransCode()
         if (KMessageBox::questionYesNo(this, i18n("File %1 already exists.\nDo you want to overwrite it?", destination + extension)) == KMessageBox::No) return;
         parameters << "-y";
     }
-    foreach(QString s, params.split(' '))
+
+    bool replaceVfParams = false;
+    foreach(QString s, params.split(' ')) {
+       if (replaceVfParams) {
+           s= m_postParams.at(1);
+           replaceVfParams = false;
+       }
         parameters << s.replace("%1", destination);
+       if (s == "-vf") {
+           replaceVfParams = true;
+       }
+    }
+    
     buttonBox->button(QDialogButtonBox::Abort)->setText(i18n("Abort"));
 
     m_destination = destination + extension;
@@ -200,14 +215,15 @@ void ClipTranscode::slotTranscodeFinished(int exitCode, QProcess::ExitStatus exi
     }
     if (exitCode == 0 && exitStatus == QProcess::NormalExit) {
         log_text->setHtml(log_text->toPlainText() + "<br /><b>" + i18n("Transcoding finished."));
-        if (auto_add->isChecked()) {
+        if (auto_add->isChecked() || m_automaticMode) {
             KUrl url;
             if (urls_list->count() > 0) {
                 QString params = ffmpeg_params->toPlainText().simplified();
                 QString extension = params.section("%1", 1, 1).section(' ', 0, 0);
                 url = KUrl(dest_url->url().path(KUrl::AddTrailingSlash) + source_url->url().fileName() + extension);
             } else url = dest_url->url();
-            emit addClip(url);
+           if (m_automaticMode) emit transcodedClip(source_url->url(), url);
+            else emit addClip(url);
         }
         if (urls_list->count() > 0 && m_urls.count() > 0) {
             m_transcodeProcess.close();
index 8de1db82e80b5b1132cf6a62cb6024bf625b0fe3..05d0841ce40a81b0224ff4a304018a818d41d8f3 100644 (file)
@@ -37,7 +37,7 @@ class ClipTranscode : public QDialog, public Ui::ClipTranscode_UI
     Q_OBJECT
 
 public:
-    ClipTranscode(KUrl::List urls, const QString &params, const QString &description, QWidget * parent = 0);
+    ClipTranscode(KUrl::List urls, const QString &params, const QStringList &postParams, const QString &description, bool automaticMode = false, QWidget * parent = 0);
     ~ClipTranscode();
 
 
@@ -51,8 +51,10 @@ private:
     QProcess m_transcodeProcess;
     KUrl::List m_urls;
     int m_duration;
+    bool m_automaticMode;
     /** @brief The path for destination transcoded file. */
     QString m_destination;
+    QStringList m_postParams;
 
 #if KDE_IS_VERSION(4,7,0)
     KMessageWidget *m_infoMessage;
@@ -60,6 +62,7 @@ private:
     
 signals:
     void addClip(KUrl url);
+    void transcodedClip(KUrl source, KUrl result);
 };
 
 
index 73d9a64ae7d2dccf105e8e325cc185b70555480b..4f058e2bae874700f4e18acd3cefb29c394fbc3b 100644 (file)
@@ -20,6 +20,7 @@
 #include "dvdwizardvob.h"
 #include "kthumb.h"
 #include "timecode.h"
+#include "cliptranscode.h"
 
 #include <mlt++/Mlt.h>
 
 #include <QTreeWidgetItem>
 #include <QHeaderView>
 
+DvdTreeWidget::DvdTreeWidget(QWidget *parent) :
+        QTreeWidget(parent)
+{
+    setAcceptDrops(true);
+}
+
+void DvdTreeWidget::dragEnterEvent(QDragEnterEvent * event ) {
+    if (event->mimeData()->hasUrls()) {
+       event->setDropAction(Qt::CopyAction);
+       event->setAccepted(true);
+    }
+    else QTreeWidget::dragEnterEvent(event);
+}
+
+void DvdTreeWidget::dragMoveEvent(QDragMoveEvent * event) {
+       event->acceptProposedAction();
+}
+
+void DvdTreeWidget::mouseDoubleClickEvent( QMouseEvent * )
+{
+    emit addNewClip();
+}
+
+void DvdTreeWidget::dropEvent(QDropEvent * event ) {
+    QList<QUrl> clips = event->mimeData()->urls();
+    event->accept();
+    emit addClips(clips);
+}
+
 DvdWizardVob::DvdWizardVob(QWidget *parent) :
-        QWizardPage(parent)
+        QWizardPage(parent),
+        m_installCheck(true)
 {
     m_view.setupUi(this);
     m_view.intro_vob->setEnabled(false);
@@ -44,43 +75,63 @@ DvdWizardVob::DvdWizardVob(QWidget *parent) :
     m_view.button_delete->setIcon(KIcon("list-remove"));
     m_view.button_up->setIcon(KIcon("go-up"));
     m_view.button_down->setIcon(KIcon("go-down"));
+    m_vobList = new DvdTreeWidget(this);
+    QVBoxLayout *lay1 = new QVBoxLayout;
+    lay1->addWidget(m_vobList);
+    m_view.list_frame->setLayout(lay1);
+    m_vobList->setColumnCount(3);
+    m_vobList->setHeaderHidden(true);
+
+    connect(m_vobList, SIGNAL(addClips(QList<QUrl>)), this, SLOT(slotAddVobList(QList<QUrl>)));
+    connect(m_vobList, SIGNAL(addNewClip()), this, SLOT(slotAddVobFile()));
+    
     connect(m_view.use_intro, SIGNAL(toggled(bool)), m_view.intro_vob, SLOT(setEnabled(bool)));
     connect(m_view.button_add, SIGNAL(clicked()), this, SLOT(slotAddVobFile()));
     connect(m_view.button_delete, SIGNAL(clicked()), this, SLOT(slotDeleteVobFile()));
     connect(m_view.button_up, SIGNAL(clicked()), this, SLOT(slotItemUp()));
     connect(m_view.button_down, SIGNAL(clicked()), this, SLOT(slotItemDown()));
-    connect(m_view.vobs_list, SIGNAL(itemSelectionChanged()), this, SLOT(slotCheckVobList()));
+    connect(m_vobList, SIGNAL(itemSelectionChanged()), this, SLOT(slotCheckVobList()));
     
-    m_view.vobs_list->setIconSize(QSize(60, 45));
+    m_vobList->setIconSize(QSize(60, 45));
 
     if (KStandardDirs::findExe("dvdauthor").isEmpty()) m_errorMessage.append(i18n("<strong>Program %1 is required for the DVD wizard.</strong>", i18n("dvdauthor")));
     if (KStandardDirs::findExe("mkisofs").isEmpty() && KStandardDirs::findExe("genisoimage").isEmpty()) m_errorMessage.append(i18n("<strong>Program %1 or %2 is required for the DVD wizard.</strong>", i18n("mkisofs"), i18n("genisoimage")));
     if (m_errorMessage.isEmpty()) m_view.error_message->setVisible(false);
-    else m_view.error_message->setText(m_errorMessage);
+    else {
+       m_view.error_message->setText(m_errorMessage);
+       m_installCheck = false;
+    }
 
     m_view.dvd_profile->addItems(QStringList() << i18n("PAL 4:3") << i18n("PAL 16:9") << i18n("NTSC 4:3") << i18n("NTSC 16:9"));
 
-    connect(m_view.dvd_profile, SIGNAL(activated(int)), this, SLOT(changeFormat()));
     connect(m_view.dvd_profile, SIGNAL(activated(int)), this, SLOT(slotCheckProfiles()));
-    m_view.vobs_list->header()->setStretchLastSection(false);
-    m_view.vobs_list->header()->setResizeMode(0, QHeaderView::Stretch);
-    m_view.vobs_list->header()->setResizeMode(1, QHeaderView::Custom);
-    m_view.vobs_list->header()->setResizeMode(2, QHeaderView::Custom);
+    m_vobList->header()->setStretchLastSection(false);
+    m_vobList->header()->setResizeMode(0, QHeaderView::Stretch);
+    m_vobList->header()->setResizeMode(1, QHeaderView::Custom);
+    m_vobList->header()->setResizeMode(2, QHeaderView::Custom);
 
     m_capacityBar = new KCapacityBar(KCapacityBar::DrawTextInline, this);
     QHBoxLayout *lay = new QHBoxLayout;
     lay->addWidget(m_capacityBar);
     m_view.size_box->setLayout(lay);
 
-    m_view.vobs_list->setItemDelegate(new DvdViewDelegate(m_view.vobs_list));
+    m_vobList->setItemDelegate(new DvdViewDelegate(m_vobList));
+    m_transcodeAction = new QAction(i18n("Transcode"), this);
+    connect(m_transcodeAction, SIGNAL(triggered()), this, SLOT(slotTranscodeFiles()));
 
 #if KDE_IS_VERSION(4,7,0)
     m_warnMessage = new KMessageWidget;
-    m_warnMessage->setText(i18n("Conflicting video standards, check DVD profile and clips"));
     m_warnMessage->setMessageType(KMessageWidget::Warning);
+    m_warnMessage->setText(i18n("Your clips do not match selected DVD format, transcoding required."));
+    m_warnMessage->setCloseButtonVisible(false);
+    m_warnMessage->addAction(m_transcodeAction);
     QGridLayout *s =  static_cast <QGridLayout*> (layout());
     s->addWidget(m_warnMessage, 3, 0, 1, -1);
     m_warnMessage->hide();
+    m_view.button_transcode->setHidden(true);
+#else
+    m_view.button_transcode->setDefaultAction(m_transcodeAction);
+    m_view.button_transcode->setEnabled(false);
 #endif
     
     slotCheckVobList();
@@ -93,25 +144,38 @@ DvdWizardVob::~DvdWizardVob()
 
 void DvdWizardVob::slotCheckProfiles()
 {
-#if KDE_IS_VERSION(4,7,0)
     bool conflict = false;
     int comboProfile = m_view.dvd_profile->currentIndex();
-    for (int i = 0; i < m_view.vobs_list->topLevelItemCount(); i++) {
-        QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(i);
+    for (int i = 0; i < m_vobList->topLevelItemCount(); i++) {
+        QTreeWidgetItem *item = m_vobList->topLevelItem(i);
         if (item->data(0, Qt::UserRole + 1).toInt() != comboProfile) {
            conflict = true;
            break;
        }
     }
-
+    m_transcodeAction->setEnabled(conflict);
     if (conflict) {
-       m_warnMessage->animatedShow();
+       showProfileError();
     }
-    else m_warnMessage->animatedHide();
+    else {
+#if KDE_IS_VERSION(4,7,0)      
+       m_warnMessage->animatedHide();
+#else
+       if (m_installCheck) m_view.error_message->setVisible(false);
 #endif
+    }
 }
 
-void DvdWizardVob::slotAddVobFile(KUrl url, const QString &chapters)
+void DvdWizardVob::slotAddVobList(QList <QUrl>list)
+{
+    foreach (const QUrl url, list) {
+       slotAddVobFile(KUrl(url), QString(), false);
+    }
+    slotCheckVobList();
+    slotCheckProfiles();
+}
+
+void DvdWizardVob::slotAddVobFile(KUrl url, const QString &chapters, bool checkFormats)
 {
     if (url.isEmpty()) url = KFileDialog::getOpenUrl(KUrl("kfiledialog:///projectfolder"), "video/mpeg", this, i18n("Add new video file"));
     if (url.isEmpty()) return;
@@ -120,12 +184,14 @@ void DvdWizardVob::slotAddVobFile(KUrl url, const QString &chapters)
 
     Mlt::Profile profile;
     profile.set_explicit(false);
-    QTreeWidgetItem *item = new QTreeWidgetItem(m_view.vobs_list, QStringList() << url.path() << QString() << KIO::convertSize(fileSize));
-    item->setData(0, Qt::UserRole, fileSize);
+    QTreeWidgetItem *item = new QTreeWidgetItem(m_vobList, QStringList() << url.path() << QString() << KIO::convertSize(fileSize));
+    item->setData(2, Qt::UserRole, fileSize);
     item->setData(0, Qt::DecorationRole, KIcon("video-x-generic").pixmap(60, 45));
     item->setToolTip(0, url.path());
-    
-    Mlt::Producer *producer = new Mlt::Producer(profile, url.path().toUtf8().data());
+
+    QString resource = url.path();
+    resource.prepend("avformat:");
+    Mlt::Producer *producer = new Mlt::Producer(profile, resource.toUtf8().data());
     if (producer && producer->is_valid() && !producer->is_blank()) {
        //Mlt::Frame *frame = producer->get_frame();
        //delete frame;
@@ -166,7 +232,8 @@ void DvdWizardVob::slotAddVobFile(KUrl url, const QString &chapters)
        }
        item->setData(0, Qt::UserRole, standardName);
        item->setData(0, Qt::UserRole + 1, standard);
-       if (m_view.vobs_list->topLevelItemCount() == 1) {
+       item->setData(0, Qt::UserRole + 2, QSize(profile.dar() * profile.height(), profile.height()));
+       if (m_vobList->topLevelItemCount() == 1) {
            // This is the first added movie, auto select DVD format
            if (standard >= 0) {
                m_view.dvd_profile->blockSignals(true);
@@ -176,6 +243,10 @@ void DvdWizardVob::slotAddVobFile(KUrl url, const QString &chapters)
        }
        
     }
+    else {
+       // Cannot load movie, reject
+       showError(i18n("The clip %1 is invalid.", url.fileName()));
+    }
     if (producer) delete producer;
 
     if (chapters.isEmpty() == false) {
@@ -201,54 +272,15 @@ void DvdWizardVob::slotAddVobFile(KUrl url, const QString &chapters)
     } else // Explicitly add a chapter at 00:00:00:00
         item->setData(1, Qt::UserRole + 1, "0");
 
-    slotCheckVobList();
-    slotCheckProfiles();
-}
-
-void DvdWizardVob::changeFormat()
-{
-    int max = m_view.vobs_list->topLevelItemCount();
-    QString profilename;
-    switch (m_view.dvd_profile->currentIndex()) {
-    case 1:
-        profilename = "dv_pal_wide";
-        break;
-    case 2:
-        profilename = "dv_ntsc";
-        break;
-    case 3:
-        profilename = "dv_ntsc_wide";
-        break;
-    default:
-        profilename = "dv_pal";
-        break;
-    }
-
-    Mlt::Profile profile(profilename.toUtf8().constData());
-    QPixmap pix(180, 135);
-
-    for (int i = 0; i < max; i++) {
-        QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(i);
-        Mlt::Producer *producer = new Mlt::Producer(profile, item->text(0).toUtf8().data());
-
-        if (producer->is_blank() == false) {
-            //pix = KThumb::getFrame(producer, 0, 135 * profile.dar(), 135);
-            //item->setIcon(0, pix);
-            item->setText(1, Timecode::getStringTimecode(producer->get_playtime(), profile.fps()));
-        }
-        delete producer;
-        int submax = item->childCount();
-        for (int j = 0; j < submax; j++) {
-            QTreeWidgetItem *subitem = item->child(j);
-            subitem->setText(1, Timecode::getStringTimecode(subitem->data(1, Qt::UserRole).toInt(), profile.fps()));
-        }
+    if (checkFormats) {
+       slotCheckVobList();
+       slotCheckProfiles();
     }
-    slotCheckVobList();
 }
 
 void DvdWizardVob::slotDeleteVobFile()
 {
-    QTreeWidgetItem *item = m_view.vobs_list->currentItem();
+    QTreeWidgetItem *item = m_vobList->currentItem();
     if (item == NULL) return;
     delete item;
     slotCheckVobList();
@@ -259,8 +291,8 @@ void DvdWizardVob::slotDeleteVobFile()
 // virtual
 bool DvdWizardVob::isComplete() const
 {
-    if (!m_view.error_message->text().isEmpty()) return false;
-    if (m_view.vobs_list->topLevelItemCount() == 0) return false;
+    if (!m_installCheck) return false;
+    if (m_vobList->topLevelItemCount() == 0) return false;
     return true;
 }
 
@@ -273,9 +305,9 @@ QStringList DvdWizardVob::selectedUrls() const
 {
     QStringList result;
     QString path;
-    int max = m_view.vobs_list->topLevelItemCount();
+    int max = m_vobList->topLevelItemCount();
     for (int i = 0; i < max; i++) {
-        QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(i);
+        QTreeWidgetItem *item = m_vobList->topLevelItem(i);
         if (item) result.append(item->text(0));
     }
     return result;
@@ -286,9 +318,9 @@ QStringList DvdWizardVob::durations() const
 {
     QStringList result;
     QString path;
-    int max = m_view.vobs_list->topLevelItemCount();
+    int max = m_vobList->topLevelItemCount();
     for (int i = 0; i < max; i++) {
-        QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(i);
+        QTreeWidgetItem *item = m_vobList->topLevelItem(i);
         if (item) result.append(QString::number(item->data(1, Qt::UserRole).toInt()));
     }
     return result;
@@ -298,9 +330,9 @@ QStringList DvdWizardVob::chapters() const
 {
     QStringList result;
     QString path;
-    int max = m_view.vobs_list->topLevelItemCount();
+    int max = m_vobList->topLevelItemCount();
     for (int i = 0; i < max; i++) {
-        QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(i);
+        QTreeWidgetItem *item = m_vobList->topLevelItem(i);
         if (item) {
             result.append(item->data(1, Qt::UserRole + 1).toString());
         }
@@ -310,9 +342,9 @@ QStringList DvdWizardVob::chapters() const
 
 void DvdWizardVob::updateChapters(QMap <QString, QString> chaptersdata)
 {
-    int max = m_view.vobs_list->topLevelItemCount();
+    int max = m_vobList->topLevelItemCount();
     for (int i = 0; i < max; i++) {
-        QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(i);
+        QTreeWidgetItem *item = m_vobList->topLevelItem(i);
         if (chaptersdata.contains(item->text(0))) item->setData(1, Qt::UserRole + 1, chaptersdata.value(item->text(0)));
     }
 }
@@ -320,7 +352,7 @@ void DvdWizardVob::updateChapters(QMap <QString, QString> chaptersdata)
 int DvdWizardVob::duration(int ix) const
 {
     int result = -1;
-    QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(ix);
+    QTreeWidgetItem *item = m_vobList->topLevelItem(ix);
     if (item) {
         result = item->data(1, Qt::UserRole).toInt();
     }
@@ -344,20 +376,20 @@ void DvdWizardVob::setIntroMovie(const QString& path)
 void DvdWizardVob::slotCheckVobList()
 {
     emit completeChanged();
-    int max = m_view.vobs_list->topLevelItemCount();
-    QTreeWidgetItem *item = m_view.vobs_list->currentItem();
+    int max = m_vobList->topLevelItemCount();
+    QTreeWidgetItem *item = m_vobList->currentItem();
     bool hasItem = true;
     if (item == NULL) hasItem = false;
     m_view.button_delete->setEnabled(hasItem);
-    if (hasItem && m_view.vobs_list->indexOfTopLevelItem(item) == 0) m_view.button_up->setEnabled(false);
+    if (hasItem && m_vobList->indexOfTopLevelItem(item) == 0) m_view.button_up->setEnabled(false);
     else m_view.button_up->setEnabled(hasItem);
-    if (hasItem && m_view.vobs_list->indexOfTopLevelItem(item) == max - 1) m_view.button_down->setEnabled(false);
+    if (hasItem && m_vobList->indexOfTopLevelItem(item) == max - 1) m_view.button_down->setEnabled(false);
     else m_view.button_down->setEnabled(hasItem);
 
     qint64 totalSize = 0;
     for (int i = 0; i < max; i++) {
-        item = m_view.vobs_list->topLevelItem(i);
-        if (item) totalSize += (qint64) item->data(0, Qt::UserRole).toInt();
+        item = m_vobList->topLevelItem(i);
+        if (item) totalSize += (qint64) item->data(2, Qt::UserRole).toInt();
     }
 
     qint64 maxSize = (qint64) 47000 * 100000;
@@ -367,21 +399,21 @@ void DvdWizardVob::slotCheckVobList()
 
 void DvdWizardVob::slotItemUp()
 {
-    QTreeWidgetItem *item = m_view.vobs_list->currentItem();
+    QTreeWidgetItem *item = m_vobList->currentItem();
     if (item == NULL) return;
-    int index = m_view.vobs_list->indexOfTopLevelItem(item);
+    int index = m_vobList->indexOfTopLevelItem(item);
     if (index == 0) return;
-    m_view.vobs_list->insertTopLevelItem(index - 1, m_view.vobs_list->takeTopLevelItem(index));
+    m_vobList->insertTopLevelItem(index - 1, m_vobList->takeTopLevelItem(index));
 }
 
 void DvdWizardVob::slotItemDown()
 {
-    int max = m_view.vobs_list->topLevelItemCount();
-    QTreeWidgetItem *item = m_view.vobs_list->currentItem();
+    int max = m_vobList->topLevelItemCount();
+    QTreeWidgetItem *item = m_vobList->currentItem();
     if (item == NULL) return;
-    int index = m_view.vobs_list->indexOfTopLevelItem(item);
+    int index = m_vobList->indexOfTopLevelItem(item);
     if (index == max - 1) return;
-    m_view.vobs_list->insertTopLevelItem(index + 1, m_view.vobs_list->takeTopLevelItem(index));
+    m_vobList->insertTopLevelItem(index + 1, m_vobList->takeTopLevelItem(index));
 }
 
 DVDFORMAT DvdWizardVob::dvdFormat() const
@@ -430,13 +462,176 @@ QString DvdWizardVob::getDvdProfile(DVDFORMAT format)
 
 void DvdWizardVob::setProfile(const QString& profile)
 {
-    if (profile == "dv_pal") m_view.dvd_profile->setCurrentIndex(PAL);
-    else if (profile == "dv_pal_wide") m_view.dvd_profile->setCurrentIndex(PAL_WIDE);
+    if (profile == "dv_pal_wide") m_view.dvd_profile->setCurrentIndex(PAL_WIDE);
     else if (profile == "dv_ntsc") m_view.dvd_profile->setCurrentIndex(NTSC);
     else if (profile == "dv_ntsc_wide") m_view.dvd_profile->setCurrentIndex(NTSC_WIDE);
+    else m_view.dvd_profile->setCurrentIndex(PAL);
 }
 
 void DvdWizardVob::clear()
 {
-    m_view.vobs_list->clear();
+    m_vobList->clear();
 }
+
+void DvdWizardVob::slotTranscodeFiles()
+{
+    // Find transcoding infos related to selected DVD profile
+    KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc");
+    KConfigGroup transConfig(config, "Transcoding");
+    // read the entries
+    QString profileEasyName;
+    QSize destSize;
+    QSize finalSize;
+    switch (m_view.dvd_profile->currentIndex()) {
+       case PAL_WIDE:
+           profileEasyName = "DVD PAL 16:9";
+           destSize = QSize(1024, 576);
+           finalSize = QSize(720, 576);
+           break;
+       case NTSC:
+           profileEasyName = "DVD NTSC 4:3";
+           destSize = QSize(640, 480);
+           finalSize = QSize(720, 480);
+           break;
+       case NTSC_WIDE:
+           profileEasyName = "DVD NTSC 16:9";
+           destSize = QSize(853, 480);
+           finalSize = QSize(720, 480);
+           break;
+       default:
+           profileEasyName = "DVD PAL 4:3";
+           destSize = QSize(768, 576);
+           finalSize = QSize(720, 576);
+    }
+    QString params = transConfig.readEntry(profileEasyName);    
+  
+    // Transcode files that do not match selected profile
+    int max = m_vobList->topLevelItemCount();
+    int format = m_view.dvd_profile->currentIndex();
+    for (int i = 0; i < max; i++) {
+        QTreeWidgetItem *item = m_vobList->topLevelItem(i);
+       if (item->data(0, Qt::UserRole + 1).toInt() != format) {
+           // File needs to be transcoded
+           m_transcodeAction->setEnabled(false);
+           QSize original = item->data(0, Qt::UserRole + 2).toSize();
+           double input_aspect= (double) original.width() / original.height();
+           QStringList postParams;
+           if (input_aspect > (double) destSize.width() / destSize.height()) {
+               // letterboxing
+               int conv_height = (int) (destSize.width() / input_aspect);
+               int conv_pad = (int) (((double) (destSize.height() - conv_height)) / 2.0);
+               if (conv_pad %2 == 1) conv_pad --;
+               postParams << "-vf" << QString("scale=%1:%2,pad=%3:%4:0:%5,setdar=%6").arg(finalSize.width()).arg(destSize.height() - 2 * conv_pad).arg(finalSize.width()).arg(finalSize.height()).arg(conv_pad).arg(input_aspect);
+           } else {
+               // pillarboxing
+               int conv_width = (int) (destSize.height() * input_aspect);
+               int conv_pad = (int) (((double) (destSize.width() - conv_width)) / destSize.width() * finalSize.width() / 2.0);
+               if (conv_pad %2 == 1) conv_pad --;
+               postParams << "-vf" << QString("scale=%1:%2,pad=%3:%4:%5:0,setdar=%6").arg(finalSize.width() - 2 * conv_pad).arg(destSize.height()).arg(finalSize.width()).arg(finalSize.height()).arg(conv_pad).arg(input_aspect);
+           }
+           ClipTranscode *d = new ClipTranscode(KUrl::List () << KUrl(item->text(0)), params.section(';', 0, 0), postParams, i18n("Transcoding to DVD format"), true, this);
+           connect(d, SIGNAL(transcodedClip(KUrl,KUrl)), this, SLOT(slotTranscodedClip(KUrl, KUrl)));
+           d->show();
+       }
+    }
+}
+
+void DvdWizardVob::slotTranscodedClip(KUrl src, KUrl transcoded)
+{
+    int max = m_vobList->topLevelItemCount();
+    for (int i = 0; i < max; i++) {
+        QTreeWidgetItem *item = m_vobList->topLevelItem(i);
+       if (KUrl(item->text(0)).path() == src.path()) {
+           // Replace movie with transcoded version
+           item->setText(0, transcoded.path());
+
+           QFile f(transcoded.path());
+           qint64 fileSize = f.size();
+
+           Mlt::Profile profile;
+           profile.set_explicit(false);
+           item->setText(2, KIO::convertSize(fileSize));
+           item->setData(2, Qt::UserRole, fileSize);
+           item->setData(0, Qt::DecorationRole, KIcon("video-x-generic").pixmap(60, 45));
+           item->setToolTip(0, transcoded.path());
+
+           QString resource = transcoded.path();
+           resource.prepend("avformat:");
+           Mlt::Producer *producer = new Mlt::Producer(profile, resource.toUtf8().data());
+           if (producer && producer->is_valid() && !producer->is_blank()) {
+               profile.from_producer(*producer);
+               int width = 45.0 * profile.dar();
+               int swidth = 45.0 * profile.width() / profile.height();
+               if (width % 2 == 1) width++;
+               item->setData(0, Qt::DecorationRole, QPixmap::fromImage(KThumb::getFrame(producer, 0, swidth, width, 45)));
+               int playTime = producer->get_playtime();
+               item->setText(1, Timecode::getStringTimecode(playTime, profile.fps()));
+               item->setData(1, Qt::UserRole, playTime);
+               int standard = -1;
+               int aspect = profile.dar() * 100;
+               if (profile.height() == 576) {
+                   if (aspect > 150) standard = 1;
+                   else standard = 0;
+               }
+               else if (profile.height() == 480) {
+                   if (aspect > 150) standard = 3;
+                   else standard = 2;
+               }
+               QString standardName;
+               switch (standard) {
+                 case 3:
+                     standardName = i18n("NTSC 16:9");
+                     break;
+                 case 2:
+                     standardName = i18n("NTSC 4:3");
+                     break;
+                 case 1:
+                     standardName = i18n("PAL 16:9");
+                     break;
+                 case 0:
+                     standardName = i18n("PAL 4:3");
+                     break;
+                 default:
+                     standardName = i18n("Unknown");
+               }
+               item->setData(0, Qt::UserRole, standardName);
+               item->setData(0, Qt::UserRole + 1, standard);
+               item->setData(0, Qt::UserRole + 2, QSize(profile.dar() * profile.height(), profile.height()));
+           }
+           else {
+               // Cannot load movie, reject
+               showError(i18n("The clip %1 is invalid.", transcoded.fileName()));
+           }
+           if (producer) delete producer;
+           slotCheckVobList();
+           slotCheckProfiles();
+           break;
+       }
+    }
+}
+
+void DvdWizardVob::showProfileError()
+{
+#if KDE_IS_VERSION(4,7,0)
+    m_warnMessage->setText(i18n("Your clips do not match selected DVD format, transcoding required."));
+    m_warnMessage->setCloseButtonVisible(false);
+    m_warnMessage->addAction(m_transcodeAction);
+    m_warnMessage->animatedShow();
+#else
+    m_view.error_message->setText(i18n("Your clips do not match selected DVD format, transcoding required."));
+    m_view.error_message->setVisible(true);
+#endif
+}
+
+void DvdWizardVob::showError(const QString error)
+{
+#if KDE_IS_VERSION(4,7,0)
+    m_warnMessage->setText(error);
+    m_warnMessage->setCloseButtonVisible(true);
+    m_warnMessage->removeAction(m_transcodeAction);
+    m_warnMessage->animatedShow();
+#else
+    m_view.error_message->setText(error);
+    m_view.error_message->setVisible(true);
+#endif    
+}
\ No newline at end of file
index 1208ff39b9f76e5dda68d05e14cf61514a7c3a2f..6f3ad2a48a5866c08af05cc4cc62a524a6a27db5 100644 (file)
 #include <QWizardPage>
 #include <QStyledItemDelegate>
 #include <QPainter>
+#include <QTreeWidget>
+#include <QDragEnterEvent>
+#include <QDropEvent>
 
 enum DVDFORMAT { PAL, PAL_WIDE, NTSC, NTSC_WIDE };
 
+class DvdTreeWidget : public QTreeWidget
+{
+    Q_OBJECT
+public:
+    DvdTreeWidget(QWidget *parent);
+
+protected:
+    virtual void dragEnterEvent(QDragEnterEvent * event );
+    virtual void dropEvent(QDropEvent * event );
+    virtual void mouseDoubleClickEvent( QMouseEvent * );
+    virtual void dragMoveEvent(QDragMoveEvent * event);
+
+signals:
+    void addNewClip();
+    void addClips(QList<QUrl>);
+};
+
 class DvdViewDelegate : public QStyledItemDelegate
 {
     Q_OBJECT
@@ -101,14 +121,20 @@ public:
 
 private:
     Ui::DvdWizardVob_UI m_view;
+    DvdTreeWidget *m_vobList;
     QString m_errorMessage;
     KCapacityBar *m_capacityBar;
+    QAction *m_transcodeAction;
+    bool m_installCheck;
 #if KDE_IS_VERSION(4,7,0)
     KMessageWidget *m_warnMessage;
 #endif
+    void showProfileError();
+    void showError(const QString error);
 
 public slots:
-    void slotAddVobFile(KUrl url = KUrl(), const QString &chapters = QString());
+    void slotAddVobFile(KUrl url = KUrl(), const QString &chapters = QString(), bool checkFormats = true);
+    void slotAddVobList(QList <QUrl>list);
     void slotCheckProfiles();
 
 private slots:
@@ -116,7 +142,8 @@ private slots:
     void slotDeleteVobFile();
     void slotItemUp();
     void slotItemDown();
-    void changeFormat();
+    void slotTranscodeFiles();
+    void slotTranscodedClip(KUrl, KUrl);
 };
 
 #endif
index b4d54169b4cfade91185e590626ea7e76e1b2b21..852a308e3f571dd81e3b664101a3a12b5b025793 100644 (file)
@@ -19,3 +19,7 @@ Remux MPEG-2 PS/VOB=-vcodec copy -acodec copy %1.mpg;Fix audio sync in MPEG-2 vo
 Lossless Matroska=-sn -vcodec huffyuv -acodec flac %1.mkv;High quality lossless encoding
 Wav 48000Hz=-vn -ar 48000 %1.wav;Extract audio as WAV file;audio
 Remux with MKV=-vcodec copy -acodec copy -sn %1.mkv
+DVD PAL 4:3=-f dvd -r 25 -vf scale=720:576 -aspect 4:3 -minrate 0 -maxrate 8000k -muxrate 10080000 -g 15 -bufsize 1835008 -packetsize 2048 -trellis 1 -me_range 63 -acodec ac3 -ab 192k -ar 48000 -vcodec mpeg2video -vb 5000k %1.vob;Dvd PAL
+DVD PAL 16:9=-f dvd -r 25 -vf scale=720:576 -aspect 16:9 -minrate 0 -maxrate 8000k -muxrate 10080000 -g 15 -bufsize 1835008 -packetsize 2048 -trellis 1 -me_range 63 -acodec ac3 -ab 192k -ar 48000 -vcodec mpeg2video -vb 5000k %1.vob;Dvd PAL wide
+DVD NTSC 4:3=-f dvd -r 23.976 -vf scale=720:480 -aspect 4:3 -minrate 0 -maxrate 9000k -muxrate 10080000 -g 18 -bufsize 1835008 -packetsize 2048 -trellis 1 -me_range 63 -acodec ac3 -ab 192k -ar 48000 -vcodec mpeg2video -vb 6000k %1.vob;Dvd PAL
+DVD NTSC 16:9=-f dvd -r 23.976 -vf scale=720:480 -aspect 16:9 -minrate 0 -maxrate 9000k -muxrate 10080000 -g 18 -bufsize 1835008 -packetsize 2048 -trellis 1 -me_range 63 -acodec ac3 -ab 192k -ar 48000 -vcodec mpeg2video -vb 6000k %1.vob;Dvd PAL wide
\ No newline at end of file
index d896068c4414ee5c1b608e2e0e80cebdddd55d2d..3ad959b15571849b9dc8826fd4e9d2ec54609a5b 100644 (file)
@@ -4018,7 +4018,7 @@ void MainWindow::slotTranscode(KUrl::List urls)
         m_messageLabel->setMessage(i18n("No clip to transcode"), ErrorMessage);
         return;
     }
-    ClipTranscode *d = new ClipTranscode(urls, params, desc);
+    ClipTranscode *d = new ClipTranscode(urls, params, QStringList(), desc);
     connect(d, SIGNAL(addClip(KUrl)), this, SLOT(slotAddProjectClip(KUrl)));
     d->show();
 }
index c7080ea0137e6c69f893263dfcd29456fcfdc89f..804d84a0ffff4978791f369948959066ec589731 100644 (file)
@@ -6,77 +6,67 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>319</width>
-    <height>248</height>
+    <width>404</width>
+    <height>261</height>
    </rect>
   </property>
   <layout class="QGridLayout" name="gridLayout_2">
    <property name="margin">
     <number>0</number>
    </property>
-   <item row="1" column="0" colspan="2">
-    <widget class="QCheckBox" name="use_intro">
-     <property name="text">
-      <string>Intro movie</string>
-     </property>
-    </widget>
+   <item row="0" column="2" colspan="6">
+    <widget class="KComboBox" name="dvd_profile"/>
    </item>
-   <item row="1" column="2" colspan="5">
-    <widget class="KUrlRequester" name="intro_vob">
+   <item row="2" column="0" colspan="7">
+    <widget class="QFrame" name="list_frame">
      <property name="sizePolicy">
-      <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+      <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
        <horstretch>0</horstretch>
        <verstretch>0</verstretch>
       </sizepolicy>
      </property>
+     <property name="minimumSize">
+      <size>
+       <width>0</width>
+       <height>20</height>
+      </size>
+     </property>
+     <property name="frameShape">
+      <enum>QFrame::NoFrame</enum>
+     </property>
+     <property name="frameShadow">
+      <enum>QFrame::Raised</enum>
+     </property>
     </widget>
    </item>
-   <item row="2" column="0" colspan="7">
-    <widget class="QTreeWidget" name="vobs_list">
-     <property name="alternatingRowColors">
-      <bool>true</bool>
-     </property>
-     <property name="rootIsDecorated">
-      <bool>true</bool>
-     </property>
-     <property name="headerHidden">
-      <bool>false</bool>
-     </property>
-     <attribute name="headerVisible">
-      <bool>true</bool>
-     </attribute>
-     <column>
-      <property name="text">
-       <string>File</string>
-      </property>
-     </column>
-     <column>
-      <property name="text">
-       <string>Duration</string>
-      </property>
-     </column>
-     <column>
-      <property name="text">
-       <string>Size</string>
-      </property>
-     </column>
-    </widget>
-   </item>
-   <item row="4" column="3">
-    <widget class="QToolButton" name="button_up">
+   <item row="4" column="4">
+    <widget class="QToolButton" name="button_down">
      <property name="text">
       <string>...</string>
      </property>
     </widget>
    </item>
-   <item row="4" column="4">
-    <widget class="QToolButton" name="button_down">
+   <item row="6" column="0" colspan="8">
+    <widget class="QLabel" name="error_message">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
      <property name="text">
-      <string>...</string>
+      <string/>
      </property>
     </widget>
    </item>
-   <item row="4" column="5" colspan="2">
+   <item row="5" column="0" colspan="8">
+    <widget class="QGroupBox" name="size_box">
+     <property name="title">
+      <string/>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="5">
     <spacer name="horizontalSpacer">
      <property name="orientation">
       <enum>Qt::Horizontal</enum>
      </property>
     </spacer>
    </item>
-   <item row="5" column="0" colspan="7">
-    <widget class="QGroupBox" name="size_box">
-     <property name="title">
-      <string/>
+   <item row="4" column="3">
+    <widget class="QToolButton" name="button_up">
+     <property name="text">
+      <string>...</string>
      </property>
     </widget>
    </item>
-   <item row="6" column="0" colspan="7">
-    <widget class="QLabel" name="error_message">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
+   <item row="1" column="0" colspan="2">
+    <widget class="QCheckBox" name="use_intro">
+     <property name="text">
+      <string>Intro movie</string>
      </property>
+    </widget>
+   </item>
+   <item row="4" column="1">
+    <widget class="QPushButton" name="button_add">
      <property name="text">
-      <string/>
+      <string>Add movie file</string>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="6">
+    <widget class="QToolButton" name="button_transcode">
+     <property name="text">
+      <string>...</string>
      </property>
     </widget>
    </item>
      </property>
     </widget>
    </item>
-   <item row="4" column="1">
-    <widget class="QPushButton" name="button_add">
-     <property name="text">
-      <string>Add movie file</string>
+   <item row="1" column="2" colspan="6">
+    <widget class="KUrlRequester" name="intro_vob">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
      </property>
     </widget>
    </item>
      </property>
     </widget>
    </item>
-   <item row="0" column="2" colspan="5">
-    <widget class="KComboBox" name="dvd_profile"/>
-   </item>
   </layout>
  </widget>
  <customwidgets>
-  <customwidget>
-   <class>KUrlRequester</class>
-   <extends>QFrame</extends>
-   <header>kurlrequester.h</header>
-  </customwidget>
   <customwidget>
    <class>KComboBox</class>
    <extends>QComboBox</extends>
    <header>kcombobox.h</header>
   </customwidget>
+  <customwidget>
+   <class>KUrlRequester</class>
+   <extends>QFrame</extends>
+   <header>kurlrequester.h</header>
+  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>