]> git.sesse.net Git - kdenlive/commitdiff
Improve stopmotion widget:
authorJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 22 Oct 2010 00:38:41 +0000 (00:38 +0000)
committerJean-Baptiste Mardelle <jb@kdenlive.org>
Fri, 22 Oct 2010 00:38:41 +0000 (00:38 +0000)
* interval capture
* last frame overlay with 4vl capture
* several overlay modes - (require qimageblitz devel package for enhanced features)

svn path=/trunk/kdenlive/; revision=5030

src/CMakeLists.txt
src/blackmagic/capture.cpp
src/blackmagic/capture.h
src/kdenlivesettings.kcfg
src/stopmotion/capturehandler.h
src/stopmotion/stopmotion.cpp
src/stopmotion/stopmotion.h
src/v4l/v4lcapture.cpp
src/v4l/v4lcapture.h
src/widgets/stopmotion_ui.ui

index 9bc29f4f6ecb6c26eb0f4102d0a78eb1cb376d6b..3ca09eb53f4e0ce4f6fb5e968aea592154c8c67e 100644 (file)
@@ -2,6 +2,7 @@ add_subdirectory( widgets )
 add_subdirectory( mimetypes )
 
 macro_optional_find_package(Nepomuk)
+pkg_check_modules(qimageblitz qimageblitz)
 
 if (Nepomuk_FOUND)
     INCLUDE_DIRECTORIES(NEPOMUK_INCLUDES )
@@ -9,6 +10,15 @@ if (Nepomuk_FOUND)
     add_definitions(-DNEPOMUK)
 endif (Nepomuk_FOUND)
 
+if (qimageblitz_FOUND)
+    INCLUDE_DIRECTORIES(QIMAGEBLITZ_INCLUDES )
+    set( optional_libs ${QIMAGEBLITZ_LIBRARIES} )
+    add_definitions(-DQIMAGEBLITZ)
+    MESSAGE( STATUS "Found QImageBlitz: ${QIMAGEBLITZ_LIBRARIES}" )
+else (qimageblitz_FOUND)
+    MESSAGE( WARNING "Install QImageBlitz devel package for improved stopmotion features" )
+endif (qimageblitz_FOUND)
+
 if (Q_WS_X11)
     include_directories (${X11_Xlib_INCLUDE_PATH} ) 
 endif (Q_WS_X11)
index 56e2ba81a927014f2b7b98f3d71ad39e42bf5c7c..edeceb148746a8d99463056a659647780505bdbd 100644 (file)
@@ -434,11 +434,13 @@ HRESULT DeckLinkCaptureDelegate::VideoInputFrameArrived(IDeckLinkVideoInputFrame
                     videoOutputFile = open(doCaptureFrame.toUtf8().constData(), O_WRONLY | O_CREAT/*|O_TRUNC*/, 0664);
                     write(videoOutputFile, frameBytes, videoFrame->GetRowBytes() * videoFrame->GetHeight());
                     close(videoOutputFile);
+                    emit frameSaved(doCaptureFrame);
                 } else {
                     QImage image(videoFrame->GetWidth(), videoFrame->GetHeight(), QImage::Format_ARGB32_Premultiplied);
                     //convert from uyvy422 to rgba
                     yuv2rgb_int((uchar *)frameBytes, (uchar *)image.bits(), videoFrame->GetWidth(), videoFrame->GetHeight());
                     image.save(doCaptureFrame);
+                    emit frameSaved(doCaptureFrame);
                 }
                 doCaptureFrame.clear();
             }
@@ -592,6 +594,7 @@ void BmdCaptureHandler::startPreview(int deviceId, int captureMode)
     delegate = new DeckLinkCaptureDelegate();
     connect(delegate, SIGNAL(gotTimeCode(ulong)), this, SIGNAL(gotTimeCode(ulong)));
     connect(delegate, SIGNAL(gotMessage(const QString &)), this, SIGNAL(gotMessage(const QString &)));
+    connect(delegate, SIGNAL(frameSaved(const QString)), this, SIGNAL(frameSaved(const QString)));
     deckLinkInput->SetCallback(delegate);
 
     previewView = new CDeckLinkGLWidget(deckLinkInput, m_parent);
index 48e940f9cd0907ea2a42ae4e9f90f11b150a19d6..4ccd54248ee30a97ed48b5ad0555b3799a4ace7b 100644 (file)
@@ -35,6 +35,7 @@ private:
 signals:
     void gotTimeCode(ulong);
     void gotMessage(const QString &);
+    void frameSaved(const QString);
 };
 
 class BmdCaptureHandler : public CaptureHandler
index 2f9444ce5d519cd26345e50b518db05405944f07..4dee03783ed368464f27cea505d0bf5b971b04e6 100644 (file)
       <label>Additionnal dvgrab parameters.</label>
       <default></default>
     </entry>
+    
+    <entry name="hdmi_capturedevice" type="Int">
+      <label>default HDMI capture device.</label>
+      <default>0</default>
+    </entry>
+
+    <entry name="hdmi_capturemode" type="Int">
+      <label>default HDMI capture mode.</label>
+      <default>0</default>
+    </entry>
+
+    <entry name="hdmifilename" type="String">
+      <label>default HDMI capture filename.</label>
+      <default>capture</default>
+    </entry>
+
+    <entry name="hdmicaptureaudio" type="Bool">
+      <label>Should we capture HDMI audio.</label>
+      <default>true</default>
+    </entry>
   </group>
 
   <group name="shuttle">
       <default>false</default>
     </entry>
 
