]> git.sesse.net Git - kdenlive/commitdiff
Merge branch 'master' into feature/pkey
authorEd Rogalsky <ed.rogalsky@googlemail.com>
Sat, 3 Nov 2012 17:53:21 +0000 (18:53 +0100)
committerEd Rogalsky <ed.rogalsky@googlemail.com>
Sat, 3 Nov 2012 17:53:21 +0000 (18:53 +0100)
22 files changed:
src/clipproperties.cpp
src/clipproperties.h
src/cliptranscode.cpp
src/cliptranscode.h
src/dvdwizard.cpp
src/dvdwizard.h
src/dvdwizardchapters.cpp
src/dvdwizardchapters.h
src/dvdwizardmenu.cpp
src/dvdwizardmenu.h
src/dvdwizardvob.cpp
src/dvdwizardvob.h
src/kdenlivesettingsdialog.cpp
src/kdenlivetranscodingrc
src/mainwindow.cpp
src/mainwindow.h
src/projectlist.cpp
src/projectlist.h
src/renderwidget.cpp
src/renderwidget.h
src/statusbarmessagelabel.cpp
src/widgets/dvdwizardvob_ui.ui

index 22bc7269baa9513479376c3679698f64386cf507..67acc240ddf61b387ce37f36f245afcfa3ddc0cc 100644 (file)
@@ -27,6 +27,7 @@
 #include <KStandardDirs>
 #include <KDebug>
 #include <KFileItem>
+#include <KFileDialog>
 #include <kdeversion.h>
 #include <KUrlLabel>
 #include <KRun>
@@ -820,7 +821,32 @@ void ClipProperties::slotDeleteMarker()
 void ClipProperties::slotDeleteAnalysis()
 {
     QTreeWidgetItem *current = m_view.analysis_list->currentItem();
-    if (current) emit deleteAnalysis(m_clip->getId(), current->text(0));
+    if (current) emit editAnalysis(m_clip->getId(), current->text(0), QString());
+}
+
+void ClipProperties::slotSaveAnalysis()
+{
+    QString url = KFileDialog::getSaveFileName(KUrl("kfiledialog:///projectfolder"), "text/plain", this, i18n("Save Analysis Data"));
+    if (url.isEmpty()) return;
+    KSharedConfigPtr config = KSharedConfig::openConfig(url, KConfig::SimpleConfig);
+    KConfigGroup analysisConfig(config, "Analysis");
+    QTreeWidgetItem *current = m_view.analysis_list->currentItem();
+    analysisConfig.writeEntry(current->text(0), current->text(1));
+}
+
+void ClipProperties::slotLoadAnalysis()
+{
+    QString url = KFileDialog::getOpenFileName(KUrl("kfiledialog:///projectfolder"), "text/plain", this, i18n("Open Analysis Data"));
+    if (url.isEmpty()) return;
+    KSharedConfigPtr config = KSharedConfig::openConfig(url, KConfig::SimpleConfig);
+    KConfigGroup transConfig(config, "Analysis");
+    // read the entries
+    QMap< QString, QString > profiles = transConfig.entryMap();
+    QMapIterator<QString, QString> i(profiles);
+    while (i.hasNext()) {
+       i.next();
+       emit editAnalysis(m_clip->getId(), i.key(), i.value());
+    }
 }
 
 const QString &ClipProperties::clipId() const
index 18ef15fdfbf86ddc11cffcd0475733baf53fb6ed..72bafa94b73028d20f61be55b5eb34e0970bb7db 100644 (file)
@@ -77,6 +77,8 @@ private slots:
     void slotLoadMarkers();
     void slotDeleteAnalysis();
     void slotGotThumbnail(const QString &id, QImage img);
+    void slotSaveAnalysis();
+    void slotLoadAnalysis();
 
 private:
     Ui::ClipProperties_UI m_view;
@@ -97,9 +99,9 @@ signals:
     void addMarkers(const QString &, QList <CommentedTime>);
     void deleteProxy(const QString);
     void applyNewClipProperties(const QString, QMap <QString, QString> , QMap <QString, QString> , bool, bool);
-    void saveMarkers(const QString &);
-    void loadMarkers(const QString &);
-    void deleteAnalysis(const QString &, const QString &);
+    void saveMarkers(const QString &id);
+    void loadMarkers(const QString &id);
+    void editAnalysis(const QString &id, const QString &name, const QString &value);
 };
 
 
index c91ec59826bed8b6acdf6e969ded5268d6b27b64..22df000d209574253f7c8af1deb2f03dc41f722c 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());
 
