]> git.sesse.net Git - kdenlive/blobdiff - src/mainwindow.cpp
Fix transition track error
[kdenlive] / src / mainwindow.cpp
index 467a8f5590010ad5f03a17d5d2e1f469fc4a9883..268c9a29acc024437327f0e2a2b2d20ec3feaa32 100644 (file)
@@ -28,6 +28,7 @@
 #include <KApplication>
 #include <KAction>
 #include <KLocale>
+#include <KGlobal>
 #include <KActionCollection>
 #include <KStandardAction>
 #include <KFileDialog>
@@ -44,6 +45,7 @@
 #include <KTemporaryFile>
 #include <KActionMenu>
 #include <KMenu>
+#include <locale.h>
 #include <ktogglefullscreenaction.h>
 
 #include <mlt++/Mlt.h>
 #include "projectsettings.h"
 #include "events.h"
 #include "renderjob.h"
+#include "clipmanager.h"
+#include "projectlist.h"
+#include "monitor.h"
+#include "recmonitor.h"
+#include "monitormanager.h"
+#include "kdenlivedoc.h"
+#include "trackview.h"
+#include "customtrackview.h"
+#include "effectslistview.h"
+#include "effectstackview.h"
+#include "transitionsettings.h"
+#include "renderwidget.h"
+#include "renderer.h"
+#include "jogshuttle.h"
+#include "clipproperties.h"
 
 #define ID_STATUS_MSG 1
 #define ID_EDITMODE_MSG 2
 
 MainWindow::MainWindow(QWidget *parent)
         : KXmlGuiWindow(parent),
