]> git.sesse.net Git - kdenlive/commitdiff
Work on firewire capture: dv should work, you now get a captured file dialog when...
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 22 Jul 2008 21:48:02 +0000 (21:48 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 22 Jul 2008 21:48:02 +0000 (21:48 +0000)
svn path=/branches/KDE4/; revision=2345

src/CMakeLists.txt
src/kdenlivesettings.kcfg
src/managecapturesdialog.cpp [new file with mode: 0644]
src/managecapturesdialog.h [new file with mode: 0644]
src/projectlist.cpp
src/recmonitor.cpp
src/recmonitor.h
src/widgets/configcapture_ui.ui
src/widgets/managecaptures_ui.ui [new file with mode: 0644]

index a213f33e9f414c0c1e059b7ffb29110445b2d407..c1be6199c29451a96926c498dd9f02c74051415a 100644 (file)
@@ -53,6 +53,7 @@ kde4_add_ui_files(kdenlive_UI
   widgets/markerdialog_ui.ui
   widgets/keyframedialog_ui.ui
   widgets/clipdurationdialog_ui.ui
+  widgets/managecaptures_ui.ui
 )
  
 set(kdenlive_SRCS 
@@ -121,6 +122,7 @@ set(kdenlive_SRCS
   regiongrabber.cpp
   editkeyframecommand.cpp
   clipdurationdialog.cpp
+  managecapturesdialog.cpp
 )
 
 kde4_add_kcfg_files(kdenlive_SRCS GENERATE_MOC kdenlivesettings.kcfgc )
index 03e1ef1956ac32d0516af1ab750bb84eb87fc0ca..f55679a518adcf78569d9f2dbfa1fced9acdcc2a 100644 (file)
       <default>0</default>
     </entry>
 
+    <entry name="firewireautosplit" type="Bool">
+      <label>Create new capture file on scene cut.</label>
+      <default>false</default>
+    </entry>
+
+    <entry name="firewiretimestamp" type="Bool">
+      <label>Add record time to captured file name.</label>
+      <default>false</default>
+    </entry>
+
     <entry name="video4vformat" type="String">
       <label>Default video4linux capture format.</label>
       <default>video4linux2</default>
diff --git a/src/managecapturesdialog.cpp b/src/managecapturesdialog.cpp
new file mode 100644 (file)
index 0000000..78fa8e8
--- /dev/null
@@ -0,0 +1,111 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.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          *
+ ***************************************************************************/
+
+#include <QTreeWidgetItem>
+#include <QFile>
+#include <QHeaderView>
+
+#include <KDebug>
+#include <KGlobalSettings>
+#include <KFileItem>
+#include <KIO/NetAccess>
+
+#include "managecapturesdialog.h"
+
+
+ManageCapturesDialog::ManageCapturesDialog(KUrl::List files, QWidget * parent): QDialog(parent) {
+    setFont(KGlobalSettings::toolBarFont());
+    m_view.setupUi(this);
+    m_importButton = m_view.buttonBox->button(QDialogButtonBox::Ok);
+    m_importButton->setText(i18n("import"));
+    foreach(const KUrl url, files) {
+        QStringList text;
+        text << url.fileName();
+        KFileItem file(KFileItem::Unknown, KFileItem::Unknown, url, true);
+        text << KIO::convertSize(file.size());
+        QTreeWidgetItem *item = new QTreeWidgetItem(m_view.treeWidget, text);
+        item->setData(0, Qt::UserRole, url.path());
+        item->setToolTip(0, url.path());
+        item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsSelectable | Qt::ItemIsEnabled);
+        item->setCheckState(0, Qt::Checked);
+    }
+    connect(m_view.treeWidget, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotRefreshButtons()));
+    connect(m_view.deleteButton, SIGNAL(pressed()), this, SLOT(slotDeleteCurrent()));
+    connect(m_view.toggleButton, SIGNAL(pressed()), this, SLOT(slotToggle()));
+    QTreeWidgetItem *item = m_view.treeWidget->topLevelItem(0);
+    if (item) m_view.treeWidget->setCurrentItem(item);
+    m_view.treeWidget->header()->setResizeMode(0, QHeaderView::Stretch);
+    adjustSize();
+}
+
+ManageCapturesDialog::~ManageCapturesDialog() {
+}
+
+void ManageCapturesDialog::slotRefreshButtons() {
+    int count = m_view.treeWidget->topLevelItemCount();
+    bool enabled = false;
+    for (int i = 0; i < count; i++) {
+        QTreeWidgetItem *item = m_view.treeWidget->topLevelItem(i);
+        if (item && item->checkState(0) == Qt::Checked) {
+            enabled = true;
+            break;
+        }
+    }
+    m_importButton->setEnabled(enabled);
+}
+
+void ManageCapturesDialog::slotDeleteCurrent() {
+    QTreeWidgetItem *item = m_view.treeWidget->currentItem();
+    if (!item) return;
+    int i = m_view.treeWidget->indexOfTopLevelItem(item);
+    m_view.treeWidget->takeTopLevelItem(i);
+    kDebug() << "DELETING FILE: " << item->text(0);
+    //KIO::NetAccess::del(KUrl(item->text(0)), this);
+    QFile f(item->data(0, Qt::UserRole).toString());
+    f.remove();
+    delete item;
+    item = NULL;
+}
+
+void ManageCapturesDialog::slotToggle() {
+    int count = m_view.treeWidget->topLevelItemCount();
+    for (int i = 0; i < count; i++) {
+        QTreeWidgetItem *item = m_view.treeWidget->topLevelItem(i);
+        if (item) {
+            if (item->checkState(0) == Qt::Checked) item->setCheckState(0, Qt::Unchecked);
+            else item->setCheckState(0, Qt::Checked);
+        }
+    }
+}
+
+KUrl::List ManageCapturesDialog::importFiles() {
+    KUrl::List result;
+
+    int count = m_view.treeWidget->topLevelItemCount();
+    for (int i = 0; i < count; i++) {
+        QTreeWidgetItem *item = m_view.treeWidget->topLevelItem(i);
+        if (item && item->checkState(0) == Qt::Checked)
+            result.append(KUrl(item->data(0, Qt::UserRole).toString()));
+    }
+    return result;
+}
+
+#include "managecapturesdialog.moc"
+
+
diff --git a/src/managecapturesdialog.h b/src/managecapturesdialog.h
new file mode 100644 (file)
index 0000000..ccf1b56
--- /dev/null
@@ -0,0 +1,58 @@
+/***************************************************************************
+ *   Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.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 CAPTUREDIALOG_H
+#define CAPTUREDIALOG_H
+
+#include <QDialog>
+#include <QPushButton>
+
+#include <KUrl>
+
+//#include "docclipbase.h"
+#include "ui_managecaptures_ui.h"
+
+class ManageCapturesDialog : public QDialog {
+    Q_OBJECT
+
+public:
+    ManageCapturesDialog(KUrl::List files, QWidget * parent = 0);
+    ~ManageCapturesDialog();
+    KUrl::List importFiles();
+
+private slots:
+    void slotRefreshButtons();
+    void slotDeleteCurrent();
+    void slotToggle();
+
+protected:
+    //void wheelEvent(QWheelEvent * event);
+
+private:
+    Ui::ManageCaptures_UI m_view;
+    QPushButton *m_importButton;
+
+signals:
+    //void updateThumb();
+};
+
+
+#endif
+
index d11deaf51639082e1d3cb97c83238cf34cb5722e..e5620ba79b5a1c3a4fbe3e072b30fd4bed39dbd3 100644 (file)
@@ -314,7 +314,7 @@ void ProjectList::slotAddClip(QUrl givenUrl, QString group) {
         list = KFileDialog::getOpenUrls(KUrl("kfiledialog:///clipfolder"), "application/vnd.kde.kdenlive application/vnd.westley.scenelist application/flv application/vnd.rn-realmedia video/x-dv video/x-msvideo video/mpeg video/x-ms-wmv audio/mpeg audio/x-mp3 audio/x-wav application/ogg video/mp4 video/quicktime image/gif image/jpeg image/png image/x-bmp image/svg+xml image/tiff image/x-xcf-gimp image/x-vnd.adobe.photoshop image/x-pcx image/x-exr\n*.m2t *.mts|HDV video\n*.dv|DV video");
     } else list.append(givenUrl);
     if (list.isEmpty()) return;
-    KUrl::List::Iterator it;
+
     int groupId = -1;
     if (group.isEmpty()) {
         ProjectItem *item = static_cast <ProjectItem*>(listView->currentItem());
@@ -329,8 +329,8 @@ void ProjectList::slotAddClip(QUrl givenUrl, QString group) {
             groupId = item->clipId();
         }
     }
-    for (it = list.begin(); it != list.end(); it++) {
-        m_doc->slotAddClipFile(*it, group, groupId);
+    foreach(const KUrl file, list) {
+        m_doc->slotAddClipFile(file, group, groupId);
     }
 }
 
index 2a2f0a9017c651c9e3d6b4bfb9b2868b0e11c63c..e823244f4d928a37ae55427302da1a86964e57f6 100644 (file)
 #include <KStandardDirs>
 #include <KComboBox>
 #include <KIO/NetAccess>
+#include <KFileItem>
 
 #include "gentime.h"
 #include "kdenlivesettings.h"
+#include "managecapturesdialog.h"
 #include "recmonitor.h"
 
 RecMonitor::RecMonitor(QString name, QWidget *parent)
-        : QWidget(parent), m_name(name), m_isActive(false), m_isCapturing(false), m_isPlaying(false) {
+        : QWidget(parent), m_name(name), m_isActive(false), m_isCapturing(false), m_isPlaying(false), m_didCapture(false) {
     ui.setupUi(this);
 
     ui.video_frame->setAttribute(Qt::WA_PaintOnScreen);
@@ -177,6 +179,9 @@ void RecMonitor::checkDeviceAvailability() {
 
 void RecMonitor::slotDisconnect() {
     if (captureProcess->state() == QProcess::NotRunning) {
+        m_captureTime = KDateTime::currentLocalDateTime();
+        kDebug() << "CURRENT TIME: " << m_captureTime.toString();
+        m_didCapture = false;
         slotStartCapture(false);
         m_discAction->setIcon(KIcon("network-disconnect"));
         m_discAction->setText(i18n("Disonnect"));
@@ -187,6 +192,9 @@ void RecMonitor::slotDisconnect() {
         m_fwdAction->setEnabled(true);
     } else {
         captureProcess->write("q", 1);
+        QTimer::singleShot(1000, captureProcess, SLOT(kill()));
+        if (m_didCapture) manageCapturedFiles();
+        m_didCapture = false;
     }
 }
 
@@ -281,8 +289,33 @@ void RecMonitor::slotStartCapture(bool play) {
 
     switch (ui.device_selector->currentIndex()) {
     case FIREWIRE:
-        m_captureArgs << "--format" << "hdv" << "-i" << "capture" << "-";
-        m_displayArgs << "-f" << "mpegts" << "-x" << QString::number(ui.video_frame->width()) << "-y" << QString::number(ui.video_frame->height()) << "-";
+        switch (KdenliveSettings::firewireformat()) {
+        case 0:
+            // RAW DV CAPTURE
+            m_captureArgs << "--format" << "raw";
+            m_displayArgs << "-f" << "dv";
+            break;
+        case 1:
+            // DV type 1
+            m_captureArgs << "--format" << "dv1";
+            m_displayArgs << "-f" << "dv";
+            break;
+        case 2:
+            // DV type 2
+            m_captureArgs << "--format" << "dv2";
+            m_displayArgs << "-f" << "dv";
+            break;
+        case 3:
+            // HDV CAPTURE
+            m_captureArgs << "--format" << "hdv";
+            m_displayArgs << "-f" << "mpegts";
+            break;
+        }
+        if (KdenliveSettings::firewireautosplit()) m_captureArgs << "--autosplit";
+        if (KdenliveSettings::firewiretimestamp()) m_captureArgs << "--timestamp";
+        m_captureArgs << "-i" << "capture" << "-";
+        m_displayArgs << "-x" << QString::number(ui.video_frame->width()) << "-y" << QString::number(ui.video_frame->height()) << "-";
+
         captureProcess->setStandardOutputProcess(displayProcess);
         captureProcess->setWorkingDirectory(KdenliveSettings::capturefolder());
         captureProcess->start("dvgrab", m_captureArgs);
@@ -334,6 +367,7 @@ void RecMonitor::slotRecord() {
         return;
     } else if (ui.device_selector->currentIndex() == FIREWIRE) {
         m_isCapturing = true;
+        m_didCapture = true;
         captureProcess->write("c\n", 3);
         return;
     }
@@ -448,9 +482,6 @@ void RecMonitor::slotProcessStatus(QProcess::ProcessState status) {
             ui.video_frame->setText(i18n("Capture crashed, please check your parameters"));
         } else {
             ui.video_frame->setText(i18n("Not connected"));
-            if (m_isCapturing && ui.device_selector->currentIndex() == FIREWIRE) {
-                //TODO: show dialog asking user confirmation for captured files
-            }
         }
         m_isCapturing = false;
     } else {
@@ -459,6 +490,47 @@ void RecMonitor::slotProcessStatus(QProcess::ProcessState status) {
     }
 }
 
+void RecMonitor::manageCapturedFiles() {
+    QString extension;
+    switch (KdenliveSettings::firewireformat()) {
+    case 0:
+        extension = ".dv";
+        break;
+    case 1:
+    case 2:
+        extension = ".avi";
+        break;
+    case 3:
+        extension = ".m2t";
+        break;
+    }
+    QDir dir(KdenliveSettings::capturefolder());
+    QStringList filters;
+    filters << "capture*" + extension;
+    QStringList result = dir.entryList(filters, QDir::Files, QDir::Time);
+    KUrl::List capturedFiles;
+    foreach(QString name, result) {
+        KUrl url = KUrl(dir.filePath(name));
+        if (KIO::NetAccess::exists(url, KIO::NetAccess::SourceSide, this)) {
+            KFileItem file(KFileItem::Unknown, KFileItem::Unknown, url, true);
+            if (file.time(KFileItem::ModificationTime) > m_captureTime) capturedFiles.append(url);
+        }
+    }
+    kDebug() << "Found : " << capturedFiles.count() << " new capture files";
+    kDebug() << capturedFiles;
+
+    if (capturedFiles.count() > 0) {
+        ManageCapturesDialog *d = new ManageCapturesDialog(capturedFiles, this);
+        if (d->exec() == QDialog::Accepted) {
+            capturedFiles = d->importFiles();
+            foreach(KUrl url, capturedFiles) {
+                emit addProjectClip(url);
+            }
+        }
+        delete d;
+    }
+}
+
 // virtual
 void RecMonitor::mousePressEvent(QMouseEvent * event) {
     slotPlay();
index 5de70a90c1a88c04442170add67a8441bb23de9c..6b89ae255630eaac0c2eed61e641d7b21d2d382d 100644 (file)
@@ -29,6 +29,7 @@
 #include <KIcon>
 #include <KAction>
 #include <KRestrictedLine>
+#include <KDateTime>
 
 #include "ui_recmonitor_ui.h"
 #include "smallruler.h"
@@ -52,7 +53,7 @@ private:
     QString m_name;
     RegionGrabber *rgnGrab;
     bool m_isActive;
-
+    KDateTime m_captureTime;
 
     KUrl m_captureFile;
     KIcon m_playIcon;
@@ -62,6 +63,8 @@ private:
     QProcess *displayProcess;
     QTimer *m_initTimer;
     bool m_isCapturing;
+    /** did the user capture something ? */
+    bool m_didCapture;
     bool m_isPlaying;
     QStringList m_captureArgs;
     QStringList m_displayArgs;