@@ -74,7 +77,7 @@ ClipTranscode::ClipTranscode(KUrl::List urls, const QString &params, const QStri
         } else transcode_info->setHidden(true);
     } else {
         // load Profiles
-        KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc");
+        KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc", KConfig::CascadeConfig);
         KConfigGroup transConfig(config, "Transcoding");
         // read the entries
         QMap< QString, QString > profiles = transConfig.entryMap();
@@ -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 0a411e659b5d0ba5f30e7823435e4bd532f46418..741d5e6f67e1dafbd79e1b3904cc7c1384cda5be 100644 (file)
@@ -19,6 +19,7 @@
 
 
 #include "dvdwizard.h"
+#include "dvdwizardvob.h"
 #include "kdenlivesettings.h"
 #include "profilesdialog.h"
 #include "timecode.h"
@@ -39,7 +40,7 @@
 #include <QGridLayout>
 
 
-DvdWizard::DvdWizard(const QString &url, const QString &profile, QWidget *parent) :
+DvdWizard::DvdWizard(const QString &url, QWidget *parent) :
         QWizard(parent),
         m_dvdauthor(NULL),
         m_mkiso(NULL),
@@ -47,19 +48,19 @@ DvdWizard::DvdWizard(const QString &url, const QString &profile, QWidget *parent
 {
     setWindowTitle(i18n("DVD Wizard"));
     //setPixmap(QWizard::WatermarkPixmap, QPixmap(KStandardDirs::locate("appdata", "banner.png")));
-    m_pageVob = new DvdWizardVob(profile, this);
+    m_pageVob = new DvdWizardVob(this);
     m_pageVob->setTitle(i18n("Select Files For Your DVD"));
     addPage(m_pageVob);
     if (!url.isEmpty()) m_pageVob->setUrl(url);
 
 
-    m_pageChapters = new DvdWizardChapters(m_pageVob->isPal(), this);
+    m_pageChapters = new DvdWizardChapters(m_pageVob->dvdFormat(), this);
     m_pageChapters->setTitle(i18n("DVD Chapters"));
     addPage(m_pageChapters);
 
 
 
-    m_pageMenu = new DvdWizardMenu(profile, this);
+    m_pageMenu = new DvdWizardMenu(m_pageVob->dvdFormat(), this);
     m_pageMenu->setTitle(i18n("Create DVD Menu"));
     addPage(m_pageMenu);
 
@@ -127,6 +128,7 @@ DvdWizard::~DvdWizard()
     m_authorFile.remove();
     m_menuFile.remove();
     m_menuVobFile.remove();
+    m_letterboxMovie.remove();
     blockSignals(true);
     delete m_burnMenu;
     if (m_dvdauthor) {
@@ -150,12 +152,12 @@ void DvdWizard::slotPageChanged(int page)
         m_pageChapters->stopMonitor();
         m_pageVob->updateChapters(m_pageChapters->chaptersData());
     } else if (page == 1) {
-        m_pageChapters->setVobFiles(m_pageVob->isPal(), m_pageVob->isWide(), m_pageVob->selectedUrls(), m_pageVob->durations(), m_pageVob->chapters());
+        m_pageChapters->setVobFiles(m_pageVob->dvdFormat(), m_pageVob->selectedUrls(), m_pageVob->durations(), m_pageVob->chapters());
     } else if (page == 2) {
         m_pageChapters->stopMonitor();
         m_pageVob->updateChapters(m_pageChapters->chaptersData());
         m_pageMenu->setTargets(m_pageChapters->selectedTitles(), m_pageChapters->selectedTargets());
-        m_pageMenu->changeProfile(m_pageVob->isPal());
+        m_pageMenu->changeProfile(m_pageVob->dvdFormat());
     }
 }
 
@@ -201,6 +203,12 @@ void DvdWizard::generateDvd()
     //temp6.setAutoRemove(false);
     temp6.open();
 
+    m_letterboxMovie.close();
+    m_letterboxMovie.setSuffix(".mpg");
+    m_letterboxMovie.setAutoRemove(false);
+    m_letterboxMovie.open();
+    
+
     m_menuFile.close();
     m_menuFile.setSuffix(".xml");
     m_menuFile.setAutoRemove(false);
@@ -225,6 +233,7 @@ void DvdWizard::generateDvd()
     m_status.error_log->clear();
     // initialize html content
     m_status.error_log->setText("<html></html>");
+    QString menuMovieUrl;
 
     if (m_pageMenu->createMenu()) {
         m_pageMenu->createButtonImages(temp1.fileName(), temp2.fileName(), temp3.fileName());
@@ -242,9 +251,7 @@ void DvdWizard::generateDvd()
             qApp->processEvents();
 
             QStringList args;
-            args.append("-profile");
-            if (m_pageMenu->isPalMenu()) args.append("dv_pal");
-            else args.append("dv_ntsc");
+            args << "-profile" << m_pageVob->dvdProfile();
             args.append(temp4.fileName());
             args.append("in=0");
             args.append("out=100");
@@ -282,9 +289,6 @@ void DvdWizard::generateDvd()
             vobitem->setIcon(KIcon("system-run"));
             qApp->processEvents();
 
-           QString std;
-           if (m_pageMenu->isPalMenu()) std = "dv_pal";
-           else std = "dv_ntsc";
            int menuLength = m_pageMenu->menuMovieLength();
            if (menuLength == -1) {
                // menu movie is invalid
@@ -293,10 +297,9 @@ void DvdWizard::generateDvd()
                 m_status.button_abort->setEnabled(false);
                 return;
            }
-
             QStringList args;
             args.append("-profile");
-            args.append(std);
+            args.append(m_pageVob->dvdProfile());
             args.append(m_pageMenu->menuMoviePath());
            args << "-track" << temp4.fileName();
            args << "out=" + QString::number(menuLength);
@@ -386,21 +389,21 @@ void DvdWizard::generateDvd()
         }
         data.close();
 
-        kDebug() << " SPUMUX DATA: " << doc.toString();
+        //kDebug() << " SPUMUX DATA: " << doc.toString();
 
         QStringList args;
-        args.append(m_menuFile.fileName());
-        kDebug() << "SPM ARGS: " << args << temp5.fileName() << m_menuVobFile.fileName();
+       args << "-s" << "0" << m_menuFile.fileName();
+        //kDebug() << "SPM ARGS: " << args << temp5.fileName() << m_menuVobFile.fileName();
 
         QProcess spumux;
 
 #if QT_VERSION >= 0x040600
         QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
-        env.insert("VIDEO_FORMAT", m_pageVob->isPal() ? "PAL" : "NTSC");
+        env.insert("VIDEO_FORMAT", m_pageVob->dvdFormat() == PAL || m_pageVob->dvdFormat() == PAL_WIDE ? "PAL" : "NTSC");
         spumux.setProcessEnvironment(env);
 #else
         QStringList env = QProcess::systemEnvironment();
-        env << QString("VIDEO_FORMAT=") + QString(m_pageVob->isPal() ? "PAL" : "NTSC");
+        env << QString("VIDEO_FORMAT=") + QString(m_pageVob->dvdFormat() == PAL || m_pageVob->dvdFormat() == PAL_WIDE ? "PAL" : "NTSC");
         spumux.setEnvironment(env);
 #endif
     
@@ -436,9 +439,87 @@ void DvdWizard::generateDvd()
             m_status.button_start->setEnabled(true);
             return;
         }
+        if (m_pageVob->dvdFormat() == PAL_WIDE || m_pageVob->dvdFormat() == NTSC_WIDE) {
+           // Second step processing for 16:9 DVD, add letterbox stream
+           m_pageMenu->createButtonImages(temp1.fileName(), temp2.fileName(), temp3.fileName(), true);
+           buttons = m_pageMenu->buttonsInfo(true);
+           // Remove previous button info
+           while(!spu.firstChild().isNull()) {
+               spu.removeChild(spu.firstChild());
+           }
+
+           max = buttons.count() - 1;
+           i = 0;
+           QMapIterator<QString, QRect> it2(buttons);
+           while (it2.hasNext()) {
+               it2.next();
+               QDomElement but = doc.createElement("button");
+               but.setAttribute("name", 'b' + QString::number(i));
+               if (i < max) but.setAttribute("down", 'b' + QString::number(i + 1));
+               else but.setAttribute("down", "b0");
+               if (i > 0) but.setAttribute("up", 'b' + QString::number(i - 1));
+               else but.setAttribute("up", 'b' + QString::number(max));
+               QRect r = it2.value();
+               // We need to make sure that the y coordinate is a multiple of 2, otherwise button may not be displayed
+               buttonsTarget.append(it2.key());
+               int y0 = r.y() - 2;
+               if (y0 % 2 == 1) y0++;
+               int y1 = r.bottom() + 2;
+               if (y1 % 2 == 1) y1++;
+               but.setAttribute("x0", QString::number(r.x()));
+               but.setAttribute("y0", QString::number(y0));
+               but.setAttribute("x1", QString::number(r.right()));
+               but.setAttribute("y1", QString::number(y1));
+               spu.appendChild(but);
+               i++;
+           }
+
+           //kDebug() << " SPUMUX DATA: " << doc.toString();
+           
+           if (data.open(QFile::WriteOnly)) {
+               data.write(doc.toString().toUtf8());
+           }
+           data.close();
+           spumux.setStandardInputFile(m_menuVobFile.fileName());
+           spumux.setStandardOutputFile(m_letterboxMovie.fileName());
+           args.clear();
+           args << "-s" << "1" << m_menuFile.fileName();
+           spumux.start("spumux", args);
+           //kDebug() << "SPM ARGS LETTERBOX: " << args << temp5.fileName() << m_letterboxMovie.fileName();
+           if (spumux.waitForFinished()) {
+               m_status.error_log->append(spumux.readAllStandardError());
+               if (spumux.exitStatus() == QProcess::CrashExit) {
+                   //TODO: inform user via messagewidget after string freeze
+                   QByteArray result = spumux.readAllStandardError();
+                   spuitem->setIcon(KIcon("dialog-close"));
+                   m_status.error_log->append(result);
+                   m_status.error_box->setHidden(false);
+                   m_status.error_box->setTabBarHidden(false);
+                   m_status.menu_file->setPlainText(m_menuFile.readAll());
+                   m_status.dvd_file->setPlainText(m_authorFile.readAll());
+                   m_status.button_start->setEnabled(true);
+                   kDebug() << "/// RENDERING SPUMUX MENU crashed";
+                   return;
+               }
+           } else {
+               kDebug() << "/// RENDERING SPUMUX MENU timed out";
+               errorMessage(i18n("Rendering job timed out"));
+               spuitem->setIcon(KIcon("dialog-close"));
+               m_status.error_log->append("<a name=\"result\" /><br /><strong>" + i18n("Menu job timed out"));
+               m_status.error_log->scrollToAnchor("result");
+               m_status.error_box->setHidden(false);
+               m_status.error_box->setTabBarHidden(false);
+               m_status.menu_file->setPlainText(m_menuFile.readAll());
+               m_status.dvd_file->setPlainText(m_authorFile.readAll());
+               m_status.button_start->setEnabled(true);
+               return;
+           }
+           menuMovieUrl = m_letterboxMovie.fileName();
+       }
+       else menuMovieUrl = m_menuVobFile.fileName();
 
         spuitem->setIcon(KIcon("dialog-ok"));
-        kDebug() << "/// DONE: " << m_menuVobFile.fileName();
+        kDebug() << "/// DONE: " << menuMovieUrl;
     }
 
     // create dvdauthor xml
