]> git.sesse.net Git - kdenlive/commitdiff
Progress on stopmotion widget (make it possible to switch between HDMI and V4L)
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 19 Oct 2010 22:37:59 +0000 (22:37 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Tue, 19 Oct 2010 22:37:59 +0000 (22:37 +0000)
svn path=/trunk/kdenlive/; revision=5024

12 files changed:
src/kdenlivesettings.kcfg
src/kdenlivesettingsdialog.cpp
src/kdenlivesettingsdialog.h
src/mainwindow.cpp
src/projectlist.cpp
src/recmonitor.cpp
src/renderwidget.cpp
src/slideshowclip.cpp
src/slideshowclip.h
src/stopmotion/stopmotion.cpp
src/stopmotion/stopmotion.h
src/widgets/configcapture_ui.ui

index 6c2d17e976f396175f31e2a5beead71578af16c8..2f9444ce5d519cd26345e50b518db05405944f07 100644 (file)
       <default>false</default>
     </entry>
 
-    <entry name="hdmicapturedevice" type="Int">
+    <entry name="hdmi_capturedevice" type="Int">
       <label>default HDMI capture device.</label>
       <default>0</default>
     </entry>
 
-    <entry name="hdmicapturemode" type="Int">
+    <entry name="hdmi_capturemode" type="Int">
       <label>default HDMI capture mode.</label>
       <default>0</default>
     </entry>
index 90c3d816b90e2c815c5d9a4daed529c5a4d22e2c..e4959223ed7f9dbeabafb525c347716432ee7188 100644 (file)
@@ -168,11 +168,8 @@ KdenliveSettingsDialog::KdenliveSettingsDialog(QWidget * parent) :
     }
 
 
