]> git.sesse.net Git - kdenlive/blobdiff - src/mainwindow.cpp
Limit the use of qApp->processEvents that might cause concurrency issues: http:/...
[kdenlive] / src / mainwindow.cpp
index 9139b6d2ec72b6ef2b6460a0131c4152f61b025a..95b00560e59af1460bff02229bc44c301b66b738 100644 (file)
@@ -142,6 +142,11 @@ EffectsList MainWindow::transitions;
 
 QMap <QString,QImage> MainWindow::m_lumacache;
 
+static bool sortByNames(const QPair<QString, KAction*> &a, const QPair<QString, KAction*> &b)
+{
+    return a.first < b.first;
+}
+
 MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString & clipsToLoad, QWidget *parent) :
     KXmlGuiWindow(parent),
     m_activeDocument(NULL),
@@ -236,7 +241,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 &)));
@@ -467,12 +472,12 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString &
 
     QMenu *clipInTimeline = static_cast<QMenu*>(factory()->container("clip_in_timeline", this));
     clipInTimeline->setIcon(KIcon("go-jump"));
-       QHash<QString,QMenu*> menus;
-       menus.insert("addMenu",static_cast<QMenu*>(factory()->container("generators", this)));
-        menus.insert("extractAudioMenu",static_cast<QMenu*>(factory()->container("extract_audio", this)));
-       menus.insert("transcodeMenu",static_cast<QMenu*>(factory()->container("transcoders", this)));
-       menus.insert("clipActionsMenu",static_cast<QMenu*>(factory()->container("clip_actions", this)));
-       menus.insert("inTimelineMenu",clipInTimeline);
+    QHash<QString,QMenu*> menus;
+    menus.insert("addMenu",static_cast<QMenu*>(factory()->container("generators", this)));
+    menus.insert("extractAudioMenu",static_cast<QMenu*>(factory()->container("extract_audio", this)));
+    menus.insert("transcodeMenu",static_cast<QMenu*>(factory()->container("transcoders", this)));
+    menus.insert("clipActionsMenu",static_cast<QMenu*>(factory()->container("clip_actions", this)));
+    menus.insert("inTimelineMenu",clipInTimeline);
     m_projectList->setupGeneratorMenu(menus);
 
     // build themes menus
@@ -574,29 +579,6 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString &
 
     slotConnectMonitors();
 
-    // Open or create a file.  Command line argument passed in Url has
-    // precedence, then "openlastproject", then just a plain empty file.
-    // If opening Url fails, openlastproject will _not_ be used.
-    if (!Url.isEmpty()) {
-        // delay loading so that the window shows up
-        m_startUrl = Url;
-        QTimer::singleShot(500, this, SLOT(openFile()));
-    } else if (KdenliveSettings::openlastproject()) {
-        QTimer::singleShot(500, this, SLOT(openLastFile()));
-    } else { //if (m_timelineArea->count() == 0) {
-        newFile(false);
-    }
-
-    if (!clipsToLoad.isEmpty() && m_activeDocument) {
-        QStringList list = clipsToLoad.split(',');
-        QList <QUrl> urls;
-        foreach(const QString &path, list) {
-            kDebug() << QDir::current().absoluteFilePath(path);
-            urls << QUrl::fromLocalFile(QDir::current().absoluteFilePath(path));
-        }
-        m_projectList->slotAddClip(urls);
-    }
-
 #ifdef USE_JOGSHUTTLE
     activateShuttleDevice();
 #endif
@@ -605,33 +587,41 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString &
     actionCollection()->addAssociatedWidget(m_clipMonitor->container());
     actionCollection()->addAssociatedWidget(m_projectMonitor->container());
 
-    QMap <QString, KAction *> viewActions;
+    QList<QPair<QString, KAction *> > viewActions;
+    QPair <QString, KAction *> pair;
     KAction *showTimeline = new KAction(i18n("Timeline"), this);
     showTimeline->setCheckable(true);
     showTimeline->setChecked(true);
     connect(showTimeline, SIGNAL(triggered(bool)), this, SLOT(slotShowTimeline(bool)));