-    <entry name="hdmi_capturedevice" type="Int">
-      <label>default HDMI capture device.</label>
-      <default>0</default>
-    </entry>
-
-    <entry name="hdmi_capturemode" type="Int">
-      <label>default HDMI capture mode.</label>
-      <default>0</default>
-    </entry>
-
-    <entry name="hdmifilename" type="String">
-      <label>default HDMI capture filename.</label>
-      <default>capture</default>
-    </entry>
-
-    <entry name="hdmicaptureaudio" type="Bool">
-      <label>Should we capture HDMI audio.</label>
+    <entry name="showstopmotionthumbs" type="Bool">
+      <label>Show sequence thumbnails in stopmotion widget.</label>
       <default>true</default>
-    </entry>
-    
+    </entry> 
     
+    <entry name="captureinterval" type="Int">
+      <label>Interval between each capture (in seconds).</label>
+      <default>5</default>
+    </entry> 
+
+    <entry name="blitzeffect" type="Int">
+      <label>Effect applied to stopmotion frame overlay.</label>
+      <default>0</default>
+    </entry> 
   </group>
 
 </kcfg>
index 08d5c52244fe0c77c8df58e7f057a5e867dd80e3..ef83ebd9149e4c3ef9864a4e199a7f4e4f4a48a1 100644 (file)
@@ -46,6 +46,7 @@ protected:
 signals:
     void gotTimeCode(ulong);
     void gotMessage(const QString &);
+    void frameSaved(const QString);
 };
 
 
index c11ddc56ffd69208f664ee8fa17de51a84d2cec8..e4c12267ec37e40a6e786759f06aad22f5299139 100644 (file)
 #include <kdeversion.h>
 #include <KNotification>
 
+#ifdef QIMAGEBLITZ
+#include <qimageblitz/qimageblitz.h>
+#endif
+
 #include <QtConcurrentRun>
 #include <QInputDialog>
 #include <QComboBox>
@@ -38,6 +42,7 @@
 #include <QPainter>
 #include <QAction>
 #include <QWheelEvent>
+#include <QMenu>
 
 MyLabel::MyLabel(QWidget *parent) :
     QLabel(parent)
@@ -52,7 +57,7 @@ void MyLabel::setImage(QImage img)
 //virtual
 void MyLabel::wheelEvent(QWheelEvent * event)
 {
-    if (event->delta() > 0) emit seek(true);
+    if(event->delta() > 0) emit seek(true);
     else emit seek(false);
 }
 
@@ -68,10 +73,10 @@ void MyLabel::paintEvent(QPaintEvent * event)
     int pictureHeight = height();
     int pictureWidth = width();
     int calculatedWidth = aspect_ratio * height();
-    if (calculatedWidth > width()) pictureHeight = width() / aspect_ratio;
+    if(calculatedWidth > width()) pictureHeight = width() / aspect_ratio;
     else {
         int calculatedHeight = width() / aspect_ratio;
-        if (calculatedHeight > height()) pictureWidth = height() * 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();
@@ -91,29 +96,96 @@ StopmotionWidget::StopmotionWidget(KUrl projectFolder, QWidget *parent) :
     setFont(KGlobalSettings::toolBarFont());
 
     live_button->setIcon(KIcon("camera-photo"));
-    frameoverlay_button->setIcon(KIcon("edit-paste"));
     m_captureAction = new QAction(KIcon("media-record"), i18n("Capture frame"), this);
     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);
-    removelast_button->setEnabled(false);
     capture_button->setEnabled(false);
 
+    // Build config menu
+    QMenu *confMenu = new QMenu;
+    m_showOverlay = new QAction(KIcon("edit-paste"), i18n("Show last frame over video"), this);
+    m_showOverlay->setCheckable(true);
+    m_showOverlay->setChecked(false);
+    connect(m_showOverlay, SIGNAL(triggered(bool)), this, SLOT(slotShowOverlay(bool)));
+    confMenu->addAction(m_showOverlay);
+
+#ifdef QIMAGEBLITZ
+    m_effectIndex = KdenliveSettings::blitzeffect();
+    QMenu *effectsMenu = new QMenu(i18n("Overlay effect"));
+    QActionGroup *effectGroup = new QActionGroup(this);
+    QAction *noEffect = new QAction(i18n("No Effect"), effectGroup);
+    noEffect->setData(1);
+    QAction *contrastEffect = new QAction(i18n("Contrast"), effectGroup);
+    contrastEffect->setData(2);
+    QAction *edgeEffect = new QAction(i18n("Edge detect"), effectGroup);
+    edgeEffect->setData(3);
+    QAction *brightEffect = new QAction(i18n("Brighten"), effectGroup);
+    brightEffect->setData(4);
+    QAction *invertEffect = new QAction(i18n("Invert"), effectGroup);
+    invertEffect->setData(5);
+    QAction *thresEffect = new QAction(i18n("Threshold"), effectGroup);
+    thresEffect->setData(6);
+
+    effectsMenu->addAction(noEffect);
+    effectsMenu->addAction(contrastEffect);
+    effectsMenu->addAction(edgeEffect);
+    effectsMenu->addAction(brightEffect);
+    effectsMenu->addAction(invertEffect);
+    effectsMenu->addAction(thresEffect);
+    QList <QAction *> list = effectsMenu->actions();
+    for(int i = 0; i < list.count(); i++) {
+        list.at(i)->setCheckable(true);
+        if(list.at(i)->data().toInt() == m_effectIndex) {
+            list.at(i)->setChecked(true);
+        }
+    }
+    connect(effectsMenu, SIGNAL(triggered(QAction*)), this, SLOT(slotUpdateOverlayEffect(QAction*)));
+    confMenu->addMenu(effectsMenu);
+#endif
+
+    QAction *showThumbs = new QAction(KIcon("image-x-generic"), i18n("Show sequence thumbnails"), this);
+    showThumbs->setCheckable(true);
+    showThumbs->setChecked(KdenliveSettings::showstopmotionthumbs());
+    connect(showThumbs, SIGNAL(triggered(bool)), this, SLOT(slotShowThumbs(bool)));
+
+    QAction *removeCurrent = new QAction(KIcon("edit-delete"), i18n("Delete current frame"), this);
+    //TODO: implement frame deletion
+    //connect(removeCurrent, SIGNAL(triggered()), this, SLOT(slotRemoveFrame()));
+
+    QAction *capInterval = new QAction(KIcon(), i18n("Set capture interval"), this);
+    connect(capInterval, SIGNAL(triggered()), this, SLOT(slotSetCaptureInterval()));
+
+    confMenu->addAction(showThumbs);
+    confMenu->addAction(capInterval);
+    confMenu->addAction(removeCurrent);
+    config_button->setIcon(KIcon("configure"));
+    config_button->setMenu(confMenu);
+
+    // Build capture menu
+    QMenu *capMenu = new QMenu;
+    m_intervalCapture = new QAction(KIcon("edit-redo"), i18n("Interval capture"), this);
+    m_intervalCapture->setCheckable(true);
+    m_intervalCapture->setChecked(false);
+    connect(m_intervalCapture, SIGNAL(triggered(bool)), this, SLOT(slotIntervalCapture(bool)));
+    capMenu->addAction(m_intervalCapture);
+    capture_button->setMenu(capMenu);
+
     connect(sequence_name, SIGNAL(textChanged(const QString &)), this, SLOT(sequenceNameChanged(const QString &)));
     m_layout = new QVBoxLayout;
