]> git.sesse.net Git - kdenlive/commitdiff
Initial support for Jog Shuttle devices
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Mon, 17 Mar 2008 21:50:49 +0000 (21:50 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Mon, 17 Mar 2008 21:50:49 +0000 (21:50 +0000)
svn path=/branches/KDE4/; revision=2069

17 files changed:
src/CMakeLists.txt
src/jogshuttle.cpp [new file with mode: 0644]
src/jogshuttle.h [new file with mode: 0644]
src/kdenlivesettings.kcfg
src/kdenlivesettingsdialog.cpp
src/kdenlivesettingsdialog.h
src/mainwindow.cpp
src/mainwindow.h
src/monitor.cpp
src/monitor.h
src/monitormanager.cpp
src/monitormanager.h
src/recmonitor.cpp
src/widgets/configcapture_ui.ui
src/widgets/configenv_ui.ui
src/widgets/configjogshuttle_ui.ui [new file with mode: 0644]
src/widgets/recmonitor_ui.ui

index d8e437eb6690c60b502a51a3b72645fec1cebcf4..1abfcfabb00e206e0955c98e9845b930be73fa9f 100644 (file)
@@ -43,6 +43,7 @@ kde4_add_ui_files(kdenlive_UI
   widgets/renderwidget_ui.ui
   widgets/saveprofile_ui.ui
   widgets/transitionsettings_ui.ui
+  widgets/configjogshuttle_ui.ui
 )
  
 set(kdenlive_SRCS 
@@ -93,6 +94,7 @@ set(kdenlive_SRCS
   abstractclipitem.cpp
   transitionsettings.cpp
   recmonitor.cpp
+  jogshuttle.cpp
 )
 
 kde4_add_kcfg_files(kdenlive_SRCS GENERATE_MOC kdenlivesettings.kcfgc )
diff --git a/src/jogshuttle.cpp b/src/jogshuttle.cpp
new file mode 100644 (file)
index 0000000..6988045
--- /dev/null
@@ -0,0 +1,261 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
+ *   Based on code by Arendt David <admin@prnet.org>                       *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
+ ***************************************************************************/
+
+
+
+#define DELAY 10
+
+#define KEY 1
+#define KEY1 256
+#define KEY2 257
+#define KEY3 258
+#define KEY4 259
+#define KEY5 260
+#define KEY6 261
+#define KEY7 262
+#define KEY8 263
+#define KEY9 264
+#define KEY10 265
+#define KEY11 266
+#define KEY12 267
+#define KEY13 268
+#define KEY14 269
+#define KEY15 270
+
+#define JOGSHUTTLE 2
+#define JOG 7
+#define SHUTTLE 8
+
+#define JOG_BACK1 10001
+#define JOG_FWD1 10002
+#define JOG_FWD 10003
+#define JOG_FWD_SLOW 10004
+#define JOG_FWD_FAST 10005
+#define JOG_BACK 10006
+#define JOG_BACK_SLOW 10007
+#define JOG_BACK_FAST 10008
+#define JOG_STOP 10009
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include <QFile>
+#include <QTextStream>
+#include <QApplication>
+#include <QEvent>
+
+#include <KDebug>
+
+
+
+#include "jogshuttle.h"
+
+
+/*unsigned short  jogvalue = 0xffff;
+int   shuttlevalue = 0xffff;
+struct timeval  last_shuttle;
+int   need_synthetic_shuttle;
+*/
+
+void ShuttleThread::init(QObject *parent, QString device) {
+    m_parent = parent;
+    m_device = device;
+    stop_me = false;
+    m_isWorking = false;
+    shuttlevalue = 0xffff;
+    jogvalue = 0xffff;
+}
+
+bool ShuttleThread::isWorking() {
+    return m_isWorking;
+}
+
+void ShuttleThread::run() {
+    kDebug() << "-------  STARTING SHUTTLE: " << m_device;
+
+    EV ev;
+    FILE * fd = fopen((char *) m_device.toUtf8().data(), "r");
+
+    if (!fd) {
+        fprintf(stderr, "Can't open file\n");
+        exit(1);
+    }
+
+    while (!stop_me) {
+        while (fread(&ev, sizeof(ev), 1, fd) == 1) handle_event(ev);
+    }
+
+
+}
+
+void ShuttleThread::handle_event(EV ev) {
+    switch (ev.type) {
+    case KEY :
+        key(ev.code, ev.value);
+        break;
+    case JOGSHUTTLE :
+        jogshuttle(ev.code, ev.value);
+        break;
+    }
+}
+
+void ShuttleThread::key(unsigned short code, unsigned int value) {
+    if (value == 0) {
+        // Button release (ignored)
+        return;
+    }
+
+    code -= KEY1 - 1;
+
+    // Bound check!
+    if (code > 16)
+        return;
+
+    kDebug() << "Button PRESSED: " << code;
+    QApplication::postEvent(m_parent, new QEvent((QEvent::Type)(20000 + code)));
+
+}
+
+void ShuttleThread::shuttle(int value) {
+    //gettimeofday( &last_shuttle, 0 );
+    //need_synthetic_shuttle = value != 0;
+
+    if (value == shuttlevalue)
+        return;
+    shuttlevalue = value;
+    switch (value) {
+    case - 7 :
+    case - 6 :
+    case - 5 :
+    case - 4 :
+    case - 3 :
+        QApplication::postEvent(m_parent, new QEvent((QEvent::Type) JOG_BACK_FAST));
+        break;  // Reverse fast
+    case - 2 :
+        QApplication::postEvent(m_parent, new QEvent((QEvent::Type) JOG_BACK));
+        break;  // Reverse
+    case - 1 :
+        QApplication::postEvent(m_parent, new QEvent((QEvent::Type) JOG_BACK_SLOW));
+        break;  // Reverse slow
+    case  0 :
+        QApplication::postEvent(m_parent, new QEvent((QEvent::Type) JOG_STOP));
+        break;  // Stop!
+    case  1 :
+        QApplication::postEvent(m_parent, new QEvent((QEvent::Type) JOG_FWD_SLOW));
+        break;  // Forward slow
+    case  2 :
+        QApplication::postEvent(m_parent, new QEvent((QEvent::Type) JOG_FWD));
+        break;  // Normal play
+    case  3 :
+    case  4 :
+    case  5 :
+    case  6 :
+    case  7 :
+        QApplication::postEvent(m_parent, new QEvent((QEvent::Type) JOG_FWD_FAST));
+        break; // Fast forward
+    }
+
+}
+
+void ShuttleThread::jog(unsigned int value) {
+    // We should generate a synthetic event for the shuttle going
+    // to the home position if we have not seen one recently
+    //check_synthetic();
+
+    if (jogvalue != 0xffff) {
+        if (value < jogvalue)
+            QApplication::postEvent(m_parent, new QEvent((QEvent::Type) JOG_BACK1));
+        else if (value > jogvalue)
+            QApplication::postEvent(m_parent, new QEvent((QEvent::Type) JOG_FWD1));
+    }
+    jogvalue = value;
+}
+
+
+void ShuttleThread::jogshuttle(unsigned short code, unsigned int value) {
+    switch (code) {
+    case JOG :
+        jog(value);
+        break;
+    case SHUTTLE :
+        shuttle(value);
+        break;
+    }
+}
+
+
+JogShuttle::JogShuttle(QString device, QObject *parent): QObject(parent) {
+    initDevice(device);
+}
+
+JogShuttle::~JogShuttle() {
+    if (m_shuttleProcess.isRunning()) m_shuttleProcess.exit();
+}
+
+void JogShuttle::initDevice(QString device) {
+    if (m_shuttleProcess.isRunning()) return;
+    m_shuttleProcess.init(this, device);
+    m_shuttleProcess.start(QThread::LowestPriority);
+}
+
+void JogShuttle::stopDevice() {
+    if (m_shuttleProcess.isRunning()) m_shuttleProcess.stop_me = true;
+}
+
+void JogShuttle::customEvent(QEvent* e) {
+    switch (e->type()) {
+    case JOG_BACK1:
+        emit rewind1();
+        break;
+    case JOG_FWD1:
+        emit forward1();
+        break;
+    case JOG_BACK:
+        emit rewind(-1);
+        break;
+    case JOG_FWD:
+        emit forward(1);
+        break;
+    case JOG_BACK_SLOW:
+        emit rewind(-0.5);
+        break;
+    case JOG_FWD_SLOW:
+        emit forward(0.5);
+        break;
+    case JOG_BACK_FAST:
+        emit rewind(-2);
+        break;
+    case JOG_FWD_FAST:
+        emit forward(2);
+        break;
+    case JOG_STOP:
+        emit stop();
+        break;
+    default:
+        emit button(e->type() - 20000);
+    }
+}
+
+
+
+// #include "jogshuttle.moc"
+
diff --git a/src/jogshuttle.h b/src/jogshuttle.h
new file mode 100644 (file)
index 0000000..2938459
--- /dev/null
@@ -0,0 +1,76 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
+ *   Based on code by Arendt David <admin@prnet.org>                       *
+ *                                                                         *
+ *   This program is free software; you can redistribute it and/or modify  *
+ *   it under the terms of the GNU General Public License as published by  *
+ *   the Free Software Foundation; either version 2 of the License, or     *
+ *   (at your option) any later version.                                   *
+ *                                                                         *
+ *   This program is distributed in the hope that it will be useful,       *
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
+ *   GNU General Public License for more details.                          *
+ *                                                                         *
+ *   You should have received a copy of the GNU General Public License     *
+ *   along with this program; if not, write to the                         *
+ *   Free Software Foundation, Inc.,                                       *
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA          *
+ ***************************************************************************/
+
+#ifndef SHUTTLE_H
+#define SHUTTLE_H
+
+#include <qthread.h>
+#include <QObject>
+
+#include <linux/input.h>
+
+
+typedef struct input_event EV;
+
+class ShuttleThread : public QThread {
+
+public:
+    virtual void run();
+    void init(QObject *parent, QString device);
+    QObject *m_parent;
+    int shuttlevalue;
+    unsigned short jogvalue;
+    bool isWorking();
+    bool stop_me;
+
+private:
+    QString m_device;
+    bool m_isWorking;
+    void handle_event(EV ev);
+    void jogshuttle(unsigned short code, unsigned int value);
+    void jog(unsigned int value);
+    void shuttle(int value);
+    void key(unsigned short code, unsigned int value);
+};
+
+
+class JogShuttle: public QObject {
+Q_OBJECT public:
+    JogShuttle(QString device, QObject * parent = 0);
+    ~JogShuttle();
+    void stopDevice();
+    void initDevice(QString device);
+
+protected:
+    virtual void customEvent(QEvent * e);
+
+private:
+    ShuttleThread m_shuttleProcess;
+
+signals:
+    void rewind1();
+    void forward1();
+    void rewind(double);
+    void forward(double);
+    void stop();
+    void button(int);
+};
+
+#endif
index 6e02f0455b342bb72109a08cdd3d290a83795a49..ff442bb7e131814fbfe5558665784e82aa8cafbb 100644 (file)
       <label>Default folder for tmp files.</label>
       <default>/tmp/</default>
     </entry>
+
+    <entry name="capturefolder" type="Path">
+      <label>Default folder for captured files.</label>
+      <default>$HOME</default>
+    </entry>
   </group>
 
   <group name="capture">
       <default>0</default>
     </entry>
 
-    <entry name="capturefolder" type="Path">
-      <label>Default folder for captured files.</label>
-      <default>$HOME</default>
-    </entry>
-
     <entry name="firewireformat" type="UInt">
       <label>Default firewire capture format.</label>
       <default>0</default>
     </entry>
   </group>
 
+  <group name="shuttle">
+    <entry name="enableshuttle" type="Bool">
+      <label>Enable jog shuttle device.</label>
+      <default>false</default>
+    </entry>
+
+    <entry name="shuttledevice" type="String">
+      <label>Path to shuttle device.</label>
+      <default>/dev/input/event0</default>
+    </entry>
+
+    <entry name="shuttle1" type="UInt">
+      <label>Action for shuttle button 1.</label>
+      <default>1</default>
+    </entry>
+
+    <entry name="shuttle2" type="UInt">
+      <label>Action for shuttle button 2.</label>
+      <default>2</default>
+    </entry>
+
+    <entry name="shuttle3" type="UInt">
+      <label>Action for shuttle button 3.</label>
+      <default>0</default>
+    </entry>
+
+    <entry name="shuttle4" type="UInt">
+      <label>Action for shuttle button 4.</label>
+      <default>0</default>
+    </entry>
+
+    <entry name="shuttle5" type="UInt">
+      <label>Action for shuttle button 5.</label>
+      <default>0</default>
+    </entry>
+  </group>
+
+
   <group name="unmanaged">
     <entry name="project_display_ratio" type="Double">
       <label>Current project display ratio.</label>
index adcb99bdd4f0b4e691e108a1589e73b0db91c462..4a73a877a18556a17d63ffc9bd0276fe74f48df8 100644 (file)
@@ -43,22 +43,36 @@ KdenliveSettingsDialog::KdenliveSettingsDialog(QWidget * parent): KConfigDialog(
     m_configEnv.rendererpathurl->lineEdit()->setObjectName("kcfg_rendererpath");
     m_configEnv.tmppathurl->setMode(KFile::Directory);
     m_configEnv.tmppathurl->lineEdit()->setObjectName("kcfg_currenttmpfolder");
+    m_configEnv.capturefolderurl->setMode(KFile::Directory);
+    m_configEnv.capturefolderurl->lineEdit()->setObjectName("kcfg_capturefolder");
     page2 = addPage(p2, i18n("Environnement"), "terminal");
 
     QWidget *p4 = new QWidget;
     m_configCapture.setupUi(p4);
-    m_configCapture.capturefolderurl->setMode(KFile::Directory);
-    m_configCapture.capturefolderurl->lineEdit()->setObjectName("kcfg_capturefolder");
     page4 = addPage(p4, i18n("Capture"), "audio-card");
 
-    connect(m_configCapture.kcfg_video4vdevice, SIGNAL(editingFinished ()), this, SLOT(rebuildVideo4Commands()));
-    connect(m_configCapture.kcfg_video4adevice, SIGNAL(editingFinished ()), this, SLOT(rebuildVideo4Commands()));
-    connect(m_configCapture.kcfg_video4vformat, SIGNAL(editingFinished ()), this, SLOT(rebuildVideo4Commands()));
-    connect(m_configCapture.kcfg_video4aformat, SIGNAL(editingFinished ()), this, SLOT(rebuildVideo4Commands()));
-    connect(m_configCapture.kcfg_video4vencoding, SIGNAL(editingFinished ()), this, SLOT(rebuildVideo4Commands()));
-    connect(m_configCapture.kcfg_video4aencoding, SIGNAL(editingFinished ()), this, SLOT(rebuildVideo4Commands()));
-    connect(m_configCapture.kcfg_video4size, SIGNAL(editingFinished ()), this, SLOT(rebuildVideo4Commands()));
-    connect(m_configCapture.kcfg_video4rate, SIGNAL(editingFinished ()), this, SLOT(rebuildVideo4Commands()));
+    QWidget *p5 = new QWidget;
+    m_configShuttle.setupUi(p5);
+    page5 = addPage(p5, i18n("JogShuttle"), "input-mouse");
+
+    QStringList actions;
+    actions << i18n("Do nothing");
+    actions << i18n("Play / Pause");
+    actions << i18n("Cut");
+    m_configShuttle.kcfg_shuttle1->addItems(actions);
+    m_configShuttle.kcfg_shuttle2->addItems(actions);
+    m_configShuttle.kcfg_shuttle3->addItems(actions);
+    m_configShuttle.kcfg_shuttle4->addItems(actions);
+    m_configShuttle.kcfg_shuttle5->addItems(actions);
+
+    connect(m_configCapture.kcfg_video4vdevice, SIGNAL(editingFinished()), this, SLOT(rebuildVideo4Commands()));
+    connect(m_configCapture.kcfg_video4adevice, SIGNAL(editingFinished()), this, SLOT(rebuildVideo4Commands()));
+    connect(m_configCapture.kcfg_video4vformat, SIGNAL(editingFinished()), this, SLOT(rebuildVideo4Commands()));
+    connect(m_configCapture.kcfg_video4aformat, SIGNAL(editingFinished()), this, SLOT(rebuildVideo4Commands()));
+    connect(m_configCapture.kcfg_video4vencoding, SIGNAL(editingFinished()), this, SLOT(rebuildVideo4Commands()));
+    connect(m_configCapture.kcfg_video4aencoding, SIGNAL(editingFinished()), this, SLOT(rebuildVideo4Commands()));
+    connect(m_configCapture.kcfg_video4size, SIGNAL(editingFinished()), this, SLOT(rebuildVideo4Commands()));
+    connect(m_configCapture.kcfg_video4rate, SIGNAL(editingFinished()), this, SLOT(rebuildVideo4Commands()));
 
     QStringList profilesNames = ProfilesDialog::getProfileNames();
     m_configMisc.profiles_list->addItems(profilesNames);
@@ -74,14 +88,14 @@ KdenliveSettingsDialog::~KdenliveSettingsDialog() {}
 
 void KdenliveSettingsDialog::rebuildVideo4Commands() {
     QString captureCommand;
-       if (!m_configCapture.kcfg_video4adevice->text().isEmpty()) captureCommand = "-f " + m_configCapture.kcfg_video4aformat->text() + " -i " + m_configCapture.kcfg_video4adevice->text();
+    if (!m_configCapture.kcfg_video4adevice->text().isEmpty()) captureCommand = "-f " + m_configCapture.kcfg_video4aformat->text() + " -i " + m_configCapture.kcfg_video4adevice->text();
 
-       captureCommand +=  " -f " + m_configCapture.kcfg_video4vformat->text() + " -s " + m_configCapture.kcfg_video4size->text() + " -r " + QString::number(m_configCapture.kcfg_video4rate->value()) + " -i " + m_configCapture.kcfg_video4vdevice->text() + " -f " + m_configCapture.kcfg_video4vencoding->text();
-       m_configCapture.kcfg_video4capture->setText(captureCommand);
+    captureCommand +=  " -f " + m_configCapture.kcfg_video4vformat->text() + " -s " + m_configCapture.kcfg_video4size->text() + " -r " + QString::number(m_configCapture.kcfg_video4rate->value()) + " -i " + m_configCapture.kcfg_video4vdevice->text() + " -f " + m_configCapture.kcfg_video4vencoding->text();
+    m_configCapture.kcfg_video4capture->setText(captureCommand);
 
-       QString playbackCommand;
-       playbackCommand =  "-f " + m_configCapture.kcfg_video4vencoding->text();
-       m_configCapture.kcfg_video4playback->setText(playbackCommand);
+    QString playbackCommand;
+    playbackCommand =  "-f " + m_configCapture.kcfg_video4vencoding->text();
+    m_configCapture.kcfg_video4playback->setText(playbackCommand);
 }
 
 bool KdenliveSettingsDialog::hasChanged() {
index 975e1a54ae34bd61c7484bdfc96e0fd91a790354..cd82bf13c7c771526f2d52139ed4decc04c4fdd2 100644 (file)
@@ -29,6 +29,7 @@
 #include "ui_configenv_ui.h"
 #include "ui_configdisplay_ui.h"
 #include "ui_configcapture_ui.h"
+#include "ui_configjogshuttle_ui.h"
 
 class KdenliveSettingsDialog : public KConfigDialog {
     Q_OBJECT
@@ -49,10 +50,12 @@ private:
     KPageWidgetItem *page2;
     KPageWidgetItem *page3;
     KPageWidgetItem *page4;
+    KPageWidgetItem *page5;
     Ui::ConfigEnv_UI m_configEnv;
     Ui::ConfigMisc_UI m_configMisc;
     Ui::ConfigDisplay_UI m_configDisplay;
     Ui::ConfigCapture_UI m_configCapture;
+    Ui::ConfigJogShuttle_UI m_configShuttle;
     QStringList m_mltProfilesList;
     QStringList m_customProfilesList;
     bool m_isCustomProfile;
index 02c20ee777504d7ae0ca5a9531769f26aee0b8c5..899ce8840b214972ca98c7a00a16474bcc742264 100644 (file)
@@ -66,7 +66,7 @@
 
 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) {
     parseProfiles();
 
     m_commandStack = new QUndoGroup;
@@ -82,7 +82,6 @@ MainWindow::MainWindow(QWidget *parent)
     m_timelineArea->setCornerWidget(closeTabButton);
     connect(m_timelineArea, SIGNAL(currentChanged(int)), this, SLOT(activateDocument()));
 
-
     initEffects::parseEffectFiles(&m_audioEffects, &m_videoEffects);
     m_monitorManager = new MonitorManager();
 
@@ -242,6 +241,8 @@ MainWindow::MainWindow(QWidget *parent)
 
     setAutoSaveSettings();
     newFile();
+
+    activateShuttleDevice();
 }
 
 //virtual
@@ -258,6 +259,52 @@ bool MainWindow::queryClose() {
     }
 }
 
+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());
 }
@@ -733,6 +780,7 @@ void MainWindow::updateConfiguration() {
     }
     timeline_buttons_ui.buttonAudio->setDown(KdenliveSettings::audiothumbnails());
     timeline_buttons_ui.buttonVideo->setDown(KdenliveSettings::videothumbnails());
+    activateShuttleDevice();
 }
 
 void MainWindow::slotSwitchVideoThumbs() {
@@ -811,4 +859,12 @@ void MainWindow::slotGotProgressInfo(KUrl url, int progress) {
     }
 }
 