-    viewActions.insert(showTimeline->text(), showTimeline);
+    
+    KMenu *viewMenu = static_cast<KMenu*>(factory()->container("dockwindows", this));
+    pair.first = showTimeline->text();
+    pair.second = showTimeline;
+    viewActions.append(pair);
     
     QList <QDockWidget *> docks = findChildren<QDockWidget *>();
     for (int i = 0; i < docks.count(); i++) {
         QDockWidget* dock = docks.at(i);
+       QAction * a = dock->toggleViewAction();
+       if (!a) continue;
        KAction* dockInformations = new KAction(this);
-       dockInformations->setText(dock->windowTitle());
+       dockInformations->setText(a->text());
        dockInformations->setCheckable(true);
        dockInformations->setChecked(!dock->isHidden());
-       connect(dockInformations,SIGNAL(toggled(bool)), dock, SLOT(setVisible(bool)));
-       viewActions.insert(dockInformations->text(), dockInformations);
-    }
-
-
-    KMenu *viewMenu = static_cast<KMenu*>(factory()->container("dockwindows", this));
-    //const QList<QAction *> viewActions = createPopupMenu()->actions();
-    QMap<QString, KAction *>::const_iterator i = viewActions.constBegin();
-    while (i != viewActions.constEnd()) {
-       viewMenu->addAction(guiActions->addAction(i.key(), i.value()));
-       ++i;
+       // HACK: since QActions cannot be used in KActionCategory to allow shortcut, we create a duplicate KAction of the dock QAction and link them
+       connect(a,SIGNAL(toggled(bool)), dockInformations, SLOT(setChecked(bool)));
+       connect(dockInformations,SIGNAL(triggered(bool)), a, SLOT(trigger()));
+       pair.first = dockInformations->text();
+       pair.second = dockInformations;
+       viewActions.append(pair);
     }
     
+    // Sort dock view action by name
+    qSort(viewActions.begin(), viewActions.end(), sortByNames);
+    // Populate view menu
+    for (int i = 0; i < viewActions.count(); i++)
+       viewMenu->addAction(guiActions->addAction(viewActions.at(i).first, viewActions.at(i).second));
+    
     // Populate encoding profiles
     KConfig conf("encodingprofiles.rc", KConfig::FullConfig, "appdata");
     if (KdenliveSettings::proxyparams().isEmpty() || KdenliveSettings::proxyextension().isEmpty()) {
@@ -669,6 +659,30 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString &
     }
     
     connect (KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), this, SLOT(slotChangePalette()));
+
+    // Open or create a file.  Command line argument passed in Url has
+    // precedence, then "openlastproject", then just a plain empty file.
+    // If opening Url fails, openlastproject will _not_ be used.
+    if (!Url.isEmpty()) {
+        // delay loading so that the window shows up
+        m_startUrl = Url;
+        QTimer::singleShot(500, this, SLOT(openFile()));
+    } else if (KdenliveSettings::openlastproject()) {
+        QTimer::singleShot(500, this, SLOT(openLastFile()));
+    } else { //if (m_timelineArea->count() == 0) {
+        newFile(false);
+    }
+
+    if (!clipsToLoad.isEmpty() && m_activeDocument) {
+        QStringList list = clipsToLoad.split(',');
+        QList <QUrl> urls;
+        foreach(const QString &path, list) {
+            kDebug() << QDir::current().absoluteFilePath(path);
+            urls << QUrl::fromLocalFile(QDir::current().absoluteFilePath(path));
+        }
+        m_projectList->slotAddClip(urls);
+    }
+    
 }
 
 MainWindow::~MainWindow()
@@ -676,6 +690,12 @@ MainWindow::~MainWindow()
     if (m_stopmotion) {
         delete m_stopmotion;
     }
