X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fprojectlist.cpp;h=d36e6ef7182e87a40fb0ab4923edf4510a7b92b2;hb=55ab81618b3e7e332109350167dcc3d094658336;hp=3cb9cad7bf7e33c779d9775286fca617fd6029a1;hpb=cdf2b2a097309ddfa428cc6b0650b907fbfe3dde;p=kdenlive diff --git a/src/projectlist.cpp b/src/projectlist.cpp index 3cb9cad7..d36e6ef7 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -587,7 +587,7 @@ void ProjectList::editClipSelection(QList list) kDebug() << "Result: " << p.key() << " = " << p.value(); }*/ if (clipList.isEmpty()) { - emit displayMessage(i18n("No available clip selected"), -2); + emit displayMessage(i18n("No available clip selected"), -2, ErrorMessage); } else emit showClipProperties(clipList, commonproperties); } @@ -739,7 +739,7 @@ void ProjectList::slotModifiedClip(const QString &id) } else { pixmap = KIcon("view-refresh").pixmap(m_listView->iconSize()); } - item->setData(0, Qt::DecorationRole, pixmap); + item->setPixmap(pixmap); } } @@ -763,7 +763,7 @@ void ProjectList::slotMissingClip(const QString &id) QPainter p(&pixmap); p.drawPixmap(3, 3, icon.pixmap(width - 6, height - 6)); p.end(); - item->setData(0, Qt::DecorationRole, pixmap); + item->setPixmap(pixmap); if (item->referencedClip()) { item->referencedClip()->setPlaceHolder(true); Mlt::Producer *newProd = m_render->invalidProducer(id); @@ -778,7 +778,7 @@ void ProjectList::slotMissingClip(const QString &id) } } update(); - emit displayMessage(i18n("Check missing clips"), -2); + emit displayMessage(i18n("Check missing clips"), -2, ErrorMessage); emit updateRenderStatus(); } @@ -948,7 +948,7 @@ void ProjectList::slotUpdateClipProperties(const QString &id, QMap setEnabled(false); const QString parent = clip->getProperty("groupid"); QString groupName = clip->getProperty("groupname"); + QSize pixelSize((int)(m_listView->iconSize().height() * m_render->dar()), m_listView->iconSize().height()); ProjectItem *item = NULL; monitorItemEditing(false); if (!parent.isEmpty()) { @@ -1307,19 +1308,16 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties) } if (parentitem) - item = new ProjectItem(parentitem, clip); + item = new ProjectItem(parentitem, clip, pixelSize); } if (item == NULL) { - item = new ProjectItem(m_listView, clip); + item = new ProjectItem(m_listView, clip, pixelSize); } if (item->data(0, DurationRole).isNull()) item->setData(0, DurationRole, i18n("Loading")); connect(clip, SIGNAL(createProxy(const QString &)), this, SLOT(slotCreateProxy(const QString &))); connect(clip, SIGNAL(abortProxy(const QString &, const QString &)), this, SLOT(slotAbortProxy(const QString, const QString))); + if (getProperties) { - int height = m_listView->iconSize().height(); - int width = (int)(height * m_render->dar()); - QPixmap pix = KIcon("video-x-generic").pixmap(QSize(width, height)); - item->setData(0, Qt::DecorationRole, pix); //item->setFlags(Qt::ItemIsSelectable); m_listView->processLayout(); QDomElement e = clip->toXML().cloneNode().toElement(); @@ -1468,8 +1466,9 @@ void ProjectList::getCachedThumbnail(ProjectItem *item) requestClipThumbnail(item->clipId()); } else { - processThumbOverlays(item, pix); - item->setData(0, Qt::DecorationRole, pix); + QPixmap result = roundedPixmap(pix); + processThumbOverlays(item, result); + item->setPixmap(result); } } else { @@ -1477,6 +1476,34 @@ void ProjectList::getCachedThumbnail(ProjectItem *item) } } +QPixmap ProjectList::roundedPixmap(QImage img) +{ + QPixmap pix(img.width(), img.height()); + pix.fill(Qt::transparent); + QPainter p(&pix); + p.setRenderHint(QPainter::Antialiasing, true); + QPainterPath path; + path.addRoundedRect(0.5, 0.5, pix.width() - 1, pix.height() - 1, 2, 2); + p.setClipPath(path); + p.drawImage(0, 0, img); + p.end(); + return pix; +} + +QPixmap ProjectList::roundedPixmap(QPixmap source) +{ + QPixmap pix(source.width(), source.height()); + pix.fill(Qt::transparent); + QPainter p(&pix); + p.setRenderHint(QPainter::Antialiasing, true); + QPainterPath path; + path.addRoundedRect(0.5, 0.5, pix.width() - 1, pix.height() - 1, 2, 2); + p.setClipPath(path); + p.drawPixmap(0, 0, source); + p.end(); + return pix; +} + void ProjectList::getCachedThumbnail(SubProjectItem *item) { if (!item) return; @@ -1564,22 +1591,22 @@ void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged, QStr } else if (clip->isPlaceHolder()) { item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled); - if (item->data(0, Qt::DecorationRole).isNull()) { - item->setData(0, Qt::DecorationRole, missingPixmap); + if (!item->hasPixmap()) { + item->setPixmap(missingPixmap); } else { QPixmap pixmap = qVariantValue(item->data(0, Qt::DecorationRole)); QPainter p(&pixmap); p.drawPixmap(3, 3, KIcon("dialog-close").pixmap(pixmap.width() - 6, pixmap.height() - 6)); p.end(); - item->setData(0, Qt::DecorationRole, pixmap); + item->setPixmap(pixmap); } } } else { if (displayRatioChanged) { requestClipThumbnail(clip->getId()); } - else if (item->data(0, Qt::DecorationRole).isNull()) { + else if (!item->hasPixmap()) { getCachedThumbnail(item); } if (item->data(0, DurationRole).toString().isEmpty()) { @@ -1594,7 +1621,7 @@ void ProjectList::updateAllClips(bool displayRatioChanged, bool fpsChanged, QStr QPainter p(&pixmap); p.drawPixmap(3, 3, KIcon("dialog-close").pixmap(pixmap.width() - 6, pixmap.height() - 6)); p.end(); - item->setData(0, Qt::DecorationRole, pixmap); + item->setPixmap(pixmap); } else if (clip->getProperty("_replaceproxy") == "1") { clip->setProperty("_replaceproxy", QString()); @@ -1817,7 +1844,7 @@ void ProjectList::slotRemoveInvalidProxy(const QString &id, bool durationError) item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsDragEnabled | Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsDropEnabled); if (durationError) { kDebug() << "Proxy duration is wrong, try changing transcoding parameters."; - emit displayMessage(i18n("Proxy clip unusable (duration is different from original)."), -2); + emit displayMessage(i18n("Proxy clip unusable (duration is different from original)."), -2, ErrorMessage); } slotUpdateJobStatus(item, PROXYJOB, JOBCRASHED, i18n("Failed to create proxy for %1. check parameters", item->text(0)), "project_settings"); QString path = item->referencedClip()->getProperty("proxy"); @@ -2012,8 +2039,11 @@ void ProjectList::slotSetThumbnail(const QString &id, int framePos, QImage img) if (item && item->parent()) pItem = static_cast (item->parent()); if (!item && framePos == 0) pItem = getItemById(id); if (!item && !pItem) return; - if (item) item->setData(0, Qt::DecorationRole, QPixmap::fromImage(img)); - else if (pItem) pItem->setData(0, Qt::DecorationRole, QPixmap::fromImage(img)); + if (item) { + if (item->type() == PROJECTCLIPTYPE) static_cast(item)->setPixmap(QPixmap::fromImage(img)); + else item->setData(0, Qt::DecorationRole, QPixmap::fromImage(img)); + } + else if (pItem) pItem->setPixmap(QPixmap::fromImage(img)); if (pItem) { QString hash = pItem->getClipHash(); if (!hash.isEmpty()) m_doc->cacheImage(hash + '#' + QString::number(framePos), img); @@ -2123,26 +2153,22 @@ void ProjectList::slotRefreshClipThumbnail(QTreeWidgetItem *it, bool update) slotProcessNextThumbnail(); return; } - QPixmap pix; QImage img; int height = m_listView->iconSize().height(); int swidth = (int)(height * m_render->frameRenderWidth() / m_render->renderHeight()+ 0.5); int dwidth = (int)(height * m_render->dar() + 0.5); - if (clip->clipType() == AUDIO) - pix = KIcon("audio-x-generic").pixmap(QSize(dwidth, height)); - else if (clip->clipType() == IMAGE) { + if (clip->clipType() == IMAGE) { img = KThumb::getFrame(item->referencedClip()->getProducer(), 0, swidth, dwidth, height); } - else { + else if (clip->clipType() != AUDIO) { img = item->referencedClip()->extractImage(frame, dwidth, height); } - if (!pix.isNull() || !img.isNull()) { + if (!img.isNull()) { monitorItemEditing(false); - if (!img.isNull()) { - pix = QPixmap::fromImage(img); - processThumbOverlays(item, pix); - } - it->setData(0, Qt::DecorationRole, pix); + QPixmap pix = roundedPixmap(img); + processThumbOverlays(item, pix); + if (isSubItem) it->setData(0, Qt::DecorationRole, pix); + else item->setPixmap(pix); monitorItemEditing(true); QString hash = item->getClipHash(); @@ -2211,7 +2237,7 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce } } - if (!replace && m_allClipsProcessed && item->data(0, Qt::DecorationRole).isNull()) { + if (!replace && m_allClipsProcessed && !item->hasPixmap()) { getCachedThumbnail(item); } if (!toReload.isEmpty()) @@ -2334,18 +2360,10 @@ void ProjectList::slotReplyGetImage(const QString &clipId, const QImage &img) { ProjectItem *item = getItemById(clipId); if (item && !img.isNull()) { - QPixmap pix(img.width(), img.height()); - pix.fill(Qt::transparent); - QPainter p(&pix); - p.setRenderHint(QPainter::Antialiasing, true); - QPainterPath path; - path.addRoundedRect(0.5, 0.5, pix.width() - 1, pix.height() - 1, 2, 2); - p.setClipPath(path); - p.drawImage(0, 0, img); - p.end(); + QPixmap pix = roundedPixmap(img); processThumbOverlays(item, pix); monitorItemEditing(false); - item->setData(0, Qt::DecorationRole, pix); + item->setPixmap(pix); monitorItemEditing(true); QString hash = item->getClipHash(); if (!hash.isEmpty()) m_doc->cacheImage(hash, img); @@ -2707,7 +2725,7 @@ void ProjectList::slotAddOrUpdateSequence(const QString frameName) m_doc->slotCreateSlideshowClipFile(properties, groupInfo.at(0), groupInfo.at(1)); } - } else emit displayMessage(i18n("Sequence not found"), -2); + } else emit displayMessage(i18n("Sequence not found"), -2, ErrorMessage); } QMap ProjectList::getProxies() @@ -2928,12 +2946,12 @@ void ProjectList::slotCheckJobProcess() int count = 0; m_jobMutex.lock(); for (int i = 0; i < m_jobList.count(); i++) { - if (m_jobList.at(i)->jobStatus == JOBWORKING || m_jobList.at(i)->jobStatus == JOBWAITING) + if (m_jobList.at(i)->status() == JOBWORKING || m_jobList.at(i)->status() == JOBWAITING) count ++; else { // remove finished jobs AbstractClipJob *job = m_jobList.takeAt(i); - delete job; + job->deleteLater(); i--; } } @@ -2963,14 +2981,14 @@ void ProjectList::slotProcessJobs() int count = 0; m_jobMutex.lock(); for (int i = 0; i < m_jobList.count(); i++) { - if (m_jobList.at(i)->jobStatus == JOBWAITING) { + if (m_jobList.at(i)->status() == JOBWAITING) { if (job == NULL) { - m_jobList.at(i)->jobStatus = JOBWORKING; + m_jobList.at(i)->setStatus(JOBWORKING); job = m_jobList.at(i); } count++; } - else if (m_jobList.at(i)->jobStatus == JOBWORKING) + else if (m_jobList.at(i)->status() == JOBWORKING) count ++; } // Set jobs count @@ -3014,15 +3032,15 @@ void ProjectList::slotProcessJobs() connect(job, SIGNAL(gotFilterJobResults(QString,int, int, stringMap,stringMap)), this, SIGNAL(gotFilterJobResults(QString,int, int,stringMap,stringMap))); } job->startJob(); - if (job->jobStatus == JOBDONE) { + if (job->status() == JOBDONE) { emit updateJobStatus(job->clipId(), job->jobType, JOBDONE); //TODO: replace with more generic clip replacement framework if (job->jobType == PROXYJOB) emit gotProxy(job->clipId()); if (job->addClipToProject()) { emit addClip(destination, QString(), QString()); } - } else if (job->jobStatus == JOBCRASHED || job->jobStatus == JOBABORTED) { - emit updateJobStatus(job->clipId(), job->jobType, job->jobStatus, job->errorMessage(), QString(), job->logDetails()); + } else if (job->status() == JOBCRASHED || job->status() == JOBABORTED) { + emit updateJobStatus(job->clipId(), job->jobType, job->status(), job->errorMessage(), QString(), job->logDetails()); } } // Thread finished, cleanup & update count @@ -3326,7 +3344,7 @@ bool ProjectList::hasPendingJob(ProjectItem *item, JOBTYPE type) for (int i = 0; i < m_jobList.count(); i++) { if (m_abortAllJobs) break; job = m_jobList.at(i); - if (job->clipId() == item->clipId() && job->jobType == type && (job->jobStatus == JOBWAITING || job->jobStatus == JOBWORKING)) return true; + if (job->clipId() == item->clipId() && job->jobType == type && (job->status() == JOBWAITING || job->status() == JOBWORKING)) return true; } return false; @@ -3418,7 +3436,7 @@ QStringList ProjectList::getPendingJobs(const QString &id) QStringList result; QMutexLocker lock(&m_jobMutex); for (int i = 0; i < m_jobList.count(); i++) { - if (m_jobList.at(i)->clipId() == id && (m_jobList.at(i)->jobStatus == JOBWAITING || m_jobList.at(i)->jobStatus == JOBWORKING)) { + if (m_jobList.at(i)->clipId() == id && (m_jobList.at(i)->status() == JOBWAITING || m_jobList.at(i)->status() == JOBWORKING)) { // discard this job result << m_jobList.at(i)->description; } @@ -3460,7 +3478,7 @@ void ProjectList::startClipFilterJob(const QString &filterName, const QString &c QString destination; ProjectItem *item = getItemById(ids.at(0)); if (!item) { - emit displayMessage(i18n("Cannot find clip to process filter %1", filterName), -2); + emit displayMessage(i18n("Cannot find clip to process filter %1", filterName), -2, ErrorMessage); return; } if (ids.count() == 1) { @@ -3489,12 +3507,24 @@ void ProjectList::startClipFilterJob(const QString &filterName, const QString &c // Producer params jobParams << QString(); // Filter params, use a smaller region of the image to speed up operation - jobParams << filterName << "bounding=\"25%x25%:25%x25\" shot_change_list=0"; + // In fact, it's faster to rescale whole image than using part of it (bounding=\"25%x25%:15%x15\") + jobParams << filterName << "shot_change_list=0 denoise=0"; // Consumer - jobParams << "null" << "all=1 terminate_on_pause=1 real_time=-1"; + jobParams << "null" << "all=1 terminate_on_pause=1 real_time=-1 rescale=nearest deinterlace_method=onefield top_field_first=-1"; QMap extraParams; extraParams.insert("key", "shot_change_list"); extraParams.insert("projecttreefilter", "1"); + QString keyword("%count"); + extraParams.insert("resultmessage", i18n("Found %1 scenes.", keyword)); + extraParams.insert("resize_profile", "160"); + if (ui.store_data->isChecked()) { + // We want to save result as clip metadata + extraParams.insert("storedata", "1"); + } + if (ui.zone_only->isChecked()) { + // We want to analyze only clip zone + extraParams.insert("zoneonly", "1"); + } if (ui.add_markers->isChecked()) { // We want to create markers extraParams.insert("addmarkers", QString::number(ui.marker_type->currentIndex())); @@ -3535,6 +3565,13 @@ void ProjectList::processClipJob(QStringList ids, const QString&destination, boo ProjectItem *item = getItemById(id); if (!item) continue; QStringList jobArgs; + if (extraParams.contains("zoneonly")) { + // Analyse clip zone only, remove in / out and replace with zone + preParams.takeFirst(); + preParams.takeFirst(); + QPoint zone = item->referencedClip()->zone(); + jobArgs << QString::number(zone.x()) << QString::number(zone.y()); + } jobArgs << preParams; if (ids.count() == 1) { jobArgs << consumer + ':' + destination; @@ -3614,21 +3651,27 @@ void ProjectList::slotClosePopup() void ProjectList::slotGotFilterJobResults(QString id, int , int , stringMap results, stringMap filterInfo) { // Currently, only the first value of results is used - kDebug()<<"// FILTER RES:\n"<childCount() == 0) @@ -3660,7 +3703,7 @@ void ProjectList::slotGotFilterJobResults(QString id, int , int , stringMap resu int newPos = pos.section("=", 0, 0).toInt(); // Don't use scenes shorter than 1 second if (newPos - cutPos < 24) continue; - CommentedTime m(GenTime(newPos, m_fps), QString::number(index), markersType); + CommentedTime m(GenTime(newPos + offset, m_fps), QString::number(index), markersType); markersList << m; index++; cutPos = newPos; @@ -3669,7 +3712,7 @@ void ProjectList::slotGotFilterJobResults(QString id, int , int , stringMap resu } if (!dataProcessed || filterInfo.contains("storedata")) { // Store returned data as clip extra data - clip->referencedClip()->setAnalysisData(filterInfo.contains("displaydataname") ? filterInfo.value("displaydataname") : key, results.value(key)); + clip->referencedClip()->setAnalysisData(filterInfo.contains("displaydataname") ? filterInfo.value("displaydataname") : key, results.value(key), filterInfo.value("offset").toInt()); emit updateAnalysisData(clip->referencedClip()); } }