+void MainWindow::customEvent(QEvent* e) {
+    if (e->type() == QEvent::User) {
+        // The timeline playing position changed...
+        kDebug() << "RECIEVED JOG EVEMNT!!!";
+    }
+}
+
+
 #include "mainwindow.moc"
index d8cf446c41d059d042ace86f13d06f0c26b63d61..4a98c20b5ea750b3a89915c456084399cc6d54ad 100644 (file)
@@ -25,6 +25,7 @@
 #include <QUndoView>
 #include <QLabel>
 #include <QProgressBar>
+#include <QEvent>
 
 #include <KXmlGuiWindow>
 #include <KTextEdit>
@@ -47,6 +48,7 @@
 #include "transitionsettings.h"
 #include "ui_timelinebuttons_ui.h"
 #include "renderwidget.h"
+#include "jogshuttle.h"
 
 class MainWindow : public KXmlGuiWindow {
     Q_OBJECT
@@ -58,6 +60,7 @@ public:
 
 protected:
     virtual bool queryClose();
+    virtual void customEvent(QEvent * e);
 
 private:
     KTabWidget* m_timelineArea;
@@ -110,9 +113,13 @@ private:
     RenderWidget *m_renderWidget;
     Ui::TimelineButtons_UI timeline_buttons_ui;
 
+    JogShuttle *m_jogProcess;
+
     KRecentFilesAction *m_fileOpenRecent;
     void readOptions();
     void saveOptions();
+    void activateShuttleDevice();
+    void slotShuttleAction(int code);
 
 public slots:
     void openFile(const KUrl &url);
@@ -153,6 +160,7 @@ private slots:
     void slotAddAudioEffect(QAction *result);
     void slotAddCustomEffect(QAction *result);
     void slotAddProjectClip(KUrl url);
+    void slotShuttleButton(int code);
 };
 
 #endif
