m_commandStack(NULL),
m_openAction(NULL),
m_reloadAction(NULL),
+ m_stabilizeAction(NULL),
m_transcodeAction(NULL),
m_doc(NULL),
m_refreshed(false),
m_menu->addActions(addMenu->actions());
}
-void ProjectList::setupGeneratorMenu(QMenu *addMenu, QMenu *transcodeMenu, QMenu *inTimelineMenu)
+void ProjectList::setupGeneratorMenu(const QHash<QString,QMenu*>& menus)
{
- if (!addMenu)
+ if (!menus.contains("addMenu") && ! menus.value("addMenu") )
return;
QMenu *menu = m_addButton->menu();
- menu->addMenu(addMenu);
- m_addButton->setMenu(menu);
-
- m_menu->addMenu(addMenu);
- if (addMenu->isEmpty())
- addMenu->setEnabled(false);
- m_menu->addMenu(transcodeMenu);
- if (transcodeMenu->isEmpty())
- transcodeMenu->setEnabled(false);
- m_transcodeAction = transcodeMenu;
+ if (menus.contains("addMenu") && menus.value("addMenu")){
+ QMenu* addMenu=menus.value("addMenu");
+ menu->addMenu(addMenu);
+ m_addButton->setMenu(menu);
+
+ m_menu->addMenu(addMenu);
+ if (addMenu->isEmpty())
+ addMenu->setEnabled(false);
+ }
+ if (menus.contains("transcodeMenu") && menus.value("transcodeMenu") ){
+ QMenu* transcodeMenu=menus.value("transcodeMenu");
+ m_menu->addMenu(transcodeMenu);
+ if (transcodeMenu->isEmpty())
+ transcodeMenu->setEnabled(false);
+ m_transcodeAction = transcodeMenu;
+ }
+ if (menus.contains("stabilizeMenu") && menus.value("stabilizeMenu") ){
+ QMenu* stabilizeMenu=menus.value("stabilizeMenu");
+ m_menu->addMenu(stabilizeMenu);
+ if (stabilizeMenu->isEmpty())
+ stabilizeMenu->setEnabled(false);
+ m_stabilizeAction=stabilizeMenu;
+
+ }
m_menu->addAction(m_reloadAction);
m_menu->addAction(m_proxyAction);
- m_menu->addMenu(inTimelineMenu);
- inTimelineMenu->setEnabled(false);
+ if (menus.contains("inTimelineMenu") && menus.value("inTimelineMenu")){
+ QMenu* inTimelineMenu=menus.value("inTimelineMenu");
+ m_menu->addMenu(inTimelineMenu);
+ inTimelineMenu->setEnabled(false);
+ }
m_menu->addAction(m_editButton->defaultAction());
m_menu->addAction(m_openAction);
m_menu->addAction(m_deleteButton->defaultAction());
m_openAction->setEnabled(false);
m_reloadAction->setEnabled(false);
m_transcodeAction->setEnabled(false);
+ m_stabilizeAction->setEnabled(false);
} else {
if (item->type() == PROJECTSUBCLIPTYPE) {
// this is a sub item, use base clip
SubProjectItem *sub = static_cast <SubProjectItem*>(item);
emit clipSelected(clip->referencedClip(), sub->zone());
m_transcodeAction->setEnabled(false);
+ m_stabilizeAction->setEnabled(false);
m_reloadAction->setEnabled(false);
adjustProxyActions(clip);
return;
m_deleteButton->defaultAction()->setEnabled(true);
m_reloadAction->setEnabled(true);
m_transcodeAction->setEnabled(true);
+ m_stabilizeAction->setEnabled(true);
if (clip && clip->clipType() == IMAGE && !KdenliveSettings::defaultimageapp().isEmpty()) {
m_openAction->setIcon(KIcon(KdenliveSettings::defaultimageapp()));
m_openAction->setEnabled(true);
}
// Display relevant transcoding actions only
adjustTranscodeActions(clip);
+ adjustStabilizeActions(clip);
// Display uses in timeline
emit findInTimeline(clip->clipId());
}
m_openAction->setEnabled(false);
m_reloadAction->setEnabled(false);
m_transcodeAction->setEnabled(false);
+ m_stabilizeAction->setEnabled(false);
}
adjustProxyActions(clip);
}
m_proxyAction->blockSignals(false);
}
+void ProjectList::adjustStabilizeActions(ProjectItem *clip) const
+{
+
+ if (clip == NULL || clip->type() != PROJECTCLIPTYPE || clip->clipType() == COLOR || clip->clipType() == TEXT || clip->clipType() == PLAYLIST || clip->clipType() == SLIDESHOW) {
+ m_stabilizeAction->setEnabled(false);
+ return;
+ }
+ m_stabilizeAction->setEnabled(true);
+
+}
+
void ProjectList::adjustTranscodeActions(ProjectItem *clip) const
{
if (clip == NULL || clip->type() != PROJECTCLIPTYPE || clip->clipType() == COLOR || clip->clipType() == TEXT || clip->clipType() == PLAYLIST || clip->clipType() == SLIDESHOW) {
m_deleteButton->defaultAction()->setEnabled(enable);
m_reloadAction->setEnabled(enable);
m_transcodeAction->setEnabled(enable);
+ m_stabilizeAction->setEnabled(enable);
if (enable) {
ProjectItem *clip = NULL;
if (m_listView->currentItem()->type() == PROJECTSUBCLIPTYPE) {
clip = static_cast <ProjectItem*>(item->parent());
m_transcodeAction->setEnabled(false);
+ m_stabilizeAction->setEnabled(false);
adjustProxyActions(clip);
} else if (m_listView->currentItem()->type() == PROJECTCLIPTYPE) {
clip = static_cast <ProjectItem*>(item);
// Display relevant transcoding actions only
adjustTranscodeActions(clip);
+ adjustStabilizeActions(clip);
adjustProxyActions(clip);
// Display uses in timeline
emit findInTimeline(clip->clipId());
} else {
m_transcodeAction->setEnabled(false);
+ m_stabilizeAction->setEnabled(false);
}
if (clip && clip->clipType() == IMAGE && !KdenliveSettings::defaultimageapp().isEmpty()) {
m_openAction->setIcon(KIcon(KdenliveSettings::defaultimageapp()));
m_openAction->setEnabled(true);
m_reloadAction->setEnabled(true);
m_transcodeAction->setEnabled(true);
+ m_stabilizeAction->setEnabled(true);
return;
}
else if (item && item->type() == PROJECTFOLDERTYPE && item->childCount() > 0) {
m_openAction->setEnabled(false);
m_reloadAction->setEnabled(false);
m_transcodeAction->setEnabled(false);
+ m_stabilizeAction->setEnabled(false);
m_proxyAction->setEnabled(false);
}
item->setText(2, QString::number(f.rating()));
}
#endif
+
+ // Add info to date column
+ QFileInfo fileInfo(url.path());
+ if (fileInfo.exists()) {
+ item->setText(3, fileInfo.lastModified().toString(QString("yyyy/MM/dd hh:mm:ss")));
+ }
+
// Add cut zones
QList <CutZoneInfo> cuts = clip->cutZones();
if (!cuts.isEmpty()) {
else requestClipThumbnail(parentItem->clipId() + '#' + QString::number(pos));
}
-void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged)
+void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged, QStringList brokenClips)
{
if (!m_allClipsProcessed) m_listView->setEnabled(false);
m_listView->setSortingEnabled(false);
item = static_cast <ProjectItem *>(*it);
clip = item->referencedClip();
if (item->referencedClip()->getProducer() == NULL) {
+ bool replace = false;
+ if (brokenClips.contains(item->clipId())) {
+ // if this is a proxy clip, disable proxy
+ item->setProxyStatus(NOPROXY);
+ clip->setProperty("proxy", "-");
+ replace = true;
+ }
if (clip->isPlaceHolder() == false && !item->isProxyRunning()) {
QDomElement xml = clip->toXML();
if (fpsChanged) {
xml.removeAttribute("file_hash");
xml.removeAttribute("proxy_out");
}
- bool replace = xml.attribute("replace") == "1";
+ if (!replace) replace = xml.attribute("replace") == "1";
if (replace) resetThumbsProducer(clip);
m_render->getFileProperties(xml, clip->getId(), m_listView->iconSize().height(), replace);
}
{
ProjectItem *item = getItemById(id);
if (item) {
+ kDebug()<<"// Proxy for clip "<<id<<" is invalid, delete";
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled);
if (durationError) {
kDebug() << "Proxy duration is wrong, try changing transcoding parameters.";
if (proxyFolder.isParentOf(KUrl(path))) {
QFile::remove(path);
}
+ if (item->referencedClip()->getProducer() == NULL) {
+ // Clip has no valid producer, request it
+ slotProxyCurrentItem(false, item);
+ }
+ else {
+ // refresh thumbs producer
+ item->referencedClip()->reloadThumbProducer();
+ }
}
m_processingClips.removeAll(id);
m_thumbnailQueue.removeAll(id);
connect(m_doc->clipManager(), SIGNAL(modifiedClip(const QString &)), this, SLOT(slotModifiedClip(const QString &)));
connect(m_doc->clipManager(), SIGNAL(missingClip(const QString &)), this, SLOT(slotMissingClip(const QString &)));
connect(m_doc->clipManager(), SIGNAL(availableClip(const QString &)), this, SLOT(slotAvailableClip(const QString &)));
- connect(m_doc->clipManager(), SIGNAL(checkAllClips(bool, bool)), this, SLOT(updateAllClips(bool, bool)));
+ connect(m_doc->clipManager(), SIGNAL(checkAllClips(bool, bool, QStringList)), this, SLOT(updateAllClips(bool, bool, QStringList)));
}
QList <DocClipBase*> ProjectList::documentClipList() const
monitorItemEditing(false);
it->setData(0, Qt::DecorationRole, pix);
monitorItemEditing(true);
-
- if (!isSubItem)
- m_doc->cachePixmap(item->getClipHash(), pix);
- else
- m_doc->cachePixmap(item->getClipHash() + '#' + QString::number(frame), pix);
+
+ QString clipId = item->getClipHash();
+ if (!clipId.isEmpty()) {
+ if (!isSubItem)
+ m_doc->cachePixmap(clipId, pix);
+ else
+ m_doc->cachePixmap(clipId + '#' + QString::number(frame), pix);
+ }
}
if (update)
emit projectModified();
item->setData(0, Qt::DecorationRole, pix);
monitorItemEditing(true);
//update();
- m_doc->cachePixmap(item->getClipHash(), pix);
+ QString clipId = item->getClipHash();
+ if (!clipId.isEmpty()) m_doc->cachePixmap(clipId, pix);
}
}
m_deleteButton->defaultAction()->setEnabled(true);
m_reloadAction->setEnabled(true);
m_transcodeAction->setEnabled(true);
+ m_stabilizeAction->setEnabled(true);
if (clip->clipType() == IMAGE && !KdenliveSettings::defaultimageapp().isEmpty()) {
m_openAction->setIcon(KIcon(KdenliveSettings::defaultimageapp()));
m_openAction->setEnabled(true);
}
QPixmap p = clip->referencedClip()->extractImage(in, (int)(sub->sizeHint(0).height() * m_render->dar()), sub->sizeHint(0).height() - 2);
sub->setData(0, Qt::DecorationRole, p);
- m_doc->cachePixmap(clip->getClipHash() + '#' + QString::number(in), p);
+ QString clipId = clip->getClipHash();
+ if (!clipId.isEmpty()) m_doc->cachePixmap(clipId + '#' + QString::number(in), p);
monitorItemEditing(true);
}
emit projectModified();
info.type = item->clipType();
info.exif = QString(item->referencedClip()->producerProperty("_exif_orientation")).toInt();
m_proxyList.append(info);
- m_proxyThreads.addFuture(QtConcurrent::run(this, &ProjectList::slotGenerateProxy));
+ if (m_proxyThreads.futures().isEmpty() || m_proxyThreads.futures().count() < KdenliveSettings::proxythreads()) m_proxyThreads.addFuture(QtConcurrent::run(this, &ProjectList::slotGenerateProxy));
}
void ProjectList::slotAbortProxy(const QString id, const QString path)
void ProjectList::slotGenerateProxy()
{
- if (m_proxyList.isEmpty() || m_abortAllProxies) return;
- emit projectModified();
- PROXYINFO info = m_proxyList.takeFirst();
- if (m_abortProxy.contains(info.dest)) {
- m_abortProxy.removeAll(info.dest);
- return;
- }
+ while (!m_proxyList.isEmpty() && !m_abortAllProxies) {
+ emit projectModified();
+ PROXYINFO info = m_proxyList.takeFirst();
+ if (m_abortProxy.contains(info.dest)) {
+ m_abortProxy.removeAll(info.dest);
+ return;
+ }
- // Make sure proxy path is writable
- QFile file(info.dest);
- if (!file.open(QIODevice::WriteOnly)) {
- setProxyStatus(info.dest, PROXYCRASHED);
- m_processingProxy.removeAll(info.dest);
- return;
- }
- file.close();
- QFile::remove(info.dest);
+ // Make sure proxy path is writable
+ QFile file(info.dest);
+ if (!file.open(QIODevice::WriteOnly)) {
+ setProxyStatus(info.dest, PROXYCRASHED);
+ m_processingProxy.removeAll(info.dest);
+ return;
+ }
+ file.close();
+ QFile::remove(info.dest);
- setProxyStatus(info.dest, CREATINGPROXY);
+ setProxyStatus(info.dest, CREATINGPROXY);
- // Get the list of clips that will need to get progress info
- QTreeWidgetItemIterator it(m_listView);
- QList <ProjectItem *> processingItems;
- while (*it && !m_abortAllProxies) {
- if ((*it)->type() == PROJECTCLIPTYPE) {
- ProjectItem *item = static_cast <ProjectItem *>(*it);
- if (item->referencedClip()->getProperty("proxy") == info.dest) {
- processingItems.append(item);
+ // Get the list of clips that will need to get progress info
+ QTreeWidgetItemIterator it(m_listView);
+ QList <ProjectItem *> processingItems;
+ while (*it && !m_abortAllProxies) {
+ if ((*it)->type() == PROJECTCLIPTYPE) {
+ ProjectItem *item = static_cast <ProjectItem *>(*it);
+ if (item->referencedClip()->getProperty("proxy") == info.dest) {
+ processingItems.append(item);
+ }
}
+ ++it;
}
- ++it;
- }
- // Special case: playlist clips (.mlt or .kdenlive project files)
- if (info.type == PLAYLIST) {
- // change FFmpeg params to MLT format
- QStringList parameters;
- parameters << info.src;
- parameters << "-consumer" << "avformat:" + info.dest;
- QStringList params = m_doc->getDocumentProperty("proxyparams").simplified().split('-', QString::SkipEmptyParts);
+ // Special case: playlist clips (.mlt or .kdenlive project files)
+ if (info.type == PLAYLIST) {
+ // change FFmpeg params to MLT format
+ QStringList parameters;
+ parameters << info.src;
+ parameters << "-consumer" << "avformat:" + info.dest;
+ QStringList params = m_doc->getDocumentProperty("proxyparams").simplified().split('-', QString::SkipEmptyParts);
- foreach(QString s, params) {
- s = s.simplified();
- if (s.count(' ') == 0) {
- s.append("=1");
+ foreach(QString s, params) {
+ s = s.simplified();
+ if (s.count(' ') == 0) {
+ s.append("=1");
+ }
+ else s.replace(' ', '=');
+ parameters << s;
}
- else s.replace(' ', '=');
- parameters << s;
- }
- parameters.append(QString("real_time=-%1").arg(KdenliveSettings::mltthreads()));
-
- //TODO: currently, when rendering an xml file through melt, the display ration is lost, so we enforce it manualy
- double display_ratio = KdenliveDoc::getDisplayRatio(info.src);
- parameters << "aspect=" + QString::number(display_ratio);
+ parameters.append(QString("real_time=-%1").arg(KdenliveSettings::mltthreads()));
+
+ //TODO: currently, when rendering an xml file through melt, the display ration is lost, so we enforce it manualy
+ double display_ratio = KdenliveDoc::getDisplayRatio(info.src);
+ parameters << "aspect=" + QString::number(display_ratio);
+
+ //kDebug()<<"TRANSCOD: "<<parameters;
+ QProcess myProcess;
+ myProcess.setProcessChannelMode(QProcess::MergedChannels);
+ myProcess.start(KdenliveSettings::rendererpath(), parameters);
+ myProcess.waitForStarted();
+ int result = -1;
+ int duration = 0;
+ while (myProcess.state() != QProcess::NotRunning) {
+ // building proxy file
+ if (m_abortProxy.contains(info.dest) || m_abortAllProxies) {
+ myProcess.close();
+ myProcess.waitForFinished();
+ QFile::remove(info.dest);
+ m_abortProxy.removeAll(info.dest);
+ m_processingProxy.removeAll(info.dest);
+ setProxyStatus(info.dest, NOPROXY);
+ result = -2;
+ }
+ else {
+ QString log = QString(myProcess.readAll());
+ processLogInfo(processingItems, &duration, log);
+ }
+ myProcess.waitForFinished(500);
+ }
+ myProcess.waitForFinished();
+ m_processingProxy.removeAll(info.dest);
+ if (result == -1) result = myProcess.exitStatus();
+ if (result == 0) {
+ // proxy successfully created
+ setProxyStatus(info.dest, PROXYDONE);
+ slotGotProxy(info.dest);
+ }
+ else if (result == 1) {
+ // Proxy process crashed
+ QFile::remove(info.dest);
+ setProxyStatus(info.dest, PROXYCRASHED);
+ }
+ continue;
+ }
+
+ if (info.type == IMAGE) {
+ // Image proxy
+ QImage i(info.src);
+ if (i.isNull()) {
+ // Cannot load image
+ setProxyStatus(info.dest, PROXYCRASHED);
+ continue;
+ }
+ QImage proxy;
+ // Images are scaled to profile size.
+ //TODO: Make it be configurable?
+ if (i.width() > i.height()) proxy = i.scaledToWidth(m_render->frameRenderWidth());
+ else proxy = i.scaledToHeight(m_render->renderHeight());
+ if (info.exif > 1) {
+ // Rotate image according to exif data
+ QImage processed;
+ QMatrix matrix;
+
+ switch ( info.exif ) {
+ case 2:
+ matrix.scale( -1, 1 );
+ break;
+ case 3:
+ matrix.rotate( 180 );
+ break;
+ case 4:
+ matrix.scale( 1, -1 );
+ break;
+ case 5:
+ matrix.rotate( 270 );
+ matrix.scale( -1, 1 );
+ break;
+ case 6:
+ matrix.rotate( 90 );
+ break;
+ case 7:
+ matrix.rotate( 90 );
+ matrix.scale( -1, 1 );
+ break;
+ case 8:
+ matrix.rotate( 270 );
+ break;
+ }
+ processed = proxy.transformed( matrix );
+ processed.save(info.dest);
+ }
+ else proxy.save(info.dest);
+ setProxyStatus(info.dest, PROXYDONE);
+ slotGotProxy(info.dest);
+ m_abortProxy.removeAll(info.dest);
+ m_processingProxy.removeAll(info.dest);
+ continue;
+ }
- //kDebug()<<"TRANSCOD: "<<parameters;
+ QStringList parameters;
+ parameters << "-i" << info.src;
+ QString params = m_doc->getDocumentProperty("proxyparams").simplified();
+ foreach(QString s, params.split(' '))
+ parameters << s;
+
+ // Make sure we don't block when proxy file already exists
+ parameters << "-y";
+ parameters << info.dest;
QProcess myProcess;
myProcess.setProcessChannelMode(QProcess::MergedChannels);
- myProcess.start(KdenliveSettings::rendererpath(), parameters);
+ myProcess.start("ffmpeg", parameters);
myProcess.waitForStarted();
int result = -1;
int duration = 0;
+
while (myProcess.state() != QProcess::NotRunning) {
// building proxy file
if (m_abortProxy.contains(info.dest) || m_abortAllProxies) {
myProcess.close();
myProcess.waitForFinished();
- QFile::remove(info.dest);
m_abortProxy.removeAll(info.dest);
m_processingProxy.removeAll(info.dest);
- setProxyStatus(info.dest, NOPROXY);
+ QFile::remove(info.dest);
+ if (!m_abortAllProxies) setProxyStatus(info.dest, NOPROXY);
result = -2;
+
}
else {
QString log = QString(myProcess.readAll());
myProcess.waitForFinished(500);
}
myProcess.waitForFinished();
+ m_abortProxy.removeAll(info.dest);
m_processingProxy.removeAll(info.dest);
if (result == -1) result = myProcess.exitStatus();
if (result == 0) {
QFile::remove(info.dest);
setProxyStatus(info.dest, PROXYCRASHED);
}
- return;
- }
-
- if (info.type == IMAGE) {
- // Image proxy
- QImage i(info.src);
- if (i.isNull()) {
- // Cannot load image
- setProxyStatus(info.dest, PROXYCRASHED);
- return;
- }
- QImage proxy;
- // Images are scaled to profile size.
- //TODO: Make it be configurable?
- if (i.width() > i.height()) proxy = i.scaledToWidth(m_render->frameRenderWidth());
- else proxy = i.scaledToHeight(m_render->renderHeight());
- if (info.exif > 1) {
- // Rotate image according to exif data
- QImage processed;
- QMatrix matrix;
-
- switch ( info.exif ) {
- case 2:
- matrix.scale( -1, 1 );
- break;
- case 3:
- matrix.rotate( 180 );
- break;
- case 4:
- matrix.scale( 1, -1 );
- break;
- case 5:
- matrix.rotate( 270 );
- matrix.scale( -1, 1 );
- break;
- case 6:
- matrix.rotate( 90 );
- break;
- case 7:
- matrix.rotate( 90 );
- matrix.scale( -1, 1 );
- break;
- case 8:
- matrix.rotate( 270 );
- break;
- }
- processed = proxy.transformed( matrix );
- processed.save(info.dest);
- }
- else proxy.save(info.dest);
- setProxyStatus(info.dest, PROXYDONE);
- slotGotProxy(info.dest);
- m_abortProxy.removeAll(info.dest);
- m_processingProxy.removeAll(info.dest);
- return;
- }
-
- QStringList parameters;
- parameters << "-i" << info.src;
- QString params = m_doc->getDocumentProperty("proxyparams").simplified();
- foreach(QString s, params.split(' '))
- parameters << s;
-
- // Make sure we don't block when proxy file already exists
- parameters << "-y";
- parameters << info.dest;
- QProcess myProcess;
- myProcess.setProcessChannelMode(QProcess::MergedChannels);
- myProcess.start("ffmpeg", parameters);
- myProcess.waitForStarted();
- int result = -1;
- int duration = 0;
-
- while (myProcess.state() != QProcess::NotRunning) {
- // building proxy file
- if (m_abortProxy.contains(info.dest) || m_abortAllProxies) {
- myProcess.close();
- myProcess.waitForFinished();
- m_abortProxy.removeAll(info.dest);
- m_processingProxy.removeAll(info.dest);
- QFile::remove(info.dest);
- if (!m_abortAllProxies) setProxyStatus(info.dest, NOPROXY);
- result = -2;
-
- }
- else {
- QString log = QString(myProcess.readAll());
- processLogInfo(processingItems, &duration, log);
- }
- myProcess.waitForFinished(500);
- }
- myProcess.waitForFinished();
- m_abortProxy.removeAll(info.dest);
- m_processingProxy.removeAll(info.dest);
- if (result == -1) result = myProcess.exitStatus();
- if (result == 0) {
- // proxy successfully created
- setProxyStatus(info.dest, PROXYDONE);
- slotGotProxy(info.dest);
- }
- else if (result == 1) {
- // Proxy process crashed
- QFile::remove(info.dest);
- setProxyStatus(info.dest, PROXYCRASHED);
}
}
else delete command;
}
-void ProjectList::slotProxyCurrentItem(bool doProxy)
+void ProjectList::slotProxyCurrentItem(bool doProxy, ProjectItem *itemToProxy)
{
- QList<QTreeWidgetItem *> list = m_listView->selectedItems();
+ QList<QTreeWidgetItem *> list;
+ if (itemToProxy == NULL) list = m_listView->selectedItems();
+ else list << itemToProxy;
QTreeWidgetItem *listItem;
QUndoCommand *command = new QUndoCommand();
if (doProxy) command->setText(i18np("Add proxy clip", "Add proxy clips", list.count()));
ProjectItem *item = static_cast <ProjectItem*>(listItem);
CLIPTYPE t = item->clipType();
if ((t == VIDEO || t == AV || t == UNKNOWN || t == IMAGE || t == PLAYLIST) && item->referencedClip()) {
- if ((doProxy && item->hasProxy()) || (!doProxy && !item->hasProxy())) continue;
+ if ((doProxy && item->hasProxy()) || (!doProxy && !item->hasProxy() && item->referencedClip()->getProducer() != NULL)) continue;
DocClipBase *clip = item->referencedClip();
if (!clip || !clip->isClean() || m_render->isProcessing(item->clipId())) {
kDebug()<<"//// TRYING TO PROXY: "<<item->clipId()<<", but it is busy";
// We need to insert empty proxy so that undo will work
oldProps.insert("proxy", QString());
}
+ else if (item->referencedClip()->getProducer() == NULL) {
+ // Force clip reload
+ newProps.insert("resource", item->referencedClip()->getProperty("resource"));
+ }
new EditClipCommand(this, item->clipId(), oldProps, newProps, true, command);
}
}