-    if (BMInterface::getBlackMagicDeviceList(capture_device, NULL)) {
+    if(BMInterface::getBlackMagicDeviceList(capture_device, NULL)) {
         // Found a BlackMagic device
         m_bmCapture = new BmdCaptureHandler(m_layout);
         connect(m_bmCapture, SIGNAL(gotMessage(const QString &)), this, SLOT(slotGotHDMIMessage(const QString &)));
     }
-    if (QFile::exists(KdenliveSettings::video4vdevice())) {
-        if (m_bmCapture == NULL) m_bmCapture = new V4lCaptureHandler(m_layout);
+    if(QFile::exists(KdenliveSettings::video4vdevice())) {
+        if(m_bmCapture == NULL) m_bmCapture = new V4lCaptureHandler(m_layout);
         capture_device->addItem(KdenliveSettings::video4vdevice(), "v4l");
     }
+
+    connect(m_bmCapture, SIGNAL(frameSaved(const QString)), this, SLOT(slotNewThumb(const QString)));
     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)));
@@ -121,16 +193,14 @@ StopmotionWidget::StopmotionWidget(KUrl projectFolder, QWidget *parent) :
     m_frame_preview->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
     video_preview->setLayout(m_layout);
     live_button->setChecked(false);
-    frameoverlay_button->setChecked(false);
     button_addsequence->setEnabled(false);
     connect(live_button, SIGNAL(clicked(bool)), this, SLOT(slotLive(bool)));
-    connect(frameoverlay_button, SIGNAL(clicked(bool)), this, SLOT(slotShowOverlay(bool)));
-    connect(frame_number, SIGNAL(valueChanged(int)), this, SLOT(slotShowFrame(int)));
     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)));
 
+    frame_list->setHidden(!KdenliveSettings::showstopmotionthumbs());
     parseExistingSequences();
 }
 
@@ -139,13 +209,56 @@ StopmotionWidget::~StopmotionWidget()
     m_bmCapture->stopPreview();
 }
 
+void StopmotionWidget::slotUpdateOverlayEffect(QAction *act)
+{
+#ifdef QIMAGEBLITZ
+    if(act) m_effectIndex = act->data().toInt();
+    KdenliveSettings::setBlitzeffect(m_effectIndex);
+    if(m_showOverlay->isChecked()) slotUpdateOverlay();
+#endif
+}
+
+void StopmotionWidget::closeEvent(QCloseEvent *e)
+{
+    slotLive(false);
+    live_button->setChecked(false);
+    QDialog::closeEvent(e);
+}
+
+void StopmotionWidget::slotSetCaptureInterval()
+{
+    int interval = QInputDialog::getInteger(this, i18n("Set Capture Interval"), i18n("Interval (in seconds)"), KdenliveSettings::captureinterval(), 1);
+    if(interval > 0 && interval != KdenliveSettings::captureinterval())
+        KdenliveSettings::setCaptureinterval(interval);
+}
+
+void StopmotionWidget::slotShowThumbs(bool show)
+{
+    KdenliveSettings::setShowstopmotionthumbs(show);
+    kDebug() << "SHOW THUMBS: " << show;
+    if(show) {
+        frame_list->clear();
+        sequenceNameChanged(sequence_name->currentText());
+    } else {
+        m_filesList.clear();
+        frame_list->clear();
+    }
+    frame_list->setHidden(!show);
+}
+
+void StopmotionWidget::slotIntervalCapture(bool capture)
+{
+    if(capture) slotCaptureFrame();
+}
+
+
 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") {
