]> git.sesse.net Git - kdenlive/blobdiff - src/mainwindow.cpp
Fix timeline handling of objects (move them instead of changing their bounding rect
[kdenlive] / src / mainwindow.cpp
index fc6955bca9b2b1277bcaeb5869e3a07d38757602..106fb0e092e7e688e33e8c9ff7d494a9361aaaf4 100644 (file)
@@ -164,6 +164,7 @@ MainWindow::MainWindow(QWidget *parent)
     addDockWidget(Qt::TopDockWidgetArea, recMonitorDock);
 
     connect(m_recMonitor, SIGNAL(addProjectClip(KUrl)), this, SLOT(slotAddProjectClip(KUrl)));
+    connect(m_recMonitor, SIGNAL(showConfigDialog(int, int)), this, SLOT(slotPreferences(int, int)));
 
     undoViewDock = new QDockWidget(i18n("Undo History"), this);
     undoViewDock->setObjectName("undo_history");
@@ -210,12 +211,12 @@ MainWindow::MainWindow(QWidget *parent)
         action->setData(name);
         audioEffectsMenu->addAction(action);
     }
-    QMenu *customEffectsMenu = static_cast<QMenu*>(factory()->container("custom_effects_menu", this));
+    m_customEffectsMenu = static_cast<QMenu*>(factory()->container("custom_effects_menu", this));
     effects = customEffects.effectNames();
     foreach(const QString &name, effects) {
         action = new QAction(name, this);
         action->setData(name);
-        customEffectsMenu->addAction(action);
+        m_customEffectsMenu->addAction(action);
     }
 
     QMenu *viewMenu = static_cast<QMenu*>(factory()->container("dockwindows", this));
@@ -224,7 +225,7 @@ MainWindow::MainWindow(QWidget *parent)
 
     connect(videoEffectsMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotAddVideoEffect(QAction *)));
     connect(audioEffectsMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotAddAudioEffect(QAction *)));
-    connect(customEffectsMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotAddCustomEffect(QAction *)));
+    connect(m_customEffectsMenu, SIGNAL(triggered(QAction *)), this, SLOT(slotAddCustomEffect(QAction *)));
 
     m_timelineContextMenu = new QMenu(this);
     m_timelineContextClipMenu = new QMenu(this);
@@ -243,15 +244,17 @@ MainWindow::MainWindow(QWidget *parent)
     m_timelineContextMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Paste)));
 
     m_timelineContextClipMenu->addAction(actionCollection()->action("delete_timeline_clip"));
+    m_timelineContextClipMenu->addAction(actionCollection()->action("change_clip_speed"));
     m_timelineContextClipMenu->addAction(actionCollection()->action("cut_timeline_clip"));
     m_timelineContextClipMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Copy)));
+    m_timelineContextClipMenu->addAction(actionCollection()->action("paste_effects"));
 
     QMenu *markersMenu = (QMenu*)(factory()->container("marker_menu", this));
     m_timelineContextClipMenu->addMenu(markersMenu);
     m_timelineContextClipMenu->addMenu(transitionsMenu);
     m_timelineContextClipMenu->addMenu(videoEffectsMenu);
     m_timelineContextClipMenu->addMenu(audioEffectsMenu);
-    m_timelineContextClipMenu->addMenu(customEffectsMenu);
+    m_timelineContextClipMenu->addMenu(m_customEffectsMenu);
 
     m_timelineContextTransitionMenu->addAction(actionCollection()->action("delete_timeline_clip"));
     m_timelineContextTransitionMenu->addAction(actionCollection()->action(KStandardAction::name(KStandardAction::Copy)));
@@ -261,6 +264,8 @@ MainWindow::MainWindow(QWidget *parent)
     //connect(m_monitorManager, SIGNAL(connectMonitors()), this, SLOT(slotConnectMonitors()));
     connect(m_monitorManager, SIGNAL(raiseClipMonitor(bool)), this, SLOT(slotRaiseMonitor(bool)));
     connect(m_effectList, SIGNAL(addEffect(QDomElement)), this, SLOT(slotAddEffect(QDomElement)));
+    connect(m_effectList, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects()));
+
     m_monitorManager->initMonitors(m_clipMonitor, m_projectMonitor);
     slotConnectMonitors();
 
@@ -308,6 +313,19 @@ void MainWindow::readProperties(KConfig *config) {
     openFile(KUrl(Lastproject));
 }
 