-        m_activeDocument(NULL), m_activeTimeline(NULL), m_renderWidget(NULL) {
+        m_activeDocument(NULL), m_activeTimeline(NULL), m_renderWidget(NULL), m_jogProcess(NULL) {
+    setlocale(LC_NUMERIC, "POSIX");
     parseProfiles();
-
+    setFont(KGlobalSettings::toolBarFont());
     m_commandStack = new QUndoGroup;
     m_timelineArea = new KTabWidget(this);
     m_timelineArea->setTabReorderingEnabled(true);
@@ -82,8 +100,7 @@ MainWindow::MainWindow(QWidget *parent)
     m_timelineArea->setCornerWidget(closeTabButton);
     connect(m_timelineArea, SIGNAL(currentChanged(int)), this, SLOT(activateDocument()));
 
-
-    initEffects::parseEffectFiles(&m_audioEffects, &m_videoEffects);
+    initEffects::parseEffectFiles(&m_audioEffects, &m_videoEffects, &m_transitions);
     m_monitorManager = new MonitorManager();
 
     projectListDock = new QDockWidget(i18n("Project Tree"), this);
@@ -108,7 +125,7 @@ MainWindow::MainWindow(QWidget *parent)
 
     transitionConfigDock = new QDockWidget(i18n("Transition"), this);
     transitionConfigDock->setObjectName("transition");
-    transitionConfig = new KListWidget(this);
+    transitionConfig = new TransitionSettings(&m_transitions, this);
     transitionConfigDock->setWidget(transitionConfig);
     addDockWidget(Qt::TopDockWidgetArea, transitionConfigDock);
 
@@ -126,6 +143,14 @@ MainWindow::MainWindow(QWidget *parent)
     projectMonitorDock->setWidget(m_projectMonitor);
     addDockWidget(Qt::TopDockWidgetArea, projectMonitorDock);
 
+    recMonitorDock = new QDockWidget(i18n("Record Monitor"), this);
+    recMonitorDock->setObjectName("record_monitor");
+    m_recMonitor = new RecMonitor("record", this);
+    recMonitorDock->setWidget(m_recMonitor);
+    addDockWidget(Qt::TopDockWidgetArea, recMonitorDock);
+
+    connect(m_recMonitor, SIGNAL(addProjectClip(KUrl)), this, SLOT(slotAddProjectClip(KUrl)));
+
     undoViewDock = new QDockWidget(i18n("Undo History"), this);
     undoViewDock->setObjectName("undo_history");
     m_undoView = new QUndoView(this);
@@ -184,7 +209,8 @@ MainWindow::MainWindow(QWidget *parent)
     timeline_buttons_ui.buttonFitZoom->setIcon(KIcon("zoom-fit-best"));
     timeline_buttons_ui.buttonFitZoom->setToolTip(i18n("Fit zoom to project"));
 
-    setupGUI(Default, "kdenliveui.rc");
+    setupGUI(Default, NULL /*"kdenliveui.rc"*/);
+    kDebug() << factory() << " " << factory()->container("video_effects_menu", this);
 
     // build effects menus
     QAction *action;
@@ -234,24 +260,80 @@ MainWindow::MainWindow(QWidget *parent)
 
     setAutoSaveSettings();
     newFile();
+
+    activateShuttleDevice();
+}
+
+void MainWindow::queryQuit() {
+    kDebug() << "----- SAVING CONFUIG";
+    if (queryClose()) kapp->quit();
 }
 
 //virtual
 bool MainWindow::queryClose() {
     saveOptions();
-    switch (KMessageBox::warningYesNoCancel(this, i18n("Save changes to document ?"))) {
-    case KMessageBox::Yes :
-        // save document here. If saving fails, return false;
-        return true;
-    case KMessageBox::No :
-        return true;
-    default: // cancel
-        return false;
+    if (m_activeDocument && m_activeDocument->isModified()) {
+        switch (KMessageBox::warningYesNoCancel(this, i18n("Save changes to document ?"))) {
+        case KMessageBox::Yes :
+            // save document here. If saving fails, return false;
+            return true;
+        case KMessageBox::No :
+            return true;
+        default: // cancel
+            return false;
+        }
+    }
+    return true;
+}
+
+void MainWindow::activateShuttleDevice() {
+    if (m_jogProcess) delete m_jogProcess;
+    m_jogProcess = NULL;
+    if (KdenliveSettings::enableshuttle() == false) return;
+    m_jogProcess = new JogShuttle(KdenliveSettings::shuttledevice());
+    connect(m_jogProcess, SIGNAL(rewind1()), m_monitorManager, SLOT(slotRewindOneFrame()));
+    connect(m_jogProcess, SIGNAL(forward1()), m_monitorManager, SLOT(slotForwardOneFrame()));
+    connect(m_jogProcess, SIGNAL(rewind(double)), m_monitorManager, SLOT(slotRewind(double)));
+    connect(m_jogProcess, SIGNAL(forward(double)), m_monitorManager, SLOT(slotForward(double)));
+    connect(m_jogProcess, SIGNAL(stop()), m_monitorManager, SLOT(slotPlay()));
+    connect(m_jogProcess, SIGNAL(button(int)), this, SLOT(slotShuttleButton(int)));
+}
+
+void MainWindow::slotShuttleButton(int code) {
+    switch (code) {
+    case 5:
+        slotShuttleAction(KdenliveSettings::shuttle1());
+        break;
+    case 6:
+        slotShuttleAction(KdenliveSettings::shuttle2());
+        break;
+    case 7:
+        slotShuttleAction(KdenliveSettings::shuttle3());
+        break;
+    case 8:
+        slotShuttleAction(KdenliveSettings::shuttle4());
+        break;
+    case 9:
+        slotShuttleAction(KdenliveSettings::shuttle5());
+        break;
+    }
+}
+
+void MainWindow::slotShuttleAction(int code) {
+    switch (code) {
+    case 0:
+        return;
+    case 1:
+        m_monitorManager->slotPlay();
+        break;
+    default:
+        m_monitorManager->slotPlay();
+        break;
     }
 }
 
 void MainWindow::slotFullScreen() {
-    KToggleFullScreenAction::setFullScreen(this, actionCollection()->action("fullscreen")->isChecked());
+    //KToggleFullScreenAction::setFullScreen(this, actionCollection()->action("fullscreen")->isChecked());
 }
 
 void MainWindow::slotAddEffect(QDomElement effect, GenTime pos, int track) {
@@ -279,6 +361,7 @@ void MainWindow::slotConnectMonitors() {
     m_projectList->setRenderer(m_clipMonitor->render);
     connect(m_projectList, SIGNAL(clipSelected(const QDomElement &)), m_clipMonitor, SLOT(slotSetXml(const QDomElement &)));
     connect(m_projectList, SIGNAL(receivedClipDuration(int, int)), this, SLOT(slotSetClipDuration(int, int)));
+    connect(m_projectList, SIGNAL(showClipProperties(DocClipBase *)), this, SLOT(slotShowClipProperties(DocClipBase *)));
     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, const QMap < QString, QString > &, const QMap < QString, QString > &)), m_projectList, SLOT(slotReplyGetFileProperties(int, const QMap < QString, QString > &, const QMap < QString, QString > &)));
@@ -318,6 +401,34 @@ void MainWindow::setupActions() {
     actionCollection()->addAction("monitor_play", monitorPlay);
     connect(monitorPlay, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotPlay()));
 
+    KAction* monitorSeekBackward = new KAction(this);
+    monitorSeekBackward->setText(i18n("Rewind"));
+    monitorSeekBackward->setIcon(KIcon("media-seek-backward"));
+    monitorSeekBackward->setShortcut(Qt::Key_J);
+    actionCollection()->addAction("monitor_seek_backward", monitorSeekBackward);
+    connect(monitorSeekBackward, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotRewind()));
+
+    KAction* monitorSeekBackwardOneFrame = new KAction(this);
+    monitorSeekBackwardOneFrame->setText(i18n("Rewind 1 Frame"));
+    monitorSeekBackwardOneFrame->setIcon(KIcon("media-skip-backward"));
+    monitorSeekBackwardOneFrame->setShortcut(Qt::Key_Left);
+    actionCollection()->addAction("monitor_seek_backward-one-frame", monitorSeekBackwardOneFrame);
+    connect(monitorSeekBackwardOneFrame, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotRewindOneFrame()));
+
+    KAction* monitorSeekForward = new KAction(this);
+    monitorSeekForward->setText(i18n("Forward"));
+    monitorSeekForward->setIcon(KIcon("media-seek-forward"));
+    monitorSeekForward->setShortcut(Qt::Key_L);
+    actionCollection()->addAction("monitor_seek_forward", monitorSeekForward);
+    connect(monitorSeekForward, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotForward()));
+
+    KAction* monitorSeekForwardOneFrame = new KAction(this);
+    monitorSeekForwardOneFrame->setText(i18n("Forward 1 Frame"));
+    monitorSeekForwardOneFrame->setIcon(KIcon("media-skip-forward"));
+    monitorSeekForwardOneFrame->setShortcut(Qt::Key_Right);
+    actionCollection()->addAction("monitor_seek_forward-one-frame", monitorSeekForwardOneFrame);
+    connect(monitorSeekForwardOneFrame, SIGNAL(triggered(bool)), m_monitorManager, SLOT(slotForwardOneFrame()));
+
     KAction* deleteTimelineClip = new KAction(this);
     deleteTimelineClip->setText(i18n("Delete Clip"));
     deleteTimelineClip->setShortcut(Qt::Key_Delete);
