]> git.sesse.net Git - kdenlive/blobdiff - src/mainwindow.cpp
Added option to enable Audio Alignment in the config dialog.
[kdenlive] / src / mainwindow.cpp
index 1df1226c578aa1aa93f1fd7637c4289a2b51d996..971009ebc1b69f76de0484ec9a4dfd0e0fa54e85 100644 (file)
@@ -144,6 +144,11 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString &
     KXmlGuiWindow(parent),
     m_activeDocument(NULL),
     m_activeTimeline(NULL),
+    m_projectList(NULL),
+    m_effectList(NULL),
+    m_effectStack(NULL),
+    m_clipMonitor(NULL),
+    m_projectMonitor(NULL),
     m_recMonitor(NULL),
     m_renderWidget(NULL),
 #ifdef USE_JOGSHUTTLE
@@ -533,12 +538,15 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString &
 
     m_timelineContextClipMenu->addAction(actionCollection()->action("clip_in_project_tree"));
     //m_timelineContextClipMenu->addAction(actionCollection()->action("clip_to_project_tree"));
-    m_timelineContextClipMenu->addAction(actionCollection()->action("edit_item_duration"));
     m_timelineContextClipMenu->addAction(actionCollection()->action("delete_item"));
     m_timelineContextClipMenu->addSeparator();
     m_timelineContextClipMenu->addAction(actionCollection()->action("group_clip"));
     m_timelineContextClipMenu->addAction(actionCollection()->action("ungroup_clip"));
     m_timelineContextClipMenu->addAction(actionCollection()->action("split_audio"));
+    if (KdenliveSettings::enableaudioalign()) {
+        m_timelineContextClipMenu->addAction(actionCollection()->action("set_audio_align_ref"));
+        m_timelineContextClipMenu->addAction(actionCollection()->action("align_audio"));
+    }
     m_timelineContextClipMenu->addSeparator();
     m_timelineContextClipMenu->addAction(actionCollection()->action("cut_timeline_clip"));
     m_timelineContextClipMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Copy)));
@@ -551,7 +559,6 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString &
     m_timelineContextClipMenu->addMenu(m_transitionsMenu);
     m_timelineContextClipMenu->addMenu(m_effectsMenu);
 
-    m_timelineContextTransitionMenu->addAction(actionCollection()->action("edit_item_duration"));
     m_timelineContextTransitionMenu->addAction(actionCollection()->action("delete_item"));
     m_timelineContextTransitionMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Copy)));
 
@@ -630,6 +637,8 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, const QString &
             KdenliveSettings::setDecklink_extension(data.section(';', 1, 1));
         }
     }
+    
+    connect (KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), this, SLOT(slotChangePalette()));
 }
 
 MainWindow::~MainWindow()
@@ -637,7 +646,7 @@ MainWindow::~MainWindow()
     if (m_stopmotion) {
         delete m_stopmotion;
     }
-    m_effectStack->slotClipItemSelected(NULL, 0);
+    m_effectStack->slotClipItemSelected(NULL);
     m_transitionConfig->slotTransitionItemSelected(NULL, 0, QPoint(), false);
 
     if (m_projectMonitor) m_projectMonitor->stop();
@@ -949,12 +958,8 @@ void MainWindow::setupActions()
 
     KToolBar *toolbar = new KToolBar("statusToolBar", this, Qt::BottomToolBarArea);
     toolbar->setMovable(false);
-    KColorScheme scheme(palette().currentColorGroup(), KColorScheme::Window, KSharedConfig::openConfig(KdenliveSettings::colortheme()));
-    QColor buttonBg = scheme.background(KColorScheme::LinkBackground).color();
-    QColor buttonBord = scheme.foreground(KColorScheme::LinkText).color();
-    QColor buttonBord2 = scheme.shade(KColorScheme::LightShade);
-    statusBar()->setStyleSheet(QString("QStatusBar QLabel {font-size:%1pt;} QStatusBar::item { border: 0px; font-size:%1pt;padding:0px; }").arg(statusBar()->font().pointSize()));
-    QString style1 = QString("QToolBar { border: 0px } QToolButton { border-style: inset; border:1px solid transparent;border-radius: 3px;margin: 0px 3px;padding: 0px;} QToolButton:hover { background: rgb(%7, %8, %9);border-style: inset; border:1px solid rgb(%7, %8, %9);border-radius: 3px;} QToolButton:checked { background-color: rgb(%1, %2, %3); border-style: inset; border:1px solid rgb(%4, %5, %6);border-radius: 3px;}").arg(buttonBg.red()).arg(buttonBg.green()).arg(buttonBg.blue()).arg(buttonBord.red()).arg(buttonBord.green()).arg(buttonBord.blue()).arg(buttonBord2.red()).arg(buttonBord2.green()).arg(buttonBord2.blue());
+    
+    setStatusBarStyleSheet(palette());
     QString styleBorderless = "QToolButton { border-width: 0px;margin: 1px 3px 0px;padding: 0px;}";
 
     //create edit mode buttons