@@ -73,6 +76,7 @@ private:
     QAction *m_discAction;
     void checkDeviceAvailability();
     QPixmap mergeSideBySide(const QPixmap& pix, const QString txt);
+    void manageCapturedFiles();
 
 private slots:
     void slotStartCapture(bool play = true);
index 452f1de217a1a3f386192deefc03f0b01db8d324..28b39cfd768290b6e456d080e18dd0cf830eb3b7 100644 (file)
       </size>
      </property>
      <property name="currentIndex" >
-      <number>2</number>
+      <number>0</number>
      </property>
      <widget class="QWidget" name="tab" >
       <property name="geometry" >
        <rect>
         <x>0</x>
         <y>0</y>
-        <width>486</width>
-        <height>270</height>
+        <width>430</width>
+        <height>238</height>
        </rect>
       </property>
       <attribute name="title" >
        <item row="0" column="0" >
         <widget class="QLabel" name="label_2" >
          <property name="text" >
-          <string>Default format</string>
+          <string>Capture format</string>
          </property>
         </widget>
        </item>
-       <item row="0" column="1" colspan="2" >
+       <item row="0" column="1" >
         <widget class="KComboBox" name="kcfg_firewireformat" >
          <item>
           <property name="text" >
@@ -91,7 +91,7 @@
          </item>
         </widget>
        </item>