@@ -456,7 +537,7 @@ void DvdWizard::generateDvd()
     auth.appendChild(vmgm);
 
     if (m_pageMenu->createMenu() && !m_pageVob->introMovie().isEmpty()) {
-        // intro movie
+        // Use first movie in list as intro movie
         QDomElement menus = dvddoc.createElement("menus");
         vmgm.appendChild(menus);
         QDomElement pgc = dvddoc.createElement("pgc");
@@ -478,6 +559,19 @@ void DvdWizard::generateDvd()
         // DVD main menu
         QDomElement menus = dvddoc.createElement("menus");
         titleset.appendChild(menus);
+       if (m_pageVob->dvdFormat() == PAL_WIDE || m_pageVob->dvdFormat() == NTSC_WIDE) {
+           // Add letterbox stream info
+           QDomElement subpict = dvddoc.createElement("subpicture");
+           QDomElement stream = dvddoc.createElement("stream");
+           stream.setAttribute("id", "0");
+           stream.setAttribute("mode", "widescreen");
+           subpict.appendChild(stream);
+           QDomElement stream2 = dvddoc.createElement("stream");
+           stream2.setAttribute("id", "1");
+           stream2.setAttribute("mode", "letterbox");
+           subpict.appendChild(stream2);
+           menus.appendChild(subpict);
+       }
         QDomElement pgc = dvddoc.createElement("pgc");
         pgc.setAttribute("entry", "root");
         menus.appendChild(pgc);
@@ -486,7 +580,7 @@ void DvdWizard::generateDvd()
         QDomText nametext = dvddoc.createTextNode("{g1 = 0;}");
         pre.appendChild(nametext);
        QDomElement menuvob = dvddoc.createElement("vob");
-        menuvob.setAttribute("file", m_menuVobFile.fileName());
+        menuvob.setAttribute("file", menuMovieUrl);
         pgc.appendChild(menuvob);
         for (int i = 0; i < buttons.count(); i++) {
             QDomElement button = dvddoc.createElement("button");
@@ -509,16 +603,28 @@ void DvdWizard::generateDvd()
     titleset.appendChild(titles);
     QDomElement video = dvddoc.createElement("video");
     titles.appendChild(video);
-    if (m_pageVob->isPal()) video.setAttribute("format", "pal");
-    else video.setAttribute("format", "ntsc");
-
-    if (m_pageVob->isWide()) video.setAttribute("aspect", "16:9");
-    else video.setAttribute("aspect", "4:3");
-
-    QStringList voburls = m_pageVob->selectedUrls();
+    switch (m_pageVob->dvdFormat()) {
+       case PAL_WIDE:
+           video.setAttribute("format", "pal");
+           video.setAttribute("aspect", "16:9");
+           break;
+       case NTSC_WIDE:
+           video.setAttribute("format", "ntsc");
+           video.setAttribute("aspect", "16:9");
+           break;
+       case NTSC:
+           video.setAttribute("format", "ntsc");
+           video.setAttribute("aspect", "4:3");
+           break;
+       default:
+           video.setAttribute("format", "pal");
+           video.setAttribute("aspect", "4:3");
+           break;
+    }
 
     QDomElement pgc2;
-
+    // Get list of clips
+    QStringList voburls = m_pageVob->selectedUrls();
 
     for (int i = 0; i < voburls.count(); i++) {
         if (!voburls.at(i).isEmpty()) {
@@ -570,11 +676,11 @@ void DvdWizard::generateDvd()
     // Set VIDEO_FORMAT variable (required by dvdauthor 0.7)
 #if QT_VERSION >= 0x040600
     QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
-    env.insert("VIDEO_FORMAT", m_pageVob->isPal() ? "PAL" : "NTSC"); 
+    env.insert("VIDEO_FORMAT", m_pageVob->dvdFormat() == PAL || m_pageVob->dvdFormat() == PAL_WIDE ? "PAL" : "NTSC"); 
     m_dvdauthor->setProcessEnvironment(env);
 #else
     QStringList env = QProcess::systemEnvironment();
-    env << QString("VIDEO_FORMAT=") + QString(m_pageVob->isPal() ? "PAL" : "NTSC");
+    env << QString("VIDEO_FORMAT=") + QString(m_pageVob->dvdFormat() == PAL || m_pageVob->dvdFormat() == PAL_WIDE ? "PAL" : "NTSC");
     m_dvdauthor->setEnvironment(env);
 #endif
     connect(m_dvdauthor, SIGNAL(finished(int , QProcess::ExitStatus)), this, SLOT(slotRenderFinished(int, QProcess::ExitStatus)));
@@ -819,19 +925,13 @@ void DvdWizard::slotSave()
     KUrl url = KFileDialog::getSaveUrl(KUrl("kfiledialog:///projectfolder"), "*.kdvd", this, i18n("Save DVD Project"));
     if (url.isEmpty()) return;
 
-    if (currentId() == 0) m_pageChapters->setVobFiles(m_pageVob->isPal(), m_pageVob->isWide(), m_pageVob->selectedUrls(), m_pageVob->durations(), m_pageVob->chapters());
+    if (currentId() == 0) m_pageChapters->setVobFiles(m_pageVob->dvdFormat(), m_pageVob->selectedUrls(), m_pageVob->durations(), m_pageVob->chapters());
 
     QDomDocument doc;
     QDomElement dvdproject = doc.createElement("dvdproject");
-    QString profile;
-    if (m_pageVob->isPal()) profile = "dv_pal";
-    else profile = "dv_ntsc";
-    if (m_pageVob->isWide()) profile.append("_wide");
-    dvdproject.setAttribute("profile", profile);
-
+    dvdproject.setAttribute("profile", m_pageVob->dvdProfile());
     dvdproject.setAttribute("tmp_folder", m_status.tmp_folder->url().path());
     dvdproject.setAttribute("iso_image", m_status.iso_image->url().path());
-
     dvdproject.setAttribute("intro_movie", m_pageVob->introMovie());
 
     doc.appendChild(dvdproject);
@@ -871,13 +971,16 @@ void DvdWizard::slotLoad()
 
     QString profile = dvdproject.attribute("profile");
     m_pageVob->setProfile(profile);
-
+    m_pageVob->clear();
     m_status.tmp_folder->setUrl(KUrl(dvdproject.attribute("tmp_folder")));
     m_status.iso_image->setUrl(KUrl(dvdproject.attribute("iso_image")));
-    m_pageVob->setIntroMovie(dvdproject.attribute("intro_movie"));
+    QString intro = dvdproject.attribute("intro_movie");
+    if (!intro.isEmpty()) {
+       m_pageVob->slotAddVobFile(KUrl(intro));
+       m_pageVob->setUseIntroMovie(true);
+    }
 
     QDomNodeList vobs = doc.elementsByTagName("vob");
-    m_pageVob->clear();
     for (int i = 0; i < vobs.count(); i++) {
         QDomElement e = vobs.at(i).toElement();
         m_pageVob->slotAddVobFile(KUrl(e.attribute("file")), e.attribute("chapters"));
index 4f045be98678bcc0be7135a00f40d2d825536a9e..cff0e0ed4c0cd7a5e259222059446ec85ff18025 100644 (file)
@@ -41,7 +41,7 @@ class DvdWizard : public QWizard
 {
     Q_OBJECT
 public:
-    explicit DvdWizard(const QString &url = QString(), const QString &profile = "dv_pal", QWidget * parent = 0);
+    explicit DvdWizard(const QString &url = QString(), QWidget * parent = 0);
     virtual ~DvdWizard();
 
 private:
@@ -57,6 +57,7 @@ private:
     KTemporaryFile m_authorFile;
     KTemporaryFile m_menuFile;
     KTemporaryFile m_menuVobFile;
+    KTemporaryFile m_letterboxMovie;
     QProcess *m_dvdauthor;
     QProcess *m_mkiso;
     QString m_creationLog;
index 52464b3f6a10bfa296046876f91dcc283923e024..7835c43ac476a47bd4e7e3acc9e7c9c10e3cf86e 100644 (file)
@@ -23,9 +23,9 @@
 
 #include <QFile>
 
-DvdWizardChapters::DvdWizardChapters(bool isPal, QWidget *parent) :
+DvdWizardChapters::DvdWizardChapters(DVDFORMAT format, QWidget *parent) :
         QWizardPage(parent),
-        m_isPal(isPal),
+        m_format(format),
         m_monitor(NULL)
 
 {
@@ -37,7 +37,7 @@ DvdWizardChapters::DvdWizardChapters(bool isPal, QWidget *parent) :
 
     // Build monitor for chapters
 
-    if (m_isPal) m_tc.setFormat(25);
+    if (m_format == PAL || m_format == PAL_WIDE) m_tc.setFormat(25);
     else m_tc.setFormat(30000.0 / 1001);
 
     m_manager = new MonitorManager(this);
@@ -134,18 +134,15 @@ void DvdWizardChapters::slotGoToChapter()
     if (m_view.chapters_list->currentItem()) m_monitor->setTimePos(m_tc.reformatSeparators(m_view.chapters_list->currentItem()->text() + ":00"));
 }
 
-void DvdWizardChapters::setVobFiles(bool isPal, bool isWide, const QStringList &movies, const QStringList &durations, const QStringList &chapters)
+void DvdWizardChapters::setVobFiles(DVDFORMAT format, const QStringList &movies, const QStringList &durations, const QStringList &chapters)
 {
-    m_isPal = isPal;
-    QString profile;
-    if (m_isPal) {
+    m_format = format;
+    QString profile = DvdWizardVob::getDvdProfile(format);
+    if (m_format == PAL || m_format == PAL_WIDE) {
         m_tc.setFormat(25);
-        profile = "dv_pal";
     } else {
         m_tc.setFormat(30000.0 / 1001);
-        profile = "dv_ntsc";
     }
-    if (isWide) profile.append("_wide");
     m_manager->resetProfiles(m_tc);
     if (m_monitor == NULL) {
         m_monitor = new Monitor(Kdenlive::dvdMonitor, m_manager, profile, this);
index 515d9425e834dcdf88b40f9d36c34fb3a4bda562..d8afa4e9d9cc6ad484809d6c42f23da223dda796 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "ui_dvdwizardchapters_ui.h"
 #include "monitor.h"
+#include "dvdwizardvob.h"
 #include "monitormanager.h"
 
 class DvdWizardChapters : public QWizardPage
@@ -34,12 +35,12 @@ class DvdWizardChapters : public QWizardPage
     Q_OBJECT
 
 public:
-    explicit DvdWizardChapters(bool isPal, QWidget * parent = 0);
+    explicit DvdWizardChapters(DVDFORMAT format, QWidget * parent = 0);
     virtual ~DvdWizardChapters();
     virtual bool isComplete() const;
-    void changeProfile(bool isPal);
+    void changeProfile(DVDFORMAT format);
     void setPal(bool isPal);
-    void setVobFiles(bool isPal, bool isWide, const QStringList &movies, const QStringList &durations, const QStringList &chapters);
+    void setVobFiles(DVDFORMAT format, const QStringList &movies, const QStringList &durations, const QStringList &chapters);
     QStringList selectedTitles() const;
     QStringList selectedTargets() const;
     QStringList chapters(int ix) const;
@@ -49,7 +50,7 @@ public:
 
 private:
     Ui::DvdWizardChapters_UI m_view;
-    bool m_isPal;
+    DVDFORMAT m_format;
     MonitorManager *m_manager;
     Monitor *m_monitor;
     Timecode m_tc;
index fb162c89378850a422ce2ddce584a64d8c6b51c6..b922bf9c4e374c02bee6880da8ceb4983a9b2b15 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "kthumb.h"
 
-DvdWizardMenu::DvdWizardMenu(const QString &profile, QWidget *parent) :
+DvdWizardMenu::DvdWizardMenu(DVDFORMAT format, QWidget *parent) :
         QWizardPage(parent),
         m_color(NULL),
         m_safeRect(NULL),
@@ -61,9 +61,7 @@ DvdWizardMenu::DvdWizardMenu(const QString &profile, QWidget *parent) :
     m_view.add_button->setToolTip(i18n("Add new button"));
     m_view.delete_button->setToolTip(i18n("Delete current button"));
 
-    if (profile == "dv_ntsc" || profile == "dv_ntsc_wide") {
-        changeProfile(false);
-    } else changeProfile(true);
+    changeProfile(format);
 
 
     // Create color background
@@ -349,17 +347,29 @@ void DvdWizardMenu::deleteButton()
     }
 }
 
-void DvdWizardMenu::changeProfile(bool isPal)
-{
-    m_isPal = isPal;
-    if (isPal == false) {
-       m_finalSize = QSize(720, 480);
-        m_width = 640;
-        m_height = 480;
-    } else {
-       m_finalSize = QSize(720, 576);
-        m_width = 768;
-        m_height = 576;
+void DvdWizardMenu::changeProfile(DVDFORMAT format)
+{
+    m_format = format;
+    switch (m_format) {
+       case PAL_WIDE:
+           m_finalSize = QSize(720, 576);
+           m_width = 1024;
+           m_height = 576;
+           break;
+       case NTSC_WIDE:
+           m_finalSize = QSize(720, 480);
+           m_width = 853;
+           m_height = 480;
+           break;
+       case NTSC:
+           m_finalSize = QSize(720, 480);
+           m_width = 640;
+           m_height = 480;
+           break;
+       default:
+           m_finalSize = QSize(720, 576);
+           m_width = 768;
+           m_height = 576;
     }
     updatePreview();
 }
@@ -443,9 +453,9 @@ void DvdWizardMenu::buildImage()
     } else if (m_view.background_list->currentIndex() == 2) {
         // video background
         m_movieLength = -1;
-        QString standard = "dv_pal";
-        if (!m_isPal) standard = "dv_ntsc";
-       Mlt::Profile profile(standard.toUtf8().constData());
+       QString profileName = DvdWizardVob::getDvdProfile(m_format);
+       Mlt::Profile profile(profileName.toUtf8().constData());
+       profile.set_explicit(true);
        Mlt::Producer *producer = new Mlt::Producer(profile, m_view.background_image->url().path().toUtf8().data());
        if (producer && producer->is_valid()) {
            pix = QPixmap::fromImage(KThumb::getFrame(producer, 0, m_finalSize.width(), m_width, m_height));
@@ -558,10 +568,19 @@ void DvdWizardMenu::updateColor(QColor c)
 }
 
 
-void DvdWizardMenu::createButtonImages(const QString &img1, const QString &img2, const QString &img3)
+void DvdWizardMenu::createButtonImages(const QString &img1, const QString &img2, const QString &img3, bool letterbox)
 {
     if (m_view.create_menu->isChecked()) {
         m_scene->clearSelection();
+       QRectF source(0, 0, m_width, m_height);
+       QRectF target;
+       if (!letterbox) target = QRectF(0, 0, m_finalSize.width(), m_finalSize.height());
+       else {
+           // Scale the button images to fit a letterbox image
+           double factor = (double) m_width / m_finalSize.width();
+           int letterboxHeight = m_height / factor;
+           target = QRectF(0, (m_finalSize.height() - letterboxHeight) / 2, m_finalSize.width(), letterboxHeight);
+       }
         if (m_safeRect->scene() != 0) m_scene->removeItem(m_safeRect);
         if (m_color->scene() != 0) m_scene->removeItem(m_color);
         if (m_background->scene() != 0) m_scene->removeItem(m_background);
@@ -578,7 +597,7 @@ void DvdWizardMenu::createButtonImages(const QString &img1, const QString &img2,
         QPainter p(&img);
         //p.setRenderHints(QPainter::Antialiasing, false);
         //p.setRenderHints(QPainter::TextAntialiasing, false);
-        m_scene->render(&p, QRectF(0, 0, m_finalSize.width(), m_finalSize.height()), QRectF(0, 0, m_width, m_height), Qt::IgnoreAspectRatio);
+        m_scene->render(&p, target, source, Qt::IgnoreAspectRatio);
         p.end();
 #if QT_VERSION >= 0x040800
 #elif QT_VERSION >= 0x040600 
@@ -598,7 +617,7 @@ void DvdWizardMenu::createButtonImages(const QString &img1, const QString &img2,
         p.begin(&img);
         //p.setRenderHints(QPainter::Antialiasing, false);
         //p.setRenderHints(QPainter::TextAntialiasing, false);
-       m_scene->render(&p, QRectF(0, 0, m_finalSize.width(), m_finalSize.height()), QRectF(0, 0, m_width, m_height), Qt::IgnoreAspectRatio);
+       m_scene->render(&p, target, source, Qt::IgnoreAspectRatio);
         p.end();
 #if QT_VERSION >= 0x040800
 #elif QT_VERSION >= 0x040600
@@ -618,7 +637,7 @@ void DvdWizardMenu::createButtonImages(const QString &img1, const QString &img2,
        p.begin(&img);
         //p.setRenderHints(QPainter::Antialiasing, false);
         //p.setRenderHints(QPainter::TextAntialiasing, false);
-        m_scene->render(&p, QRectF(0, 0, m_finalSize.width(), m_finalSize.height()), QRectF(0, 0, m_width, m_height), Qt::IgnoreAspectRatio);
+        m_scene->render(&p, target, source, Qt::IgnoreAspectRatio);
         p.end();
 #if QT_VERSION >= 0x040800
 #elif QT_VERSION >= 0x040600
@@ -718,16 +737,23 @@ int DvdWizardMenu::menuMovieLength() const
 }
 
 
-QMap <QString, QRect> DvdWizardMenu::buttonsInfo()
+QMap <QString, QRect> DvdWizardMenu::buttonsInfo(bool letterbox)
 {
     QMap <QString, QRect> info;
     QList<QGraphicsItem *> list = m_scene->items();
-    double ratio = (double) m_finalSize.width() / m_width;
+    double ratiox = (double) m_finalSize.width() / m_width;
+    double ratioy = 1;
+    int offset = 0;
+    if (letterbox) {
+       int letterboxHeight = m_height * ratiox;
+       ratioy = (double) letterboxHeight / m_finalSize.height();
+       offset = (m_finalSize.height() - letterboxHeight) / 2;
+    }
     for (int i = 0; i < list.count(); i++) {
         if (list.at(i)->type() == QGraphicsItem::UserType + 1) {
             DvdButton *button = static_cast < DvdButton* >(list.at(i));
            QRectF r = button->sceneBoundingRect();
-           QRect adjustedRect(r.x() * ratio, r.y(), r.width() * ratio, r.height());
+           QRect adjustedRect(r.x() * ratiox, offset + r.y() * ratioy, r.width() * ratiox, r.height() * ratioy);
            // Make sure y1 is not odd (requested by spumux)
             if (adjustedRect.height() % 2 == 1) adjustedRect.setHeight(adjustedRect.height() + 1);
             if (adjustedRect.y() % 2 == 1) adjustedRect.setY(adjustedRect.y() - 1);
@@ -739,11 +765,6 @@ QMap <QString, QRect> DvdWizardMenu::buttonsInfo()
     return info;
 }
 
-bool DvdWizardMenu::isPalMenu() const
-{
-    return m_isPal;
-}
-
 QDomElement DvdWizardMenu::toXml() const
 {
     QDomDocument doc;
index 2ecdcae18b9c41153d5b40bf8680cfd7fe19eb20..3854d8b950c8d713587a4484fb8ab60b55b31aec 100644 (file)
@@ -35,6 +35,7 @@
 #include <KMessageWidget>
 #endif
 
+#include "dvdwizardvob.h"
 #include "ui_dvdwizardmenu_ui.h"
 
 class DvdScene : public QGraphicsScene
@@ -129,20 +130,19 @@ class DvdWizardMenu : public QWizardPage
     Q_OBJECT
 
 public:
-    explicit DvdWizardMenu(const QString &profile, QWidget * parent = 0);
+    explicit DvdWizardMenu(DVDFORMAT format, QWidget * parent = 0);
     virtual ~DvdWizardMenu();
     virtual bool isComplete() const;
     bool createMenu() const;
     void createBackgroundImage(const QString &overlayMenu, const QString &img1);
-    void createButtonImages(const QString &img1, const QString &img2, const QString &img3);
+    void createButtonImages(const QString &img1, const QString &img2, const QString &img3, bool letterbox = false);
     void setTargets(QStringList list, QStringList targetlist);
-    QMap <QString, QRect> buttonsInfo();
+    QMap <QString, QRect> buttonsInfo(bool letterbox = false);
     bool loopMovie() const;
     bool menuMovie() const;
     QString menuMoviePath() const;
     int menuMovieLength() const;
-    bool isPalMenu() const;
-    void changeProfile(bool isPal);
+    void changeProfile(DVDFORMAT format);
     QDomElement toXml() const;
     void loadXml(QDomElement xml);
     void prepareUnderLines();
@@ -150,7 +150,7 @@ public:
 
 private:
     Ui::DvdWizardMenu_UI m_view;
-    bool m_isPal;
+    DVDFORMAT m_format;
     DvdScene *m_scene;
     QGraphicsPixmapItem *m_background;
     QGraphicsRectItem *m_color;
index 0dc32551e98c0f1dc2369be8e36ac108b8f517ea..0d99f697a53446f0011383503aea5296b32f08dd 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>
 
-DvdWizardVob::DvdWizardVob(const QString &profile, QWidget *parent) :
-        QWizardPage(parent)
+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),
+        m_installCheck(true)
 {
     m_view.setupUi(this);
-    m_view.intro_vob->setEnabled(false);
-    m_view.intro_vob->setFilter("video/mpeg");
-    m_view.button_add->setIcon(KIcon("document-new"));
-    m_view.button_delete->setIcon(KIcon("edit-delete"));
+    m_view.button_add->setIcon(KIcon("list-add"));
+    m_view.button_delete->setIcon(KIcon("list-remove"));
     m_view.button_up->setIcon(KIcon("go-up"));
     m_view.button_down->setIcon(KIcon("go-down"));
-    connect(m_view.use_intro, SIGNAL(toggled(bool)), m_view.intro_vob, SLOT(setEnabled(bool)));
+    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.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"));
-    if (profile == "dv_pal_wide") m_view.dvd_profile->setCurrentIndex(1);
-    else if (profile == "dv_ntsc") m_view.dvd_profile->setCurrentIndex(2);
-    else if (profile == "dv_ntsc_wide") m_view.dvd_profile->setCurrentIndex(3);
 
-    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();
@@ -96,54 +140,54 @@ 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;
     QFile f(url.path());
     qint64 fileSize = f.size();
-    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());
+    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;
@@ -184,8 +228,21 @@ void DvdWizardVob::slotAddVobFile(KUrl url, const QString &chapters)
        }
        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()));
+       if (m_vobList->topLevelItemCount() == 1) {
+           // This is the first added movie, auto select DVD format
+           if (standard >= 0) {
+               m_view.dvd_profile->blockSignals(true);
+               m_view.dvd_profile->setCurrentIndex(standard);
+               m_view.dvd_profile->blockSignals(false);
+           }
+       }
        
     }
+    else {
+       // Cannot load movie, reject
+       showError(i18n("The clip %1 is invalid.", url.fileName()));
+    }
     if (producer) delete producer;
 
     if (chapters.isEmpty() == false) {
@@ -211,54 +268,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();
@@ -269,8 +287,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;
 }
 
@@ -283,9 +301,14 @@ QStringList DvdWizardVob::selectedUrls() const
 {
     QStringList result;
     QString path;
-    int max = m_view.vobs_list->topLevelItemCount();
-    for (int i = 0; i < max; i++) {
-        QTreeWidgetItem *item = m_view.vobs_list->topLevelItem(i);
+    int max = m_vobList->topLevelItemCount();
+    int i = 0;
+    if (m_view.use_intro->isChecked()) {
+       // First movie is only for intro
+       i = 1;
+    }
+    for (; i < max; i++) {
+        QTreeWidgetItem *item = m_vobList->topLevelItem(i);
         if (item) result.append(item->text(0));
     }
     return result;
@@ -296,9 +319,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;
@@ -308,9 +331,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());
         }
@@ -320,9 +343,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)));
     }
 }
@@ -330,44 +353,42 @@ 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();
     }
     return result;
 }
 
-
-QString DvdWizardVob::introMovie() const
+const QString DvdWizardVob::introMovie() const
 {
-    if (!m_view.use_intro->isChecked()) return QString();
-    return m_view.intro_vob->url().path();
+    QString url;
+    if (m_view.use_intro->isChecked() && m_vobList->topLevelItemCount() > 0) url = m_vobList->topLevelItem(0)->text(0);
+    return url;
 }
 
-void DvdWizardVob::setIntroMovie(const QString& path)
+void DvdWizardVob::setUseIntroMovie(bool use)
 {
-    m_view.intro_vob->setUrl(KUrl(path));
-    m_view.use_intro->setChecked(path.isEmpty() == false);
+    m_view.use_intro->setChecked(use);
 }
 
-
 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;
@@ -377,42 +398,239 @@ 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));
 }
 
-bool DvdWizardVob::isPal() const
+DVDFORMAT DvdWizardVob::dvdFormat() const
 {
-    return m_view.dvd_profile->currentIndex() < 2;
+    return (DVDFORMAT) m_view.dvd_profile->currentIndex();
 }
 
-bool DvdWizardVob::isWide() const
+const QString DvdWizardVob::dvdProfile() const
 {
-    return (m_view.dvd_profile->currentIndex() == 1 || m_view.dvd_profile->currentIndex() == 3);
+    QString profile;
+    switch (m_view.dvd_profile->currentIndex()) {
+       case PAL_WIDE:
+           profile = "dv_pal_wide";
+           break;
+       case NTSC:
+           profile = "dv_ntsc";
+           break;
+       case NTSC_WIDE:
+           profile = "dv_ntsc_wide";
+           break;
+       default:
+           profile = "dv_pal";
+    }
+    return profile;
+}
+
+//static
+QString DvdWizardVob::getDvdProfile(DVDFORMAT format)
+{
+    QString profile;
+    switch (format) {
+       case PAL_WIDE:
+           profile = "dv_pal_wide";
+           break;
+       case NTSC:
+           profile = "dv_ntsc";
+           break;
+       case NTSC_WIDE:
+           profile = "dv_ntsc_wide";
+           break;
+       default:
+           profile = "dv_pal";
+    }
+    return profile;
 }
 
 void DvdWizardVob::setProfile(const QString& profile)
 {
-    if (profile == "dv_pal") m_view.dvd_profile->setCurrentIndex(0);
-    else if (profile == "dv_pal_wide") m_view.dvd_profile->setCurrentIndex(1);
-    else if (profile == "dv_ntsc") m_view.dvd_profile->setCurrentIndex(2);
-    else if (profile == "dv_ntsc_wide") m_view.dvd_profile->setCurrentIndex(3);
+    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", KConfig::CascadeConfig);
+    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 0b634a7743d04468f5819258aed02ce8c87a137f..a33b562c65a5c2de2098023dd184c4a59c29a385 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
 {
@@ -80,32 +102,39 @@ class DvdWizardVob : public QWizardPage
     Q_OBJECT
 
 public:
-    explicit DvdWizardVob(const QString &profile, QWidget * parent = 0);
+    explicit DvdWizardVob(QWidget * parent = 0);
     virtual ~DvdWizardVob();
     virtual bool isComplete() const;
     QStringList selectedUrls() const;
     void setUrl(const QString &url);
-    QString introMovie() const;
-    bool isPal() const;
-    bool isWide() const;
+    DVDFORMAT dvdFormat() const;
+    const QString dvdProfile() const;
     int duration(int ix) const;
     QStringList durations() const;
     QStringList chapters() const;
     void setProfile(const QString& profile);
     void clear();
+    const QString introMovie() const;
+    void setUseIntroMovie(bool use);
     void updateChapters(QMap <QString, QString> chaptersdata);
-    void setIntroMovie(const QString& path);
+    static QString getDvdProfile(DVDFORMAT format);
 
 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:
@@ -113,7 +142,8 @@ private slots:
     void slotDeleteVobFile();
     void slotItemUp();
     void slotItemDown();
-    void changeFormat();
+    void slotTranscodeFiles();
+    void slotTranscodedClip(KUrl, KUrl);
 };
 
 #endif
index c50b354e1090c6e73044c8d68d3a0336dbf03f92..7afa59472bc36cbd4e965c6f0c52974499c4f92f 100644 (file)
@@ -759,7 +759,7 @@ void KdenliveSettingsDialog::slotCheckAlsaDriver()
 
 void KdenliveSettingsDialog::loadTranscodeProfiles()
 {
-    KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc");
+    KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc", KConfig::CascadeConfig);
     KConfigGroup transConfig(config, "Transcoding");
     // read the entries
     m_configTranscode.profiles_list->blockSignals(true);
@@ -781,7 +781,7 @@ void KdenliveSettingsDialog::loadTranscodeProfiles()
 
 void KdenliveSettingsDialog::saveTranscodeProfiles()
 {
-    KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc");
+    KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc", KConfig::CascadeConfig);
     //KSharedConfigPtr config = KGlobal::config();
     KConfigGroup transConfig(config, "Transcoding");
     // read the entries
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 013a5e14808c14548994ebc7a6a12fb29f6d8740..e8126e0755542159d5baa820280f351033d13f91 100644 (file)
@@ -236,7 +236,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString &
     connect(m_projectList, SIGNAL(clipSelected(DocClipBase *, QPoint, bool)), m_clipMonitor, SLOT(slotSetClipProducer(DocClipBase *, QPoint, bool)));
     connect(m_projectList, SIGNAL(raiseClipMonitor(bool)), m_clipMonitor, SLOT(slotActivateMonitor(bool)));
     connect(m_projectList, SIGNAL(loadingIsOver()), this, SLOT(slotElapsedTime()));
-    connect(m_projectList, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int)));
+    connect(m_projectList, SIGNAL(displayMessage(const QString&, int, MessageType)), this, SLOT(slotGotProgressInfo(const QString&, int, MessageType)));
     connect(m_projectList, SIGNAL(updateRenderStatus()), this, SLOT(slotCheckRenderStatus()));
     connect(m_projectList, SIGNAL(clipNeedsReload(const QString&)),this, SLOT(slotUpdateClip(const QString &)));
     connect(m_projectList, SIGNAL(updateProfile(const QString &)), this, SLOT(slotUpdateProjectProfile(const QString &)));
@@ -2421,7 +2421,7 @@ void MainWindow::slotRenderProject()
         connect(m_renderWidget, SIGNAL(selectedRenderProfile(QMap <QString, QString>)), this, SLOT(slotSetDocumentRenderProfile(QMap <QString, QString>)));
         connect(m_renderWidget, SIGNAL(prepareRenderingData(bool, bool, const QString&)), this, SLOT(slotPrepareRendering(bool, bool, const QString&)));
         connect(m_renderWidget, SIGNAL(abortProcess(const QString &)), this, SIGNAL(abortRenderJob(const QString &)));
-        connect(m_renderWidget, SIGNAL(openDvdWizard(const QString &, const QString &)), this, SLOT(slotDvdWizard(const QString &, const QString &)));
+        connect(m_renderWidget, SIGNAL(openDvdWizard(const QString &)), this, SLOT(slotDvdWizard(const QString &)));
         if (m_activeDocument) {
             m_renderWidget->setProfile(m_activeDocument->mltProfile());
             m_renderWidget->setGuides(m_activeDocument->guidesXml(), m_activeDocument->projectDuration());
@@ -3217,19 +3217,13 @@ void MainWindow::slotUpdateZoomSliderToolTip(int zoomlevel)
     m_zoomSlider->setToolTip(i18n("Zoom Level: %1/13", (13 - zoomlevel)));
 }
 
-void MainWindow::slotGotProgressInfo(const QString &message, int progress)
+void MainWindow::slotGotProgressInfo(const QString &message, int progress, MessageType type)
 {
-    m_statusProgressBar->setValue(progress);
+    if (type == DefaultMessage) m_statusProgressBar->setValue(progress);
+    m_messageLabel->setMessage(message, type);
     if (progress >= 0) {
-        if (!message.isEmpty())
-            m_messageLabel->setMessage(message, InformationMessage);//statusLabel->setText(message);
-        m_statusProgressBar->setVisible(true);
-    } else if (progress == -2) {
-        if (!message.isEmpty())
-            m_messageLabel->setMessage(message, ErrorMessage);
-        m_statusProgressBar->setVisible(false);
+        if (type == DefaultMessage) m_statusProgressBar->setVisible(true);
     } else {
-        m_messageLabel->setMessage(QString(), DefaultMessage);
         m_statusProgressBar->setVisible(false);
     }
 }
@@ -3337,7 +3331,7 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip)
     }
     
     connect(dia, SIGNAL(addMarkers(const QString &, QList <CommentedTime>)), m_activeTimeline->projectView(), SLOT(slotAddClipMarker(const QString &, QList <CommentedTime>)));