@@ -1040,7 +1045,6 @@ void MainWindow::setupActions()
     actionWidget->setMaximumWidth(max);
     actionWidget->setMaximumHeight(max - 4);
 
-    toolbar->setStyleSheet(style1);
     connect(toolGroup, SIGNAL(triggered(QAction *)), this, SLOT(slotChangeTool(QAction *)));
 
     toolbar->addSeparator();
@@ -1391,6 +1395,10 @@ void MainWindow::setupActions()
     KAction* editItemDuration = new KAction(KIcon("measure"), i18n("Edit Duration"), this);
     collection.addAction("edit_item_duration", editItemDuration);
     connect(editItemDuration, SIGNAL(triggered(bool)), this, SLOT(slotEditItemDuration()));
+    
+    KAction* saveTimelineClip = new KAction(KIcon("document-save"), i18n("Save clip"), this);
+    collection.addAction("save_timeline_clip", saveTimelineClip);
+    connect(saveTimelineClip, SIGNAL(triggered(bool)), this, SLOT(slotSaveTimelineClip()));
 
     KAction* clipInProjectTree = new KAction(KIcon("go-jump-definition"), i18n("Clip in Project Tree"), this);
     collection.addAction("clip_in_project_tree", clipInProjectTree);
@@ -1457,7 +1465,7 @@ void MainWindow::setupActions()
     collection.addAction("edit_clip_marker", editClipMarker);
     connect(editClipMarker, SIGNAL(triggered(bool)), this, SLOT(slotEditClipMarker()));
 
-    KAction *addMarkerGuideQuickly = new KAction(KIcon("bookmark-new"), i18n("Add Marker/Guide quickly"), this);
+    KActionaddMarkerGuideQuickly = new KAction(KIcon("bookmark-new"), i18n("Add Marker/Guide quickly"), this);
     addMarkerGuideQuickly->setShortcut(Qt::Key_Asterisk);
     collection.addAction("add_marker_guide_quickly", addMarkerGuideQuickly);
     connect(addMarkerGuideQuickly, SIGNAL(triggered(bool)), this, SLOT(slotAddMarkerGuideQuickly()));
@@ -1466,6 +1474,14 @@ void MainWindow::setupActions()
     collection.addAction("split_audio", splitAudio);
     connect(splitAudio, SIGNAL(triggered(bool)), this, SLOT(slotSplitAudio()));
 
+    KAction* setAudioAlignReference = new KAction(i18n("Set Audio Reference"), this);
+    collection.addAction("set_audio_align_ref", setAudioAlignReference);
+    connect(setAudioAlignReference, SIGNAL(triggered()), this, SLOT(slotSetAudioAlignReference()));
+
+    KAction* alignAudio = new KAction(i18n("Align Audio to Reference"), this);
+    collection.addAction("align_audio", alignAudio);
+    connect(alignAudio, SIGNAL(triggered()), this, SLOT(slotAlignAudio()));
+
     KAction* audioOnly = new KAction(KIcon("document-new"), i18n("Audio Only"), this);
     collection.addAction("clip_audio_only", audioOnly);
     audioOnly->setData("clip_audio_only");
@@ -1683,6 +1699,17 @@ void MainWindow::slotDisplayActionMessage(QAction *a)
     statusBar()->showMessage(a->data().toString(), 3000);
 }
 
