+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)) {
+ // discard this job
+ result << m_jobList.at(i)->description;
+ }
+ }
+ return result;
+}
+
+void ProjectList::discardJobs(const QString &id, JOBTYPE type) {
+ QMutexLocker lock(&m_jobMutex);
+ for (int i = 0; i < m_jobList.count(); i++) {
+ if (m_jobList.at(i)->clipId() == id && (m_jobList.at(i)->jobType == type || type == NOJOBTYPE)) {
+ // discard this job
+ m_jobList.at(i)->setStatus(JOBABORTED);
+ }
+ }
+}
+
+void ProjectList::slotStartFilterJob(ItemInfo info, const QString&id, const QString&filterName, const QString&filterParams, const QString&finalFilterName, const QString&consumer, const QString&consumerParams, const QStringList &extraParams)
+{
+ ProjectItem *item = getItemById(id);
+ if (!item) return;
+ QStringList jobParams;
+ jobParams << QString::number(info.cropStart.frames(m_fps)) << QString::number((info.cropStart + info.cropDuration).frames(m_fps));
+ jobParams << QString() << filterName << filterParams << consumer << consumerParams << QString::number(info.startPos.frames(m_fps)) << QString::number(info.track) << finalFilterName;
+ MeltJob *job = new MeltJob(item->clipType(), id, jobParams, extraParams);
+ if (job->isExclusive() && hasPendingJob(item, job->jobType)) {
+ delete job;
+ return;
+ }
+ job->description = i18n("Filter %1", finalFilterName);
+ m_jobList.append(job);
+ setJobStatus(item, job->jobType, JOBWAITING, 0, job->statusMessage());
+ slotCheckJobProcess();
+}
+
+void ProjectList::startClipFilterJob(const QString &filterName, const QString &condition)
+{
+ QStringList ids = getConditionalIds(condition);
+ QString destination;
+ ProjectItem *item = getItemById(ids.at(0));
+ if (!item) {
+ emit displayMessage(i18n("Cannot find clip to process filter %1", filterName), -2);
+ return;
+ }
+ if (ids.count() == 1) {
+ destination = item->clipUrl().path();
+ }
+ else {
+ destination = item->clipUrl().directory();
+ }
+ if (filterName == "motion_est") {
+ // Show config dialog
+ QPointer<QDialog> d = new QDialog(this);
+ Ui::SceneCutDialog_UI ui;
+ ui.setupUi(d);
+ // Set up categories
+ for (int i = 0; i < 5; ++i) {
+ ui.marker_type->insertItem(i, i18n("Category %1", i));
+ ui.marker_type->setItemData(i, CommentedTime::markerColor(i), Qt::DecorationRole);
+ }
+ ui.marker_type->setCurrentIndex(KdenliveSettings::default_marker_type());
+ if (d->exec() != QDialog::Accepted) {
+ delete d;
+ return;
+ }
+ // Autosplit filter
+ QStringList jobParams;
+ // 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";
+ // Consumer
+ jobParams << "null" << "all=1 terminate_on_pause=1 real_time=-1";
+ QStringList extraParams;
+ extraParams << "key:shot_change_list";
+ extraParams << "projecttreefilter";
+ if (ui.add_markers->isChecked()) {
+ // We want to create markers
+ extraParams << QString("addmarkers:%1").arg(ui.marker_type->currentIndex());
+ }
+ if (ui.cut_scenes->isChecked()) {
+ // We want to cut scenes
+ extraParams << "cutscenes";
+ }
+ delete d;
+ processClipJob(ids, QString(), false, jobParams, i18n("Auto split"), extraParams);
+ }
+ else {
+ QPointer<ClipStabilize> d = new ClipStabilize(destination, ids.count(), filterName);
+ if (d->exec() == QDialog::Accepted) {
+ QStringList extraParams;
+ extraParams << "producer_profile";
+ processClipJob(ids, d->destination(), d->autoAddClip(), d->params(), d->desc(), extraParams);
+ }
+ delete d;
+ }
+}
+
+void ProjectList::processClipJob(QStringList ids, const QString&destination, bool autoAdd, QStringList jobParams, const QString &description, QStringList extraParams)
+{
+ QStringList preParams;
+ // in and out
+ preParams << QString::number(0) << QString::number(-1);
+ // producer params
+ preParams << jobParams.takeFirst();
+ // filter name
+ preParams << jobParams.takeFirst();
+ // filter params
+ preParams << jobParams.takeFirst();
+ // consumer
+ QString consumer = jobParams.takeFirst();
+
+ foreach(const QString&id, ids) {
+ ProjectItem *item = getItemById(id);
+ if (!item) continue;
+ QStringList jobArgs;
+ jobArgs << preParams;
+ if (ids.count() == 1) {
+ jobArgs << consumer + ':' + destination;
+ }
+ else {
+ jobArgs << consumer + ':' + destination + item->clipUrl().fileName() + ".mlt";
+ }
+ jobArgs << jobParams;
+
+ MeltJob *job = new MeltJob(item->clipType(), id, jobArgs, extraParams);
+ if (autoAdd) {
+ job->setAddClipToProject(true);
+ kDebug()<<"// ADDING TRUE";
+ }
+ else kDebug()<<"// ADDING FALSE!!!";
+
+ if (job->isExclusive() && hasPendingJob(item, job->jobType)) {
+ delete job;
+ return;
+ }
+ job->description = description;
+ m_jobList.append(job);
+ setJobStatus(item, job->jobType, JOBWAITING, 0, job->statusMessage());
+ }
+ slotCheckJobProcess();
+}
+
+void ProjectList::slotPrepareJobsMenu()
+{
+ ProjectItem *item;
+ if (!m_listView->currentItem() || m_listView->currentItem()->type() == PROJECTFOLDERTYPE)
+ return;
+ if (m_listView->currentItem()->type() == PROJECTSUBCLIPTYPE)
+ item = static_cast <ProjectItem*>(m_listView->currentItem()->parent());
+ else
+ item = static_cast <ProjectItem*>(m_listView->currentItem());
+ if (item && (item->flags() & Qt::ItemIsDragEnabled)) {
+ QString id = item->clipId();
+ m_discardCurrentClipJobs->setData(id);
+ QStringList jobs = getPendingJobs(id);
+ m_discardCurrentClipJobs->setEnabled(!jobs.isEmpty());
+ } else {
+ m_discardCurrentClipJobs->setData(QString());
+ m_discardCurrentClipJobs->setEnabled(false);
+ }
+}
+
+void ProjectList::slotDiscardClipJobs()
+{
+ QString id = m_discardCurrentClipJobs->data().toString();
+ if (id.isEmpty()) return;
+ discardJobs(id);
+}
+
+void ProjectList::updatePalette()
+{
+ m_infoLabel->setStyleSheet(SmallInfoLabel::getStyleSheet(QApplication::palette()));
+ m_listView->updateStyleSheet();
+}
+
+void ProjectList::slotResetInfoMessage()
+{
+#if KDE_IS_VERSION(4,7,0)
+ m_errorLog.clear();
+ QList<QAction *> actions = m_infoMessage->actions();
+ for (int i = 0; i < actions.count(); i++) {
+ m_infoMessage->removeAction(actions.at(i));
+ }
+#endif
+}
+
+void ProjectList::slotClosePopup()
+{
+ m_errorLog.clear();
+}
+
+void ProjectList::slotGotFilterJobResults(QString id, int , int , QString filter, stringMap results, QStringList extra)
+{
+ ProjectItem *clip = getItemById(id);
+ if (!clip) return;
+ // Check for return value
+ QString returnKey;
+ int markersType = -1;
+ for (int i = 0; i < extra.count(); i++) {
+ if (extra.at(i).startsWith("key:"))
+ returnKey = extra.at(i).section(':', 1);
+ if (extra.at(i).startsWith("addmarkers:")) {
+ markersType = extra.at(i).section(':', 1).toInt();
+ }
+ }
+ if (returnKey.isEmpty()) {
+ emit displayMessage(i18n("No data returned from clip analysis"), ErrorMessage);
+ return;
+ }
+ QStringList returnData = results.value(returnKey).split(';', QString::SkipEmptyParts);
+ if (returnData.isEmpty()) {
+ emit displayMessage(i18n("No data returned from clip analysis"), ErrorMessage);
+ return;
+ }
+ emit displayMessage(i18n("Processing data analysis"), InformationMessage);
+ bool dataProcessed = false;
+ if (extra.contains("cutscenes")) {
+ // Check if we want to cut scenes from returned data
+ dataProcessed = true;
+ int cutPos = 0;
+ QUndoCommand *command = new QUndoCommand();
+ command->setText(i18n("Auto Split Clip"));
+ foreach (QString pos, returnData) {
+ if (!pos.contains("=")) continue;
+ int newPos = pos.section("=", 0, 0).toInt();
+ // Don't use scenes shorter than 1 second
+ if (newPos - cutPos < 24) continue;
+ (void) new AddClipCutCommand(this, id, cutPos, newPos, QString(), true, false, command);
+ cutPos = newPos;
+ }
+ if (command->childCount() == 0)
+ delete command;
+ else m_commandStack->push(command);
+ }
+ if (markersType >= 0) {
+ // Add markers from returned data
+ dataProcessed = true;
+ int cutPos = 0;
+ QUndoCommand *command = new QUndoCommand();
+ command->setText(i18n("Add Markers"));
+ QList <CommentedTime> markersList;
+ int index = 1;
+ foreach (QString pos, returnData) {
+ if (!pos.contains("=")) continue;
+ 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);
+ markersList << m;
+ index++;
+ cutPos = newPos;
+ }
+ emit addMarkers(id, markersList);
+ }
+ if (!dataProcessed || extra.contains("storedata")) {
+ // Store returned data as clip extra data
+
+ clip->referencedClip()->setAnalysisData(i18n("Motion vectors"), results.value(returnKey));
+ emit updateAnalysisData(clip->referencedClip());
+ }
+}
+
+