+void MainWindow::slotReloadEffects() {
+    initEffects::parseCustomEffectsFile();
+    m_customEffectsMenu->clear();
+    const QStringList effects = customEffects.effectNames();
+    QAction *action;
+    foreach(const QString &name, effects) {
+        action = new QAction(name, this);
+        action->setData(name);
+        m_customEffectsMenu->addAction(action);
+    }
+    m_effectList->reloadEffectList();
+}
+
 void MainWindow::activateShuttleDevice() {
     if (m_jogProcess) delete m_jogProcess;
     m_jogProcess = NULL;
@@ -386,6 +404,9 @@ void MainWindow::slotConnectMonitors() {
     connect(m_projectList, SIGNAL(getFileProperties(const QDomElement &, int)), m_clipMonitor->render, SLOT(getFileProperties(const QDomElement &, int)));
     connect(m_clipMonitor->render, SIGNAL(replyGetImage(int, int, const QPixmap &, int, int)), m_projectList, SLOT(slotReplyGetImage(int, int, const QPixmap &, int, int)));
     connect(m_clipMonitor->render, SIGNAL(replyGetFileProperties(int, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &)), m_projectList, SLOT(slotReplyGetFileProperties(int, Mlt::Producer*, const QMap < QString, QString > &, const QMap < QString, QString > &)));
+
+    connect(m_clipMonitor->render, SIGNAL(removeInvalidClip(int)), m_projectList, SLOT(slotRemoveInvalidClip(int)));
+
     connect(m_clipMonitor, SIGNAL(refreshClipThumbnail(int)), m_projectList, SLOT(slotRefreshClipThumbnail(int)));
 }
 
@@ -607,6 +628,10 @@ void MainWindow::setupActions() {
     actionCollection()->addAction("delete_timeline_clip", deleteTimelineClip);
     connect(deleteTimelineClip, SIGNAL(triggered(bool)), this, SLOT(slotDeleteTimelineClip()));
 
+    KAction* editTimelineClipSpeed = new KAction(KIcon("edit-delete"), i18n("Change Clip Speed"), this);
+    actionCollection()->addAction("change_clip_speed", editTimelineClipSpeed);
+    connect(editTimelineClipSpeed, SIGNAL(triggered(bool)), this, SLOT(slotChangeClipSpeed()));
+
     KAction* cutTimelineClip = new KAction(KIcon("edit-cut"), i18n("Cut Clip"), this);
     cutTimelineClip->setShortcut(Qt::SHIFT + Qt::Key_R);
     actionCollection()->addAction("cut_timeline_clip", cutTimelineClip);
@@ -644,6 +669,10 @@ void MainWindow::setupActions() {
     actionCollection()->addAction("delete_all_guides", delAllGuides);
     connect(delAllGuides, SIGNAL(triggered()), this, SLOT(slotDeleteAllGuides()));
 
+    QAction *pasteEffects = new KAction(KIcon("edit-paste"), i18n("Paste Effects"), this);
+    actionCollection()->addAction("paste_effects", pasteEffects);
+    connect(pasteEffects , SIGNAL(triggered()), this, SLOT(slotPasteEffects()));
+
     KStandardAction::quit(this, SLOT(queryQuit()),
                           actionCollection());
 
@@ -671,11 +700,15 @@ void MainWindow::setupActions() {
     KStandardAction::paste(this, SLOT(slotPaste()),
                            actionCollection());
 
-    KStandardAction::undo(this, SLOT(undo()),
-                          actionCollection());
+    KAction *undo = KStandardAction::undo(m_commandStack, SLOT(undo()),
+                                          actionCollection());
+    undo->setEnabled(false);
+    connect(m_commandStack, SIGNAL(canUndoChanged(bool)), undo, SLOT(setEnabled(bool)));
 
-    KStandardAction::redo(this, SLOT(redo()),
-                          actionCollection());
+    KAction *redo = KStandardAction::redo(m_commandStack, SLOT(redo()),
+                                          actionCollection());
+    redo->setEnabled(false);
+    connect(m_commandStack, SIGNAL(canRedoChanged(bool)), redo, SLOT(setEnabled(bool)));
 
     KStandardAction::fullScreen(this, SLOT(slotFullScreen()), this, actionCollection());
 
@@ -687,14 +720,6 @@ void MainWindow::setupActions() {
     readOptions();
 }
 
-void MainWindow::undo() {
-    m_commandStack->undo();
-}
-
-void MainWindow::redo() {
-    m_commandStack->redo();
-}
-
 void MainWindow::slotDisplayActionMessage(QAction *a) {
     statusBar()->showMessage(a->data().toString(), 3000);
 }
@@ -792,8 +817,9 @@ void MainWindow::openFile() {
 
 void MainWindow::openLastFile() {
     KSharedConfigPtr config = KGlobal::config();
-    QString Lastproject = config->group("Recent Files").readPathEntry("File1", QString());
-    openFile(KUrl(Lastproject));
+    KUrl::List urls = m_fileOpenRecent->urls();
+    if (urls.isEmpty()) newFile();
+    else openFile(urls.last());
 }
 
 void MainWindow::openFile(const KUrl &url) {
@@ -1007,6 +1033,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
             disconnect(effectStack, SIGNAL(changeEffectState(ClipItem*, int, bool)), m_activeTimeline->projectView(), SLOT(slotChangeEffectState(ClipItem*, int, bool)));
             disconnect(effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, int)));
             disconnect(effectStack, SIGNAL(refreshEffectStack(ClipItem*)), m_activeTimeline->projectView(), SLOT(slotRefreshEffects(ClipItem*)));
+            disconnect(effectStack, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects()));
             disconnect(transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement)));
             disconnect(m_activeTimeline->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(activateMonitor()));
         }