+void MainWindow::setStatusBarStyleSheet(const QPalette &p)
+{
+    KColorScheme scheme(p.currentColorGroup(), KColorScheme::Window, KSharedConfig::openConfig(KdenliveSettings::colortheme()));
+    QColor buttonBg = scheme.background(KColorScheme::LinkBackground).color();
+    QColor buttonBord = scheme.foreground(KColorScheme::LinkText).color();
+    QColor buttonBord2 = scheme.shade(KColorScheme::LightShade);
+    statusBar()->setStyleSheet(QString("QStatusBar QLabel {font-size:%1pt;} QStatusBar::item { border: 0px; font-size:%1pt;padding:0px; }").arg(statusBar()->font().pointSize()));
+    QString style1 = QString("QToolBar { border: 0px } QToolButton { border-style: inset; border:1px solid transparent;border-radius: 3px;margin: 0px 3px;padding: 0px;} QToolButton:hover { background: %3;border-style: inset; border:1px solid %3;border-radius: 3px;} QToolButton:checked { background-color: %1; border-style: inset; border:1px solid %2;border-radius: 3px;}").arg(buttonBg.name()).arg(buttonBord.name()).arg(buttonBord2.name());
+    statusBar()->setStyleSheet(style1);
+}
+
 void MainWindow::loadLayouts()
 {
     QMenu *saveLayout = (QMenu*)(factory()->container("layout_save_as", this));
@@ -2316,7 +2343,7 @@ void MainWindow::slotUpdateProjectProfile(const QString &profile)
     }
 
     // Deselect current effect / transition
-    m_effectStack->slotClipItemSelected(NULL, 0);
+    m_effectStack->slotClipItemSelected(NULL);
     m_transitionConfig->slotTransitionItemSelected(NULL, 0, QPoint(), false);
     m_clipMonitor->slotSetClipProducer(NULL);
     bool updateFps = m_activeDocument->setProfilePath(profile);
@@ -2456,12 +2483,9 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
             disconnect(m_activeDocument, SIGNAL(signalDeleteProjectClip(const QString &)), this, SLOT(slotDeleteClip(const QString &)));
             disconnect(m_activeDocument, SIGNAL(updateClipDisplay(const QString &)), m_projectList, SLOT(slotUpdateClip(const QString &)));
             disconnect(m_activeDocument, SIGNAL(selectLastAddedClip(const QString &)), m_projectList, SLOT(slotSelectClip(const QString &)));
-            disconnect(m_activeTimeline->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), m_effectStack, SLOT(slotClipItemSelected(ClipItem*, int)));
-            disconnect(m_activeTimeline->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), this, SLOT(slotActivateEffectStackView(ClipItem*, int, bool)));
-            disconnect(m_activeTimeline->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), m_projectMonitor, SLOT(slotSetSelectedClip(ClipItem*)));
+            disconnect(m_activeTimeline->projectView(), SIGNAL(clipItemSelected(ClipItem*, bool)), this, SLOT(slotTimelineClipSelected(ClipItem*, bool)));
             disconnect(m_activeTimeline->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), m_transitionConfig, SLOT(slotTransitionItemSelected(Transition*, int, QPoint, bool)));
             disconnect(m_activeTimeline->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), this, SLOT(slotActivateTransitionView(Transition *)));
-            disconnect(m_activeTimeline->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), m_projectMonitor, SLOT(slotSetSelectedClip(Transition*)));
             disconnect(m_activeTimeline->projectView(), SIGNAL(playMonitor()), m_projectMonitor, SLOT(slotPlay()));
             disconnect(m_activeTimeline->projectView(), SIGNAL(displayMessage(const QString&, MessageType)), m_messageLabel, SLOT(setMessage(const QString&, MessageType)));
             disconnect(m_activeTimeline->projectView(), SIGNAL(showClipFrame(DocClipBase *, QPoint, bool, const int)), m_clipMonitor, SLOT(slotSetClipProducer(DocClipBase *, QPoint, bool, const int)));
@@ -2474,7 +2498,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
             disconnect(m_effectStack, SIGNAL(removeEffect(ClipItem*, int, QDomElement)), m_activeTimeline->projectView(), SLOT(slotDeleteEffect(ClipItem*, int, QDomElement)));
            disconnect(m_effectStack, SIGNAL(addEffect(ClipItem*, QDomElement)), trackView->projectView(), SLOT(slotAddEffect(ClipItem*, QDomElement)));
             disconnect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, int, bool)), m_activeTimeline->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, int, bool)));
-            disconnect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, int, int)), m_activeTimeline->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, int, int)));
+            disconnect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, QList<int>, int)), m_activeTimeline->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, QList <int>, int)));
             disconnect(m_effectStack, SIGNAL(refreshEffectStack(ClipItem*)), m_activeTimeline->projectView(), SLOT(slotRefreshEffects(ClipItem*)));
             disconnect(m_effectStack, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects()));
             disconnect(m_effectStack, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int)));
