X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fslideshowclip.cpp;h=488ce636d1e0d8803ecc8ee214278000a806a96d;hb=2dec53c46fdf42af12c81a62949be701c7bfd03c;hp=e4557ab07e2a5dd7abce223f1337d2fedc0380d9;hpb=5143c0fd6b774ee8a036427bb1630126270a6364;p=kdenlive diff --git a/src/slideshowclip.cpp b/src/slideshowclip.cpp index e4557ab0..488ce636 100644 --- a/src/slideshowclip.cpp +++ b/src/slideshowclip.cpp @@ -23,15 +23,16 @@ #include #include #include +#include #include 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")); @@ -43,6 +44,7 @@ SlideshowClip::SlideshowClip(Timecode tc, QWidget * parent) : 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.pattern_url, SIGNAL(textChanged(const QString &)), this, SLOT(parseFolder())); connect(m_view.show_thumbs, SIGNAL(stateChanged(int)), this, SLOT(slotEnableThumbs(int))); connect(m_view.slide_fade, SIGNAL(stateChanged(int)), this, SLOT(slotEnableLuma(int))); @@ -55,31 +57,40 @@ SlideshowClip::SlideshowClip(Timecode tc, QWidget * parent) : m_view.image_type->addItem("BMP (*.bmp)", "bmp"); m_view.image_type->addItem("GIF (*.gif)", "gif"); m_view.image_type->addItem("TGA (*.tga)", "tga"); + m_view.image_type->addItem("TIF (*.tif)", "tif"); m_view.image_type->addItem("TIFF (*.tiff)", "tiff"); m_view.image_type->addItem("Open EXR (*.exr)", "exr"); - - m_view.clip_duration->setInputMask(""); - m_view.clip_duration->setValidator(m_timecode.validator()); - m_view.clip_duration->setText(m_timecode.reformatSeparators(KdenliveSettings::image_duration())); - m_view.luma_duration->setInputMask(""); - m_view.luma_duration->setValidator(m_timecode.validator()); + m_view.animation->addItem(i18n("None"), QString()); + m_view.animation->addItem(i18n("Pan"), "Pan"); + m_view.animation->addItem(i18n("Pan, low-pass"), "Pan, low-pass"); + m_view.animation->addItem(i18n("Pan and zoom"), "Pan and zoom"); + m_view.animation->addItem(i18n("Pan and zoom, low-pass"), "Pan and zoom, low-pass"); + m_view.animation->addItem(i18n("Zoom"), "Zoom"); + m_view.animation->addItem(i18n("Zoom, low-pass"), "Zoom, low-pass"); + + m_view.clip_duration->setInputMask(m_timecode.mask()); + m_view.luma_duration->setInputMask(m_timecode.mask()); m_view.luma_duration->setText(m_timecode.getTimecodeFromFrames(int(ceil(m_timecode.fps())))); m_view.folder_url->setUrl(QDir::homePath()); - m_view.clip_duration_format->addItem(i18n("hh:mm:ss::ff")); + m_view.clip_duration_format->addItem(i18n("hh:mm:ss:ff")); m_view.clip_duration_format->addItem(i18n("Frames")); connect(m_view.clip_duration_format, SIGNAL(activated(int)), this, SLOT(slotUpdateDurationFormat(int))); m_view.clip_duration_frames->setHidden(true); m_view.luma_duration_frames->setHidden(true); + m_view.method_mime->setChecked(KdenliveSettings::slideshowbymime()); + connect(m_view.method_mime, SIGNAL(toggled(bool)), this, SLOT(slotMethodChanged(bool))); + slotMethodChanged(m_view.method_mime->isChecked()); + // Check for Kdenlive installed luma files QStringList filters; 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); } @@ -91,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); } @@ -145,31 +156,92 @@ void SlideshowClip::slotEnableLumaFile(int state) m_view.label_softness->setEnabled(enable); } +// static +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; + filter.remove(filter.size() - 1, 1); + } + if (!hasDigit) return 0; + + + // 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; +} + void SlideshowClip::parseFolder() { m_view.icon_list->clear(); - QDir dir(m_view.folder_url->url().path()); - QStringList filters; - QString filter = m_view.image_type->itemData(m_view.image_type->currentIndex()).toString(); - filters << "*." + filter; - // TODO: improve jpeg image detection with extension like jpeg, requires change in MLT image producers - // << "*.jpeg"; + bool isMime = m_view.method_mime->isChecked(); + QString path = isMime ? m_view.folder_url->url().path() : m_view.pattern_url->url().directory(); + QDir dir(path); + if (path.isEmpty() || !dir.exists()) return; - dir.setNameFilters(filters); - const QStringList result = dir.entryList(QDir::Files); - 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++; + QStringList result; + QStringList filters; + QString filter; + if (isMime) { + // TODO: improve jpeg image detection with extension like jpeg, requires change in MLT image producers + filter = m_view.image_type->itemData(m_view.image_type->currentIndex()).toString(); + filters << "*." + filter; + dir.setNameFilters(filters); + 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); + } + 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++; + } + } + } + QListWidgetItem *item; + 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); } @@ -189,7 +261,13 @@ void SlideshowClip::slotGenerateThumbs() } } } - m_thumbJob = new KIO::PreviewJob(fileList, 50, 0, 0, 0, true, true, 0); +#if KDE_IS_VERSION(4,7,0) + m_thumbJob = new KIO::PreviewJob(fileList, QSize(50, 50)); + m_thumbJob->setScaleType(KIO::PreviewJob::Scaled); +#else + m_thumbJob = new KIO::PreviewJob(fileList, 50, 0, 0, 0, true, false, 0); +#endif + m_thumbJob->setAutoDelete(false); connect(m_thumbJob, SIGNAL(gotPreview(const KFileItem &, const QPixmap &)), this, SLOT(slotSetPixmap(const KFileItem &, const QPixmap &))); m_thumbJob->start(); @@ -211,10 +289,66 @@ void SlideshowClip::slotSetPixmap(const KFileItem &fileItem, const QPixmap &pix) } -QString SlideshowClip::selectedPath() const +QString SlideshowClip::selectedPath() +{ + QStringList list; + KUrl url; + if (m_view.method_mime->isChecked()) url = m_view.folder_url->url(); + else url = m_view.pattern_url->url(); + QString path = selectedPath(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 +int SlideshowClip::getFrameNumberFromPath(KUrl path) +{ + 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 extension = "/.all." + m_view.image_type->itemData(m_view.image_type->currentIndex()).toString(); - return m_view.folder_url->url().path() + extension; + QString folder; + if (isMime) { + folder = url.path(KUrl::AddTrailingSlash); + } else { + folder = url.directory(KUrl::AppendTrailingSlash); + 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); + } + + // Find number of digits in sequence + int precision = fullSize - filter.size(); + + // 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)) { + (*list).append(folder + path); + gap = 0; + } else { + gap++; + } + } + extension = filter + "%." + QString::number(precision) + "d" + ext; + } + kDebug() << "// FOUND " << (*list).count() << " items for " << url.path(); + return folder + extension; } @@ -247,6 +381,11 @@ bool SlideshowClip::loop() const return m_view.slide_loop->isChecked(); } +bool SlideshowClip::crop() const +{ + return m_view.slide_crop->isChecked(); +} + bool SlideshowClip::fade() const { return m_view.slide_fade->isChecked(); @@ -267,6 +406,12 @@ QString SlideshowClip::lumaFile() const return m_view.luma_file->itemData(m_view.luma_file->currentIndex()).toString(); } +QString SlideshowClip::animation() const +{ + if (m_view.animation->itemData(m_view.animation->currentIndex()).isNull()) return QString(); + return m_view.animation->itemData(m_view.animation->currentIndex()).toString(); +} + void SlideshowClip::slotUpdateDurationFormat(int ix) { bool framesFormat = ix == 1; @@ -276,11 +421,7 @@ void SlideshowClip::slotUpdateDurationFormat(int ix) m_view.luma_duration_frames->setValue(m_timecode.getFrameCount(m_view.luma_duration->text())); } else { // switching to timecode format - m_view.clip_duration->setInputMask(""); - m_view.clip_duration->setValidator(m_timecode.validator()); m_view.clip_duration->setText(m_timecode.getTimecodeFromFrames(m_view.clip_duration_frames->value())); - m_view.luma_duration->setInputMask(""); - m_view.luma_duration->setValidator(m_timecode.validator()); m_view.luma_duration->setText(m_timecode.getTimecodeFromFrames(m_view.luma_duration_frames->value())); } m_view.clip_duration_frames->setHidden(!framesFormat); @@ -289,6 +430,40 @@ void SlideshowClip::slotUpdateDurationFormat(int ix) m_view.luma_duration->setHidden(framesFormat); } +void SlideshowClip::slotMethodChanged(bool active) +{ + if (active) { + // User wants mimetype image sequence + 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 + m_view.clip_duration->setText(m_timecode.reformatSeparators(KdenliveSettings::sequence_duration())); + m_view.stackedWidget->setCurrentIndex(1); + KdenliveSettings::setSlideshowbymime(false); + } + parseFolder(); +} + +// static +QString SlideshowClip::animationToGeometry(const QString &animation, int &ttl) +{ + QString geometry; + if (animation.startsWith("Pan and zoom")) { + geometry = QString().sprintf("0=0/0:100%%x100%%;%d=-14%%/-14%%:120%%x120%%;%d=-5%%/-5%%:110%%x110%%;%d=0/0:110%%x110%%;%d=0/-5%%:110%%x110%%;%d=-5%%/0:110%%x110%%", + ttl - 1, ttl, ttl * 2 - 1, ttl * 2, ttl * 3 - 1); + ttl *= 3; + } else if (animation.startsWith("Pan")) { + geometry = QString().sprintf("0=-5%%/-5%%:110%%x110%%;%d=0/0:110%%x110%%;%d=0/0:110%%x110%%;%d=0/-5%%:110%%x110%%;%d=0/-5%%:110%%x110%%;%d=-5%%/-5%%:110%%x110%%;%d=0/-5%%:110%%x110%%;%d=-5%%/0:110%%x110%%", + ttl - 1, ttl, ttl * 2 - 1, ttl * 2, ttl * 3 - 1, ttl * 3, ttl * 4 - 1); + ttl *= 4; + } else if (animation.startsWith("Zoom")) { + geometry = QString().sprintf("0=0/0:100%%x100%%;%d=-14%%/-14%%:120%%x120%%", ttl - 1); + } + return geometry; +} + #include "slideshowclip.moc"