-       <item row="0" column="3" >
+       <item row="0" column="2" >
         <spacer name="horizontalSpacer" >
          <property name="orientation" >
           <enum>Qt::Horizontal</enum>
          </property>
         </spacer>
        </item>
-       <item row="1" column="2" >
+       <item row="1" column="0" colspan="3" >
+        <widget class="QCheckBox" name="kcfg_firewireautosplit" >
+         <property name="text" >
+          <string>Automatically start a new file on scene cut</string>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="0" colspan="3" >
+        <widget class="QCheckBox" name="kcfg_firewiretimestamp" >
+         <property name="text" >
+          <string>Add recording time to captured file name</string>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="1" >
         <spacer name="verticalSpacer_2" >
          <property name="orientation" >
           <enum>Qt::Vertical</enum>
        <rect>
         <x>0</x>
         <y>0</y>
-        <width>486</width>
-        <height>270</height>
+        <width>430</width>
+        <height>238</height>
        </rect>
       </property>
       <attribute name="title" >
     </widget>
    </item>
   </layout>
-  <zorder>label</zorder>
-  <zorder>kcfg_defaultcapture</zorder>
-  <zorder>tabWidget</zorder>
  </widget>
  <customwidgets>
   <customwidget>
diff --git a/src/widgets/managecaptures_ui.ui b/src/widgets/managecaptures_ui.ui
new file mode 100644 (file)
index 0000000..e3bc200
--- /dev/null
@@ -0,0 +1,106 @@
+<ui version="4.0" >
+ <class>ManageCaptures_UI</class>
+ <widget class="QDialog" name="ManageCaptures_UI" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>440</width>
+    <height>245</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Captured files</string>
+  </property>
+  <layout class="QGridLayout" name="gridLayout" >
+   <item row="0" column="0" colspan="3" >
+    <widget class="QTreeWidget" name="treeWidget" >
+     <property name="alternatingRowColors" >
+      <bool>true</bool>
+     </property>
+     <property name="rootIsDecorated" >
+      <bool>false</bool>
+     </property>
+     <property name="itemsExpandable" >
+      <bool>false</bool>
+     </property>
+     <property name="sortingEnabled" >
+      <bool>true</bool>
+     </property>
+     <property name="allColumnsShowFocus" >
+      <bool>true</bool>
+     </property>
+     <column>
+      <property name="text" >
+       <string>File name</string>
+      </property>
+     </column>
+     <column>
+      <property name="text" >
+       <string>Size</string>
+      </property>
+     </column>
+    </widget>
+   </item>
+   <item row="1" column="0" >
+    <widget class="QPushButton" name="deleteButton" >
+     <property name="text" >
+      <string>Delete current file</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1" >
+    <widget class="QPushButton" name="toggleButton" >
+     <property name="text" >
+      <string>Toggle selection</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="2" >
+    <widget class="QDialogButtonBox" name="buttonBox" >
+     <property name="orientation" >
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons" >
+      <set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>ManageCaptures_UI</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>ManageCaptures_UI</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>