@@ -2525,12 +2549,10 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
 
     connect(m_notesWidget, SIGNAL(textChanged()), doc, SLOT(setModified()));
 
-    connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), m_effectStack, SLOT(slotClipItemSelected(ClipItem*, int)));
     connect(trackView->projectView(), SIGNAL(updateClipMarkers(DocClipBase *)), this, SLOT(slotUpdateClipMarkers(DocClipBase*)));
-    connect(trackView, SIGNAL(showTrackEffects(int, TrackInfo)), m_effectStack, SLOT(slotTrackItemSelected(int, TrackInfo)));
-    connect(trackView, SIGNAL(showTrackEffects(int, TrackInfo)), this, SLOT(slotActivateEffectStackView()));
+    connect(trackView, SIGNAL(showTrackEffects(int, TrackInfo)), this, SLOT(slotTrackSelected(int, TrackInfo)));
 
-    connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), this, SLOT(slotActivateEffectStackView(ClipItem*, int, bool)));
+    connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, bool)), this, SLOT(slotTimelineClipSelected(ClipItem*, bool)));
     connect(trackView->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), m_transitionConfig, SLOT(slotTransitionItemSelected(Transition*, int, QPoint, bool)));
     connect(trackView->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), this, SLOT(slotActivateTransitionView(Transition *)));
     m_zoomSlider->setValue(doc->zoom().x());
@@ -2542,23 +2564,25 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
     connect(trackView->projectView(), SIGNAL(showClipFrame(DocClipBase *, QPoint, bool, const int)), m_clipMonitor, SLOT(slotSetClipProducer(DocClipBase *, QPoint, bool, const int)));
     connect(trackView->projectView(), SIGNAL(playMonitor()), m_projectMonitor, SLOT(slotPlay()));
 
-    connect(trackView->projectView(), SIGNAL(clipItemSelected(ClipItem*, int, bool)), m_projectMonitor, SLOT(slotSetSelectedClip(ClipItem*)));
     connect(trackView->projectView(), SIGNAL(transitionItemSelected(Transition*, int, QPoint, bool)), m_projectMonitor, SLOT(slotSetSelectedClip(Transition*)));
 
     connect(m_projectList, SIGNAL(gotFilterJobResults(const QString &, int, int, const QString &, stringMap)), trackView->projectView(), SLOT(slotGotFilterJobResults(const QString &, int, int, const QString &, stringMap)));
 
+    // Effect stack signals
     connect(m_effectStack, SIGNAL(updateEffect(ClipItem*, int, QDomElement, QDomElement, int,bool)), trackView->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, int, QDomElement, QDomElement, int,bool)));
     connect(m_effectStack, SIGNAL(updateClipRegion(ClipItem*, int, QString)), trackView->projectView(), SLOT(slotUpdateClipRegion(ClipItem*, int, QString)));
     connect(m_effectStack, SIGNAL(removeEffect(ClipItem*, int, QDomElement)), trackView->projectView(), SLOT(slotDeleteEffect(ClipItem*, int, QDomElement)));
     connect(m_effectStack, SIGNAL(addEffect(ClipItem*, QDomElement)), trackView->projectView(), SLOT(slotAddEffect(ClipItem*, QDomElement)));
     connect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, int, bool)), trackView->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, int, bool)));
-    connect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, int, int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, int, int)));
+    connect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, QList <int>, int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, QList <int>, int)));
     connect(m_effectStack, SIGNAL(refreshEffectStack(ClipItem*)), trackView->projectView(), SLOT(slotRefreshEffects(ClipItem*)));
-    connect(m_transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement)));
-    connect(m_transitionConfig, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(setCursorPos(int)));
     connect(m_effectStack, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(setCursorPos(int)));
     connect(m_effectStack, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects()));
     connect(m_effectStack, SIGNAL(displayMessage(const QString&, int)), this, SLOT(slotGotProgressInfo(const QString&, int)));
+    
+    // Transition config signals
+    connect(m_transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement)));
+    connect(m_transitionConfig, SIGNAL(seekTimeline(int)), trackView->projectView() , SLOT(setCursorPos(int)));
 
     connect(trackView->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(slotActivateMonitor()));
     connect(trackView, SIGNAL(zoneMoved(int, int)), this, SLOT(slotZoneMoved(int, int)));