@@ -325,7 +436,7 @@ void MainWindow::setupActions() {
     actionCollection()->addAction("delete_timeline_clip", deleteTimelineClip);
     connect(deleteTimelineClip, SIGNAL(triggered(bool)), this, SLOT(slotDeleteTimelineClip()));
 
-    KStandardAction::quit(kapp, SLOT(quit()),
+    KStandardAction::quit(this, SLOT(queryQuit()),
                           actionCollection());
 
     KStandardAction::open(this, SLOT(openFile()),
@@ -375,6 +486,7 @@ void MainWindow::slotDisplayActionMessage(QAction *a) {
 }
 
 void MainWindow::saveOptions() {
+    KdenliveSettings::self()->writeConfig();
     KSharedConfigPtr config = KGlobal::config();
     m_fileOpenRecent->saveEntries(KConfigGroup(config, "Recent Files"));
     config->sync();
@@ -612,17 +724,20 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
             disconnect(m_projectMonitor, SIGNAL(renderPosition(int)), m_activeTimeline, SLOT(moveCursorPos(int)));
             disconnect(m_projectMonitor, SIGNAL(durationChanged(int)), m_activeTimeline, SLOT(setDuration(int)));
             disconnect(m_activeDocument, SIGNAL(addProjectClip(DocClipBase *)), m_projectList, SLOT(slotAddClip(DocClipBase *)));
+            disconnect(m_activeDocument, SIGNAL(addProjectFolder(const QString, int, bool, bool)), m_projectList, SLOT(slotAddFolder(const QString, int, bool, bool)));
             disconnect(m_activeDocument, SIGNAL(signalDeleteProjectClip(int)), m_projectList, SLOT(slotDeleteClip(int)));
             disconnect(m_activeDocument, SIGNAL(updateClipDisplay(int)), m_projectList, SLOT(slotUpdateClip(int)));
             disconnect(m_activeDocument, SIGNAL(deletTimelineClip(int)), m_activeTimeline, SLOT(slotDeleteClip(int)));
             disconnect(m_activeDocument, SIGNAL(thumbsProgress(KUrl, int)), this, SLOT(slotGotProgressInfo(KUrl, int)));
             disconnect(m_activeTimeline, SIGNAL(clipItemSelected(ClipItem*)), effectStack, SLOT(slotClipItemSelected(ClipItem*)));
+            disconnect(m_activeTimeline, SIGNAL(transitionItemSelected(Transition*)), transitionConfig, SLOT(slotTransitionItemSelected(Transition*)));
             disconnect(timeline_buttons_ui.zoom_slider, SIGNAL(valueChanged(int)), m_activeTimeline, SLOT(slotChangeZoom(int)));
             disconnect(m_activeDocument, SIGNAL(docModified(bool)), this, SLOT(slotUpdateDocumentState(bool)));
             disconnect(effectStack, SIGNAL(updateClipEffect(ClipItem*, QDomElement, QDomElement)), m_activeTimeline->projectView(), SLOT(slotUpdateClipEffect(ClipItem*, QDomElement, QDomElement)));
             disconnect(effectStack, SIGNAL(removeEffect(ClipItem*, QDomElement)), m_activeTimeline->projectView(), SLOT(slotDeleteEffect(ClipItem*, QDomElement)));
             disconnect(effectStack, SIGNAL(changeEffectState(ClipItem*, QDomElement, bool)), m_activeTimeline->projectView(), SLOT(slotChangeEffectState(ClipItem*, QDomElement, bool)));
             disconnect(effectStack, SIGNAL(refreshEffectStack(ClipItem*)), m_activeTimeline->projectView(), SLOT(slotRefreshEffects(ClipItem*)));
+            disconnect(transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement)));
             disconnect(m_activeTimeline->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(activateMonitor()));
         }
         m_activeDocument->setRenderer(NULL);
@@ -637,6 +752,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
     connect(m_projectMonitor, SIGNAL(renderPosition(int)), trackView, SLOT(moveCursorPos(int)));
     connect(m_projectMonitor, SIGNAL(durationChanged(int)), trackView, SLOT(setDuration(int)));
     connect(doc, SIGNAL(addProjectClip(DocClipBase *)), m_projectList, SLOT(slotAddClip(DocClipBase *)));
+    connect(doc, SIGNAL(addProjectFolder(const QString, int, bool, bool)), m_projectList, SLOT(slotAddFolder(const QString, int, bool, bool)));
     connect(doc, SIGNAL(signalDeleteProjectClip(int)), m_projectList, SLOT(slotDeleteClip(int)));
     connect(doc, SIGNAL(updateClipDisplay(int)), m_projectList, SLOT(slotUpdateClip(int)));
     connect(doc, SIGNAL(deletTimelineClip(int)), trackView, SLOT(slotDeleteClip(int)));
@@ -644,6 +760,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
     connect(doc, SIGNAL(docModified(bool)), this, SLOT(slotUpdateDocumentState(bool)));
 
     connect(trackView, SIGNAL(clipItemSelected(ClipItem*)), effectStack, SLOT(slotClipItemSelected(ClipItem*)));
+    connect(trackView, SIGNAL(transitionItemSelected(Transition*)), transitionConfig, SLOT(slotTransitionItemSelected(Transition*)));
     timeline_buttons_ui.zoom_slider->setValue(trackView->currentZoom());
     connect(timeline_buttons_ui.zoom_slider, SIGNAL(valueChanged(int)), trackView, SLOT(slotChangeZoom(int)));
     connect(trackView->projectView(), SIGNAL(zoomIn()), this, SLOT(slotZoomIn()));
@@ -652,6 +769,7 @@ void MainWindow::connectDocument(TrackView *trackView, KdenliveDoc *doc) { //cha
     connect(effectStack, SIGNAL(removeEffect(ClipItem*, QDomElement)), trackView->projectView(), SLOT(slotDeleteEffect(ClipItem*, QDomElement)));
     connect(effectStack, SIGNAL(changeEffectState(ClipItem*, QDomElement, bool)), trackView->projectView(), SLOT(slotChangeEffectState(ClipItem*, QDomElement, bool)));
     connect(effectStack, SIGNAL(refreshEffectStack(ClipItem*)), trackView->projectView(), SLOT(slotRefreshEffects(ClipItem*)));
+    connect(transitionConfig, SIGNAL(transitionUpdated(Transition *, QDomElement)), trackView->projectView() , SLOT(slotTransitionUpdated(Transition *, QDomElement)));
     connect(trackView->projectView(), SIGNAL(activateDocumentMonitor()), m_projectMonitor, SLOT(activateMonitor()));
     trackView->projectView()->setContextMenu(m_timelineContextMenu, m_timelineContextClipMenu, m_timelineContextTransitionMenu);
     m_activeTimeline = trackView;
@@ -691,10 +809,13 @@ void MainWindow::updateConfiguration() {
     if (currentTab) {
         currentTab->refresh();
         currentTab->projectView()->checkAutoScroll();
+        currentTab->projectView()->checkTrackHeight();
         if (m_activeDocument) m_activeDocument->clipManager()->checkAudioThumbs();
     }
     timeline_buttons_ui.buttonAudio->setDown(KdenliveSettings::audiothumbnails());
     timeline_buttons_ui.buttonVideo->setDown(KdenliveSettings::videothumbnails());
+    activateShuttleDevice();
+
 }
 
 void MainWindow::slotSwitchVideoThumbs() {
@@ -724,6 +845,11 @@ void MainWindow::slotDeleteTimelineClip() {
     }
 }
 
+void MainWindow::slotAddProjectClip(KUrl url) {
+    if (m_activeDocument)
+        m_activeDocument->slotAddClipFile(url, QString());
+}
+
 void MainWindow::slotAddVideoEffect(QAction *result) {
     if (!result) return;
     QDomElement effect = m_videoEffects.getEffectByName(result->data().toString());
@@ -768,4 +894,19 @@ void MainWindow::slotGotProgressInfo(KUrl url, int progress) {
     }
 }
 
+void MainWindow::slotShowClipProperties(DocClipBase *clip) {
+    ClipProperties dia(clip, m_activeDocument->timecode(), m_activeDocument->fps(), this);
+    if (dia.exec() == QDialog::Accepted) {
+        m_projectList->slotUpdateClipProperties(dia.clipId(), dia.properties());
+    }
+}
+
+void MainWindow::customEvent(QEvent* e) {
+    if (e->type() == QEvent::User) {
+        // The timeline playing position changed...
+        kDebug() << "RECIEVED JOG EVEMNT!!!";
+    }
+}
+
+
 #include "mainwindow.moc"