index 5ac13d2a7586d7ae9bc7f5b0bf3149ef8e9713c7..d22a90bdbbe08e5c8762498db46e7ef146c5cb47 100644 (file)
@@ -133,20 +133,24 @@ void Monitor::slotSeek(int pos) {
     m_timePos->setText(m_monitorManager->timecode().getTimecodeFromFrames(m_position));
 }
 
-void Monitor::slotRewind() {
+void Monitor::slotRewind(double speed) {
     if (!m_isActive) m_monitorManager->activateMonitor(m_name);
-    double speed = render->playSpeed();
-    if (speed >= 0) render->play(-2);
-    else render->play(speed * 2);
+    if (speed == 0) {
+        double currentspeed = render->playSpeed();
+        if (currentspeed >= 0) render->play(-2);
+        else render->play(currentspeed * 2);
+    } else render->play(speed);
     m_playAction->setChecked(true);
     m_playAction->setIcon(m_pauseIcon);
 }
 
-void Monitor::slotForward() {
+void Monitor::slotForward(double speed) {
     if (!m_isActive) m_monitorManager->activateMonitor(m_name);
-    double speed = render->playSpeed();
-    if (speed <= 1) render->play(2);
-    else render->play(speed * 2);
+    if (speed == 0) {
+        double currentspeed = render->playSpeed();
+        if (currentspeed <= 1) render->play(2);
+        else render->play(currentspeed * 2);
+    } else render->play(speed);
     m_playAction->setChecked(true);
     m_playAction->setIcon(m_pauseIcon);
 }
index 39e7e2ff628251f562461c9b1aa5d138fd09eb9c..3ae530b4e14b921ba8ee94911fa79dc9cb9742fb 100644 (file)
@@ -89,8 +89,8 @@ public slots:
     void start();
     void activateMonitor();
     void slotPlay();
-    void slotForward();
-    void slotRewind();
+    void slotForward(double speed = 0);
+    void slotRewind(double speed = 0);
     void slotRewindOneFrame();
     void slotForwardOneFrame();
     void saveSceneList(QString path, QDomElement e = QDomElement());
index aff200877f0f5221b97caa388cdc390c8c7e6641..9c163f07c91b7bdaae5996f6f7509184e797f821 100644 (file)
@@ -79,14 +79,14 @@ void MonitorManager::slotPlay() {
     else m_projectMonitor->slotPlay();
 }
 
-void MonitorManager::slotRewind() {
-    if (m_activeMonitor == "clip") m_clipMonitor->slotRewind();
-    else m_projectMonitor->slotRewind();
+void MonitorManager::slotRewind(double speed) {
+    if (m_activeMonitor == "clip") m_clipMonitor->slotRewind(speed);
+    else m_projectMonitor->slotRewind(speed);
 }
 
-void MonitorManager::slotForward() {
-    if (m_activeMonitor == "clip") m_clipMonitor->slotForward();
-    else m_projectMonitor->slotForward();
+void MonitorManager::slotForward(double speed) {
+    if (m_activeMonitor == "clip") m_clipMonitor->slotForward(speed);
+    else m_projectMonitor->slotForward(speed);
 }
 
 void MonitorManager::slotRewindOneFrame() {
index e8f5aa779afcfab4e0827d4e3dfcd3762104ceef..a33af55cbf72a2725c92e8a41f2fdc07be421f15 100644 (file)
@@ -40,8 +40,8 @@ public:
 public slots:
     void activateMonitor(QString name = QString::null);
     void slotPlay();
-    void slotRewind();
-    void slotForward();
+    void slotRewind(double speed = 0);
+    void slotForward(double speed = 0);
     void slotRewindOneFrame();
     void slotForwardOneFrame();
 
index bdb3fb68979427873a7d91c0328d943be3740cba..5203bc92e72a724e3bca3dfd18b7bdc49ca42d14 100644 (file)
@@ -83,17 +83,17 @@ RecMonitor::RecMonitor(QString name, QWidget *parent)
     displayProcess->setEnvironment(env);
 
     if (KdenliveSettings::video4capture().isEmpty()) {
-       QString captureCommand;
-       if (!KdenliveSettings::video4adevice().isEmpty()) captureCommand = "-f " + KdenliveSettings::video4aformat() + " -i " + KdenliveSettings::video4adevice();
+        QString captureCommand;
+        if (!KdenliveSettings::video4adevice().isEmpty()) captureCommand = "-f " + KdenliveSettings::video4aformat() + " -i " + KdenliveSettings::video4adevice();
 
-       captureCommand +=  " -f " + KdenliveSettings::video4vformat() + " -s " + KdenliveSettings::video4size() + " -r " + QString::number(KdenliveSettings::video4rate()) + " -i " + KdenliveSettings::video4vdevice() + " -f " + KdenliveSettings::video4vencoding();
-       KdenliveSettings::setVideo4capture(captureCommand);
+        captureCommand +=  " -f " + KdenliveSettings::video4vformat() + " -s " + KdenliveSettings::video4size() + " -r " + QString::number(KdenliveSettings::video4rate()) + " -i " + KdenliveSettings::video4vdevice() + " -f " + KdenliveSettings::video4vencoding();
+        KdenliveSettings::setVideo4capture(captureCommand);
     }
 
     if (KdenliveSettings::video4playback().isEmpty()) {
-       QString playbackCommand;
-       playbackCommand =  "-f " + KdenliveSettings::video4vencoding();
-       KdenliveSettings::setVideo4playback(playbackCommand);
+        QString playbackCommand;
+        playbackCommand =  "-f " + KdenliveSettings::video4vencoding();
+        KdenliveSettings::setVideo4playback(playbackCommand);
     }
     kDebug() << "/////// BUILDING MONITOR, ID: " << ui.video_frame->winId();
 }
@@ -227,7 +227,7 @@ void RecMonitor::slotStartCapture(bool play) {
         m_captureArgs << "--format" << "hdv" << "-i" << "capture" << "-";
         m_displayArgs << "-f" << "mpegts" << "-x" << QString::number(ui.video_frame->width()) << "-y" << QString::number(ui.video_frame->height()) << "-";
     } else {
-       m_captureArgs << KdenliveSettings::video4capture().simplified().split(' ') << "-";
+        m_captureArgs << KdenliveSettings::video4capture().simplified().split(' ') << "-";
         m_displayArgs << KdenliveSettings::video4playback().simplified().split(' ') << "-x" << QString::number(ui.video_frame->width()) << "-y" << QString::number(ui.video_frame->height()) << "-";
     }
 
@@ -288,8 +288,8 @@ void RecMonitor::slotRecord() {
             m_captureArgs << "--format" << "hdv" << "-i" << "capture" << "-";
             m_displayArgs << "-f" << "mpegts" << "-x" << QString::number(ui.video_frame->width()) << "-y" << QString::number(ui.video_frame->height()) << "-";
         } else {
-           m_captureArgs << KdenliveSettings::video4capture().simplified().split(' ') << "-y" << m_captureFile.path() << "-f" << KdenliveSettings::video4vencoding() << "-";
-           m_displayArgs << KdenliveSettings::video4playback().simplified().split(' ') << "-x" << QString::number(ui.video_frame->width()) << "-y" << QString::number(ui.video_frame->height()) << "-";
+            m_captureArgs << KdenliveSettings::video4capture().simplified().split(' ') << "-y" << m_captureFile.path() << "-f" << KdenliveSettings::video4vencoding() << "-";
+            m_displayArgs << KdenliveSettings::video4playback().simplified().split(' ') << "-x" << QString::number(ui.video_frame->width()) << "-y" << QString::number(ui.video_frame->height()) << "-";
         }
 
         captureProcess->setStandardOutputProcess(displayProcess);
index 647a8136b14c1502fb82b67a7ba43c62c5e116ca..559f1435efb7913f21970c390ea32b12efc80d37 100644 (file)
      </item>
     </widget>
    </item>
-   <item row="1" column="0" >
-    <widget class="QLabel" name="label_10" >
-     <property name="text" >
-      <string>Capture folder</string>
-     </property>
-    </widget>
-   </item>
-   <item row="1" column="1" >
-    <widget class="KUrlRequester" name="capturefolderurl" />
-   </item>
-   <item row="2" column="0" colspan="2" >
+   <item row="1" column="0" colspan="2" >
     <widget class="QTabWidget" name="tabWidget" >
      <property name="minimumSize" >
       <size>
        <string>Video4Linux2 / FFmpeg</string>
       </attribute>
       <layout class="QGridLayout" name="gridLayout" >
+       <item row="1" column="1" colspan="3" >
+        <widget class="KLineEdit" name="kcfg_video4vdevice" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text" >
+          <string>/dev/video0</string>
+         </property>
+        </widget>
+       </item>
        <item row="0" column="0" >
         <widget class="QLabel" name="label_7" >
          <property name="text" >
          </property>
         </widget>
        </item>
-       <item row="1" column="0" >
-        <widget class="QLabel" name="label_14" >
-         <property name="text" >
-          <string>Device</string>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="1" colspan="3" >
-        <widget class="KLineEdit" name="kcfg_video4vdevice" >
+       <item row="1" column="4" >
+        <widget class="QLabel" name="label_3" >
          <property name="sizePolicy" >
-          <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
+          <sizepolicy vsizetype="Preferred" hsizetype="Maximum" >
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="text" >
-          <string>/dev/video0</string>
+          <string>Format</string>
          </property>
         </widget>
        </item>
-       <item row="1" column="4" >
-        <widget class="QLabel" name="label_3" >
+       <item row="1" column="7" colspan="2" >
+        <widget class="QLabel" name="label_5" >
          <property name="sizePolicy" >
           <sizepolicy vsizetype="Preferred" hsizetype="Maximum" >
            <horstretch>0</horstretch>
           </sizepolicy>
          </property>
          <property name="text" >
-          <string>Format</string>
+          <string>Encoding</string>
          </property>
         </widget>
        </item>
          </property>
         </widget>
        </item>
-       <item row="1" column="7" colspan="2" >
-        <widget class="QLabel" name="label_5" >
+       <item row="1" column="9" >
+        <widget class="KLineEdit" name="kcfg_video4vencoding" >
          <property name="sizePolicy" >
-          <sizepolicy vsizetype="Preferred" hsizetype="Maximum" >
+          <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
          <property name="text" >
-          <string>Encoding</string>
+          <string>ogg</string>
          </property>
         </widget>
        </item>
-       <item row="1" column="9" >
-        <widget class="KLineEdit" name="kcfg_video4vencoding" >
+       <item row="1" column="0" >
+        <widget class="QLabel" name="label_14" >
+         <property name="text" >
+          <string>Device</string>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="9" >
+        <widget class="KLineEdit" name="kcfg_video4aencoding" >
          <property name="sizePolicy" >
           <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
            <horstretch>0</horstretch>
            <verstretch>0</verstretch>
           </sizepolicy>
          </property>
-         <property name="text" >
-          <string>ogg</string>
-         </property>
         </widget>
        </item>
-       <item row="2" column="0" colspan="2" >
-        <widget class="QLabel" name="label_15" >
+       <item row="3" column="1" colspan="3" >
+        <widget class="KLineEdit" name="kcfg_video4adevice" >
          <property name="text" >
-          <string>Audio</string>
+          <string>/dev/dsp</string>
          </property>
         </widget>
        </item>
          </property>
         </widget>
        </item>
-       <item row="3" column="0" >
-        <widget class="QLabel" name="label_16" >
-         <property name="text" >
-          <string>Device</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="1" colspan="3" >
-        <widget class="KLineEdit" name="kcfg_video4adevice" >
-         <property name="text" >
-          <string>/dev/dsp</string>
-         </property>
-        </widget>
-       </item>
        <item row="3" column="4" >
         <widget class="QLabel" name="label_9" >
          <property name="sizePolicy" >
          </property>
         </widget>
        </item>
-       <item row="3" column="5" colspan="2" >
-        <widget class="KLineEdit" name="kcfg_video4aformat" >
-         <property name="sizePolicy" >
-          <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
+       <item row="3" column="0" >
+        <widget class="QLabel" name="label_16" >
+         <property name="text" >
+          <string>Device</string>
          </property>
+        </widget>
+       </item>
+       <item row="2" column="0" colspan="2" >
+        <widget class="QLabel" name="label_15" >
          <property name="text" >
-          <string>oss</string>
+          <string>Audio</string>
          </property>
         </widget>
        </item>
          </property>
         </widget>
        </item>
-       <item row="3" column="9" >
-        <widget class="KLineEdit" name="kcfg_video4aencoding" >
-         <property name="sizePolicy" >
-          <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
-           <horstretch>0</horstretch>
-           <verstretch>0</verstretch>
-          </sizepolicy>
-         </property>
-        </widget>
-       </item>
        <item row="4" column="0" colspan="10" >
         <widget class="Line" name="line_3" >
          <property name="orientation" >
          </property>
         </widget>
        </item>
+       <item row="5" column="6" colspan="2" >
+        <widget class="QLabel" name="label_6" >
+         <property name="text" >
+          <string>Frame rate</string>
+         </property>
+        </widget>
+       </item>
        <item row="5" column="3" colspan="3" >
         <widget class="KLineEdit" name="kcfg_video4size" >
          <property name="text" >
          </property>
         </widget>
        </item>
-       <item row="5" column="6" colspan="2" >
-        <widget class="QLabel" name="label_6" >
+       <item row="6" column="0" colspan="3" >
+        <widget class="QLabel" name="label_11" >
          <property name="text" >
-          <string>Frame rate</string>
+          <string>Capture params</string>
          </property>
         </widget>
        </item>
          </property>
         </widget>
        </item>
-       <item row="6" column="0" colspan="3" >
-        <widget class="QLabel" name="label_11" >
-         <property name="text" >
-          <string>Capture params</string>
-         </property>
-        </widget>
-       </item>
        <item row="6" column="3" colspan="7" >
         <widget class="KLineEdit" name="kcfg_video4capture" />
        </item>
+       <item row="7" column="3" colspan="7" >
+        <widget class="KLineEdit" name="kcfg_video4playback" />
+       </item>
        <item row="7" column="0" colspan="3" >
         <widget class="QLabel" name="label_12" >
          <property name="text" >
          </property>
         </widget>
        </item>
-       <item row="7" column="3" colspan="7" >
-        <widget class="KLineEdit" name="kcfg_video4playback" />
+       <item row="3" column="5" colspan="2" >
+        <widget class="KLineEdit" name="kcfg_video4aformat" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Fixed" hsizetype="MinimumExpanding" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text" >
+          <string>oss</string>
+         </property>
+        </widget>
        </item>
       </layout>
       <zorder>kcfg_video4vdevice</zorder>
      </widget>
     </widget>
    </item>
-   <item row="3" column="1" >
+   <item row="2" column="1" >
     <spacer name="verticalSpacer" >
      <property name="orientation" >
       <enum>Qt::Vertical</enum>
    <extends>QLineEdit</extends>
    <header>klineedit.h</header>
   </customwidget>
-  <customwidget>
-   <class>KUrlRequester</class>
-   <extends>QFrame</extends>
-   <header>kurlrequester.h</header>
-  </customwidget>
  </customwidgets>
  <resources/>
  <connections/>
index 716850a6424827a30b6cd7a051facdf1473427f2..2c2b49474fe80ae58719756d5b4e877de625bf40 100644 (file)
@@ -5,8 +5,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>394</width>
-    <height>203</height>
+    <width>416</width>
+    <height>238</height>
    </rect>
   </property>
   <layout class="QGridLayout" name="gridLayout_3" >
       <item row="0" column="1" >
        <widget class="KUrlRequester" name="tmppathurl" />
       </item>
+      <item row="1" column="0" >
+       <widget class="QLabel" name="label_10" >
+        <property name="text" >
+         <string>Capture folder</string>
+        </property>
+       </widget>
+      </item>
+      <item row="1" column="1" >
+       <widget class="KUrlRequester" name="capturefolderurl" />
+      </item>
      </layout>
     </widget>
    </item>
diff --git a/src/widgets/configjogshuttle_ui.ui b/src/widgets/configjogshuttle_ui.ui
new file mode 100644 (file)
index 0000000..0c2dafa
--- /dev/null
@@ -0,0 +1,113 @@
+<ui version="4.0" >
+ <class>ConfigJogShuttle_UI</class>
+ <widget class="QWidget" name="ConfigJogShuttle_UI" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>299</width>
+    <height>260</height>
+   </rect>
+  </property>
+  <layout class="QGridLayout" name="gridLayout" >
+   <item row="0" column="0" colspan="2" >
+    <widget class="QCheckBox" name="kcfg_enableshuttle" >
+     <property name="text" >
+      <string>Enable Jog Shuttle device</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0" >
+    <widget class="QLabel" name="label" >
+     <property name="text" >
+      <string>Device path</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1" >
+    <widget class="KLineEdit" name="kcfg_shuttledevice" >
+     <property name="text" >
+      <string>/dev/input/event1</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0" >
+    <widget class="QLabel" name="label_2" >
+     <property name="text" >
+      <string>Button 1</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="1" >
+    <widget class="KComboBox" name="kcfg_shuttle1" />
+   </item>
+   <item row="3" column="0" >
+    <widget class="QLabel" name="label_4" >
+     <property name="text" >
+      <string>Button 2</string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="1" >
+    <widget class="KComboBox" name="kcfg_shuttle2" />
+   </item>
+   <item row="4" column="0" >
+    <widget class="QLabel" name="label_3" >
+     <property name="text" >
+      <string>Button 3</string>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="1" >
+    <widget class="KComboBox" name="kcfg_shuttle3" />
+   </item>
+   <item row="5" column="0" >
+    <widget class="QLabel" name="label_7" >
+     <property name="text" >
+      <string>Button 4</string>
+     </property>
+    </widget>
+   </item>
+   <item row="5" column="1" >
+    <widget class="KComboBox" name="kcfg_shuttle4" />
+   </item>
+   <item row="6" column="0" >
+    <widget class="QLabel" name="label_5" >
+     <property name="text" >
+      <string>Button 5</string>
+     </property>
+    </widget>
+   </item>
+   <item row="6" column="1" >
+    <widget class="KComboBox" name="kcfg_shuttle5" />
+   </item>
+   <item row="7" column="1" >
+    <spacer name="verticalSpacer" >
+     <property name="orientation" >
+      <enum>Qt::Vertical</enum>
+     </property>
+     <property name="sizeHint" stdset="0" >
+      <size>
+       <width>20</width>
+       <height>56</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>KComboBox</class>
+   <extends>QComboBox</extends>
+   <header>kcombobox.h</header>
+  </customwidget>
+  <customwidget>
+   <class>KLineEdit</class>
+   <extends>QLineEdit</extends>
+   <header>klineedit.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
index 21b41a2b9581ffbf2b0a513e42419564daaef322..e04a324f62efb1ef58dfebfda7bd98bb67799182 100644 (file)
     <widget class="KComboBox" name="device_selector" >
      <item>
       <property name="text" >
-       <string>Firewire / dvgrab</string>
+       <string>Firewire</string>
       </property>
      </item>
      <item>
       <property name="text" >
-       <string>Video4Linux / ffmpeg</string>
+       <string>Video4Linux</string>
       </property>
      </item>
     </widget>