-    BMInterface::getBlackMagicDeviceList(m_configCapture.hdmi_list, m_configCapture.hdmi_capturemode);
-    connect(m_configCapture.hdmi_list, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateHDMIModes()));
-    connect(m_configCapture.hdmi_capturemode, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateHDMICaptureMode()));
-    m_configCapture.hdmi_list->setCurrentIndex(KdenliveSettings::hdmicapturedevice());
-    m_configCapture.hdmi_capturemode->setCurrentIndex(KdenliveSettings::hdmicapturemode());
+    BMInterface::getBlackMagicDeviceList(m_configCapture.kcfg_hdmi_capturedevice, m_configCapture.kcfg_hdmi_capturemode);
+    connect(m_configCapture.kcfg_hdmi_capturedevice, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateHDMIModes()));
 
     double dvgrabVersion = 0;
     if (!KdenliveSettings::dvgrab_path().isEmpty()) {
@@ -208,15 +205,9 @@ KdenliveSettingsDialog::~KdenliveSettingsDialog() {}
 
 void KdenliveSettingsDialog::slotUpdateHDMIModes()
 {
-    QStringList modes = m_configCapture.hdmi_list->itemData(m_configCapture.hdmi_list->currentIndex()).toStringList();
-    m_configCapture.hdmi_capturemode->clear();
-    m_configCapture.hdmi_capturemode->insertItems(0, modes);
-    KdenliveSettings::setHdmicapturedevice(m_configCapture.hdmi_list->currentIndex());
-}
-
-void KdenliveSettingsDialog::slotUpdateHDMICaptureMode()
-{
-    KdenliveSettings::setHdmicapturemode(m_configCapture.hdmi_capturemode->currentIndex());
+    QStringList modes = m_configCapture.kcfg_hdmi_capturedevice->itemData(m_configCapture.kcfg_hdmi_capturedevice->currentIndex()).toStringList();
+    m_configCapture.kcfg_hdmi_capturemode->clear();
+    m_configCapture.kcfg_hdmi_capturemode->insertItems(0, modes);
 }
 
 void KdenliveSettingsDialog::slotUpdateRmdRegionStatus()
index 871dd905dedab1427d63eca31724589d8325c29a..2e265e47d7627dcb36c31519aa71c3a8eba9fb87 100644 (file)
@@ -67,7 +67,6 @@ private slots:
     void slotDialogModified();
     void slotEnableCaptureFolder();
     void slotUpdateHDMIModes();
-    void slotUpdateHDMICaptureMode();
 
 private:
     KPageWidgetItem *m_page1;
index 6da2cacaffb174b85b3a4dc9ccdde1e8409f7977..25942b1961aa007798396e059e5607e7bcd4ac80 100644 (file)
@@ -1967,6 +1967,12 @@ void MainWindow::doOpenFile(const KUrl &url, KAutoSaveFile *stale)
     if (!m_timelineArea->isEnabled()) return;
     m_fileRevert->setEnabled(true);
 
+    // Recreate stopmotion widget on document change
+    if (m_stopmotion) {
+       delete m_stopmotion;
+       m_stopmotion = NULL;
+    }
+
     KProgressDialog progressDialog(this, i18n("Loading project"), i18n("Loading project"));
     progressDialog.setAllowCancel(false);
     progressDialog.progressBar()->setMaximum(4);
@@ -2163,6 +2169,12 @@ void MainWindow::slotUpdateProjectProfile(const QString &profile)
 {
     double dar = m_activeDocument->dar();
 
+    // Recreate the stopmotion widget if profile changes
+    if (m_stopmotion) {
+       delete m_stopmotion;
+       m_stopmotion = NULL;
+    }
+
     // Deselect current effect / transition
     m_effectStack->slotClipItemSelected(NULL, 0);
     m_transitionConfig->slotTransitionItemSelected(NULL, 0, QPoint(), false);
index b41fc50e8d33f926283d8749aa4aaaeb597c6d7c..66cf7d752b6e7960c7f0f0bd12543d918ea7f879 100644 (file)
@@ -1104,9 +1104,10 @@ void ProjectList::slotAddClip(const QList <QUrl> givenList, const QString &group
             if (fileName.at(fileName.size() - 1).isDigit()) {
                 KFileItem item(KFileItem::Unknown, KFileItem::Unknown, url);
                 if (item.mimetype().startsWith("image")) {
-                    int count = 0;
                     // import as sequence if we found more than one image in the sequence
-                    QString pattern = SlideshowClip::selectedPath(url.path(), false, QString(), &count);
+                    QStringList list;
+                    QString pattern = SlideshowClip::selectedPath(url.path(), false, QString(), &list);
+                    int count = list.count();
                     if (count > 1) {
                         delete d;
                         QStringList groupInfo = getGroup();
@@ -1841,33 +1842,32 @@ void ProjectList::slotForceProcessing(const QString &id)
 void ProjectList::slotAddOrUpdateSequence(const QString frameName)
 {
     QString fileName = KUrl(frameName).fileName().section('_', 0, -2);
-    int count;
-    QString pattern = SlideshowClip::selectedPath(frameName, false, QString(), &count);
+    QStringList list;
+    QString pattern = SlideshowClip::selectedPath(frameName, false, QString(), &list);
+    int count = list.count();
     if (count > 1) {
-         const QList <DocClipBase *> existing = m_doc->clipManager()->getClipByResource(pattern);
-       if (!existing.isEmpty()) {
-           // Sequence already exists, update
-           QString id = existing.at(0)->getId();
-           //ProjectItem *item = getItemById(id);
+        const QList <DocClipBase *> existing = m_doc->clipManager()->getClipByResource(pattern);
+        if (!existing.isEmpty()) {
+            // Sequence already exists, update
+            QString id = existing.at(0)->getId();
+            //ProjectItem *item = getItemById(id);
             QMap <QString, QString> oldprops;
             QMap <QString, QString> newprops;
-           int ttl = existing.at(0)->getProperty("ttl").toInt();
+            int ttl = existing.at(0)->getProperty("ttl").toInt();
             oldprops["out"] = existing.at(0)->getProperty("out");
             newprops["out"] = QString::number(ttl * count - 1);
-           slotUpdateClipProperties(id, newprops);
+            slotUpdateClipProperties(id, newprops);
             EditClipCommand *command = new EditClipCommand(this, id, oldprops, newprops, false);
             m_commandStack->push(command);
-       }
-       else {
-           // Create sequence
-           QStringList groupInfo = getGroup();
-           m_doc->slotCreateSlideshowClipFile(fileName, pattern, count, m_timecode.reformatSeparators(KdenliveSettings::sequence_duration()),
-                                                           false, false, false,
-                                                           m_timecode.getTimecodeFromFrames(int(ceil(m_timecode.fps()))), QString(), 0,
-                                                           QString(), groupInfo.at(0), groupInfo.at(1));
-       }
-    }
-    else emit displayMessage(i18n("Sequence not found"), -2);
+        } else {
+            // Create sequence
+            QStringList groupInfo = getGroup();
+            m_doc->slotCreateSlideshowClipFile(fileName, pattern, count, m_timecode.reformatSeparators(KdenliveSettings::sequence_duration()),
+                                               false, false, false,
+                                               m_timecode.getTimecodeFromFrames(int(ceil(m_timecode.fps()))), QString(), 0,
+                                               QString(), groupInfo.at(0), groupInfo.at(1));
+        }
+    } else emit displayMessage(i18n("Sequence not found"), -2);
 }
 
 #include "projectlist.moc"
index bb1115ec63cda19b8c7db36083e27a549d4858d7..d917731d6da91dab7ba6a4e688716748212de9e9 100644 (file)
@@ -456,7 +456,7 @@ void RecMonitor::slotStartCapture(bool play)
     case HDMI:
        video_capture->setVisible(true);
        video_frame->setHidden(true);
-       m_bmCapture->startPreview(KdenliveSettings::hdmicapturedevice(), KdenliveSettings::hdmicapturemode());
+       m_bmCapture->startPreview(KdenliveSettings::hdmi_capturedevice(), KdenliveSettings::hdmi_capturemode());
        m_playAction->setEnabled(false);
        m_stopAction->setEnabled(true);
        m_recAction->setEnabled(true);
index 61e49c5370ddec5df2a82fd926dca3ffcffb314b..1b85df4e8a8c95845e9325a728cf53175db74207 100644 (file)
@@ -176,7 +176,6 @@ RenderWidget::RenderWidget(const QString &projectfolder, QWidget * parent) :
     m_view.running_jobs->setItemDelegate(m_jobsDelegate);
 
     QHeaderView *header = m_view.running_jobs->header();
-    QFontMetrics fm = fontMetrics();
     header->setResizeMode(0, QHeaderView::Fixed);
     header->resizeSection(0, 30);
     header->setResizeMode(1, QHeaderView::Interactive);
index dcdbd845c3162986f73e525704bc0a1d50a7e0c4..60c090c57e13e67a3750f741ee030418725c4451 100644 (file)
 
 
 SlideshowClip::SlideshowClip(Timecode tc, QWidget * parent) :
-        QDialog(parent),
-        m_count(0),
-        m_timecode(tc),
-        m_thumbJob(NULL)
+    QDialog(parent),
+    m_count(0),
+    m_timecode(tc),
+    m_thumbJob(NULL)
 {
     setFont(KGlobalSettings::toolBarFont());
     setWindowTitle(i18n("Add Slideshow Clip"));
@@ -88,9 +88,9 @@ SlideshowClip::SlideshowClip(Timecode tc, QWidget * parent) :
     filters << "*.pgm" << "*.png";
 
     QStringList customLumas = KGlobal::dirs()->findDirs("appdata", "lumas");
-    foreach(const QString &folder, customLumas) {
+    foreach(const QString & folder, customLumas) {
         QStringList filesnames = QDir(folder).entryList(filters, QDir::Files);
-        foreach(const QString &fname, filesnames) {
+        foreach(const QString & fname, filesnames) {
             QString filePath = KUrl(folder).path(KUrl::AddTrailingSlash) + fname;
             m_view.luma_file->addItem(KIcon(filePath), fname, filePath);
         }
@@ -102,7 +102,7 @@ SlideshowClip::SlideshowClip(Timecode tc, QWidget * parent) :
     folder.append("/lumas/PAL"); // TODO: cleanup the PAL / NTSC mess in luma files
     QDir lumafolder(folder);
     QStringList filesnames = lumafolder.entryList(filters, QDir::Files);
-    foreach(const QString &fname, filesnames) {
+    foreach(const QString & fname, filesnames) {
         QString filePath = KUrl(folder).path(KUrl::AddTrailingSlash) + fname;
         m_view.luma_file->addItem(KIcon(filePath), fname, filePath);
     }
@@ -160,9 +160,11 @@ void SlideshowClip::slotEnableLumaFile(int state)
 int SlideshowClip::sequenceCount(KUrl file)
 {
     // find pattern
+    int count = 0;
     QString filter = file.fileName();
     QString ext = filter.section('.', -1);
     filter = filter.section('.', 0, -2);
+    int fullSize = filter.size();
     bool hasDigit = false;
     while (filter.at(filter.size() - 1).isDigit()) {
         hasDigit = true;
@@ -170,15 +172,22 @@ int SlideshowClip::sequenceCount(KUrl file)
     }
     if (!hasDigit) return 0;
 
-    QString regexp = "^" + filter + "\\d+\\." + ext + "$";
-    QRegExp rx(regexp);
-
-    QDir dir(file.directory());
-    QStringList result = dir.entryList(QDir::Files);
 
-    int count = 0;
-    foreach(const QString &path, result) {
-        if (rx.exactMatch(path)) count ++;
+    // Find number of digits in sequence
+    int precision = fullSize - filter.size();
+    QString folder = file.directory(KUrl::AppendTrailingSlash);
+    // Check how many files we have
+    QDir dir(folder);
+    QString path;
+    int gap = 0;
+    for (int i = 0; gap < 100; i++) {
+        path = filter + QString::number(i).rightJustified(precision, '0', false) + ext;
+        if (dir.exists(path)) {
+            count ++;
+            gap = 0;
+        } else {
+            gap++;
+        }
     }
     return count;
 }
@@ -191,6 +200,8 @@ void SlideshowClip::parseFolder()
     QDir dir(path);
     if (path.isEmpty() || !dir.exists()) return;
 
+    KIcon unknownicon("unknown");
+    QStringList result;
     QStringList filters;
     QString filter;
     if (isMime) {
@@ -198,41 +209,39 @@ void SlideshowClip::parseFolder()
         filter = m_view.image_type->itemData(m_view.image_type->currentIndex()).toString();
         filters << "*." + filter;
         dir.setNameFilters(filters);
-    }
-
-    QStringList result = dir.entryList(QDir::Files);
-
-    if (!isMime) {
+        result = dir.entryList(QDir::Files);
+    } else {
         // find pattern
         filter = m_view.pattern_url->url().fileName();
         QString ext = filter.section('.', -1);
         filter = filter.section('.', 0, -2);
-
+        int fullSize = filter.size();
         while (filter.at(filter.size() - 1).isDigit()) {
             filter.remove(filter.size() - 1, 1);
         }
-        QString regexp = "^" + filter + "\\d+\\." + ext + "$";
-        QRegExp rx(regexp);
-        QStringList entries;
-        foreach(const QString &path, result) {
-            if (rx.exactMatch(path)) entries << path;
+        int precision = fullSize - filter.size();
+        QString path;
+        int gap = 0;
+        for (int i = 0; gap < 100; i++) {
+            path = filter + QString::number(i).rightJustified(precision, '0', false) + ext;
+            if (dir.exists(path)) {
+                result.append(path);
+                gap = 0;
+            } else {
+                gap++;
+            }
         }
-        result = entries;
     }
-
-    m_count = result.count();
-    if (m_count == 0) m_view.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
-    else m_view.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
-    m_view.label_info->setText(i18np("1 image found", "%1 images found", m_count));
     QListWidgetItem *item;
-    int i = 0;
-    KIcon unknownicon("unknown");
-    foreach(const QString &path, result) {
-        i++;
+    foreach(const QString & path, result) {
         item = new QListWidgetItem(unknownicon, KUrl(path).fileName());
         item->setData(Qt::UserRole, dir.filePath(path));
         m_view.icon_list->addItem(item);
     }
+    m_count = result.count();
+    if (m_count == 0) m_view.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
+    else m_view.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(true);
+    m_view.label_info->setText(i18np("1 image found", "%1 images found", m_count));
     if (m_view.show_thumbs->isChecked()) slotGenerateThumbs();
     m_view.icon_list->setCurrentRow(0);
 }
@@ -276,15 +285,30 @@ void SlideshowClip::slotSetPixmap(const KFileItem &fileItem, const QPixmap &pix)
 
 QString SlideshowClip::selectedPath()
 {
-    return selectedPath(m_view.folder_url->url(), m_view.method_mime->isChecked(), ".all." + m_view.image_type->itemData(m_view.image_type->currentIndex()).toString(), &m_count);
+    QStringList list;
+    QString path = selectedPath(m_view.folder_url->url(), m_view.method_mime->isChecked(), ".all." + m_view.image_type->itemData(m_view.image_type->currentIndex()).toString(), &list);
+    m_count = list.count();
+    return path;
 
 
 }
+
 // static
-QString SlideshowClip::selectedPath(KUrl url, bool isMime, QString extension, int *count)
+int SlideshowClip::getFrameNumberFromPath(KUrl path)
 {
-    QString folder;
+    QString filter = path.fileName();
+    filter = filter.section('.', 0, -2);
+    int ix = filter.size() - 1;
+    while (filter.at(ix).isDigit()) {
+        ix--;
+    }
+    return filter.remove(0, ix + 1).toInt();
+}
 
+// static
+QString SlideshowClip::selectedPath(KUrl url, bool isMime, QString extension, QStringList *list)
+{
+    QString folder;
     if (isMime) {
         folder = url.path(KUrl::AddTrailingSlash);
     } else {
@@ -292,41 +316,31 @@ QString SlideshowClip::selectedPath(KUrl url, bool isMime, QString extension, in
         QString filter = url.fileName();
         QString ext = '.' + filter.section('.', -1);
         filter = filter.section('.', 0, -2);
+        int fullSize = filter.size();
 
         while (filter.at(filter.size() - 1).isDigit()) {
             filter.chop(1);
         }
-        // Check that the first image exists and which format it has (image1.jpg or image001.jpg, ...)
 
-        // Find first image in sequence
-        QString regexp = "^" + filter + "\\d+" + ext + "$";
-        QRegExp rx(regexp);
-        QStringList entries;
+        // Find number of digits in sequence
+        int precision = fullSize - filter.size();
 
+        // Check how many files we have
         QDir dir(folder);
-        QStringList result = dir.entryList(QDir::Files);
-        int precision = 1;
-        QString pathValue;
-        QMap <int, QString> sortedList;
-        foreach(const QString &path, result) {
-            if (rx.exactMatch(path)) {
-                pathValue = path.section('.', 0, -2);
-                pathValue.remove(0, filter.size());
-                sortedList.insert(pathValue.toInt(), path);
+        QString path;
+        int gap = 0;
+        for (int i = 0; gap < 100; i++) {
+            path = filter + QString::number(i).rightJustified(precision, '0', false) + ext;
+            if (dir.exists(path)) {
+                (*list).append(folder + path);
+                gap = 0;
+            } else {
+                gap++;
             }
         }
-        *count = sortedList.size();
-        if (*count == 0) kDebug() << "No IMAGE FOUND!!!!!!!";
-        else  {
-            QMapIterator<int, QString> i(sortedList);
-            i.next();
-            QString result = i.value();
-            result.remove(0, filter.size());
-            result = result.section('.', 0, -2);
-            precision = result.size();
-        }
         extension = filter + "%." + QString::number(precision) + "d" + ext;
     }
+    kDebug() << "// FOUND " << (*list).count() << " items for " << url.path();
     return  folder + extension;
 }
 
@@ -418,15 +432,15 @@ void SlideshowClip::slotMethodChanged(bool active)
     if (active) {
         // User wants mimetype image sequence
         if (m_view.clip_duration->text().isEmpty()) {
-           m_view.clip_duration->setText(m_timecode.reformatSeparators(KdenliveSettings::image_duration()));
-       }
+            m_view.clip_duration->setText(m_timecode.reformatSeparators(KdenliveSettings::image_duration()));
+        }
         m_view.stackedWidget->setCurrentIndex(0);
         KdenliveSettings::setSlideshowbymime(true);
     } else {
         // User wants pattern image sequence
         if (m_view.clip_duration->text().isEmpty()) {
-           m_view.clip_duration->setText(m_timecode.reformatSeparators(KdenliveSettings::sequence_duration()));
-       }
+            m_view.clip_duration->setText(m_timecode.reformatSeparators(KdenliveSettings::sequence_duration()));
+        }
         m_view.stackedWidget->setCurrentIndex(1);
         KdenliveSettings::setSlideshowbymime(false);
     }
index 36ba0a2a3343dcd5e6a95b2c30f46db3f20b01c3..69fc496fcbcfee1c950aa8b21a6541a62ddcffbd 100644 (file)
@@ -51,8 +51,10 @@ public:
 
     /** @brief Check if there are several files with filename pattern, like: image_001.jpg, image_002.jpg,... */
     static int sequenceCount(KUrl file);
+    /** @brief Get the image frame number from a file path, for example image_047.jpg will return 47. */
+    static int getFrameNumberFromPath(KUrl path);
     /** @brief return the url pattern for selected slideshow. */
-    static QString selectedPath(KUrl url, bool isMime, QString extension, int *count);
+    static QString selectedPath(KUrl url, bool isMime, QString extension, QStringList *list);
     /** @brief Convert the selection animation style into an affine geometry string. */
     static QString animationToGeometry(const QString &animation, int &ttl);
 
index db1244c5fc2a9cb82676b02333d5a36a684ddf41..c11ddc56ffd69208f664ee8fa17de51a84d2cec8 100644 (file)
@@ -40,7 +40,7 @@
 #include <QWheelEvent>
 
 MyLabel::MyLabel(QWidget *parent) :
-        QLabel(parent)
+    QLabel(parent)
 {
 }
 
@@ -57,7 +57,7 @@ void MyLabel::wheelEvent(QWheelEvent * event)
 }
 
 //virtual
-void MyLabel::paintEvent( QPaintEvent * event)
+void MyLabel::paintEvent(QPaintEvent * event)
 {
     Q_UNUSED(event);
 
@@ -70,8 +70,8 @@ void MyLabel::paintEvent( QPaintEvent * event)
     int calculatedWidth = aspect_ratio * height();
     if (calculatedWidth > width()) pictureHeight = width() / aspect_ratio;
     else {
-       int calculatedHeight = width() / aspect_ratio;
-       if (calculatedHeight > height()) pictureWidth = height() * aspect_ratio;
+        int calculatedHeight = width() / aspect_ratio;
+        if (calculatedHeight > height()) pictureWidth = height() * aspect_ratio;
     }
     p.drawImage(QRect((width() - pictureWidth) / 2, (height() - pictureHeight) / 2, pictureWidth, pictureHeight), m_img, QRect(0, 0, m_img.width(), m_img.height()));
     p.end();
@@ -79,12 +79,12 @@ void MyLabel::paintEvent( QPaintEvent * event)
 
 
 StopmotionWidget::StopmotionWidget(KUrl projectFolder, QWidget *parent) :
-        QDialog(parent)
-        , Ui::Stopmotion_UI()
-       , m_projectFolder(projectFolder)
-       , m_bmCapture(NULL)
-       , m_sequenceFrame(0)
-       , m_animatedIndex(-1)
+    QDialog(parent)
+    , Ui::Stopmotion_UI()
+    , m_projectFolder(projectFolder)
+    , m_bmCapture(NULL)
+    , m_sequenceFrame(0)
+    , m_animatedIndex(-1)
 {
     setupUi(this);
     setWindowTitle(i18n("Stop Motion Capture"));
@@ -96,7 +96,7 @@ StopmotionWidget::StopmotionWidget(KUrl projectFolder, QWidget *parent) :
     m_captureAction->setShortcut(QKeySequence(Qt::Key_Space));
     connect(m_captureAction, SIGNAL(triggered()), this, SLOT(slotCaptureFrame()));
     capture_button->setDefaultAction(m_captureAction);
-    
+
     preview_button->setIcon(KIcon("media-playback-start"));
     removelast_button->setIcon(KIcon("edit-delete"));
     frameoverlay_button->setEnabled(false);
@@ -104,23 +104,22 @@ StopmotionWidget::StopmotionWidget(KUrl projectFolder, QWidget *parent) :
     capture_button->setEnabled(false);
 
     connect(sequence_name, SIGNAL(textChanged(const QString &)), this, SLOT(sequenceNameChanged(const QString &)));
-    QVBoxLayout *lay = new QVBoxLayout;
+    m_layout = new QVBoxLayout;
     if (BMInterface::getBlackMagicDeviceList(capture_device, NULL)) {
-       // Found a BlackMagic device
-       kDebug()<<"CREATE BM DEVICE";
-       m_bmCapture = new BmdCaptureHandler(lay);
-       connect(m_bmCapture, SIGNAL(gotMessage(const QString &)), this, SLOT(slotGotHDMIMessage(const QString &)));
+        // Found a BlackMagic device
+        m_bmCapture = new BmdCaptureHandler(m_layout);
+        connect(m_bmCapture, SIGNAL(gotMessage(const QString &)), this, SLOT(slotGotHDMIMessage(const QString &)));
     }
-    else {
-       kDebug()<<"CREATE V4L DEVICE";
-       m_bmCapture = new V4lCaptureHandler(lay);
-       capture_device->addItem(KdenliveSettings::video4vdevice());
+    if (QFile::exists(KdenliveSettings::video4vdevice())) {
+        if (m_bmCapture == NULL) m_bmCapture = new V4lCaptureHandler(m_layout);
+        capture_device->addItem(KdenliveSettings::video4vdevice(), "v4l");
     }
+    connect(capture_device, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateHandler()));
     m_frame_preview = new MyLabel(this);
     connect(m_frame_preview, SIGNAL(seek(bool)), this, SLOT(slotSeekFrame(bool)));
-    lay->addWidget(m_frame_preview);
+    m_layout->addWidget(m_frame_preview);
     m_frame_preview->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
-    video_preview->setLayout(lay);
+    video_preview->setLayout(m_layout);
     live_button->setChecked(false);
     frameoverlay_button->setChecked(false);
     button_addsequence->setEnabled(false);
@@ -130,8 +129,8 @@ StopmotionWidget::StopmotionWidget(KUrl projectFolder, QWidget *parent) :
     connect(button_addsequence, SIGNAL(clicked(bool)), this, SLOT(slotAddSequence()));
     connect(preview_button, SIGNAL(clicked(bool)), this, SLOT(slotPlayPreview()));
     connect(frame_list, SIGNAL(currentRowChanged(int)), this, SLOT(slotShowSelectedFrame()));
-    connect(this, SIGNAL(doCreateThumbs(QImage, int)), this, SLOT(slotCreateThumbs(QImage,int)));
-    
+    connect(this, SIGNAL(doCreateThumbs(QImage, int)), this, SLOT(slotCreateThumbs(QImage, int)));
+
     parseExistingSequences();
 }
 
@@ -140,6 +139,21 @@ StopmotionWidget::~StopmotionWidget()
     m_bmCapture->stopPreview();
 }
 
+void StopmotionWidget::slotUpdateHandler()
+{
+    QString data = capture_device->itemData(capture_device->currentIndex()).toString();
+    m_bmCapture->stopPreview();
+    delete m_bmCapture;
+    m_layout->removeWidget(m_frame_preview);
+    if (data == "v4l") {
+        m_bmCapture = new V4lCaptureHandler(m_layout);
+    } else {
+        m_bmCapture = new BmdCaptureHandler(m_layout);
+        connect(m_bmCapture, SIGNAL(gotMessage(const QString &)), this, SLOT(slotGotHDMIMessage(const QString &)));
+    }
+    m_layout->addWidget(m_frame_preview);
+}
+
 void StopmotionWidget::slotGotHDMIMessage(const QString &message)
 {
     log_box->insertItem(0, message);
@@ -156,33 +170,31 @@ void StopmotionWidget::parseExistingSequences()
     QStringList sequences = dir.entryList(filters, QDir::Files, QDir::Name);
     //kDebug()<<"PF: "<<<<", sm: "<<sequences;
     foreach(QString sequencename, sequences) {
-       sequence_name->addItem(sequencename.section("_", 0, -2));
+        sequence_name->addItem(sequencename.section("_", 0, -2));
     }
 }
 
 void StopmotionWidget::slotLive(bool isOn)
 {
     if (isOn) {
-       m_frame_preview->setImage(QImage());
-       m_frame_preview->setHidden(true);
-       m_bmCapture->startPreview(KdenliveSettings::hdmicapturedevice(), KdenliveSettings::hdmicapturemode());
-       capture_button->setEnabled(true);
-    }
-    else {
-       m_bmCapture->stopPreview();
-       capture_button->setEnabled(false);
+        m_frame_preview->setImage(QImage());
+        m_frame_preview->setHidden(true);
+        m_bmCapture->startPreview(KdenliveSettings::hdmi_capturedevice(), KdenliveSettings::hdmi_capturemode());
+        capture_button->setEnabled(true);
+    } else {
+        m_bmCapture->stopPreview();
+        capture_button->setEnabled(false);
     }
 }
 
 void StopmotionWidget::slotShowOverlay(bool isOn)
 {
     if (isOn) {
-       if (live_button->isChecked() && m_sequenceFrame > 0) {
-           slotUpdateOverlay();
-       }
-    }
-    else {
-       m_bmCapture->hideOverlay();
+        if (live_button->isChecked() && m_sequenceFrame > 0) {
+            slotUpdateOverlay();
+        }
+    } else {
+        m_bmCapture->hideOverlay();
     }
 }
 
@@ -192,8 +204,8 @@ void StopmotionWidget::slotUpdateOverlay()
     if (!QFile::exists(path)) return;
     QImage img(path);
     if (img.isNull()) {
-       QTimer::singleShot(1000, this, SLOT(slotUpdateOverlay()));
-       return;
+        QTimer::singleShot(1000, this, SLOT(slotUpdateOverlay()));
+        return;
     }
     m_bmCapture->showOverlay(img);
 }
@@ -201,60 +213,52 @@ void StopmotionWidget::slotUpdateOverlay()
 void StopmotionWidget::sequenceNameChanged(const QString &name)
 {
     // Get rid of frames from previous sequence
-    disconnect(this, SIGNAL(doCreateThumbs(QImage, int)), this, SLOT(slotCreateThumbs(QImage,int)));
+    disconnect(this, SIGNAL(doCreateThumbs(QImage, int)), this, SLOT(slotCreateThumbs(QImage, int)));
     m_filesList.clear();
     m_future.waitForFinished();
     frame_list->clear();
     if (name.isEmpty()) {
-       button_addsequence->setEnabled(false);
-       frame_number->blockSignals(true);
-       frame_number->setValue(m_sequenceFrame);
-       frame_number->blockSignals(false);
-       frameoverlay_button->setEnabled(false);
-       removelast_button->setEnabled(false);
-    }
-    else {
-       // Check if we are editing an existing sequence
-       int count = 0;
-       QString pattern = SlideshowClip::selectedPath(getPathForFrame(0, sequence_name->currentText()), false, QString(), &count);
-       m_sequenceFrame = count;
-       frame_number->blockSignals(true);
-       frame_number->setValue(0);
-       frame_number->blockSignals(false);
-       m_currentIndex = 0;
-       if (count > 0) {
-           m_sequenceName = sequence_name->currentText();
-           //TODO: Do the thumbnail stuff in a thread
-           for (int i = 0; i < count; i++) {
-               //slotUpdateFrameList(i);
-               m_filesList.append(getPathForFrame(i));
-           }
-           connect(this, SIGNAL(doCreateThumbs(QImage, int)), this, SLOT(slotCreateThumbs(QImage,int)));
-           m_future = QtConcurrent::run(this, &StopmotionWidget::slotPrepareThumbs);
-           button_addsequence->setEnabled(true);
-           frameoverlay_button->setEnabled(true);
-       }
-       else {
-           button_addsequence->setEnabled(false);
-           frameoverlay_button->setEnabled(false);
-       }
-       frame_number->setRange(0, m_sequenceFrame);
-       capture_button->setEnabled(true);
+        button_addsequence->setEnabled(false);
+        frame_number->blockSignals(true);
+        frame_number->setValue(m_sequenceFrame);
+        frame_number->blockSignals(false);
+        frameoverlay_button->setEnabled(false);
+        removelast_button->setEnabled(false);
+    } else {
+        // Check if we are editing an existing sequence
+        QString pattern = SlideshowClip::selectedPath(getPathForFrame(0, sequence_name->currentText()), false, QString(), &m_filesList);
+        m_sequenceFrame = m_filesList.size();
+        frame_number->blockSignals(true);
+        frame_number->setValue(0);
+        frame_number->blockSignals(false);
+        m_currentIndex = 0;
+        if (!m_filesList.isEmpty()) {
+            m_sequenceName = sequence_name->currentText();
+            connect(this, SIGNAL(doCreateThumbs(QImage, int)), this, SLOT(slotCreateThumbs(QImage, int)));
+            m_future = QtConcurrent::run(this, &StopmotionWidget::slotPrepareThumbs);
+            button_addsequence->setEnabled(true);
+            frameoverlay_button->setEnabled(true);
+        } else {
+            button_addsequence->setEnabled(false);
+            frameoverlay_button->setEnabled(false);
+        }
+        frame_number->setRange(0, m_sequenceFrame);
+        capture_button->setEnabled(true);
     }
 }
 
 void StopmotionWidget::slotCaptureFrame()
 {
     if (sequence_name->currentText().isEmpty()) {
-       QString seqName = QInputDialog::getText(this, i18n("Create New Sequence"), i18n("Enter sequence name"));
-       if (seqName.isEmpty()) return;
-       sequence_name->blockSignals(true);
-       sequence_name->setItemText(sequence_name->currentIndex(), seqName);
-       sequence_name->blockSignals(false);
+        QString seqName = QInputDialog::getText(this, i18n("Create New Sequence"), i18n("Enter sequence name"));
+        if (seqName.isEmpty()) return;
+        sequence_name->blockSignals(true);
+        sequence_name->setItemText(sequence_name->currentIndex(), seqName);
+        sequence_name->blockSignals(false);
     }
     if (m_sequenceName != sequence_name->currentText()) {
-       m_sequenceName = sequence_name->currentText();
-       m_sequenceFrame = 0;
+        m_sequenceName = sequence_name->currentText();
+        m_sequenceFrame = 0;
     }
     capture_button->setEnabled(false);
     m_bmCapture->captureFrame(getPathForFrame(m_sequenceFrame));
@@ -274,15 +278,15 @@ void StopmotionWidget::slotPrepareThumbs()
 {
     if (m_filesList.isEmpty()) return;
     QString path = m_filesList.takeFirst();
-    emit doCreateThumbs(QImage(path), m_currentIndex++);
-    
+    emit doCreateThumbs(QImage(path), SlideshowClip::getFrameNumberFromPath(path));
+
 }
 
 void StopmotionWidget::slotCreateThumbs(QImage img, int ix)
 {
     if (img.isNull()) {
-       m_future = QtConcurrent::run(this, &StopmotionWidget::slotPrepareThumbs);
-       return;
+        m_future = QtConcurrent::run(this, &StopmotionWidget::slotPrepareThumbs);
+        return;
     }
     int height = 90;
     int width = height * img.width() / img.height();
@@ -297,23 +301,24 @@ void StopmotionWidget::slotCreateThumbs(QImage img, int ix)
     p.end();
     QIcon icon(pix);
     QListWidgetItem *item = new QListWidgetItem(icon, QString(), frame_list);
+    item->setToolTip(getPathForFrame(ix, sequence_name->currentText()));
     item->setData(Qt::UserRole, ix);
     m_future = QtConcurrent::run(this, &StopmotionWidget::slotPrepareThumbs);
 }
 
 void StopmotionWidget::slotUpdateFrameList(int ix)
 {
-    kDebug()<< "// GET FRAME: "<<ix;
+    kDebug() << "// GET FRAME: " << ix;
     if (ix == -1) ix = m_sequenceFrame - 1;
     QString path = getPathForFrame(ix);
     if (!QFile::exists(path)) {
-       capture_button->setEnabled(true);
-       return;
+        capture_button->setEnabled(true);
+        return;
     }
     QImage img(path);
     if (img.isNull()) {
-       if (ix == m_sequenceFrame - 1) QTimer::singleShot(1000, this, SLOT(slotUpdateFrameList()));
-       return;
+        if (ix == m_sequenceFrame - 1) QTimer::singleShot(1000, this, SLOT(slotUpdateFrameList()));
+        return;
     }
     int height = 90;
     int width = height * img.width() / img.height();
@@ -329,6 +334,9 @@ void StopmotionWidget::slotUpdateFrameList(int ix)
     QIcon icon(pix);
     QListWidgetItem *item = new QListWidgetItem(icon, QString(), frame_list);
     item->setData(Qt::UserRole, ix);
+    frame_list->blockSignals(true);
+    frame_list->setCurrentItem(item);
+    frame_list->blockSignals(true);
     capture_button->setEnabled(true);
 }
 
@@ -341,46 +349,46 @@ QString StopmotionWidget::getPathForFrame(int ix, QString seqName)
 void StopmotionWidget::slotShowFrame(int ix)
 {
     if (m_sequenceFrame == 0) {
-       //there are no images in sequence
-       return;
+        //there are no images in sequence
+        return;
     }
     frameoverlay_button->blockSignals(true);
     frameoverlay_button->setChecked(false);
     frameoverlay_button->blockSignals(false);
     if (ix < m_sequenceFrame) {
-       // Show previous frame
-       slotLive(false);
-       live_button->setChecked(false);
-       QImage img(getPathForFrame(ix));
-       capture_button->setEnabled(false);
-       if (!img.isNull()) {
-           //m_bmCapture->showOverlay(img, false);
-           m_bmCapture->hidePreview(true);
-           m_frame_preview->setImage(img);
-           m_frame_preview->setHidden(false);
-           m_frame_preview->update();
-           selectFrame(ix);
-       }
+        // Show previous frame
+        slotLive(false);
+        live_button->setChecked(false);
+        QImage img(getPathForFrame(ix));
+        capture_button->setEnabled(false);
+        if (!img.isNull()) {
+            //m_bmCapture->showOverlay(img, false);
+            m_bmCapture->hidePreview(true);
+            m_frame_preview->setImage(img);
+            m_frame_preview->setHidden(false);
+            m_frame_preview->update();
+            selectFrame(ix);
+        }
     }
     /*else {
-       slotLive(true);
-       m_frame_preview->setImage(QImage());
-       m_frame_preview->setHidden(true);
-       m_bmCapture->hideOverlay();
-       m_bmCapture->hidePreview(false);
-       capture_button->setEnabled(true);
-    }*/   
+    slotLive(true);
+    m_frame_preview->setImage(QImage());
+    m_frame_preview->setHidden(true);
+    m_bmCapture->hideOverlay();
+    m_bmCapture->hidePreview(false);
+    capture_button->setEnabled(true);
+    }*/
 }
 
 void StopmotionWidget::slotShowSelectedFrame()
 {
     QListWidgetItem *item = frame_list->currentItem();
     if (item) {
-       int ix = item->data(Qt::UserRole).toInt();
-       //frame_number->blockSignals(true);
-       frame_number->setValue(ix);
-       //frame_number->blockSignals(false);
-       //slotShowFrame(ix);
+        int ix = item->data(Qt::UserRole).toInt();
+        //frame_number->blockSignals(true);
+        frame_number->setValue(ix);
+        //frame_number->blockSignals(false);
+        //slotShowFrame(ix);
     }
 }
 
@@ -392,13 +400,13 @@ void StopmotionWidget::slotAddSequence()
 void StopmotionWidget::slotPlayPreview()
 {
     if (m_animatedIndex != -1) {
-       // stop animation
-       m_animatedIndex = -1;
-       return;
+        // stop animation
+        m_animatedIndex = -1;
+        return;
     }
     QListWidgetItem *item = frame_list->currentItem();
     if (item) {
-       m_animatedIndex = item->data(Qt::UserRole).toInt();
+        m_animatedIndex = item->data(Qt::UserRole).toInt();
     }
     QTimer::singleShot(200, this, SLOT(slotAnimate()));
 }
@@ -411,34 +419,45 @@ void StopmotionWidget::slotAnimate()
     else m_animatedIndex = -1;
 }
 
-void StopmotionWidget::selectFrame(int ix)
+QListWidgetItem *StopmotionWidget::getFrameFromIndex(int ix)
 {
-    frame_list->blockSignals(true);
-    QListWidgetItem *item = frame_list->item(ix);
-    int current = item->data(Qt::UserRole).toInt();
-    if (current == ix) {
-       frame_list->setCurrentItem(item);
-    }
-    else if (current < ix) {
-       for (int i = ix; i < frame_list->count(); i++) {
-           item = frame_list->item(i);
-           current = item->data(Qt::UserRole).toInt();
-           if (current == ix) {
-               frame_list->setCurrentItem(item);
-               break;
-           }
-       }
+    QListWidgetItem *item = NULL;
+    int pos = ix;
+    if (ix >= frame_list->count()) {
+        pos = frame_list->count() - 1;
     }
-    else {
-       for (int i = ix; i >= 0; i--) {
-           item = frame_list->item(i);
-           current = item->data(Qt::UserRole).toInt();
-           if (current == ix) {
-               frame_list->setCurrentItem(item);
-               break;
-           }
-       }
+    if (ix < 0) pos = 0;
+    item = frame_list->item(pos);
+
+    int value = item->data(Qt::UserRole).toInt();
+    if (value == ix) return item;
+    else if (value < ix) {
+        pos++;
+        while (pos < frame_list->count()) {
+            item = frame_list->item(pos);
+            value = item->data(Qt::UserRole).toInt();
+            if (value == ix) return item;
+            pos++;
+        }
+    } else {
+        pos --;
+        while (pos >= 0) {
+            item = frame_list->item(pos);
+            value = item->data(Qt::UserRole).toInt();
+            if (value == ix) return item;
+            pos --;
+        }
     }
+    return NULL;
+}
+
+
+void StopmotionWidget::selectFrame(int ix)
+{
+    frame_list->blockSignals(true);
+    QListWidgetItem *item = getFrameFromIndex(ix);
+    if (!item) return;
+    frame_list->setCurrentItem(item);
     frame_list->blockSignals(false);
 }
 
@@ -446,9 +465,8 @@ void StopmotionWidget::slotSeekFrame(bool forward)
 {
     int ix = frame_list->currentRow();
     if (forward) {
-       if (ix < frame_list->count() - 1) frame_list->setCurrentRow(ix + 1);
-    }
-    else if (ix > 0) frame_list->setCurrentRow(ix - 1);
+        if (ix < frame_list->count() - 1) frame_list->setCurrentRow(ix + 1);
+    } else if (ix > 0) frame_list->setCurrentRow(ix - 1);
 }
 
 
index eab6c9d1e334fbf46e6aed60ea86b3b8d5cfad28..2976a3bdff8dbec42e1100a6d0bbce047b800042 100644 (file)
@@ -24,6 +24,7 @@
 #include <KUrl>
 #include <QLabel>
 #include <QFuture>
+#include <QVBoxLayout>
 
 class MyLabel : public QLabel
 {
@@ -62,6 +63,9 @@ protected:
 
 
 private:
+  /** @brief Widget layout holding video and frame preview. */
+  QVBoxLayout *m_layout;
+  
   /** @brief Current project folder (where the captured frames will be saved). */
   KUrl m_projectFolder;
 
@@ -97,6 +101,9 @@ private:
   
   /** @brief Holds the state of the threaded thumbnail generation. */
   QFuture<void> m_future;
+
+  /** @brief Get the frame number ix. */
+  QListWidgetItem *getFrameFromIndex(int ix);
   
 private slots:
   /** @brief Display the live feed from capture device.
@@ -152,6 +159,9 @@ private slots:
   /** @brief Prepare thumbnails creation. */
   void slotPrepareThumbs();
 
+  /** @brief Called when user switches the video capture backend. */
+  void slotUpdateHandler();
+
 signals:
   /** @brief Ask to add sequence to current project. */
   void addOrUpdateSequence(const QString);
index 9f4f97e3bad9bdd553fa7977927c9cc4a1763604..66bc1530491452a519902565f5d99ed599be4d33 100644 (file)
         </widget>
        </item>
        <item row="0" column="1">
-        <widget class="KComboBox" name="hdmi_list">
+        <widget class="KComboBox" name="kcfg_hdmi_capturedevice">
          <property name="sizePolicy">
           <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
            <horstretch>0</horstretch>
         </widget>
        </item>
        <item row="1" column="1">
-        <widget class="KComboBox" name="hdmi_capturemode"/>
+        <widget class="KComboBox" name="kcfg_hdmi_capturemode"/>
        </item>
        <item row="2" column="0">
         <widget class="QLabel" name="label_29">