From 953b93d0b005bb31840cabd824bc75d87c2752dd Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Mardelle Date: Sun, 20 Jul 2008 18:26:30 +0000 Subject: [PATCH] some progress on slideshow clips svn path=/branches/KDE4/; revision=2331 --- src/clipmanager.cpp | 5 +- src/clipmanager.h | 2 +- src/clipproperties.cpp | 50 +++++++++++- src/docclipbase.cpp | 64 ++++++++++++++++ src/docclipbase.h | 1 + src/effectstackview.cpp | 2 +- src/kdenlivedoc.cpp | 4 +- src/kdenlivedoc.h | 2 +- src/monitor.cpp | 1 + src/projectlist.cpp | 2 +- src/renderer.cpp | 29 +++++-- src/slideshowclip.cpp | 52 ++++++++++++- src/slideshowclip.h | 5 ++ src/widgets/clipproperties_ui.ui | 128 ++++++++++++++++++------------- src/widgets/slideshowclip_ui.ui | 99 ++++++++++++++---------- 15 files changed, 335 insertions(+), 111 deletions(-) diff --git a/src/clipmanager.cpp b/src/clipmanager.cpp index 67691ff2..40a6485c 100644 --- a/src/clipmanager.cpp +++ b/src/clipmanager.cpp @@ -131,7 +131,7 @@ void ClipManager::slotAddColorClipFile(const QString name, const QString color, m_doc->commandStack()->push(command); } -void ClipManager::slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, const bool loop, QString group, const int groupId) { +void ClipManager::slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, const bool loop, const bool fade, const QString &luma_duration, const QString &luma_file, QString group, const int groupId) { QDomDocument doc; QDomElement prod = doc.createElement("producer"); prod.setAttribute("resource", path); @@ -141,8 +141,11 @@ void ClipManager::slotAddSlideshowClipFile(const QString name, const QString pat prod.setAttribute("in", "0"); prod.setAttribute("out", m_doc->getFramePos(duration) * count); prod.setAttribute("ttl", m_doc->getFramePos(duration)); + prod.setAttribute("luma_duration", m_doc->getFramePos(luma_duration)); prod.setAttribute("name", name); prod.setAttribute("loop", loop); + prod.setAttribute("fade", fade); + prod.setAttribute("luma_file", luma_file); if (!group.isEmpty()) { prod.setAttribute("groupname", group); prod.setAttribute("groupid", groupId); diff --git a/src/clipmanager.h b/src/clipmanager.h index 48b7c545..9c9b54c1 100644 --- a/src/clipmanager.h +++ b/src/clipmanager.h @@ -51,7 +51,7 @@ Q_OBJECT public: void slotAddClipFile(const KUrl url, const QString group, const int groupId); void slotAddTextClipFile(const QString path, const QString xml, const QString group, const int groupId); void slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group, const int groupId); - void slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, bool loop, const QString group, const int groupId); + void slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, const bool loop, const bool fade, const QString &luma_duration, const QString &luma_file, const QString group, const int groupId); DocClipBase *getClipById(int clipId); void slotDeleteClip(uint clipId); void setThumbsProgress(const QString &message, int progress); diff --git a/src/clipproperties.cpp b/src/clipproperties.cpp index 8e9436ae..5383988f 100644 --- a/src/clipproperties.cpp +++ b/src/clipproperties.cpp @@ -71,12 +71,38 @@ ClipProperties::ClipProperties(DocClipBase *clip, Timecode tc, double fps, QWidg types << "JPG" << "PNG" << "BMP" << "GIF"; m_view.image_type->addItems(types); m_view.slide_loop->setChecked(props.value("loop").toInt()); + m_view.slide_fade->setChecked(props.value("fade").toInt()); QString path = props.value("resource"); if (path.endsWith("png")) m_view.image_type->setCurrentIndex(TYPE_PNG); else if (path.endsWith("bmp")) m_view.image_type->setCurrentIndex(TYPE_BMP); else if (path.endsWith("gif")) m_view.image_type->setCurrentIndex(TYPE_GIF); m_view.slide_duration->setText(tc.getTimecodeFromFrames(props.value("ttl").toInt())); parseFolder(); + + m_view.luma_duration->setText(tc.getTimecodeFromFrames(props.value("luma_duration").toInt())); + QString lumaFile = props.value("luma_file"); + QString profilePath = KdenliveSettings::mltpath(); + profilePath = profilePath.section('/', 0, -3); + profilePath += "/lumas/PAL/"; + + QDir dir(profilePath); + QStringList result = dir.entryList(QDir::Files); + QStringList imagefiles; + QStringList imagenamelist; + int current; + foreach(QString file, result) { + if (file.endsWith(".pgm")) { + m_view.luma_file->addItem(KIcon(profilePath + file), file, profilePath + file); + if (!lumaFile.isEmpty() && lumaFile == QString(profilePath + file)) + current = m_view.luma_file->count() - 1; + } + } + + if (!lumaFile.isEmpty()) { + m_view.slide_luma->setChecked(true); + m_view.luma_file->setCurrentIndex(current); + } + connect(m_view.image_type, SIGNAL(currentIndexChanged(int)), this, SLOT(parseFolder())); } else if (t != AUDIO) { m_view.tabWidget->removeTab(SLIDETAB); @@ -182,8 +208,12 @@ QMap ClipProperties::properties() { props["colour"] = "0x" + new_color.right(6) + "ff"; } } else if (t == SLIDESHOW) { - props["loop"] = QString::number((int) m_view.slide_loop->isChecked()); QMap old_props = m_clip->properties(); + QString value = QString::number((int) m_view.slide_loop->isChecked()); + if (old_props.value("loop") != value) props["loop"] = value; + value = QString::number((int) m_view.slide_fade->isChecked()); + if (old_props.value("fade") != value) props["fade"] = value; + QString extension; switch (m_view.image_type->currentIndex()) { case TYPE_PNG: @@ -215,6 +245,24 @@ QMap ClipProperties::properties() { m_clipNeedsRefresh = true; props["out"] = QString::number(duration * m_count); } + if (m_view.slide_fade->isChecked()) { + int luma_duration = m_tc.getFrameCount(m_view.luma_duration->text(), m_fps); + if (luma_duration != old_props.value("luma_duration").toInt()) { + m_clipNeedsRefresh = true; + props["luma_duration"] = QString::number(luma_duration); + } + QString lumaFile; + if (m_view.slide_luma->isChecked()) + lumaFile = m_view.luma_file->itemData(m_view.luma_file->currentIndex()).toString(); + if (lumaFile != old_props.value("luma_file")) { + m_clipNeedsRefresh = true; + props["luma_file"] = lumaFile; + } + } else { + if (old_props.value("luma_file") != QString()) { + props["luma_file"] = QString(); + } + } } return props; diff --git a/src/docclipbase.cpp b/src/docclipbase.cpp index 3bb9dab3..4abf90fb 100644 --- a/src/docclipbase.cpp +++ b/src/docclipbase.cpp @@ -365,16 +365,80 @@ Mlt::Producer *DocClipBase::producer() { return m_clipProducer; } +void DocClipBase::slotRefreshProducer() { + if (m_clipProducer == NULL) return; + kDebug() << "//////////// REFRESH CLIP !!!!!!!!!!!!!!!!"; + if (m_clipType == SLIDESHOW) { + /*char *tmp = (char *) qstrdup(getProperty("resource").toUtf8().data()); + Mlt::Producer producer(*(m_clipProducer->profile()), tmp); + delete[] tmp; + delete m_clipProducer; + m_clipProducer = new Mlt::Producer(producer.get_producer()); + if (!getProperty("out").isEmpty()) m_clipProducer->set_in_and_out(getProperty("in").toInt(), getProperty("out").toInt());*/ + m_clipProducer->set("ttl", getProperty("ttl").toInt()); + //m_clipProducer->set("id", getProperty("id")); + if (getProperty("fade") == "1") { + // we want a fade filter effect + kDebug() << "//////////// FADE WANTED"; + Mlt::Service clipService(m_clipProducer->get_service()); + int ct = 0; + Mlt::Filter *filter = clipService.filter(ct); + while (filter) { + if (filter->get("mlt_service") == "luma") { + break; + } + ct++; + filter = clipService.filter(ct); + } + + if (filter && filter->get("mlt_service") == "luma") { + filter->set("period", getProperty("ttl").toInt() - 1); + filter->set("luma.out", getProperty("luma_duration").toInt()); + QString resource = getProperty("luma_file"); + char *tmp = (char *) qstrdup(resource.toUtf8().data()); + filter->set("luma.resource", tmp); + delete[] tmp; + } else { + // filter does not exist, create it... + Mlt::Filter *filter = new Mlt::Filter(*(m_clipProducer->profile()), "luma"); + filter->set("period", getProperty("ttl").toInt() - 1); + filter->set("luma.out", getProperty("luma_duration").toInt()); + QString resource = getProperty("luma_file"); + char *tmp = (char *) qstrdup(resource.toUtf8().data()); + filter->set("luma.resource", tmp); + delete[] tmp; + clipService.attach(*filter); + } + } else { + kDebug() << "//////////// FADE NOT WANTED!!!"; + Mlt::Service clipService(m_clipProducer->get_service()); + int ct = 0; + Mlt::Filter *filter = clipService.filter(0); + while (filter) { + if (filter->get("mlt_service") == "luma") { + clipService.detach(*filter); + } else ct++; + filter = clipService.filter(ct); + } + } + } +} + void DocClipBase::setProperties(QMap properties) { // changing clip type is not allowed properties.remove("type"); QMapIterator i(properties); + bool refreshProducer = false; + QStringList keys; + keys << "luma_duration" << "luma_file" << "fade" << "ttl"; while (i.hasNext()) { i.next(); m_properties.insert(i.key(), i.value()); if (i.key() == "resource") m_thumbProd->updateClipUrl(KUrl(i.value())); else if (i.key() == "out") setDuration(GenTime(i.value().toInt(), KdenliveSettings::project_fps())); + else if (m_clipType == SLIDESHOW && keys.contains(i.key())) refreshProducer = true; } + if (refreshProducer) slotRefreshProducer(); } void DocClipBase::setProperty(QString key, QString value) { diff --git a/src/docclipbase.h b/src/docclipbase.h index 51ecdd03..cd77e06d 100644 --- a/src/docclipbase.h +++ b/src/docclipbase.h @@ -215,6 +215,7 @@ private: // Private attributes QMap m_properties; /** Create connections for audio thumbnails */ void slotCreateAudioTimer(); + void slotRefreshProducer(); public slots: void updateAudioThumbnail(QMap > data); diff --git a/src/effectstackview.cpp b/src/effectstackview.cpp index 4c0b6889..09c92f5f 100644 --- a/src/effectstackview.cpp +++ b/src/effectstackview.cpp @@ -162,7 +162,7 @@ void EffectStackView::setupListView(int ix) { ui.buttonDown->setEnabled(false); } else { if (ix < 0) ix = 0; - if (ix > ui.effectlist->count() - 1) ix = ui.effectlist->count() - 1; + if (ix > ui.effectlist->count() - 1) ix = ui.effectlist->count() - 1; ui.effectlist->setCurrentRow(ix); ui.buttonDel->setEnabled(true); ui.buttonSave->setEnabled(true); diff --git a/src/kdenlivedoc.cpp b/src/kdenlivedoc.cpp index 1fb0f1b5..0c1c6aa3 100644 --- a/src/kdenlivedoc.cpp +++ b/src/kdenlivedoc.cpp @@ -646,8 +646,8 @@ void KdenliveDoc::slotAddColorClipFile(const QString name, const QString color, setModified(true); } -void KdenliveDoc::slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, bool loop, const QString group, const int groupId) { - m_clipManager->slotAddSlideshowClipFile(name, path, count, duration, loop, group, groupId); +void KdenliveDoc::slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, const bool loop, const bool fade, const QString &luma_duration, const QString &luma_file, const QString group, const int groupId) { + m_clipManager->slotAddSlideshowClipFile(name, path, count, duration, loop, fade, luma_duration, luma_file, group, groupId); setModified(true); } diff --git a/src/kdenlivedoc.h b/src/kdenlivedoc.h index 76f123b7..89747508 100644 --- a/src/kdenlivedoc.h +++ b/src/kdenlivedoc.h @@ -73,7 +73,7 @@ Q_OBJECT public: void slotDeleteFolder(const QString folderName, const int id); void slotEditFolder(const QString folderName, const QString oldfolderName, int clipId); void slotAddColorClipFile(const QString name, const QString color, QString duration, const QString group, const int groupId = -1); - void slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, bool loop, const QString group, const int groupId = -1); + void slotAddSlideshowClipFile(const QString name, const QString path, int count, const QString duration, const bool loop, const bool fade, const QString &luma_duration, const QString &luma_file, const QString group, const int groupId = -1); void deleteClip(const uint clipId); int getFramePos(QString duration); DocClipBase *getBaseClip(int clipId); diff --git a/src/monitor.cpp b/src/monitor.cpp index ac44012a..03cc00db 100644 --- a/src/monitor.cpp +++ b/src/monitor.cpp @@ -303,6 +303,7 @@ void Monitor::slotSetXml(DocClipBase *clip, const int position) { m_currentClip = clip; render->setProducer(clip->producer(), 0); m_ruler->slotNewValue(0); + //adjustRulerSize(clip->producer()->get_playtime()); m_timePos->setText("00:00:00:00"); m_position = 0; } diff --git a/src/projectlist.cpp b/src/projectlist.cpp index b9191ced..c93a7031 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -386,7 +386,7 @@ void ProjectList::slotAddSlideshowClip() { groupId = item->clipId(); } - m_doc->slotAddSlideshowClipFile(dia->clipName(), dia->selectedPath(), dia->imageCount(), dia->clipDuration(), dia->loop(), group, groupId); + m_doc->slotAddSlideshowClipFile(dia->clipName(), dia->selectedPath(), dia->imageCount(), dia->clipDuration(), dia->loop(), dia->fade(), dia->lumaDuration(), dia->lumaFile(), group, groupId); } delete dia; } diff --git a/src/renderer.cpp b/src/renderer.cpp index 1ba4b8b4..7166e753 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -392,7 +392,6 @@ void Render::getFileProperties(const QDomElement &xml, int clipId) { if (xml.attribute("type").toInt() == COLOR) { char *tmp = decodedString("colour:" + xml.attribute("colour")); producer = new Mlt::Producer(*m_mltProfile, "fezzik", tmp); - producer->set_in_and_out(xml.attribute("in").toInt(), xml.attribute("out").toInt()); delete[] tmp; } else if (url.isEmpty()) { QDomDocument doc; @@ -408,10 +407,10 @@ void Render::getFileProperties(const QDomElement &xml, int clipId) { } else { char *tmp = decodedString(url.path()); producer = new Mlt::Producer(*m_mltProfile, tmp); - if (!xml.attribute("out").isEmpty()) producer->set_in_and_out(xml.attribute("in").toInt(), xml.attribute("out").toInt()); - if (!xml.attribute("ttl").isEmpty()) producer->set("ttl", xml.attribute("ttl").toInt()); delete[] tmp; } + if (xml.hasAttribute("out")) producer->set_in_and_out(xml.attribute("in").toInt(), xml.attribute("out").toInt()); + if (producer->is_blank()) { kDebug() << " / / / / / / / /ERRROR / / / / // CANNOT LOAD PRODUCER: "; return; @@ -426,6 +425,25 @@ void Render::getFileProperties(const QDomElement &xml, int clipId) { //kDebug() << "/////// PRODUCER: " << url.path() << " IS: " << producer.get_playtime(); Mlt::Frame * frame = producer->get_frame(); + + if (xml.attribute("type").toInt() == SLIDESHOW) { + if (xml.hasAttribute("ttl")) producer->set("ttl", xml.attribute("ttl").toInt()); + if (xml.attribute("fade") == "1") { + // user wants a fade effect to slideshow + Mlt::Filter *filter = new Mlt::Filter(*m_mltProfile, "luma"); + if (xml.hasAttribute("ttl")) filter->set("period", xml.attribute("ttl").toInt() - 1); + if (xml.hasAttribute("luma_duration") && !xml.attribute("luma_duration").isEmpty()) filter->set("luma.out", xml.attribute("luma_duration").toInt()); + if (xml.hasAttribute("luma_file") && !xml.attribute("luma_file").isEmpty()) { + char *tmp = decodedString(xml.attribute("luma_file")); + filter->set("luma.resource", tmp); + delete[] tmp; + } + Mlt::Service clipService(producer->get_service()); + clipService.attach(*filter); + } + } + + filePropertyMap["fps"] = producer->get("source_fps"); if (frame && frame->is_valid()) { @@ -857,7 +875,7 @@ void Render::switchPlay() { if (!m_mltProducer) return; if (m_mltProducer->get_speed() == 0.0) { - m_isBlocked = false; + //m_isBlocked = false; m_mltProducer->set_speed(1.0); m_mltConsumer->set("refresh", 1); kDebug() << " ********* RENDER PLAY: " << m_mltProducer->get_speed(); @@ -865,7 +883,7 @@ void Render::switchPlay() { //m_isBlocked = true; m_mltConsumer->set("refresh", 0); m_mltProducer->set_speed(0.0); - m_isBlocked = true; + //m_isBlocked = true; m_mltProducer->seek((int) m_framePosition); //kDebug()<<" ********* RENDER PAUSE: "<get_speed(); //m_mltConsumer->set("refresh", 0); @@ -934,7 +952,6 @@ void Render::seekToFrame(int pos) { //kDebug()<<" ********* RENDER SEEK TO POS"; if (!m_mltProducer) return; - //kDebug()<<"////////// KDENLIVE SEEK: "<<(int) (time.frames(m_fps)); m_mltProducer->seek(pos); refresh(); } diff --git a/src/slideshowclip.cpp b/src/slideshowclip.cpp index 79ce97f0..6fba3673 100644 --- a/src/slideshowclip.cpp +++ b/src/slideshowclip.cpp @@ -40,15 +40,51 @@ SlideshowClip::SlideshowClip(QWidget * parent): QDialog(parent), m_count(0) { m_view.icon_list->setIconSize(QSize(50, 50)); connect(m_view.folder_url, SIGNAL(textChanged(const QString &)), this, SLOT(parseFolder())); connect(m_view.image_type, SIGNAL(currentIndexChanged(int)), this, SLOT(parseFolder())); + + connect(m_view.slide_fade, SIGNAL(stateChanged(int)), this, SLOT(slotEnableLuma(int))); + connect(m_view.luma_fade, SIGNAL(stateChanged(int)), this, SLOT(slotEnableLumaFile(int))); + m_view.image_type->addItem("JPG"); m_view.image_type->addItem("PNG"); m_view.image_type->addItem("BMP"); m_view.image_type->addItem("GIF"); - m_view.clip_duration->setText("00:00:03:00"); + m_view.clip_duration->setText(KdenliveSettings::image_duration()); + m_view.luma_duration->setText("00:00:00:24"); m_view.folder_url->setUrl(QDir::homePath()); + + + QString profilePath = KdenliveSettings::mltpath(); + profilePath = profilePath.section('/', 0, -3); + profilePath += "/lumas/PAL/"; + + QDir dir(profilePath); + QStringList result = dir.entryList(QDir::Files); + QStringList imagefiles; + QStringList imagenamelist; + foreach(QString file, result) { + if (file.endsWith(".pgm")) { + m_view.luma_file->addItem(KIcon(profilePath + file), file, profilePath + file); + } + } + adjustSize(); } +void SlideshowClip::slotEnableLuma(int state) { + bool enable = false; + if (state == Qt::Checked) enable = true; + m_view.luma_duration->setEnabled(enable); + m_view.luma_fade->setEnabled(enable); + if (enable) m_view.luma_file->setEnabled(m_view.luma_fade->isChecked()); + else m_view.luma_file->setEnabled(false); +} + +void SlideshowClip::slotEnableLumaFile(int state) { + bool enable = false; + if (state == Qt::Checked) enable = true; + m_view.luma_file->setEnabled(enable); +} + void SlideshowClip::parseFolder() { m_view.icon_list->clear(); QDir dir(m_view.folder_url->url().path()); @@ -117,6 +153,20 @@ int SlideshowClip::imageCount() const { bool SlideshowClip::loop() const { return m_view.slide_loop->isChecked(); } + +bool SlideshowClip::fade() const { + return m_view.slide_fade->isChecked(); +} + +QString SlideshowClip::lumaDuration() const { + return m_view.luma_duration->text(); +} + +QString SlideshowClip::lumaFile() const { + if (!m_view.luma_fade->isChecked() || !m_view.luma_file->isEnabled()) return QString(); + return m_view.luma_file->itemData(m_view.luma_file->currentIndex()).toString(); +} + #include "slideshowclip.moc" diff --git a/src/slideshowclip.h b/src/slideshowclip.h index eae190bb..024d008f 100644 --- a/src/slideshowclip.h +++ b/src/slideshowclip.h @@ -37,11 +37,16 @@ public: QString selectedPath() const; QString clipName() const; QString clipDuration() const; + QString lumaDuration() const; int imageCount() const; bool loop() const; + bool fade() const; + QString lumaFile() const; private slots: void parseFolder(); + void slotEnableLuma(int state); + void slotEnableLumaFile(int state); private: Ui::SlideshowClip_UI m_view; diff --git a/src/widgets/clipproperties_ui.ui b/src/widgets/clipproperties_ui.ui index e71b9a79..4f23f5fb 100644 --- a/src/widgets/clipproperties_ui.ui +++ b/src/widgets/clipproperties_ui.ui @@ -5,8 +5,8 @@ 0 0 - 304 - 456 + 315 + 440 @@ -75,18 +75,41 @@ + + + + Qt::Vertical + + + + 20 + 17 + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + - 0 + 3 0 0 - 284 - 204 + 288 + 210 @@ -169,8 +192,8 @@ 0 0 - 284 - 204 + 288 + 210 @@ -246,8 +269,8 @@ 0 0 - 284 - 204 + 288 + 210 @@ -284,8 +307,8 @@ 0 0 - 284 - 204 + 299 + 194 @@ -317,23 +340,44 @@ + + + Loop + + + + Crossfade - + + + + 99:99:99:99; + + + + Luma file - + - + + + + No image found + + + + Qt::Vertical @@ -346,20 +390,6 @@ - - - - Loop - - - - - - - No image found - - - @@ -367,8 +397,8 @@ 0 0 - 284 - 204 + 288 + 210 @@ -445,8 +475,8 @@ 0 0 - 284 - 204 + 288 + 210 @@ -525,30 +555,18 @@ - - - - Qt::Vertical - - - - 20 - 17 - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - + clip_thumb + label_5 + clip_path + label_3 + clip_description + clip_filesize_2 + clip_duration + clip_filesize_3 + clip_filesize + buttonBox + tabWidget diff --git a/src/widgets/slideshowclip_ui.ui b/src/widgets/slideshowclip_ui.ui index 48ba5772..c818c547 100644 --- a/src/widgets/slideshowclip_ui.ui +++ b/src/widgets/slideshowclip_ui.ui @@ -5,14 +5,14 @@ 0 0 - 319 - 332 + 251 + 392 Slideshow Clip - + @@ -20,60 +20,47 @@ - + - + + + + Folder + + + + + + + Frame Duration - + 99:99:99:99; - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - Folder - - - - - - - + Image Type - - + + - - + + - No image found + Loop @@ -84,20 +71,50 @@ - + + + false + Luma File - - + + + + false + + + + + - - + + - Loop + No image found + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + false + + + 99:99:99:99; -- 2.39.2