@@ -1052,6 +1079,8 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
     connect(effectStack, SIGNAL(changeEffectPosition(ClipItem*, int, int)), trackView->projectView(), SLOT(slotChangeEffectPosition(ClipItem*, int, int)));
     connect(effectStack, SIGNAL(refreshEffectStack(ClipItem*)), trackView->projectView(), SLOT(slotRefreshEffects(ClipItem*)));
     connect(transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement)));
+    connect(effectStack, SIGNAL(reloadEffects()), this, SLOT(slotReloadEffects()));
+
     connect(trackView->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(activateMonitor()));
     trackView->projectView()->setContextMenu(m_timelineContextMenu, m_timelineContextClipMenu, m_timelineContextTransitionMenu);
     m_activeTimeline = trackView;
@@ -1074,18 +1103,22 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
     m_activeDocument = doc;
 }
 
-void MainWindow::slotPreferences() {
+void MainWindow::slotPreferences(int page, int option) {
     //An instance of your dialog could be already created and could be
     // cached, in which case you want to display the cached dialog
     // instead of creating another one
-    if (KConfigDialog::showDialog("settings"))
+    if (KConfigDialog::showDialog("settings")) {
+        if (page != -1) static_cast <KdenliveSettingsDialog*>(KConfigDialog::exists("settings"))->showPage(page, option);
         return;
+    }
 
     // KConfigDialog didn't find an instance of this dialog, so lets
     // create it :
     KdenliveSettingsDialog* dialog = new KdenliveSettingsDialog(this);
     connect(dialog, SIGNAL(settingsChanged(const QString&)), this, SLOT(updateConfiguration()));
+    connect(dialog, SIGNAL(doResetProfile()), this, SLOT(resetProfiles()));
     dialog->show();
+    if (page != -1) dialog->showPage(page, option);
 }
 
 void MainWindow::updateConfiguration() {
@@ -1102,6 +1135,10 @@ void MainWindow::updateConfiguration() {
 
 }
 
+void MainWindow::resetProfiles() {
+    m_monitorManager->resetProfiles(m_activeDocument->profilePath());
+}
+
 void MainWindow::slotSwitchVideoThumbs() {
     KdenliveSettings::setVideothumbnails(!KdenliveSettings::videothumbnails());
     if (m_activeTimeline) {
@@ -1140,6 +1177,12 @@ void MainWindow::slotDeleteTimelineClip() {
     }
 }
 
+void MainWindow::slotChangeClipSpeed() {
+    if (m_activeTimeline) {
+        m_activeTimeline->projectView()->changeClipSpeed();
+    }
+}
+
 void MainWindow::slotAddClipMarker() {
     if (m_activeTimeline) {
         m_activeTimeline->projectView()->slotAddClipMarker();
@@ -1326,6 +1369,11 @@ void MainWindow::slotPaste() {
     m_activeTimeline->projectView()->pasteClip();
 }
 
+void MainWindow::slotPasteEffects() {
+    if (!m_activeDocument || !m_activeTimeline) return;
+    m_activeTimeline->projectView()->pasteClipEffects();
+}
+
 void MainWindow::slotFind() {
     if (!m_activeDocument || !m_activeTimeline) return;
     m_projectSearch->setEnabled(false);