1 /***************************************************************************
2 stopmotion.cpp - description
5 copyright : (C) 2010 by Jean-Baptiste Mardelle
6 email : jb@kdenlive.org
7 ***************************************************************************/
9 /***************************************************************************
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 ***************************************************************************/
18 #include "stopmotion.h"
19 #include "../blackmagic/devices.h"
20 #include "../slideshowclip.h"
21 #include "kdenlivesettings.h"
25 #include <KGlobalSettings>
26 #include <KFileDialog>
27 #include <KStandardDirs>
28 #include <KMessageBox>
29 #include <kdeversion.h>
30 #include <KNotification>
33 #include <QVBoxLayout>
37 StopmotionWidget::StopmotionWidget(KUrl projectFolder, QWidget *parent) :
38 m_projectFolder(projectFolder)
44 setWindowTitle(i18n("Stop Motion Capture"));
45 setFont(KGlobalSettings::toolBarFont());
47 live_button->setIcon(KIcon("camera-photo"));
48 frameoverlay_button->setIcon(KIcon("edit-paste"));
49 m_captureAction = new QAction(KIcon("media-record"), i18n("Capture frame"), this);
50 m_captureAction->setShortcut(QKeySequence(Qt::Key_Space));
51 connect(m_captureAction, SIGNAL(triggered()), this, SLOT(slotCaptureFrame()));
52 capture_button->setDefaultAction(m_captureAction);
54 preview_button->setIcon(KIcon("media-playback-start"));
55 removelast_button->setIcon(KIcon("edit-delete"));
57 capture_button->setEnabled(false);
58 frameoverlay_button->setEnabled(false);
59 removelast_button->setEnabled(false);
61 #if KDE_IS_VERSION(4,4,0)
62 sequence_name->setClickMessage(i18n("Enter sequence name..."));
65 connect(sequence_name, SIGNAL(textChanged(const QString &)), this, SLOT(sequenceNameChanged(const QString &)));
66 BMInterface::getBlackMagicDeviceList(capture_device, NULL);
67 QVBoxLayout *lay = new QVBoxLayout;
68 m_bmCapture = new CaptureHandler(lay);
69 video_preview->setLayout(lay);
70 live_button->setChecked(false);
71 frameoverlay_button->setChecked(false);
72 button_addsequence->setEnabled(false);
73 connect(live_button, SIGNAL(clicked(bool)), this, SLOT(slotLive(bool)));
74 connect(frameoverlay_button, SIGNAL(clicked(bool)), this, SLOT(slotShowOverlay(bool)));
75 connect(frame_number, SIGNAL(valueChanged(int)), this, SLOT(slotShowFrame(int)));
76 connect(button_addsequence, SIGNAL(clicked(bool)), this, SLOT(slotAddSequence()));
79 StopmotionWidget::~StopmotionWidget()
81 m_bmCapture->stopPreview();
84 void StopmotionWidget::slotLive(bool isOn)
87 m_bmCapture->startPreview(KdenliveSettings::hdmicapturedevice(), KdenliveSettings::hdmicapturemode());
88 capture_button->setEnabled(sequence_name->text().isEmpty() == false);
91 m_bmCapture->stopPreview();
92 capture_button->setEnabled(false);
96 void StopmotionWidget::slotShowOverlay(bool isOn)
99 if (live_button->isChecked() && m_sequenceFrame > 0) {
104 m_bmCapture->hideOverlay();
108 void StopmotionWidget::slotUpdateOverlay()
110 QString path = getPathForFrame(m_sequenceFrame - 1);
111 if (!QFile::exists(path)) return;
114 QTimer::singleShot(1000, this, SLOT(slotUpdateOverlay()));
117 m_bmCapture->showOverlay(img);
120 void StopmotionWidget::sequenceNameChanged(const QString &name)
122 if (name.isEmpty()) {
123 button_addsequence->setEnabled(false);
124 capture_button->setEnabled(false);
125 frame_number->blockSignals(true);
126 frame_number->setValue(m_sequenceFrame);
127 frame_number->blockSignals(false);
128 frameoverlay_button->setEnabled(false);
129 removelast_button->setEnabled(false);
132 // Check if we are editing an existing sequence
134 QString pattern = SlideshowClip::selectedPath(getPathForFrame(0, sequence_name->text()), false, QString(), &count);
135 m_sequenceFrame = count;
137 m_sequenceName = sequence_name->text();
138 button_addsequence->setEnabled(true);
139 frameoverlay_button->setEnabled(true);
142 button_addsequence->setEnabled(false);
143 frameoverlay_button->setEnabled(false);
145 frame_number->setRange(0, m_sequenceFrame);
146 frame_number->blockSignals(true);
147 frame_number->setValue(m_sequenceFrame);
148 frame_number->blockSignals(false);
149 capture_button->setEnabled(true);
153 void StopmotionWidget::slotCaptureFrame()
155 if (m_sequenceName != sequence_name->text()) {
156 m_sequenceName = sequence_name->text();
160 m_bmCapture->captureFrame(getPathForFrame(m_sequenceFrame));
161 KNotification::event("FrameCaptured");
162 frameoverlay_button->setEnabled(true);
164 frame_number->setRange(0, m_sequenceFrame);
165 frame_number->blockSignals(true);
166 frame_number->setValue(m_sequenceFrame);
167 frame_number->blockSignals(false);
168 button_addsequence->setEnabled(true);
169 if (frameoverlay_button->isChecked()) QTimer::singleShot(1000, this, SLOT(slotUpdateOverlay()));
172 QString StopmotionWidget::getPathForFrame(int ix, QString seqName)
174 if (seqName.isEmpty()) seqName = m_sequenceName;
175 return m_projectFolder.path(KUrl::AddTrailingSlash) + seqName + "_" + QString::number(ix).rightJustified(4, '0', false) + ".png";
178 void StopmotionWidget::slotShowFrame(int ix)
180 if (m_sequenceFrame == 0) {
181 //there are no images in sequence
184 frameoverlay_button->blockSignals(true);
185 frameoverlay_button->setChecked(false);
186 frameoverlay_button->blockSignals(false);
187 if (ix < m_sequenceFrame) {
188 // Show previous frame
189 QImage img(getPathForFrame(ix));
190 capture_button->setEnabled(false);
191 if (!img.isNull()) m_bmCapture->showOverlay(img, false);
194 m_bmCapture->hideOverlay();
195 capture_button->setEnabled(true);
200 void StopmotionWidget::slotAddSequence()
202 emit addOrUpdateSequence(getPathForFrame(0));