-    connect(dia, SIGNAL(deleteAnalysis(QString,QString)), m_activeTimeline->projectView(), SLOT(slotAddClipExtraData(QString,QString)));
+    connect(dia, SIGNAL(editAnalysis(QString,QString,QString)), m_activeTimeline->projectView(), SLOT(slotAddClipExtraData(QString,QString,QString)));
     connect(m_activeTimeline->projectView(), SIGNAL(updateClipMarkers(DocClipBase *)), dia, SLOT(slotFillMarkersList(DocClipBase *)));
     connect(m_activeTimeline->projectView(), SIGNAL(updateClipExtraData(DocClipBase *)), dia, SLOT(slotUpdateAnalysisData(DocClipBase *)));
     connect(m_projectList, SIGNAL(updateAnalysisData(DocClipBase *)), dia, SLOT(slotUpdateAnalysisData(DocClipBase *)));
@@ -3882,12 +3876,12 @@ void MainWindow::slotUpdateClipType(QAction *action)
     }
 }
 
-void MainWindow::slotDvdWizard(const QString &url, const QString &profile)
+void MainWindow::slotDvdWizard(const QString &url)
 {
     // We must stop the monitors since we create a new on in the dvd wizard
     m_clipMonitor->stop();
     m_projectMonitor->stop();
-    QPointer<DvdWizard> w = new DvdWizard(url, profile, this);
+    QPointer<DvdWizard> w = new DvdWizard(url, this);
     w->exec();
     m_projectMonitor->start();
     delete w;
@@ -3954,7 +3948,7 @@ void MainWindow::loadTranscoders()
     QMenu *extractAudioMenu = static_cast<QMenu*>(factory()->container("extract_audio", this));
     extractAudioMenu->clear();
 
-    KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc");
+    KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc", KConfig::CascadeConfig);
     KConfigGroup transConfig(config, "Transcoding");
     // read the entries
     QMap< QString, QString > profiles = transConfig.entryMap();
@@ -4023,7 +4017,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 db1cbc2252d415b8877429a991d45720d1c7ebfc..acba2873dcc8e3dfa3ed21188db0b26c82b2eb36 100644 (file)
@@ -328,7 +328,7 @@ public slots:
     *
     * Checks if already open and whether backup exists */
     void openFile(const KUrl &url);
-    void slotGotProgressInfo(const QString &message, int progress);
+    void slotGotProgressInfo(const QString &message, int progress, MessageType type = DefaultMessage);
     void slotReloadEffects();
     Q_SCRIPTABLE void setRenderingProgress(const QString &url, int progress);
     Q_SCRIPTABLE void setRenderingFinished(const QString &url, int status, const QString &error);
@@ -486,7 +486,7 @@ private slots:
     /** @brief Lets the sampleplugin create a generator.  */
     void generateClip();
     void slotZoneMoved(int start, int end);
-    void slotDvdWizard(const QString &url = QString(), const QString &profile = "dv_pal");
+    void slotDvdWizard(const QString &url = QString());
     void slotGroupClips();
     void slotUnGroupClips();
     void slotEditItemDuration();
index 3cb9cad7bf7e33c779d9775286fca617fd6029a1..5db34b1a4b288e05e0ae2db6986895133576455b 100644 (file)
@@ -587,7 +587,7 @@ void ProjectList::editClipSelection(QList<QTreeWidgetItem *> list)
         kDebug() << "Result: " << p.key() << " = " << p.value();
     }*/
     if (clipList.isEmpty()) {
-        emit displayMessage(i18n("No available clip selected"), -2);
+        emit displayMessage(i18n("No available clip selected"), -2, ErrorMessage);
     }
     else emit showClipProperties(clipList, commonproperties);
 }