+    if(data == "v4l") {
         m_bmCapture = new V4lCaptureHandler(m_layout);
     } else {
         m_bmCapture = new BmdCaptureHandler(m_layout);
@@ -176,7 +289,7 @@ void StopmotionWidget::parseExistingSequences()
 
 void StopmotionWidget::slotLive(bool isOn)
 {
-    if (isOn) {
+    if(isOn) {
         m_frame_preview->setImage(QImage());
         m_frame_preview->setHidden(true);
         m_bmCapture->startPreview(KdenliveSettings::hdmi_capturedevice(), KdenliveSettings::hdmi_capturemode());
@@ -189,8 +302,8 @@ void StopmotionWidget::slotLive(bool isOn)
 
 void StopmotionWidget::slotShowOverlay(bool isOn)
 {
-    if (isOn) {
-        if (live_button->isChecked() && m_sequenceFrame > 0) {
+    if(isOn) {
+        if(live_button->isChecked() && m_sequenceFrame > 0) {
             slotUpdateOverlay();
         }
     } else {
@@ -201,12 +314,36 @@ void StopmotionWidget::slotShowOverlay(bool isOn)
 void StopmotionWidget::slotUpdateOverlay()
 {
     QString path = getPathForFrame(m_sequenceFrame - 1);
-    if (!QFile::exists(path)) return;
+    if(!QFile::exists(path)) return;
     QImage img(path);
-    if (img.isNull()) {
+    if(img.isNull()) {
         QTimer::singleShot(1000, this, SLOT(slotUpdateOverlay()));
         return;
     }
+
+#ifdef QIMAGEBLITZ
+    //img = Blitz::convolveEdge(img, 0, Blitz::Low);
+    switch(m_effectIndex) {
+    case 2:
+        img = Blitz::contrast(img, true);
+        break;
+    case 3:
+        img = Blitz::edge(img);
+        break;
+    case 4:
+        img = Blitz::intensity(img, 0.5);
+        break;
+    case 5:
+        Blitz::invert(img);
+        break;
+    case 6:
+        img = Blitz::threshold(img, 200, Blitz::Grayscale, qRgba(255, 0, 0, 255), qRgba(0, 0, 0, 0));
+        break;
+    default:
+        break;
+
+    }
+#endif
     m_bmCapture->showOverlay(img);
 }
 
@@ -217,66 +354,61 @@ void StopmotionWidget::sequenceNameChanged(const QString &name)
     m_filesList.clear();
     m_future.waitForFinished();
     frame_list->clear();
-    if (name.isEmpty()) {
+    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
         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_sequenceFrame = m_filesList.isEmpty() ? 0 : SlideshowClip::getFrameNumberFromPath(m_filesList.last()) + 1;
+        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 {
+            // new sequence
+            connect(this, SIGNAL(doCreateThumbs(QImage, int)), this, SLOT(slotCreateThumbs(QImage, int)));
             button_addsequence->setEnabled(false);
-            frameoverlay_button->setEnabled(false);
         }
-        frame_number->setRange(0, m_sequenceFrame);
-        capture_button->setEnabled(true);
+        capture_button->setEnabled(live_button->isChecked());
     }
 }
 
 void StopmotionWidget::slotCaptureFrame()
 {
-    if (sequence_name->currentText().isEmpty()) {
+    if(sequence_name->currentText().isEmpty()) {
         QString seqName = QInputDialog::getText(this, i18n("Create New Sequence"), i18n("Enter sequence name"));
-        if (seqName.isEmpty()) return;
+        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()) {
+    if(m_sequenceName != sequence_name->currentText()) {
         m_sequenceName = sequence_name->currentText();
         m_sequenceFrame = 0;
     }
-    capture_button->setEnabled(false);
-    m_bmCapture->captureFrame(getPathForFrame(m_sequenceFrame));
+    //capture_button->setEnabled(false);
+    QString currentPath = getPathForFrame(m_sequenceFrame);
+    kDebug() << "Capture FRame NB: " << m_sequenceFrame;
+    m_bmCapture->captureFrame(currentPath);
     KNotification::event("FrameCaptured");
-    frameoverlay_button->setEnabled(true);
     m_sequenceFrame++;
-    frame_number->setRange(0, m_sequenceFrame);
-    frame_number->blockSignals(true);
-    frame_number->setValue(m_sequenceFrame);
-    frame_number->blockSignals(false);
     button_addsequence->setEnabled(true);
-    //if (frameoverlay_button->isChecked()) QTimer::singleShot(1000, this, SLOT(slotUpdateOverlay()));
-    QTimer::singleShot(1000, this, SLOT(slotUpdateFrameList()));
+    if(m_intervalCapture->isChecked()) QTimer::singleShot(KdenliveSettings::captureinterval() * 1000, this, SLOT(slotCaptureFrame()));
+}
+
+
+void StopmotionWidget::slotNewThumb(const QString path)
+{
+    if(!KdenliveSettings::showstopmotionthumbs()) return;
+    m_filesList.append(path);
+    if(m_showOverlay->isChecked()) slotUpdateOverlay();
+    if(!m_future.isRunning()) m_future = QtConcurrent::run(this, &StopmotionWidget::slotPrepareThumbs);
 }
 
 void StopmotionWidget::slotPrepareThumbs()
 {
-    if (m_filesList.isEmpty()) return;
+    if(m_filesList.isEmpty()) return;
     QString path = m_filesList.takeFirst();
     emit doCreateThumbs(QImage(path), SlideshowClip::getFrameNumberFromPath(path));
 
@@ -284,7 +416,7 @@ void StopmotionWidget::slotPrepareThumbs()
 
 void StopmotionWidget::slotCreateThumbs(QImage img, int ix)
 {
-    if (img.isNull()) {
+    if(img.isNull()) {
         m_future = QtConcurrent::run(this, &StopmotionWidget::slotPrepareThumbs);
         return;
     }
@@ -295,7 +427,7 @@ void StopmotionWidget::slotCreateThumbs(QImage img, int ix)
     QString nb = QString::number(ix);
     QPainter p(&pix);
     QFontInfo finfo(font());
-    p.fillRect(0, 0, finfo.pixelSize() * nb.count() + 6, finfo.pixelSize() + 6, QColor(0, 0, 0, 150));
+    p.fillRect(0, 0, finfo.pixelSize() * nb.count() + 6, finfo.pixelSize() + 6, QColor(80, 80, 80, 150));
     p.setPen(Qt::white);
     p.drawText(QPoint(3, finfo.pixelSize() + 3), nb);
     p.end();
@@ -306,62 +438,25 @@ void StopmotionWidget::slotCreateThumbs(QImage img, int ix)
     m_future = QtConcurrent::run(this, &StopmotionWidget::slotPrepareThumbs);
 }
 
-void StopmotionWidget::slotUpdateFrameList(int 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;
-    }
-    QImage img(path);
-    if (img.isNull()) {
-        if (ix == m_sequenceFrame - 1) QTimer::singleShot(1000, this, SLOT(slotUpdateFrameList()));
-        return;
-    }
-    int height = 90;
-    int width = height * img.width() / img.height();
-    frame_list->setIconSize(QSize(width, height));
-    QPixmap pix = QPixmap::fromImage(img).scaled(width, height);
-    QString nb = QString::number(ix);
-    QPainter p(&pix);
-    QFontInfo finfo(font());
-    p.fillRect(0, 0, finfo.pixelSize() * nb.count() + 6, finfo.pixelSize() + 6, QColor(0, 0, 0, 150));
-    p.setPen(Qt::white);
-    p.drawText(QPoint(3, finfo.pixelSize() + 3), nb);
-    p.end();
-    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);
-}
-
 QString StopmotionWidget::getPathForFrame(int ix, QString seqName)
 {
-    if (seqName.isEmpty()) seqName = m_sequenceName;
+    if(seqName.isEmpty()) seqName = m_sequenceName;
     return m_projectFolder.path(KUrl::AddTrailingSlash) + seqName + "_" + QString::number(ix).rightJustified(4, '0', false) + ".png";
 }
 
 void StopmotionWidget::slotShowFrame(int ix)
 {
-    if (m_sequenceFrame == 0) {
+    if(m_sequenceFrame == 0) {
         //there are no images in sequence
         return;
     }
-    frameoverlay_button->blockSignals(true);
-    frameoverlay_button->setChecked(false);
-    frameoverlay_button->blockSignals(false);
-    if (ix < m_sequenceFrame) {
+    if(ix < m_sequenceFrame) {
         // Show previous frame
         slotLive(false);
         live_button->setChecked(false);
         QImage img(getPathForFrame(ix));
         capture_button->setEnabled(false);
-        if (!img.isNull()) {
+        if(!img.isNull()) {
             //m_bmCapture->showOverlay(img, false);
             m_bmCapture->hidePreview(true);
             m_frame_preview->setImage(img);
@@ -383,11 +478,8 @@ void StopmotionWidget::slotShowFrame(int ix)
 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);
+    if(item) {
+        int ix = item->data(Qt::UserRole).toInt();;
         //slotShowFrame(ix);
     }
 }
@@ -399,13 +491,13 @@ void StopmotionWidget::slotAddSequence()
 
 void StopmotionWidget::slotPlayPreview()
 {
-    if (m_animatedIndex != -1) {
+    if(m_animatedIndex != -1) {
         // stop animation
         m_animatedIndex = -1;
         return;
     }
     QListWidgetItem *item = frame_list->currentItem();
-    if (item) {
+    if(item) {
         m_animatedIndex = item->data(Qt::UserRole).toInt();
     }
     QTimer::singleShot(200, this, SLOT(slotAnimate()));
@@ -415,7 +507,7 @@ void StopmotionWidget::slotAnimate()
 {
     slotShowFrame(m_animatedIndex);
     m_animatedIndex++;
-    if (m_animatedIndex < m_sequenceFrame) QTimer::singleShot(200, this, SLOT(slotAnimate()));
+    if(m_animatedIndex < m_sequenceFrame) QTimer::singleShot(200, this, SLOT(slotAnimate()));
     else m_animatedIndex = -1;
 }
 
@@ -423,28 +515,28 @@ QListWidgetItem *StopmotionWidget::getFrameFromIndex(int ix)
 {
     QListWidgetItem *item = NULL;
     int pos = ix;
-    if (ix >= frame_list->count()) {
+    if(ix >= frame_list->count()) {
         pos = frame_list->count() - 1;
     }
-    if (ix < 0) pos = 0;
+    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) {
+    if(value == ix) return item;
+    else if(value < ix) {
         pos++;
-        while (pos < frame_list->count()) {
+        while(pos < frame_list->count()) {
             item = frame_list->item(pos);
             value = item->data(Qt::UserRole).toInt();
-            if (value == ix) return item;
+            if(value == ix) return item;
             pos++;
         }
     } else {
         pos --;
-        while (pos >= 0) {
+        while(pos >= 0) {
             item = frame_list->item(pos);
             value = item->data(Qt::UserRole).toInt();
-            if (value == ix) return item;
+            if(value == ix) return item;
             pos --;
         }
     }
@@ -456,7 +548,7 @@ void StopmotionWidget::selectFrame(int ix)
 {
     frame_list->blockSignals(true);
     QListWidgetItem *item = getFrameFromIndex(ix);
-    if (!item) return;
+    if(!item) return;
     frame_list->setCurrentItem(item);
     frame_list->blockSignals(false);
 }
@@ -464,9 +556,9 @@ void StopmotionWidget::selectFrame(int ix)
 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(forward) {
+        if(ix < frame_list->count() - 1) frame_list->setCurrentRow(ix + 1);
+    } else if(ix > 0) frame_list->setCurrentRow(ix - 1);
 }
 
 
index 2976a3bdff8dbec42e1100a6d0bbce047b800042..a3593d46f9a87c971084a031c46c5555c6dc52cf 100644 (file)
 
 class MyLabel : public QLabel
 {
-  Q_OBJECT
+    Q_OBJECT
 public:
     MyLabel(QWidget *parent = 0);
     void setImage(QImage img);
 
 protected:
-    virtual void paintEvent( QPaintEvent * event);
+    virtual void paintEvent(QPaintEvent * event);
     virtual void wheelEvent(QWheelEvent * event);
 
 private:
@@ -58,115 +58,133 @@ public:
     StopmotionWidget(KUrl projectFolder, QWidget *parent = 0);
     virtual ~StopmotionWidget();
 
-
 protected:
-
+    virtual void closeEvent(QCloseEvent *e);
 
 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;
-
-  /** @brief Capture holder that will handle all video operation. */
-  CaptureHandler *m_bmCapture;
-
-  /** @brief Holds the name of the current sequence.
-   * Files will be saved in project folder with name: sequence001.png */
-  QString m_sequenceName;
-
-  /** @brief Holds the frame number of the current sequence. */
-  int m_sequenceFrame;
-
-  QAction *m_captureAction;
-  
-  /** @brief Holds the index of the frame to be displayed in the frame preview mode. */
-  int m_animatedIndex;
-
-  /** @brief Find all stopmotion sequences in current project folder. */
-  void parseExistingSequences();
-
-  /** @brief Select a frame in the list. */
-  void selectFrame(int ix);
-
-  /** @brief This widget will hold the frame preview. */
-  MyLabel *m_frame_preview;
-
-  /** @brief The list of files in the sequence to create thumbnails. */
-  QStringList m_filesList;
-  
-  /** @brief The index of currently created thumbnail. */
-  int m_currentIndex;
-  
-  /** @brief Holds the state of the threaded thumbnail generation. */
-  QFuture<void> m_future;
-
-  /** @brief Get the frame number ix. */
-  QListWidgetItem *getFrameFromIndex(int ix);
-  
+    /** @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;
+
+    /** @brief Capture holder that will handle all video operation. */
+    CaptureHandler *m_bmCapture;
+
+    /** @brief Holds the name of the current sequence.
+     * Files will be saved in project folder with name: sequence001.png */
+    QString m_sequenceName;
+
+    /** @brief Holds the frame number of the current sequence. */
+    int m_sequenceFrame;
+
+    QAction *m_captureAction;
+
+    /** @brief Holds the index of the frame to be displayed in the frame preview mode. */
+    int m_animatedIndex;
+
+    /** @brief Find all stopmotion sequences in current project folder. */
+    void parseExistingSequences();
+
+    /** @brief Select a frame in the list. */
+    void selectFrame(int ix);
+
+    /** @brief This widget will hold the frame preview. */
+    MyLabel *m_frame_preview;
+
+    /** @brief The list of files in the sequence to create thumbnails. */
+    QStringList m_filesList;
+
+    /** @brief Holds the state of the threaded thumbnail generation. */
+    QFuture<void> m_future;
+
+    /** @brief Get the frame number ix. */
+    QListWidgetItem *getFrameFromIndex(int ix);
+
+    /** @brief The action triggering interval capture. */
+    QAction *m_intervalCapture;
+
+    /** @brief The action triggering display of last frame over current live video feed. */
+    QAction *m_showOverlay;
+
+#ifdef QIMAGEBLITZ
+    int m_effectIndex;
+#endif
+
 private slots:
-  /** @brief Display the live feed from capture device.
-   @param isOn enable or disable the feature */
-  void slotLive(bool isOn);
+    /** @brief Display the live feed from capture device.
+     @param isOn enable or disable the feature */
+    void slotLive(bool isOn);
+
+    /** @brief Display the last captured frame over current live feed.
+     @param isOn enable or disable the feature */
+    void slotShowOverlay(bool isOn);
+
+    /** @brief Display the last captured frame over current live feed. */
+    void slotUpdateOverlay();
+
+    /** @brief User changed the capture name. */
+    void sequenceNameChanged(const QString &name);
+
+    /** @brief Grab a frame from current capture feed. */
+    void slotCaptureFrame();
+
+    /** @brief Display a previous frame in monitor. */
+    void slotShowFrame(int);
+
+    /** @brief Get full path for a frame in the sequence.
+     *  @param ix the frame number.
+     *  @param seqName (optional) the name of the sequence. */
+    QString getPathForFrame(int ix, QString seqName = QString());
+
+    /** @brief Add sequence to current project. */
+    void slotAddSequence();
 
-  /** @brief Display the last captured frame over current live feed.
-   @param isOn enable or disable the feature */
-  void slotShowOverlay(bool isOn);
+    /** @brief Display selected fram in monitor. */
+    void slotShowSelectedFrame();
 
-  /** @brief Display the last captured frame over current live feed. */
-  void slotUpdateOverlay();
+    /** @brief Start animation preview mode. */
+    void slotPlayPreview();
 
-  /** @brief User changed the capture name. */
-  void sequenceNameChanged(const QString &name);
+    /** @brief Simulate animation. */
+    void slotAnimate();
 
-  /** @brief Grab a frame from current capture feed. */
-  void slotCaptureFrame();
+    /** @brief Seek to previous or next captured frame.
+     *  @param forward set to true for next frame, false for previous one. */
+    void slotSeekFrame(bool forward);
 
-  /** @brief Display a previous frame in monitor. */
-  void slotShowFrame(int);
+    /** @brief Display warning / error message from capture backend. */
+    void slotGotHDMIMessage(const QString &message);
 
-  /** @brief Get full path for a frame in the sequence.
-   *  @param ix the frame number.
-   *  @param seqName (optional) the name of the sequence. */
-  QString getPathForFrame(int ix, QString seqName = QString());
+    /** @brief Create thumbnails for existing sequence frames. */
+    void slotCreateThumbs(QImage img, int ix);
 
-  /** @brief Add sequence to current project. */
-  void slotAddSequence();
+    /** @brief Prepare thumbnails creation. */
+    void slotPrepareThumbs();
 
-  /** @brief Update the frame list widget with newly created frame. */
-  void slotUpdateFrameList(int ix = -1);
-  
-  /** @brief Display selected fram in monitor. */
-  void slotShowSelectedFrame();
+    /** @brief Called when user switches the video capture backend. */
+    void slotUpdateHandler();
 
-  /** @brief Start animation preview mode. */
-  void slotPlayPreview();
-  
-  /** @brief Simulate animation. */
-  void slotAnimate();
-  
-  /** @brief Seek to previous or next captured frame.
-   *  @param forward set to true for next frame, false for previous one. */
-  void slotSeekFrame(bool forward);
+    /** @brief Show / hide sequence thumbnails. */
+    void slotShowThumbs(bool show);
 
-  /** @brief Display warning / error message from capture backend. */
-  void slotGotHDMIMessage(const QString &message);
+    /** @brief Capture one frame every interval time. */
+    void slotIntervalCapture(bool capture);
 
-  /** @brief Create thumbnails for existing sequence frames. */
-  void slotCreateThumbs(QImage img, int ix);
+    /** @brief Set the interval between each capture (in seconds). */
+    void slotSetCaptureInterval();
 
-  /** @brief Prepare thumbnails creation. */
-  void slotPrepareThumbs();
+    /** @brief Prepare to crete thumb for newly captured frame. */
+    void slotNewThumb(const QString path);
 
-  /** @brief Called when user switches the video capture backend. */
-  void slotUpdateHandler();
+    /** @brief Set the effect to be applied to overlay frame. */
+    void slotUpdateOverlayEffect(QAction *act);
 
 signals:
-  /** @brief Ask to add sequence to current project. */
-  void addOrUpdateSequence(const QString);
+    /** @brief Ask to add sequence to current project. */
+    void addOrUpdateSequence(const QString);
 
-  void doCreateThumbs(QImage, int);
+    void doCreateThumbs(QImage, int);
 };
 
 #endif
index be7b22be04d1e2d7ca03c8835ca62fc13eeaae17..63dc71d422172d8febb8a105359433f6d0c2287b 100644 (file)
@@ -27,6 +27,7 @@
 #include <QDebug>
 #include <QImage>
 #include <QTimer>
+#include <QPainter>
 
 #include <KDebug>
 #include <KLocale>
@@ -204,8 +205,16 @@ void V4lCaptureHandler::slotUpdate()
     yuv2rgb_int3((uchar *)img, (uchar *)qimg.bits(), v4lsrc.width, v4lsrc.height);
     if(!m_captureFramePath.isEmpty()) {
         qimg.save(m_captureFramePath);
+        emit frameSaved(m_captureFramePath);
         m_captureFramePath.clear();
     }
+    if(!m_overlayImage.isNull()) {
+        // overlay image
+        QPainter p(&qimg);
+        p.setOpacity(0.5);
+        p.drawImage(0, 0, m_overlayImage);
+        p.end();
+    }
     m_display->setPixmap(QPixmap::fromImage(qimg));
     if(m_update) QTimer::singleShot(200, this, SLOT(slotUpdate()));
 }
@@ -223,12 +232,14 @@ void V4lCaptureHandler::captureFrame(const QString &fname)
     m_captureFramePath = fname;
 }
 
-void V4lCaptureHandler::showOverlay(QImage /*img*/, bool /*transparent*/)
+void V4lCaptureHandler::showOverlay(QImage img, bool /*transparent*/)
 {
+    m_overlayImage = img;
 }
 
 void V4lCaptureHandler::hideOverlay()
 {
+    m_overlayImage = QImage();
 }
 
 void V4lCaptureHandler::hidePreview(bool hide)
index 2eaf5fefee82c0db1885a5370db04b6bfc61e052..ef81e54ac5c0f7e3b11f55749eb6cc52a4d062b4 100644 (file)
 
 class V4lCaptureHandler : public CaptureHandler
 {
-  Q_OBJECT
+    Q_OBJECT
 public:
-       V4lCaptureHandler(QVBoxLayout *lay, QWidget *parent = 0);
-       ~V4lCaptureHandler();
-       void startPreview(int deviceId, int captureMode);
-       void stopPreview();
-       void startCapture(const QString &path);
-       void stopCapture();
-       void captureFrame(const QString &fname);
-       void showOverlay(QImage img, bool transparent = true);
-       void hideOverlay();
-       void hidePreview(bool hide);
-       
+    V4lCaptureHandler(QVBoxLayout *lay, QWidget *parent = 0);
+    ~V4lCaptureHandler();
+    void startPreview(int deviceId, int captureMode);
+    void stopPreview();
+    void startCapture(const QString &path);
+    void stopCapture();
+    void captureFrame(const QString &fname);
+    void showOverlay(QImage img, bool transparent = true);
+    void hideOverlay();
+    void hidePreview(bool hide);
+
 private:
-       bool m_update;
-       QLabel *m_display;
-       QString m_captureFramePath;
-       
+    bool m_update;
+    QLabel *m_display;
+    QString m_captureFramePath;
+    QImage m_overlayImage;
+
 private slots:
-      void slotUpdate();
-signals:
+    void slotUpdate();
 };
 
 
index 4841f1d8b6a82cf46351336f4c7a2204588a31d4..f88a01ba4f5e3c3ca9983870df9110f0f3971fdb 100644 (file)
@@ -6,15 +6,15 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>643</width>
-    <height>395</height>
+    <width>671</width>
+    <height>406</height>
    </rect>
   </property>
   <property name="windowTitle">
    <string>Dialog</string>
   </property>
   <layout class="QGridLayout" name="gridLayout">
-   <item row="0" column="0" colspan="11">
+   <item row="0" column="0" colspan="13">
     <widget class="QSplitter" name="splitter">
      <property name="orientation">
       <enum>Qt::Vertical</enum>
      </widget>
     </widget>
    </item>
-   <item row="1" column="0">
-    <widget class="QToolButton" name="live_button">
+   <item row="1" column="7">
+    <widget class="KComboBox" name="sequence_name">
      <property name="toolTip">
-      <string>Live view</string>
-     </property>
-     <property name="whatsThis">
-      <string/>
-     </property>
-     <property name="text">
-      <string>...</string>
-     </property>
-     <property name="checkable">
-      <bool>true</bool>
+      <string>Sequence name</string>
      </property>
-     <property name="autoRaise">
+     <property name="editable">
       <bool>true</bool>
      </property>
     </widget>
    </item>
-   <item row="1" column="1">
-    <widget class="QToolButton" name="frameoverlay_button">
+   <item row="1" column="9">
+    <widget class="KComboBox" name="capture_device">
      <property name="toolTip">
-      <string>Overlay last frame</string>
+      <string>Capture device</string>
      </property>
      <property name="whatsThis">
       <string/>
      </property>
-     <property name="text">
-      <string>...</string>
+    </widget>
+   </item>
+   <item row="1" column="10">
+    <widget class="KComboBox" name="log_box">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
      </property>
-     <property name="checkable">
-      <bool>true</bool>
+     <property name="maxCount">
+      <number>10</number>
      </property>
-     <property name="autoRaise">
-      <bool>true</bool>
+     <property name="frame">
+      <bool>false</bool>
      </property>
     </widget>
    </item>
-   <item row="1" column="2">
+   <item row="1" column="11">
+    <widget class="QPushButton" name="button_addsequence">
+     <property name="text">
+      <string>Add to project</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="5">
     <widget class="QToolButton" name="preview_button">
      <property name="toolTip">
       <string>Preview sequence</string>
      </property>
     </widget>
    </item>
-   <item row="1" column="4">
-    <widget class="QSpinBox" name="frame_number">
-     <property name="toolTip">
-      <string>Frame number</string>
-     </property>
-     <property name="whatsThis">
-      <string/>
-     </property>
-    </widget>
-   </item>
-   <item row="1" column="5">
-    <widget class="QToolButton" name="capture_button">
+   <item row="1" column="2">
+    <widget class="QToolButton" name="config_button">
      <property name="toolTip">
-      <string>Capture frame</string>
+      <string>Overlay last frame</string>
      </property>
      <property name="whatsThis">
       <string/>
      <property name="text">
       <string>...</string>
      </property>
+     <property name="popupMode">
+      <enum>QToolButton::InstantPopup</enum>
+     </property>
     </widget>
    </item>
-   <item row="1" column="6">
-    <widget class="QToolButton" name="removelast_button">
+   <item row="1" column="3">
+    <widget class="QToolButton" name="live_button">
      <property name="toolTip">
-      <string>Remove current frame</string>
+      <string>Live view</string>
      </property>
      <property name="whatsThis">
       <string/>
      <property name="text">
       <string>...</string>
      </property>
+     <property name="checkable">
+      <bool>true</bool>
+     </property>
+     <property name="autoRaise">
+      <bool>true</bool>
+     </property>
     </widget>
    </item>
-   <item row="1" column="7">
-    <widget class="KComboBox" name="capture_device">
+   <item row="1" column="4">
+    <widget class="QToolButton" name="capture_button">
      <property name="toolTip">
-      <string>Capture device</string>
+      <string>Capture frame</string>
      </property>
      <property name="whatsThis">
       <string/>
      </property>
-    </widget>
-   </item>
-   <item row="1" column="9">
-    <widget class="QPushButton" name="button_addsequence">
      <property name="text">
-      <string>Add to project</string>
-     </property>
-    </widget>
-   </item>
-   <item row="1" column="10">
-    <widget class="QDialogButtonBox" name="buttonBox">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Maximum" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="orientation">
-      <enum>Qt::Horizontal</enum>
+      <string>...</string>
      </property>
-     <property name="standardButtons">
-      <set>QDialogButtonBox::Close</set>
+     <property name="popupMode">
+      <enum>QToolButton::MenuButtonPopup</enum>
      </property>
     </widget>
    </item>
-   <item row="1" column="3">
-    <widget class="KComboBox" name="sequence_name">
-     <property name="toolTip">
+   <item row="1" column="6">
+    <widget class="QLabel" name="label">
+     <property name="text">
       <string>Sequence name</string>
      </property>
-     <property name="editable">
-      <bool>true</bool>
-     </property>
-    </widget>
-   </item>
-   <item row="1" column="8">
-    <widget class="KComboBox" name="log_box">
-     <property name="sizePolicy">
-      <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
-       <horstretch>0</horstretch>
-       <verstretch>0</verstretch>
-      </sizepolicy>
-     </property>
-     <property name="maxCount">
-      <number>10</number>
-     </property>
-     <property name="frame">
-      <bool>false</bool>
-     </property>
     </widget>
    </item>
   </layout>
   </customwidget>
  </customwidgets>
  <resources/>
- <connections>
-  <connection>
-   <sender>buttonBox</sender>
-   <signal>accepted()</signal>
-   <receiver>Stopmotion_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>Stopmotion_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>
+ <connections/>
 </ui>