+
+#ifdef USE_JOGSHUTTLE
+    if (m_jogProcess)
+       delete m_jogProcess;
+#endif
+
     m_effectStack->slotClipItemSelected(NULL);
     m_transitionConfig->slotTransitionItemSelected(NULL, 0, QPoint(), false);
 
@@ -919,7 +939,6 @@ void MainWindow::slotConnectMonitors()
     connect(m_projectMonitor->render, SIGNAL(replyGetImage(const QString &, const QString &, int, int)), m_projectList, SLOT(slotReplyGetImage(const QString &, const QString &, int, int)));
     connect(m_projectMonitor->render, SIGNAL(replyGetImage(const QString &, const QImage &)), m_projectList, SLOT(slotReplyGetImage(const QString &, const QImage &)));
 
-    kDebug()<<"  - - - - - -\n CONNECTED REPLY";
     connect(m_projectMonitor->render, SIGNAL(replyGetFileProperties(const QString &, Mlt::Producer*, const stringMap &, const stringMap &, bool)), m_projectList, SLOT(slotReplyGetFileProperties(const QString &, Mlt::Producer*, const stringMap &, const stringMap &, bool)));
 
     connect(m_projectMonitor->render, SIGNAL(removeInvalidClip(const QString &, bool)), m_projectList, SLOT(slotRemoveInvalidClip(const QString &, bool)));
@@ -1248,14 +1267,12 @@ void MainWindow::setupActions()
     connect(projectAdjust, SIGNAL(triggered(bool)), m_projectList, SLOT(adjustProjectProfileToItem()));
 
     KAction* monitorPlay = new KAction(KIcon("media-playback-start"), i18n("Play"), this);
-    KShortcut playShortcut;
-    playShortcut.setPrimary(Qt::Key_Space);
-    playShortcut.setAlternate(Qt::Key_K);
-    monitorPlay->setShortcut(playShortcut);
+    monitorPlay->setShortcut(Qt::Key_Space);
     collection.addAction("monitor_play", monitorPlay);
     connect(monitorPlay, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotPlay()));
 
     KAction* monitorPause = new KAction(KIcon("media-playback-stop"), i18n("Pause"), this);
+    monitorPause->setShortcut(Qt::Key_K);
     collection.addAction("monitor_pause", monitorPause);
     connect(monitorPause, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotPause()));
 
@@ -1402,6 +1419,11 @@ void MainWindow::setupActions()
     collection.addAction("delete_timeline_clip", deleteItem);
     connect(deleteItem, SIGNAL(triggered(bool)), this, SLOT(slotDeleteItem()));
 