@@ -778,7 +778,7 @@ void ProjectList::slotMissingClip(const QString &id)
         }
     }
     update();
-    emit displayMessage(i18n("Check missing clips"), -2);
+    emit displayMessage(i18n("Check missing clips"), -2, ErrorMessage);
     emit updateRenderStatus();
 }
 
@@ -954,10 +954,11 @@ void ProjectList::slotUpdateClipProperties(const QString &id, QMap <QString, QSt
                    properties.contains("xmldata") ||
                    properties.contains("force_aspect_num") ||
                    properties.contains("force_aspect_den") ||
+                   properties.contains("full_luma") ||
                    properties.contains("templatetext")) {
             slotRefreshClipThumbnail(item);
             emit refreshClip(id, true);
-        } else if (properties.contains("full_luma") || properties.contains("force_colorspace") || properties.contains("loop")) {
+        } else if (properties.contains("force_colorspace") || properties.contains("loop")) {
             emit refreshClip(id, false);
         }
     }
@@ -1817,7 +1818,7 @@ void ProjectList::slotRemoveInvalidProxy(const QString &id, bool durationError)
         item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled);
         if (durationError) {
             kDebug() << "Proxy duration is wrong, try changing transcoding parameters.";
-            emit displayMessage(i18n("Proxy clip unusable (duration is different from original)."), -2);
+            emit displayMessage(i18n("Proxy clip unusable (duration is different from original)."), -2, ErrorMessage);
         }
         slotUpdateJobStatus(item, PROXYJOB, JOBCRASHED, i18n("Failed to create proxy for %1. check parameters", item->text(0)), "project_settings");
         QString path = item->referencedClip()->getProperty("proxy");
