X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fprojectlist.cpp;h=44e2311d17536d952bad6afb2248cdf528ce87f4;hb=020035a721ab682e4171443afaf10b5efa189586;hp=72a7acbb02efca47c40fc75d49a5c10b130e9602;hpb=a830589d50452bf5ba05da1273c57bcfa33985e9;p=kdenlive diff --git a/src/projectlist.cpp b/src/projectlist.cpp index 72a7acbb..44e2311d 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -19,7 +19,7 @@ #include "projectlist.h" #include "projectitem.h" -#include "addfoldercommand.h" +#include "commands/addfoldercommand.h" #include "kdenlivesettings.h" #include "slideshowclip.h" #include "ui_colorclip_ui.h" @@ -33,10 +33,10 @@ #include "projectlistview.h" #include "timecodedisplay.h" #include "profilesdialog.h" -#include "editclipcommand.h" -#include "editclipcutcommand.h" -#include "editfoldercommand.h" -#include "addclipcutcommand.h" +#include "commands/editclipcommand.h" +#include "commands/editclipcutcommand.h" +#include "commands/editfoldercommand.h" +#include "commands/addclipcutcommand.h" #include "ui_templateclip_ui.h" @@ -115,6 +115,7 @@ ProjectList::ProjectList(QWidget *parent) : m_transcodeAction(NULL), m_doc(NULL), m_refreshed(false), + m_allClipsProcessed(false), m_thumbnailQueue(), m_abortAllProxies(false), m_invalidClipDialog(NULL) @@ -129,10 +130,6 @@ ProjectList::ProjectList(QWidget *parent) : QHBoxLayout *box = new QHBoxLayout; KTreeWidgetSearchLine *searchView = new KTreeWidgetSearchLine; - m_refreshMonitorTimer.setSingleShot(true); - m_refreshMonitorTimer.setInterval(100); - connect(&m_refreshMonitorTimer, SIGNAL(timeout()), this, SLOT(slotRefreshMonitor())); - box->addWidget(searchView); //int s = style()->pixelMetric(QStyle::PM_SmallIconSize); //m_toolbar->setIconSize(QSize(s, s)); @@ -257,6 +254,10 @@ void ProjectList::setupGeneratorMenu(QMenu *addMenu, QMenu *transcodeMenu, QMenu m_menu->insertSeparator(m_deleteButton->defaultAction()); } +void ProjectList::clearSelection() +{ + m_listView->clearSelection(); +} QByteArray ProjectList::headerInfo() const { @@ -625,7 +626,6 @@ void ProjectList::setRenderer(Render *projectRender) void ProjectList::slotClipSelected() { - m_refreshMonitorTimer.stop(); QTreeWidgetItem *item = m_listView->currentItem(); ProjectItem *clip = NULL; if (item) { @@ -1129,7 +1129,7 @@ void ProjectList::slotGotProxy(const QString &proxyPath) QTreeWidgetItemIterator it(m_listView); ProjectItem *item; - while (*it) { + while (*it && !m_abortAllProxies) { if ((*it)->type() == PROJECTCLIPTYPE) { item = static_cast (*it); if (item->referencedClip()->getProperty("proxy") == proxyPath) @@ -1143,6 +1143,12 @@ void ProjectList::slotGotProxy(ProjectItem *item) { if (item == NULL || !m_refreshed) return; DocClipBase *clip = item->referencedClip(); + if (!clip || !clip->isClean() || m_render->isProcessing(item->clipId())) { + // Clip is being reprocessed, abort + kDebug()<<"//// TRYING TO PROXY: "<clipId()<<", but it is busy"; + return; + } + // Proxy clip successfully created QDomElement e = clip->toXML().cloneNode().toElement(); @@ -1160,14 +1166,18 @@ void ProjectList::slotGotProxy(ProjectItem *item) void ProjectList::slotResetProjectList() { + m_listView->blockSignals(true); m_abortAllProxies = true; m_proxyThreads.waitForFinished(); m_proxyThreads.clearFutures(); m_thumbnailQueue.clear(); m_listView->clear(); + m_listView->setEnabled(true); emit clipSelected(NULL); m_refreshed = false; + m_allClipsProcessed = false; m_abortAllProxies = false; + m_listView->blockSignals(false); } void ProjectList::slotUpdateClip(const QString &id) @@ -1192,13 +1202,35 @@ void ProjectList::getCachedThumbnail(ProjectItem *item) } else item->setData(0, Qt::DecorationRole, pix); } - else requestClipThumbnail(item->clipId()); + else { + requestClipThumbnail(item->clipId()); + } +} + +void ProjectList::getCachedThumbnail(SubProjectItem *item) +{ + if (!item) return; + ProjectItem *parentItem = static_cast (item->parent()); + if (!parentItem) return; + DocClipBase *clip = parentItem->referencedClip(); + if (!clip) return; + int pos = item->zone().x(); + QString cachedPixmap = m_doc->projectFolder().path(KUrl::AddTrailingSlash) + "thumbs/" + clip->getClipHash() + "#" + QString::number(pos) + ".png"; + if (QFile::exists(cachedPixmap)) { + QPixmap pix(cachedPixmap); + if (pix.isNull()) { + KIO::NetAccess::del(KUrl(cachedPixmap), this); + requestClipThumbnail(parentItem->clipId() + '#' + QString::number(pos)); + } + else item->setData(0, Qt::DecorationRole, pix); + } + else requestClipThumbnail(parentItem->clipId() + '#' + QString::number(pos)); } void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged) { + if (!m_allClipsProcessed) m_listView->setEnabled(false); m_listView->setSortingEnabled(false); - QTreeWidgetItemIterator it(m_listView); DocClipBase *clip; ProjectItem *item; @@ -1211,15 +1243,23 @@ void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged) QPainter p(&missingPixmap); p.drawPixmap(3, 3, icon.pixmap(width - 6, height - 6)); p.end(); - kDebug()<<"//////////////7 UPDATE ALL CLPS"; + + int max = m_doc->clipManager()->clipsCount(); + max = qMax(1, max); + int ct = 0; + while (*it) { + emit displayMessage(i18n("Loading thumbnails"), (int)(100 *(max - ct++) / max)); if ((*it)->type() == PROJECTSUBCLIPTYPE) { // subitem SubProjectItem *sub = static_cast (*it); - if (displayRatioChanged || sub->data(0, Qt::DecorationRole).isNull()) { + if (displayRatioChanged) { item = static_cast ((*it)->parent()); requestClipThumbnail(item->clipId() + '#' + QString::number(sub->zone().x())); } + else if (sub->data(0, Qt::DecorationRole).isNull()) { + getCachedThumbnail(sub); + } ++it; continue; } else if ((*it)->type() == PROJECTFOLDERTYPE) { @@ -1230,7 +1270,7 @@ void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged) item = static_cast (*it); clip = item->referencedClip(); if (item->referencedClip()->getProducer() == NULL) { - if (clip->isPlaceHolder() == false) { + if (clip->isPlaceHolder() == false && !item->isProxyRunning()) { QDomElement xml = clip->toXML(); if (fpsChanged) { xml.removeAttribute("out"); @@ -1281,6 +1321,7 @@ void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged) } m_listView->setSortingEnabled(true); + m_allClipsProcessed = true; if (m_render->processingItems() == 0) { monitorItemEditing(true); slotProcessNextThumbnail(); @@ -1562,6 +1603,7 @@ void ProjectList::setDocument(KdenliveDoc *doc) m_listView->setSortingEnabled(false); emit clipSelected(NULL); m_refreshed = false; + m_allClipsProcessed = false; m_fps = doc->fps(); m_timecode = doc->timecode(); m_commandStack = doc->commandStack(); @@ -1578,7 +1620,11 @@ void ProjectList::setDocument(KdenliveDoc *doc) } QList list = doc->clipManager()->documentClipList(); - if (list.isEmpty()) m_refreshed = true; + if (list.isEmpty()) { + // blank document + m_refreshed = true; + m_allClipsProcessed = true; + } for (int i = 0; i < list.count(); i++) slotAddClip(list.at(i), false); @@ -1603,7 +1649,6 @@ QDomElement ProjectList::producersList() QDomDocument doc; QDomElement prods = doc.createElement("producerlist"); doc.appendChild(prods); - kDebug() << "//////////// PRO LIST BUILD PRDSLIST "; QTreeWidgetItemIterator it(m_listView); while (*it) { if ((*it)->type() != PROJECTCLIPTYPE) { @@ -1620,10 +1665,12 @@ QDomElement ProjectList::producersList() void ProjectList::slotCheckForEmptyQueue() { if (m_render->processingItems() == 0 && m_thumbnailQueue.isEmpty()) { - if (!m_refreshed) { - emit loadingIsOver(); - emit displayMessage(QString(), -1); + if (!m_refreshed && m_allClipsProcessed) { m_refreshed = true; + m_listView->setEnabled(true); + slotClipSelected(); + QTimer::singleShot(500, this, SIGNAL(loadingIsOver())); + emit displayMessage(QString(), -1); } updateButtons(); } else if (!m_refreshed) { @@ -1720,26 +1767,13 @@ void ProjectList::slotRefreshClipThumbnail(QTreeWidgetItem *it, bool update) } } -void ProjectList::slotRefreshMonitor() -{ - if (m_listView->selectedItems().count() == 1 && m_render && m_render->processingItems() == 0) { - if (m_listView->currentItem() && m_listView->currentItem()->type() != PROJECTFOLDERTYPE) { - ProjectItem *item = static_cast (m_listView->currentItem()); - DocClipBase *clip = item->referencedClip(); - if (clip && clip->isClean() && !m_render->isProcessing(item->clipId())) emit clipSelected(clip); - } - } -} -void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Producer *producer, const stringMap &properties, const stringMap &metadata, bool replace, bool refreshThumbnail) +void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Producer *producer, const stringMap &properties, const stringMap &metadata, bool replace) { QString toReload; ProjectItem *item = getItemById(clipId); int queue = m_render->processingItems(); - if (queue == 0) { - m_listView->setEnabled(true); - } if (item && producer) { monitorItemEditing(false); DocClipBase *clip = item->referencedClip(); @@ -1753,7 +1787,7 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce item->setProperties(properties, metadata); clip->setProducer(producer, replace); clip->askForAudioThumbs(); - if (refreshThumbnail) getCachedThumbnail(item); + // Proxy stuff QString size = properties.value("frame_size"); if (!useProxy() && clip->getProperty("proxy").isEmpty()) setProxyStatus(item, NOPROXY); @@ -1781,8 +1815,8 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce } } - if (!replace && item->data(0, Qt::DecorationRole).isNull() && !refreshThumbnail) { - requestClipThumbnail(clipId); + if (!replace && m_allClipsProcessed && item->data(0, Qt::DecorationRole).isNull()) { + getCachedThumbnail(item); } if (!toReload.isEmpty()) item->slotSetToolTip(); @@ -1804,20 +1838,16 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce } } else { int max = m_doc->clipManager()->clipsCount(); - emit displayMessage(i18n("Loading clips"), (int)(100 *(max - queue) / max)); + if (max > 0) emit displayMessage(i18n("Loading clips"), (int)(100 *(max - queue) / max)); } - processNextThumbnail(); - } - if (replace && item) { - toReload = clipId; - // update clip in clip monitor - /*if (queue == 0 && item->isSelected() && m_listView->selectedItems().count() == 1) - m_refreshMonitorTimer.start();*/ + if (m_allClipsProcessed) emit processNextThumbnail(); } if (!item) { // no item for producer, delete it delete producer; + return; } + if (replace) toReload = clipId; if (!toReload.isEmpty()) emit clipNeedsReload(toReload); } @@ -2308,6 +2338,19 @@ void ProjectList::slotGenerateProxy() QFile::remove(info.dest); setProxyStatus(info.dest, CREATINGPROXY); + + // Get the list of clips that will need to get progress info + QTreeWidgetItemIterator it(m_listView); + QList processingItems; + while (*it && !m_abortAllProxies) { + if ((*it)->type() == PROJECTCLIPTYPE) { + ProjectItem *item = static_cast (*it); + if (item->referencedClip()->getProperty("proxy") == info.dest) { + processingItems.append(item); + } + } + ++it; + } // Special case: playlist clips (.mlt or .kdenlive project files) if (info.type == PLAYLIST) { @@ -2352,7 +2395,7 @@ void ProjectList::slotGenerateProxy() } else { QString log = QString(myProcess.readAll()); - processLogInfo(info.dest, &duration, log); + processLogInfo(processingItems, &duration, log); } myProcess.waitForFinished(500); } @@ -2368,8 +2411,8 @@ void ProjectList::slotGenerateProxy() // Proxy process crashed QFile::remove(info.dest); setProxyStatus(info.dest, PROXYCRASHED); - } - + } + return; } if (info.type == IMAGE) { @@ -2435,13 +2478,13 @@ void ProjectList::slotGenerateProxy() // Make sure we don't block when proxy file already exists parameters << "-y"; parameters << info.dest; - kDebug()<<"// STARTING PROXY GEN: "<items, int *duration, const QString &log) { int progress; if (*duration == 0) { @@ -2494,7 +2537,8 @@ void ProjectList::processLogInfo(const QString &path, int *duration, const QStri progress = numbers.at(0).toInt() * 3600 + numbers.at(1).toInt() * 60 + numbers.at(2).toDouble(); } else progress = (int) time.toDouble(); - setProxyStatus(path, CREATINGPROXY, (int) (100.0 * progress / (*duration))); + for (int i = 0; i < items.count(); i++) + setProxyStatus(items.at(i), CREATINGPROXY, (int) (100.0 * progress / (*duration))); } } @@ -2602,7 +2646,11 @@ void ProjectList::slotProxyCurrentItem(bool doProxy) if ((t == VIDEO || t == AV || t == UNKNOWN || t == IMAGE || t == PLAYLIST) && item->referencedClip()) { if ((doProxy && item->hasProxy()) || (!doProxy && !item->hasProxy())) continue; DocClipBase *clip = item->referencedClip(); - if (!clip->isClean() || m_render->isProcessing(item->clipId())) continue; + if (!clip || !clip->isClean() || m_render->isProcessing(item->clipId())) { + kDebug()<<"//// TRYING TO PROXY: "<clipId()<<", but it is busy"; + continue; + } + resetThumbsProducer(clip); oldProps = clip->properties(); if (doProxy) { @@ -2656,7 +2704,7 @@ void ProjectList::setProxyStatus(const QString proxyPath, PROXYSTATUS status, in if (proxyPath.isEmpty() || m_abortAllProxies) return; QTreeWidgetItemIterator it(m_listView); ProjectItem *item; - while (*it) { + while (*it && !m_abortAllProxies) { if ((*it)->type() == PROJECTCLIPTYPE) { item = static_cast (*it); if (item->referencedClip()->getProperty("proxy") == proxyPath) {