+    KAction* alignPlayhead = new KAction(i18n("Align Playhead to Mouse Position"), this);
+    alignPlayhead->setShortcut(Qt::Key_P);
+    collection.addAction("align_playhead", alignPlayhead);
+    connect(alignPlayhead, SIGNAL(triggered(bool)), this, SLOT(slotAlignPlayheadToMousePos()));
+
     /*KAction* editTimelineClipSpeed = new KAction(i18n("Change Clip Speed"), this);
     collection.addAction("change_clip_speed", editTimelineClipSpeed);
     editTimelineClipSpeed->setData("change_speed");
@@ -1505,14 +1527,20 @@ void MainWindow::setupActions()
 
     KAction* splitAudio = new KAction(KIcon("document-new"), i18n("Split Audio"), this);
     collection.addAction("split_audio", splitAudio);
+    // "A+V" as data means this action should only be available for clips with audio AND video
+    splitAudio->setData("A+V");
     connect(splitAudio, SIGNAL(triggered(bool)), this, SLOT(slotSplitAudio()));
 
     KAction* setAudioAlignReference = new KAction(i18n("Set Audio Reference"), this);
     collection.addAction("set_audio_align_ref", setAudioAlignReference);
+    // "A" as data means this action should only be available for clips with audio
+    setAudioAlignReference->setData("A");
     connect(setAudioAlignReference, SIGNAL(triggered()), this, SLOT(slotSetAudioAlignReference()));
 
     KAction* alignAudio = new KAction(i18n("Align Audio to Reference"), this);
     collection.addAction("align_audio", alignAudio);
+    // "A" as data means this action should only be available for clips with audio
+    alignAudio->setData("A");
     connect(alignAudio, SIGNAL(triggered()), this, SLOT(slotAlignAudio()));
 
     KAction* audioOnly = new KAction(KIcon("document-new"), i18n("Audio Only"), this);
@@ -2053,11 +2081,14 @@ void MainWindow::openFile()
 
 void MainWindow::openLastFile()
 {
-    KSharedConfigPtr config = KGlobal::config();
-    KUrl::List urls = m_fileOpenRecent->urls();
-    //WARNING: this is buggy, we get a random url, not the last one. Bug in KRecentFileAction?
-    if (urls.isEmpty()) newFile(false);
-    else openFile(urls.last());
+    if (m_fileOpenRecent->selectableActionGroup()->actions().isEmpty()) {
+        // No files in history
+        newFile(false);
+        return;
+    }
+    QAction *firstUrlAction = m_fileOpenRecent->selectableActionGroup()->actions().last();
+    if (firstUrlAction) firstUrlAction->trigger();
+    else newFile(false);
 }
 
 void MainWindow::openFile(const KUrl &url)
@@ -2137,7 +2168,6 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale)
     progressDialog.progressBar()->setMaximum(4);
     progressDialog.show();
     progressDialog.progressBar()->setValue(0);
-    qApp->processEvents();
 
     bool openBackup;
     KdenliveDoc *doc = new KdenliveDoc(stale ? KUrl(stale->fileName()) : url, KdenliveSettings::defaultprojectfolder(), m_commandStack, KdenliveSettings::default_profile(), QMap <QString, QString> (), QMap <QString, QString> (), QPoint(KdenliveSettings::videotracks(), KdenliveSettings::audiotracks()), m_projectMonitor->render, m_notesWidget, &openBackup, this, &progressDialog);
@@ -2145,7 +2175,7 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale)
     progressDialog.progressBar()->setValue(1);
     progressDialog.progressBar()->setMaximum(4);
     progressDialog.setLabelText(i18n("Loading project"));
-    qApp->processEvents();
+    progressDialog.repaint();
 
     if (stale == NULL) {
         QByteArray hash = QCryptographicHash::hash(url.encodedPath(), QCryptographicHash::Md5).toHex();
@@ -2160,13 +2190,13 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale)
     connectDocumentInfo(doc);
 
     progressDialog.progressBar()->setValue(2);
-    qApp->processEvents();
+    progressDialog.repaint();
 
     bool ok;
     TrackView *trackView = new TrackView(doc, m_tracksActionCollection->actions(), &ok, this);
     connectDocument(trackView, doc);
     progressDialog.progressBar()->setValue(3);
-    qApp->processEvents();
+    progressDialog.repaint();
 
     m_timelineArea->setCurrentIndex(m_timelineArea->addTab(trackView, KIcon("kdenlive"), doc->description()));
     if (!ok) {
@@ -2179,7 +2209,6 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale)
     }
     m_timelineArea->setTabToolTip(m_timelineArea->currentIndex(), doc->url().path());
     trackView->setDuration(trackView->duration());
-    trackView->projectView()->initCursorPos(m_projectMonitor->render->seekPosition().frames(doc->fps()));
 
     if (m_timelineArea->count() > 1) m_timelineArea->setTabBarHidden(false);
     slotGotProgressInfo(QString(), -1);
@@ -2416,7 +2445,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());
@@ -2568,8 +2597,8 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
     connect(trackView, SIGNAL(mousePosition(int)), this, SLOT(slotUpdateMousePosition(int)));
     connect(trackView->projectView(), SIGNAL(forceClipProcessing(const QString &)), m_projectList, SLOT(slotForceProcessing(const QString &)));
 
-    connect(trackView->projectView(), SIGNAL(importKeyframes(GRAPHICSRECTITEM, const QString&)), this, SLOT(slotProcessImportKeyframes(GRAPHICSRECTITEM, const QString&)));
-    
+    connect(trackView->projectView(), SIGNAL(importKeyframes(GRAPHICSRECTITEM, const QString&, int)), this, SLOT(slotProcessImportKeyframes(GRAPHICSRECTITEM, const QString&, int)));
+
     connect(m_projectMonitor, SIGNAL(renderPosition(int)), trackView, SLOT(moveCursorPos(int)));
     connect(m_projectMonitor, SIGNAL(zoneUpdated(QPoint)), trackView, SLOT(slotSetZone(QPoint)));
     connect(m_projectMonitor, SIGNAL(zoneUpdated(QPoint)), doc, SLOT(setModified()));
@@ -2987,7 +3016,7 @@ void MainWindow::slotRemoveSpace()
 
 void MainWindow::slotInsertTrack(int ix)
 {
-    m_projectMonitor->slotActivateMonitor();
+    m_monitorManager->activateMonitor(Kdenlive::projectMonitor);
     if (m_activeTimeline) {
         if (ix == -1) ix = m_activeTimeline->projectView()->selectedTrack();
         m_activeTimeline->projectView()->slotInsertTrack(ix);
@@ -2998,7 +3027,7 @@ void MainWindow::slotInsertTrack(int ix)
 
 void MainWindow::slotDeleteTrack(int ix)
 {
-    m_projectMonitor->slotActivateMonitor();
+    m_monitorManager->activateMonitor(Kdenlive::projectMonitor);
     if (m_activeTimeline) {
         if (ix == -1) ix = m_activeTimeline->projectView()->selectedTrack();
         m_activeTimeline->projectView()->slotDeleteTrack(ix);
@@ -3009,7 +3038,7 @@ void MainWindow::slotDeleteTrack(int ix)
 
 void MainWindow::slotConfigTrack(int ix)
 {
-    m_projectMonitor->slotActivateMonitor();
+    m_monitorManager->activateMonitor(Kdenlive::projectMonitor);
     if (m_activeTimeline)
         m_activeTimeline->projectView()->slotConfigTracks(ix);
     if (m_activeDocument)
@@ -3018,7 +3047,7 @@ void MainWindow::slotConfigTrack(int ix)
 
 void MainWindow::slotSelectTrack()
 {
-    m_projectMonitor->slotActivateMonitor();
+    m_monitorManager->activateMonitor(Kdenlive::projectMonitor);
     if (m_activeTimeline) {
         m_activeTimeline->projectView()->slotSelectClipsInTrack();
     }
@@ -3026,7 +3055,7 @@ void MainWindow::slotSelectTrack()
 
 void MainWindow::slotSelectAllTracks()
 {
-    m_projectMonitor->slotActivateMonitor();
+    m_monitorManager->activateMonitor(Kdenlive::projectMonitor);
     if (m_activeTimeline)
         m_activeTimeline->projectView()->slotSelectAllClips();
 }
@@ -3212,19 +3241,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);
     }
 }
@@ -3296,12 +3319,12 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip)
         if (dia_ui->exec() == QDialog::Accepted) {
             QMap <QString, QString> newprops;
             newprops.insert("xmldata", dia_ui->xml().toString());
-            if (dia_ui->outPoint() != clip->duration().frames(m_activeDocument->fps())) {
+            if (dia_ui->duration() != clip->duration().frames(m_activeDocument->fps())) {
                 // duration changed, we need to update duration
-                newprops.insert("out", QString::number(dia_ui->outPoint()));
+                newprops.insert("out", QString::number(dia_ui->duration() - 1));
                 int currentLength = QString(clip->producerProperty("length")).toInt();
-                if (currentLength <= dia_ui->outPoint())
-                        newprops.insert("length", QString::number(dia_ui->outPoint() + 1));
+                if (currentLength <= dia_ui->duration())
+                        newprops.insert("length", QString::number(dia_ui->duration()));
                 else newprops.insert("length", clip->producerProperty("length"));
             }
             if (!path.isEmpty()) {
@@ -3325,14 +3348,14 @@ void MainWindow::slotShowClipProperties(DocClipBase *clip)
     // any type of clip but a title
     ClipProperties *dia = new ClipProperties(clip, m_activeDocument->timecode(), m_activeDocument->fps(), this);
 
-    if (clip->clipType() == AV || clip->clipType() == VIDEO || clip->clipType() == PLAYLIST) {
+    if (clip->clipType() == AV || clip->clipType() == VIDEO || clip->clipType() == PLAYLIST || clip->clipType() == SLIDESHOW) {
        // request clip thumbnails
        m_activeDocument->clipManager()->requestThumbs(QString('?' + clip->getId()), QList<int>() << clip->getClipThumbFrame());
        connect(m_activeDocument->clipManager(), SIGNAL(gotClipPropertyThumbnail(const QString&,QImage)), dia, SLOT(slotGotThumbnail(const QString&,QImage)));
     }
     
     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 *)));
@@ -3877,12 +3900,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;
@@ -3918,24 +3941,39 @@ void MainWindow::loadClipActions()
                Mlt::Profile profile;
                Mlt::Filter *filter = Mlt::Factory::filter(profile,(char*)"videostab");
                if (filter) {
-                       delete filter;
-                       QAction *action=actionMenu->addAction(i18n("Stabilize (vstab)"));
-                       action->setData("videostab");
-                       connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction()));
+                       if (!filter->is_valid()) {
+                           delete filter;
+                       }
+                       else {
+                           delete filter;
+                           QAction *action=actionMenu->addAction(i18n("Stabilize (vstab)"));
+                           action->setData("videostab");
+                           connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction()));
+                       }
                }
                filter = Mlt::Factory::filter(profile,(char*)"videostab2");
                if (filter) {
-                       delete filter;
-                       QAction *action=actionMenu->addAction(i18n("Stabilize (transcode)"));
-                       action->setData("videostab2");
-                       connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction()));
+                       if (!filter->is_valid()) {
+                           delete filter;
+                       }
+                       else {
+                           delete filter;
+                           QAction *action=actionMenu->addAction(i18n("Stabilize (transcode)"));
+                           action->setData("videostab2");
+                           connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction()));
+                       }
                }
                filter = Mlt::Factory::filter(profile,(char*)"motion_est");
                if (filter) {
-                       delete filter;
-                       QAction *action=actionMenu->addAction(i18n("Automatic scene split"));
-                       action->setData("motion_est");
-                       connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction()));
+                       if (!filter->is_valid()) {
+                           delete filter;
+                       }
+                       else {
+                           delete filter;
+                           QAction *action=actionMenu->addAction(i18n("Automatic scene split"));
+                           action->setData("motion_est");
+                           connect(action,SIGNAL(triggered()), this, SLOT(slotStartClipAction()));
+                       }
                }
        }
 
@@ -3949,7 +3987,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();
@@ -4018,7 +4056,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();
 }
@@ -4573,20 +4611,26 @@ void MainWindow::slotSaveTimelineClip()
     }
 }
 
-void MainWindow::slotProcessImportKeyframes(GRAPHICSRECTITEM type, const QString& data)
+void MainWindow::slotProcessImportKeyframes(GRAPHICSRECTITEM type, const QString& data, int maximum)
 {
     if (type == AVWIDGET) {
        // This data should be sent to the effect stack
+       m_effectStack->setKeyframes(data, maximum);
     }
     else if (type == TRANSITIONWIDGET) {
        // This data should be sent to the transition stack
-       m_transitionConfig->setKeyframes(data);
+       m_transitionConfig->setKeyframes(data, maximum);
     }
     else {
        // Error
     }
 }
 
+void MainWindow::slotAlignPlayheadToMousePos()
+{
+    m_monitorManager->activateMonitor(Kdenlive::projectMonitor);
+    m_activeTimeline->projectView()->slotAlignPlayheadToMousePos();
+}
 
 #include "mainwindow.moc"