@@ -2707,7 +2708,7 @@ void ProjectList::slotAddOrUpdateSequence(const QString frameName)
                         
             m_doc->slotCreateSlideshowClipFile(properties, groupInfo.at(0), groupInfo.at(1));
         }
-    } else emit displayMessage(i18n("Sequence not found"), -2);
+    } else emit displayMessage(i18n("Sequence not found"), -2, ErrorMessage);
 }
 
 QMap <QString, QString> ProjectList::getProxies()
@@ -3460,7 +3461,7 @@ void ProjectList::startClipFilterJob(const QString &filterName, const QString &c
     QString destination;
     ProjectItem *item = getItemById(ids.at(0));
     if (!item) {
-        emit displayMessage(i18n("Cannot find clip to process filter %1", filterName), -2);
+        emit displayMessage(i18n("Cannot find clip to process filter %1", filterName), -2, ErrorMessage);
         return;
     }
     if (ids.count() == 1) {
@@ -3489,12 +3490,13 @@ void ProjectList::startClipFilterJob(const QString &filterName, const QString &c
        // Producer params
        jobParams << QString();
        // Filter params, use a smaller region of the image to speed up operation
-       jobParams << filterName << "bounding=\"25%x25%:25%x25\" shot_change_list=0";
+       jobParams << filterName << "bounding=\"25%x25%:15%x15\" shot_change_list=0 denoise=0";
        // Consumer
        jobParams << "null" << "all=1 terminate_on_pause=1 real_time=-1";
        QMap <QString, QString> extraParams;
        extraParams.insert("key", "shot_change_list");
        extraParams.insert("projecttreefilter", "1");
+       extraParams.insert("resultmessage", i18n("Found %1 scenes.", "%count"));
        if (ui.add_markers->isChecked()) {
            // We want to create markers
            extraParams.insert("addmarkers", QString::number(ui.marker_type->currentIndex()));
@@ -3621,14 +3623,19 @@ void ProjectList::slotGotFilterJobResults(QString id, int , int , stringMap resu
     int markersType = -1;
     if (filterInfo.contains("addmarkers")) markersType = filterInfo.value("addmarkers").toInt();
     if (results.isEmpty()) {
-       emit displayMessage(i18n("No data returned from clip analysis"), ErrorMessage);
+       emit displayMessage(i18n("No data returned from clip analysis"), 0, ErrorMessage);
        return;
     }
-    emit displayMessage(i18n("Processing data analysis"), InformationMessage);
     bool dataProcessed = false;
     QString key = filterInfo.value("key");
     QStringList value = results.value(key).split(';', QString::SkipEmptyParts);
     kDebug()<<"// RESULT; "<<key<<" = "<<value;
+    if (filterInfo.contains("resultmessage")) {
+       QString mess = filterInfo.value("resultmessage");
+       mess.replace("%count", QString::number(value.count()));
+       emit displayMessage(mess, 0, InformationMessage);
+    }
+    else emit displayMessage(i18n("Processing data analysis"), 0, InformationMessage);
     if (filterInfo.contains("cutscenes")) {
        // Check if we want to cut scenes from returned data
        dataProcessed = true;
index 49bccdf0e87374f87c74e332bdc6b876378a2eb5..af8605b1e67235bb20657115dcd4a247759affae 100644 (file)
@@ -501,7 +501,7 @@ signals:
     void showClipProperties(QList <DocClipBase *>, QMap<QString, QString> commonproperties);
     void projectModified();
     void loadingIsOver();
-    void displayMessage(const QString, int progress);
+    void displayMessage(const QString, int progress, MessageType type = DefaultMessage);
     void clipNameChanged(const QString, const QString);
     void clipNeedsReload(const QString&);
     /** @brief A property affecting display was changed, so we need to update monitors and thumbnails
index 89887ea1326fdc53fbe161d06b0b9771744579df..78d15196e6493e3f884afb86a78e5b7f65b5e4bf 100644 (file)
@@ -1801,7 +1801,7 @@ void RenderWidget::setRenderStatus(const QString &dest, int status, const QStrin
         item->setData(1, Qt::UserRole, t);
         QString itemGroup = item->data(0, Qt::UserRole).toString();
         if (itemGroup == "dvd") {
-            emit openDvdWizard(item->text(1), item->metadata());
+            emit openDvdWizard(item->text(1));
         } else if (itemGroup == "websites") {
             QString url = item->metadata();
             if (!url.isEmpty()) new KRun(url, this);
index 0fa647ace57fd69a07ce6085733d6b75e46bffca..3b4b644271d7f76f4fd44bf06244b9290a60b32e 100644 (file)
@@ -209,7 +209,7 @@ private:
 
 signals:
     void abortProcess(const QString &url);
-    void openDvdWizard(const QString &url, const QString &profile);
+    void openDvdWizard(const QString &url);
     /** Send the infos about rendering that will be saved in the document:
     (profile destination, profile name and url of rendered file */
     void selectedRenderProfile(QMap <QString, QString> renderProps);
index a50b5db6ba01e03d8a902355e6ffedf856a1752b..acc24487016014c0056a8babe29fb97aef2c5584 100644 (file)
@@ -135,7 +135,7 @@ bool StatusBarMessageLabel::slotMessageTimeout()
 
             // If we only have the default message left to show in the queue,
             // keep the current one for a little longer.
-            m_queueTimer.start(m_currentMessage.timeoutMillis + 2000*(m_messageQueue.at(0).type == DefaultMessage));
+            m_queueTimer.start(m_currentMessage.timeoutMillis + 4000*(m_messageQueue.at(0).type == DefaultMessage));
 
         }
     }
index c7080ea0137e6c69f893263dfcd29456fcfdc89f..515605daeaab704d98776fe19d8954c8a6989e94 100644 (file)
@@ -6,77 +6,43 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>319</width>
-    <height>248</height>
+    <width>459</width>
+    <height>255</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">
+   <item row="3" column="2">
+    <widget class="QPushButton" name="button_delete">
      <property name="text">
-      <string>Intro movie</string>
+      <string>Remove file</string>
      </property>
     </widget>
    </item>
-   <item row="1" column="2" colspan="5">
-    <widget class="KUrlRequester" name="intro_vob">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
+   <item row="3" column="5">
+    <widget class="QCheckBox" name="use_intro">
+     <property name="text">
+      <string>Use first movie as intro</string>
      </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">
-     <property name="text">
-      <string>...</string>
+   <item row="4" column="0" colspan="9">
+    <widget class="QGroupBox" name="size_box">
+     <property name="title">
+      <string/>
      </property>
     </widget>
    </item>
-   <item row="4" column="4">
-    <widget class="QToolButton" name="button_down">
+   <item row="0" column="0" colspan="2">
+    <widget class="QLabel" name="label">
      <property name="text">
-      <string>...</string>
+      <string>DVD format</string>
      </property>
     </widget>
    </item>
-   <item row="4" column="5" colspan="2">
+   <item row="3" column="6">
     <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="3" column="7">
+    <widget class="QToolButton" name="button_transcode">
+     <property name="text">
+      <string>...</string>
      </property>
     </widget>
    </item>
-   <item row="6" column="0" colspan="7">
+   <item row="0" column="2" colspan="7">
+    <widget class="KComboBox" name="dvd_profile"/>
+   </item>
+   <item row="3" column="1">
+    <widget class="QPushButton" name="button_add">
+     <property name="text">
+      <string>Add movie file</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="0" colspan="9">
     <widget class="QLabel" name="error_message">
      <property name="sizePolicy">
       <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
      </property>
     </widget>
    </item>
-   <item row="0" column="0" colspan="2">
-    <widget class="QLabel" name="label">
-     <property name="text">
-      <string>DVD format</string>
+   <item row="1" column="0" colspan="8">
+    <widget class="QFrame" name="list_frame">
+     <property name="sizePolicy">
+      <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="4" column="1">
-    <widget class="QPushButton" name="button_add">
+   <item row="3" column="3">
+    <widget class="QToolButton" name="button_up">
      <property name="text">
-      <string>Add movie file</string>
+      <string>...</string>
      </property>
     </widget>
    </item>
-   <item row="4" column="2">
-    <widget class="QPushButton" name="button_delete">
+   <item row="3" column="4">
+    <widget class="QToolButton" name="button_down">
      <property name="text">
-      <string>Remove file</string>
+      <string>...</string>
      </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>