]> git.sesse.net Git - kdenlive/blobdiff - src/mainwindow.cpp
Color clip dialog:
[kdenlive] / src / mainwindow.cpp
index e9a896760c55ab966d5b53ee2cf17cada2e0922a..1dbdef51b7b2dbb1c34999cebaee6bc309a4683e 100644 (file)
@@ -58,7 +58,9 @@
 #include <KLocale>
 #include <KGlobal>
 #include <KActionCollection>
+#include <KActionCategory>
 #include <KStandardAction>
+#include <KShortcutsDialog>
 #include <KFileDialog>
 #include <KMessageBox>
 #include <KDebug>
@@ -355,6 +357,7 @@ MainWindow::MainWindow(const QString &MltPath, const KUrl & Url, QWidget *parent
     m_timelineContextMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Paste)));
 
     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->addAction(actionCollection()->action("group_clip"));
@@ -450,7 +453,10 @@ bool MainWindow::queryClose()
     }
     saveOptions();
     if (m_monitorManager) m_monitorManager->stopActiveMonitor();
-    if (m_activeDocument && m_activeDocument->isModified()) {
+    // warn the user to save if document is modified and we have clips in our project list
+    if (m_activeDocument && m_activeDocument->isModified()
+            && ((m_projectList->documentClipList().isEmpty() && !m_activeDocument->url().isEmpty())
+                || !m_projectList->documentClipList().isEmpty())) {
         switch (KMessageBox::warningYesNoCancel(this, i18n("Save changes to document?"))) {
         case KMessageBox::Yes :
             // save document here. If saving fails, return false;
@@ -530,7 +536,8 @@ void MainWindow::generateClip()
     QAction *action = qobject_cast<QAction *>(sender());
     ClipGenerator *iGenerator = qobject_cast<ClipGenerator *>(action->parent());
 
-    KUrl clipUrl = iGenerator->generatedClip(action->data().toString(), m_activeDocument->projectFolder(), QStringList(), QStringList(), 25, 720, 576);
+    KUrl clipUrl = iGenerator->generatedClip(action->data().toString(), m_activeDocument->projectFolder(),
+                   QStringList(), QStringList(), m_activeDocument->fps(), m_activeDocument->width(), m_activeDocument->height());
     if (!clipUrl.isEmpty()) {
         m_projectList->slotAddClip(QList <QUrl> () << clipUrl);
     }
@@ -850,6 +857,13 @@ void MainWindow::setupActions()
 
     toolbar->addSeparator();
 
+    //create automatic audio split button
+    m_buttonAutomaticSplitAudio = new KAction(KIcon("kdenlive-split-audio"), i18n("Split audio and video automatically"), this);
+    toolbar->addAction(m_buttonAutomaticSplitAudio);
+    m_buttonAutomaticSplitAudio->setCheckable(true);
+    m_buttonAutomaticSplitAudio->setChecked(KdenliveSettings::splitaudio());
+    connect(m_buttonAutomaticSplitAudio, SIGNAL(triggered()), this, SLOT(slotSwitchSplitAudio()));
+
     m_buttonVideoThumbs = new KAction(KIcon("kdenlive-show-videothumb"), i18n("Show video thumbnails"), this);
     toolbar->addAction(m_buttonVideoThumbs);
     m_buttonVideoThumbs->setCheckable(true);
@@ -874,6 +888,10 @@ void MainWindow::setupActions()
     m_buttonSnap->setChecked(KdenliveSettings::snaptopoints());
     connect(m_buttonSnap, SIGNAL(triggered()), this, SLOT(slotSwitchSnap()));
 
+    actionWidget = toolbar->widgetForAction(m_buttonAutomaticSplitAudio);
+    actionWidget->setMaximumWidth(max);
+    actionWidget->setMaximumHeight(max - 4);
+
     actionWidget = toolbar->widgetForAction(m_buttonVideoThumbs);
     actionWidget->setMaximumWidth(max);
     actionWidget->setMaximumHeight(max - 4);
@@ -907,6 +925,7 @@ void MainWindow::setupActions()
     collection->addAction("razor_tool", m_buttonRazorTool);
     collection->addAction("spacer_tool", m_buttonSpacerTool);
 
+    collection->addAction("automatic_split_audio", m_buttonAutomaticSplitAudio);
     collection->addAction("show_video_thumbs", m_buttonVideoThumbs);
     collection->addAction("show_audio_thumbs", m_buttonAudioThumbs);
     collection->addAction("show_markers", m_buttonShowMarkers);
@@ -930,13 +949,10 @@ void MainWindow::setupActions()
     collection->addAction("manage_profiles", profilesAction);
     connect(profilesAction, SIGNAL(triggered(bool)), this, SLOT(slotEditProfiles()));
 
-    KNS3::standardAction(i18n("Download New Wipes..."), this, SLOT(slotGetNewLumaStuff()), actionCollection(), "get_new_lumas");
-
-    KNS3::standardAction(i18n("Download New Render Profiles..."), this, SLOT(slotGetNewRenderStuff()), actionCollection(), "get_new_profiles");
-
+    KNS3::standardAction(i18n("Download New Wipes..."),            this, SLOT(slotGetNewLumaStuff()),       actionCollection(), "get_new_lumas");
+    KNS3::standardAction(i18n("Download New Render Profiles..."),  this, SLOT(slotGetNewRenderStuff()),     actionCollection(), "get_new_profiles");
     KNS3::standardAction(i18n("Download New Project Profiles..."), this, SLOT(slotGetNewMltProfileStuff()), actionCollection(), "get_new_mlt_profiles");
-
-    KNS3::standardAction(i18n("Download New Title Templates..."), this, SLOT(slotGetNewTitleStuff()), actionCollection(), "get_new_titles");
+    KNS3::standardAction(i18n("Download New Title Templates..."),  this, SLOT(slotGetNewTitleStuff()),      actionCollection(), "get_new_titles");
 
     KAction* wizAction = new KAction(KIcon("configure"), i18n("Run Config Wizard"), this);
     collection->addAction("run_wizard", wizAction);
@@ -1122,6 +1138,10 @@ void MainWindow::setupActions()
     collection->addAction("clip_in_project_tree", clipInProjectTree);
     connect(clipInProjectTree, SIGNAL(triggered(bool)), this, SLOT(slotClipInProjectTree()));
 
+    /*KAction* clipToProjectTree = new KAction(KIcon("go-jump-definition"), i18n("Add Clip to Project Tree"), this);
+    collection->addAction("clip_to_project_tree", clipToProjectTree);
+    connect(clipToProjectTree, SIGNAL(triggered(bool)), this, SLOT(slotClipToProjectTree()));*/
+
     KAction* insertOvertwrite = new KAction(KIcon(), i18n("Insert Clip Zone in Timeline (Overwrite)"), this);
     insertOvertwrite->setShortcut(Qt::Key_V);
     collection->addAction("overwrite_to_in_point", insertOvertwrite);
@@ -1220,9 +1240,9 @@ void MainWindow::setupActions()
     collection->addAction("delete_track", deleteTrack);
     connect(deleteTrack, SIGNAL(triggered()), this, SLOT(slotDeleteTrack()));
 
-    KAction *changeTrack = new KAction(KIcon(), i18n("Change Track"), this);
-    collection->addAction("change_track", changeTrack);
-    connect(changeTrack, SIGNAL(triggered()), this, SLOT(slotChangeTrack()));
+    KAction *configTracks = new KAction(KIcon("configure"), i18n("Configure Tracks"), this);
+    collection->addAction("config_tracks", configTracks);
+    connect(configTracks, SIGNAL(triggered()), this, SLOT(slotConfigTrack()));
 
     KAction *addGuide = new KAction(KIcon("document-new"), i18n("Add Guide"), this);
     collection->addAction("add_guide", addGuide);
@@ -1264,26 +1284,19 @@ void MainWindow::setupActions()
     maxCurrent->setChecked(false);
     connect(maxCurrent, SIGNAL(triggered(bool)), this, SLOT(slotMaximizeCurrent(bool)));*/
 
-
-    m_closeAction = KStandardAction::close(this, SLOT(closeCurrentDocument()), collection);
-
-    KStandardAction::quit(this, SLOT(queryQuit()), collection);
-
-    KStandardAction::open(this, SLOT(openFile()), collection);
-
-    m_saveAction = KStandardAction::save(this, SLOT(saveFile()), collection);
-
-    KStandardAction::saveAs(this, SLOT(saveFileAs()), collection);
-
-    KStandardAction::openNew(this, SLOT(newFile()), collection);
-
-    KStandardAction::preferences(this, SLOT(slotPreferences()), collection);
-
-    KStandardAction::configureNotifications(this , SLOT(configureNotifications()), collection);
-
-    KStandardAction::copy(this, SLOT(slotCopy()), collection);
-
-    KStandardAction::paste(this, SLOT(slotPaste()), collection);
+    m_closeAction = KStandardAction::close(this,  SLOT(closeCurrentDocument()),   collection);
+    KStandardAction::quit(this,                   SLOT(queryQuit()),              collection);
+    KStandardAction::open(this,                   SLOT(openFile()),               collection);
+    m_saveAction = KStandardAction::save(this,    SLOT(saveFile()),               collection);
+    KStandardAction::saveAs(this,                 SLOT(saveFileAs()),             collection);
+    KStandardAction::openNew(this,                SLOT(newFile()),                collection);
+    // TODO: make the following connection to slotEditKeys work
+    KStandardAction::keyBindings(this,            SLOT(slotEditKeys()),           collection);
+    KStandardAction::preferences(this,            SLOT(slotPreferences()),        collection);
+    KStandardAction::configureNotifications(this, SLOT(configureNotifications()), collection);
+    KStandardAction::copy(this,                   SLOT(slotCopy()),               collection);
+    KStandardAction::paste(this,                  SLOT(slotPaste()),              collection);
+    KStandardAction::fullScreen(this,             SLOT(slotFullScreen()), this,   collection);
 
     KAction *undo = KStandardAction::undo(m_commandStack, SLOT(undo()), collection);
     undo->setEnabled(false);
@@ -1293,8 +1306,6 @@ void MainWindow::setupActions()
     redo->setEnabled(false);
     connect(m_commandStack, SIGNAL(canRedoChanged(bool)), redo, SLOT(setEnabled(bool)));
 
-    KStandardAction::fullScreen(this, SLOT(slotFullScreen()), this, collection);
-
     /*
     //TODO: Add status tooltip to actions ?
     connect(collection, SIGNAL(actionHovered(QAction*)),
@@ -1364,38 +1375,48 @@ void MainWindow::setupActions()
     m_projectList->setupMenu(addClips, addClip);
 
     // Setup effects and transitions actions.
+    m_effectsActionCollection = new KActionCollection(this, KGlobal::mainComponent());
+    //KActionCategory *videoEffectActions = new KActionCategory(i18n("Video Effects"), m_effectsActionCollection);
+    KActionCategory *videoEffectActions = new KActionCategory(i18n("Video Effects"), collection);
     m_videoEffects = new KAction*[videoEffects.count()];
     for (int i = 0; i < videoEffects.count(); ++i) {
         QStringList effectInfo = videoEffects.effectIdInfo(i);
         m_videoEffects[i] = new KAction(KIcon("kdenlive-show-video"), effectInfo.at(0), this);
         m_videoEffects[i]->setData(effectInfo);
         m_videoEffects[i]->setIconVisibleInMenu(false);
-        collection->addAction("video_effect_" + effectInfo.at(0), m_videoEffects[i]);
+        videoEffectActions->addAction("video_effect_" + effectInfo.at(0), m_videoEffects[i]);
     }
+    //KActionCategory *audioEffectActions = new KActionCategory(i18n("Audio Effects"), m_effectsActionCollection);
+    KActionCategory *audioEffectActions = new KActionCategory(i18n("Audio Effects"), collection);
     m_audioEffects = new KAction*[audioEffects.count()];
     for (int i = 0; i < audioEffects.count(); ++i) {
         QStringList effectInfo = audioEffects.effectIdInfo(i);
         m_audioEffects[i] = new KAction(KIcon("kdenlive-show-audio"), effectInfo.at(0), this);
         m_audioEffects[i]->setData(effectInfo);
         m_audioEffects[i]->setIconVisibleInMenu(false);
-        collection->addAction("audio_effect_" + effectInfo.at(0), m_audioEffects[i]);
+        audioEffectActions->addAction("audio_effect_" + effectInfo.at(0), m_audioEffects[i]);
     }
+    //KActionCategory *customEffectActions = new KActionCategory(i18n("Custom Effects"), m_effectsActionCollection);
+    KActionCategory *customEffectActions = new KActionCategory(i18n("Custom Effects"), collection);
     m_customEffects = new KAction*[customEffects.count()];
     for (int i = 0; i < customEffects.count(); ++i) {
         QStringList effectInfo = customEffects.effectIdInfo(i);
         m_customEffects[i] = new KAction(KIcon("kdenlive-custom-effect"), effectInfo.at(0), this);
         m_customEffects[i]->setData(effectInfo);
         m_customEffects[i]->setIconVisibleInMenu(false);
-        collection->addAction("custom_effect_" + effectInfo.at(0), m_customEffects[i]);
+        customEffectActions->addAction("custom_effect_" + effectInfo.at(0), m_customEffects[i]);
     }
+    //KActionCategory *transitionActions = new KActionCategory(i18n("Transitions"), m_effectsActionCollection);
+    KActionCategory *transitionActions = new KActionCategory(i18n("Transitions"), collection);
     m_transitions = new KAction*[transitions.count()];
     for (int i = 0; i < transitions.count(); i++) {
         QStringList effectInfo = transitions.effectIdInfo(i);
         m_transitions[i] = new KAction(effectInfo.at(0), this);
         m_transitions[i]->setData(effectInfo);
         m_transitions[i]->setIconVisibleInMenu(false);
-        collection->addAction("transition_" + effectInfo.at(0), m_transitions[i]);
+        transitionActions->addAction("transition_" + effectInfo.at(0), m_transitions[i]);
     }
+    m_effectsActionCollection->readSettings();
 
     //connect(collection, SIGNAL( clearStatusText() ),
     //statusBar(), SLOT( clear() ) );
@@ -1993,7 +2014,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
             disconnect(m_activeTimeline, SIGNAL(cursorMoved()), m_projectMonitor, SLOT(activateMonitor()));
             disconnect(m_activeTimeline, SIGNAL(insertTrack(int)), this, SLOT(slotInsertTrack(int)));
             disconnect(m_activeTimeline, SIGNAL(deleteTrack(int)), this, SLOT(slotDeleteTrack(int)));
-            disconnect(m_activeTimeline, SIGNAL(changeTrack(int)), this, SLOT(slotChangeTrack(int)));
+            disconnect(m_activeTimeline, SIGNAL(configTrack(int)), this, SLOT(slotConfigTrack(int)));
             disconnect(m_activeDocument, SIGNAL(docModified(bool)), this, SLOT(slotUpdateDocumentState(bool)));
             disconnect(m_effectStack, SIGNAL(updateClipEffect(ClipItem*, QDomElement, QDomElement, int)), m_activeTimeline->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, QDomElement, QDomElement, int)));
             disconnect(m_effectStack, SIGNAL(removeEffect(ClipItem*, QDomElement)), m_activeTimeline->projectView(), SLOT(slotDeleteEffect(ClipItem*, QDomElement)));
@@ -2035,7 +2056,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
     connect(trackView, SIGNAL(cursorMoved()), m_projectMonitor, SLOT(activateMonitor()));
     connect(trackView, SIGNAL(insertTrack(int)), this, SLOT(slotInsertTrack(int)));
     connect(trackView, SIGNAL(deleteTrack(int)), this, SLOT(slotDeleteTrack(int)));
-    connect(trackView, SIGNAL(changeTrack(int)), this, SLOT(slotChangeTrack(int)));
+    connect(trackView, SIGNAL(configTrack(int)), this, SLOT(slotConfigTrack(int)));
     connect(trackView, SIGNAL(updateTracksInfo()), this, SLOT(slotUpdateTrackInfo()));
     connect(trackView, SIGNAL(mousePosition(int)), this, SLOT(slotUpdateMousePosition(int)));
     connect(m_projectMonitor, SIGNAL(renderPosition(int)), trackView, SLOT(moveCursorPos(int)));
@@ -2072,6 +2093,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc)   //cha
 
 
     connect(m_effectStack, SIGNAL(updateClipEffect(ClipItem*, QDomElement, QDomElement, int)), trackView->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, QDomElement, QDomElement, int)));
+    connect(m_effectStack, SIGNAL(updateClipRegion(ClipItem*, int, QString)), trackView->projectView(), SLOT(slotUpdateClipRegion(ClipItem*, int, QString)));
     connect(m_effectStack, SIGNAL(removeEffect(ClipItem*, QDomElement)), trackView->projectView(), SLOT(slotDeleteEffect(ClipItem*, QDomElement)));
     connect(m_effectStack, SIGNAL(changeEffectState(ClipItem*, int, bool)), trackView->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, bool)));
     connect(m_effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, int)));
@@ -2130,6 +2152,14 @@ void MainWindow::slotGuidesUpdated()
     if (m_renderWidget) m_renderWidget->setGuides(m_activeDocument->guidesXml(), m_activeDocument->projectDuration());
 }
 
+void MainWindow::slotEditKeys()
+{
+    KShortcutsDialog dialog(KShortcutsEditor::AllActions, KShortcutsEditor::LetterShortcutsAllowed, this);
+    dialog.addCollection(actionCollection(), i18nc("general keyboard shortcuts", "General"));
+    dialog.addCollection(m_effectsActionCollection, i18nc("effects and transitions keyboard shortcuts", "Effects & Transitions"));
+    dialog.configure();
+}
+
 void MainWindow::slotPreferences(int page, int option)
 {
     //An instance of your dialog could be already created and could be
@@ -2175,6 +2205,7 @@ void MainWindow::updateConfiguration()
     }
     m_buttonAudioThumbs->setChecked(KdenliveSettings::audiothumbnails());
     m_buttonVideoThumbs->setChecked(KdenliveSettings::videothumbnails());
+    m_buttonAutomaticSplitAudio->setChecked(KdenliveSettings::splitaudio());
 
     // Update list of transcoding profiles
     loadTranscoders();
@@ -2184,6 +2215,11 @@ void MainWindow::updateConfiguration()
 
 }
 
+void MainWindow::slotSwitchSplitAudio()
+{
+    KdenliveSettings::setSplitaudio(!KdenliveSettings::splitaudio());
+    m_buttonAutomaticSplitAudio->setChecked(KdenliveSettings::splitaudio());
+}
 
 void MainWindow::slotSwitchVideoThumbs()
 {
@@ -2404,11 +2440,13 @@ void MainWindow::slotDeleteTrack(int ix)
         m_transitionConfig->updateProjectFormat(m_activeDocument->mltProfile(), m_activeDocument->timecode(), m_activeDocument->tracksList());
 }
 
-void MainWindow::slotChangeTrack(int ix)
+void MainWindow::slotConfigTrack(int ix)
 {
     m_projectMonitor->activateMonitor();
     if (m_activeTimeline)
-        m_activeTimeline->projectView()->slotChangeTrack(ix);
+        m_activeTimeline->projectView()->slotConfigTracks(ix);
+    if (m_activeDocument)
+        m_transitionConfig->updateProjectFormat(m_activeDocument->mltProfile(), m_activeDocument->timecode(), m_activeDocument->tracksList());
 }
 
 void MainWindow::slotEditGuide()
@@ -2909,7 +2947,6 @@ void MainWindow::slotClipInTimeline(const QString &clipId)
                 j++;
             }
             actionList.insert(j, a);
-
         }
         inTimelineMenu->addActions(actionList);
 
@@ -2934,6 +2971,18 @@ void MainWindow::slotClipInProjectTree()
     }
 }
 
+/*void MainWindow::slotClipToProjectTree()
+{
+    if (m_activeTimeline) {
+    const QList<ClipItem *> clips =  m_activeTimeline->projectView()->selectedClipItems();
+        if (clips.isEmpty()) return;
+        for (int i = 0; i < clips.count(); i++) {
+        m_projectList->slotAddXmlClip(clips.at(i)->itemXml());
+        }
+        //m_projectList->selectItemById(clipIds.at(i));
+    }
+}*/
+
 void MainWindow::slotSelectClipInTimeline()
 {
     if (m_activeTimeline) {
@@ -3314,7 +3363,10 @@ void MainWindow::slotUpdateTimecodeFormat(int ix)
     KdenliveSettings::setFrametimecode(ix == 1);
     m_clipMonitor->updateTimecodeFormat();
     m_projectMonitor->updateTimecodeFormat();
-    m_activeTimeline->projectView()->clearSelection();
+    m_transitionConfig->updateTimecodeFormat();
+    m_effectStack->updateTimecodeFormat();
+    //m_activeTimeline->projectView()->clearSelection();
+    m_activeTimeline->updateRuler();
 }
 
 void MainWindow::slotRemoveFocus()
@@ -3380,6 +3432,8 @@ void MainWindow::slotChangePalette(QAction *action, const QString &themename)
                 ((QWidget*)subchild)->setPalette(plt);
         }
     }
+    if (m_activeTimeline)
+        m_activeTimeline->projectView()->updatePalette();
 }