@@ -3075,9 +3099,9 @@ void MainWindow::slotAddVideoEffect(QAction *result)
 
     if (info.isEmpty() || info.size() < 3) return;
     QDomElement effect ;
-    if (info.at(2) == QString::number((int) EFFECT_VIDEO))
+    if (info.last() == QString::number((int) EFFECT_VIDEO))
             effect = videoEffects.getEffectByTag(info.at(0), info.at(1));
-    else if (info.at(2) == QString::number((int) EFFECT_AUDIO))
+    else if (info.last() == QString::number((int) EFFECT_AUDIO))
             effect = audioEffects.getEffectByTag(info.at(0), info.at(1));
     else
             effect = customEffects.getEffectByTag(info.at(0), info.at(1));
@@ -3299,11 +3323,18 @@ void MainWindow::customEvent(QEvent* e)
     if (e->type() == QEvent::User)
         m_messageLabel->setMessage(static_cast <MltErrorEvent *>(e)->message(), MltError);
 }
-void MainWindow::slotActivateEffectStackView(ClipItem* item, int ix, bool raise)
+
+void MainWindow::slotTimelineClipSelected(ClipItem* item, bool raise)
 {
-    Q_UNUSED(item)
-    Q_UNUSED(ix)
+    m_effectStack->slotClipItemSelected(item);
+    m_projectMonitor->slotSetSelectedClip(item);
+    if (raise)
+        m_effectStack->raiseWindow(m_effectStackDock);
+}
 
+void MainWindow::slotTrackSelected(int index, TrackInfo info, bool raise)
+{
+    m_effectStack->slotTrackItemSelected(index, info);
     if (raise)
         m_effectStack->raiseWindow(m_effectStackDock);
 }
@@ -3751,6 +3782,20 @@ void MainWindow::slotSplitAudio()
         m_activeTimeline->projectView()->splitAudio();
 }
 
+void MainWindow::slotSetAudioAlignReference()
+{
+    if (m_activeTimeline) {
+        m_activeTimeline->projectView()->setAudioAlignReference();
+    }
+}
+
+void MainWindow::slotAlignAudio()
+{
+    if (m_activeTimeline) {
+        m_activeTimeline->projectView()->alignAudio();
+    }
+}
+
 void MainWindow::slotUpdateClipType(QAction *action)
 {
     if (m_activeTimeline) {
@@ -4176,6 +4221,7 @@ void MainWindow::slotChangePalette(QAction *action, const QString &themename)
     }
 
     kapp->setPalette(plt);
+    slotChangePalette();
     const QObjectList children = statusBar()->children();
 
     foreach(QObject * child, children) {
@@ -4187,9 +4233,6 @@ void MainWindow::slotChangePalette(QAction *action, const QString &themename)
                 ((QWidget*)subchild)->setPalette(plt);
         }
     }
-    if (m_activeTimeline) {
-        m_activeTimeline->projectView()->updatePalette();
-    }
 }
 
 
@@ -4418,6 +4461,36 @@ void MainWindow::slotDownloadResources()
     d->show();
 }
 
+void MainWindow::slotChangePalette()
+{
+    QPalette plt = QApplication::palette();
+    if (m_effectStack) m_effectStack->updatePalette();
+    if (m_projectList) m_projectList->updatePalette();
+    if (m_effectList) m_effectList->updatePalette();
+    
+    if (m_clipMonitor) m_clipMonitor->setPalette(plt);
+    if (m_projectMonitor) m_projectMonitor->setPalette(plt);
+    
+    setStatusBarStyleSheet(plt);
+    if (m_activeTimeline) {
+        m_activeTimeline->updatePalette();
+    }
+}
+
+void MainWindow::slotSaveTimelineClip()
+{
+    if (m_activeTimeline && m_projectMonitor->render) {
+       ClipItem *clip = m_activeTimeline->projectView()->getActiveClipUnderCursor(true);
+       if (!clip) {
+           m_messageLabel->setMessage(i18n("Select a clip to save"), InformationMessage);
+           return;
+       }
+       KUrl url = KFileDialog::getSaveUrl(m_activeDocument->projectFolder(), "video/mlt-playlist");
+       if (!url.isEmpty()) m_projectMonitor->render->saveClip(m_activeDocument->tracksCount() - clip->track(), clip->startPos(), url);
+    }
+}
+
+
 #include "mainwindow.moc"
 
 #ifdef DEBUG_MAINW