m_modifiedTimer.setInterval(1500);
connect(&m_fileWatcher, SIGNAL(dirty(const QString &)), this, SLOT(slotClipModified(const QString &)));
connect(&m_fileWatcher, SIGNAL(deleted(const QString &)), this, SLOT(slotClipMissing(const QString &)));
- connect(&m_fileWatcher, SIGNAL(created(const QString &)), this, SLOT(slotClipAvailable(const QString &)));
+
+ // Seems like a dirty signal is emitted anyways when a watched file is created, so don't react twice.
+ //connect(&m_fileWatcher, SIGNAL(created(const QString &)), this, SLOT(slotClipAvailable(const QString &)));
connect(&m_modifiedTimer, SIGNAL(timeout()), this, SLOT(slotProcessModifiedClips()));
#if KDE_IS_VERSION(4,5,0)
void ClipManager::stopThumbs(const QString &id)
{
- if (m_requestedThumbs.isEmpty() || m_closing) return;
+ if (m_closing || (m_requestedThumbs.isEmpty() && m_processingThumbId != id && m_audioThumbsQueue.isEmpty() && m_processingAudioThumbId != id)) return;
+ // Abort video thumbs for this clip
m_abortThumb = true;
m_thumbsThread.waitForFinished();
m_thumbsMutex.lock();
m_requestedThumbs.remove(id);
+ m_audioThumbsQueue.removeAll(id);
m_thumbsMutex.unlock();
m_abortThumb = false;
- if (!m_thumbsThread.isRunning()) {
+
+ // Abort audio thumbs for this clip
+ if (m_processingAudioThumbId == id) {
+ m_abortAudioThumb = true;
+ m_audioThumbsThread.waitForFinished();
+ m_abortAudioThumb = false;
+ }
+
+ if (!m_thumbsThread.isRunning() && !m_requestedThumbs.isEmpty()) {
m_thumbsThread = QtConcurrent::run(this, &ClipManager::slotGetThumbs);
}
+
+ if (!m_audioThumbsThread.isRunning() && !m_audioThumbsQueue.isEmpty()) {
+ m_audioThumbsThread = QtConcurrent::run(this, &ClipManager::slotGetAudioThumbs);
+ }
}
void ClipManager::slotGetThumbs()
{
- QMap<QString, int>::iterator i = m_requestedThumbs.begin();
+ QMap<QString, int>::const_iterator i;
int max;
int done = 0;
- while (i != m_requestedThumbs.end() && !m_abortThumb) {
- QString producerId = i.key();
+ while (!m_requestedThumbs.isEmpty() && !m_abortThumb) {
m_thumbsMutex.lock();
- QList<int> values = m_requestedThumbs.values(producerId);
- m_requestedThumbs.remove(producerId);
- i = m_requestedThumbs.begin();
+ i = m_requestedThumbs.constBegin();
+ m_processingThumbId = i.key();
+ QList<int> values = m_requestedThumbs.values(m_processingThumbId);
+ m_requestedThumbs.remove(m_processingThumbId);
m_thumbsMutex.unlock();
qSort(values);
- DocClipBase *clip = getClipById(producerId);
+ DocClipBase *clip = getClipById(m_processingThumbId);
if (!clip) continue;
max = m_requestedThumbs.size() + values.count();
while (!values.isEmpty() && clip->thumbProducer() && !m_abortThumb) {
if (max > 3) emit displayMessage(i18n("Loading thumbnails"), 100 * done / max);
}
}
+ m_processingThumbId.clear();
emit displayMessage(QString(), -1);
}
m_thumbsMutex.lock();
for (int i = 0; i < m_clipList.count(); i++) {
DocClipBase *clip = m_clipList.at(i);
- if (clip->clipType() & (AUDIO | AV | PLAYLIST) && !clip->audioThumbCreated())
+ if (clip->hasAudioThumb() && !clip->audioThumbCreated())
m_audioThumbsQueue.append(m_clipList.at(i)->getId());
}
m_thumbsMutex.unlock();
- if (!m_audioThumbsThread.isRunning()) m_audioThumbsThread = QtConcurrent::run(this, &ClipManager::slotGetAudioThumbs);
+ if (!m_audioThumbsThread.isRunning() && !m_audioThumbsQueue.isEmpty()) {
+ m_audioThumbsThread = QtConcurrent::run(this, &ClipManager::slotGetAudioThumbs);
+ }
}
void ClipManager::askForAudioThumb(const QString &id)
{
DocClipBase *clip = getClipById(id);
- if (clip && KdenliveSettings::audiothumbnails() && (clip->clipType() & (AUDIO | AV | PLAYLIST))) {
+ if (clip && KdenliveSettings::audiothumbnails() && (clip->hasAudioThumb())) {
m_thumbsMutex.lock();
if (!m_audioThumbsQueue.contains(id)) m_audioThumbsQueue.append(id);
m_thumbsMutex.unlock();
mlt_audio_format audioFormat = mlt_audio_pcm;
while (!m_abortAudioThumb && !m_audioThumbsQueue.isEmpty()) {
m_thumbsMutex.lock();
- QString clipId = m_audioThumbsQueue.takeFirst();
+ m_processingAudioThumbId = m_audioThumbsQueue.takeFirst();
m_thumbsMutex.unlock();
- DocClipBase *clip = getClipById(clipId);
+ DocClipBase *clip = getClipById(m_processingAudioThumbId);
if (!clip || clip->audioThumbCreated()) continue;
KUrl url = clip->fileURL();
QString hash = clip->getClipHash();
kDebug() << "++++++++ INVALID CLIP: " << url.path();
continue;
}
+
+ producer.set("video_index", "-1");
if (KdenliveSettings::normaliseaudiothumbs()) {
Mlt::Filter m_convert(prof, "volume");
producer.seek(z);
mlt_frame = producer.get_frame();
if (mlt_frame && mlt_frame->is_valid()) {
- int samples = mlt_sample_calculator(framesPerSecond, frequency, mlt_frame_get_position(mlt_frame->get_frame()));
+ int samples = mlt_sample_calculator(framesPerSecond, frequency, mlt_frame->get_position());
qint16* pcm = static_cast<qint16*>(mlt_frame->get_audio(audioFormat, frequency, channels, samples));
for (int c = 0; c < channels; c++) {
QByteArray audioArray;
clip->updateAudioThumbnail(storeIn);
}
}
+ m_processingAudioThumbId.clear();
}
void ClipManager::setThumbsProgress(const QString &message, int progress)
emit checkAllClips(displayRatioChanged, fpsChanged, brokenClips);
}
-void ClipManager::slotAddClipList(const KUrl::List urls, const QString &group, const QString &groupId)
+void ClipManager::slotAddClipList(const KUrl::List urls, const QString &group, const QString &groupId, const QString &comment)
{
QUndoCommand *addClips = new QUndoCommand();
-
foreach(const KUrl & file, urls) {
- if (KIO::NetAccess::exists(file, KIO::NetAccess::SourceSide, NULL)) {
+ if (QFile::exists(file.path())) {//KIO::NetAccess::exists(file, KIO::NetAccess::SourceSide, NULL)) {
if (!getClipByResource(file.path()).empty()) {
if (KMessageBox::warningContinueCancel(kapp->activeWindow(), i18n("Clip <b>%1</b><br />already exists in project, what do you want to do?", file.path()), i18n("Clip already exists")) == KMessageBox::Cancel)
continue;
prod.setAttribute("resource", file.path());
uint id = m_clipIdCounter++;
prod.setAttribute("id", QString::number(id));
+ if (!comment.isEmpty()) prod.setAttribute("description", comment);
if (!group.isEmpty()) {
prod.setAttribute("groupname", group);
prod.setAttribute("groupid", groupId);
}
new AddClipCommand(m_doc, doc.documentElement(), QString::number(id), true, addClips);
}
+ else kDebug()<<"// CANNOT READ FILE: "<<file;
}
if (addClips->childCount() > 0) {
addClips->setText(i18np("Add clip", "Add clips", addClips->childCount()));
}
}
-void ClipManager::slotAddClipFile(const KUrl &url, const QString &group, const QString &groupId)
+void ClipManager::slotAddClipFile(const KUrl &url, const QString &group, const QString &groupId, const QString &comment)
{
- slotAddClipList(KUrl::List(url), group, groupId);
+ slotAddClipList(KUrl::List(url), group, groupId, comment);
}
void ClipManager::slotAddXmlClipFile(const QString &name, const QDomElement &xml, const QString &group, const QString &groupId)
m_doc->commandStack()->push(command);
}
-void ClipManager::slotAddSlideshowClipFile(const QString &name, const QString &path, int count, const QString &duration,
- const bool loop, const bool crop, const bool fade,
- const QString &luma_duration, const QString &luma_file, const int softness,
- const QString &animation, const QString &group, const QString &groupId)
+void ClipManager::slotAddSlideshowClipFile(QMap <QString, QString> properties, const QString &group, const QString &groupId)
{
QDomDocument doc;
QDomElement prod = doc.createElement("producer");
doc.appendChild(prod);
- prod.setAttribute("resource", path);
+ QMap<QString, QString>::const_iterator i = properties.constBegin();
+ while (i != properties.constEnd()) {
+ prod.setAttribute(i.key(), i.value());
+ ++i;
+ }
prod.setAttribute("type", (int) SLIDESHOW);
uint id = m_clipIdCounter++;
- prod.setAttribute("id", QString::number(id));
- 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("crop", crop);
- prod.setAttribute("fade", fade);
- prod.setAttribute("softness", QString::number(softness));
- prod.setAttribute("luma_file", luma_file);
- prod.setAttribute("animation", animation);
if (!group.isEmpty()) {
prod.setAttribute("groupname", group);
prod.setAttribute("groupid", groupId);