X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Frenderwidget.cpp;h=afd745ef13384bc884af2b78a2ed8907ea3a29f2;hb=d99fc865a759d1909af9031903b0b8e87be5449c;hp=72ab8d3ab0491dc2b54c2dcac9447d8068f29ef1;hpb=69d0882da5bab36886887868ed7caec816819258;p=kdenlive diff --git a/src/renderwidget.cpp b/src/renderwidget.cpp index 72ab8d3a..afd745ef 100644 --- a/src/renderwidget.cpp +++ b/src/renderwidget.cpp @@ -21,6 +21,7 @@ #include "renderwidget.h" #include "kdenlivesettings.h" #include "ui_saveprofile_ui.h" +#include "timecode.h" #include #include @@ -159,19 +160,20 @@ RenderWidget::RenderWidget(const QString &projectfolder, QWidget * parent) : QHeaderView *header = m_view.running_jobs->header(); QFontMetrics fm = fontMetrics(); - //header->resizeSection(0, fm.width("typical-name-for-a-torrent.torrent")); header->setResizeMode(0, QHeaderView::Fixed); header->resizeSection(0, 30); header->setResizeMode(1, QHeaderView::Interactive); - header->resizeSection(1, fm.width("typical-name-for-a-file.torrent")); header->setResizeMode(2, QHeaderView::Fixed); - header->resizeSection(1, width() * 2 / 3); + header->resizeSection(1, width() * 2 / 3 - 15); header->setResizeMode(2, QHeaderView::Interactive); //header->setResizeMode(1, QHeaderView::Fixed); - m_view.scripts_list->setHeaderLabels(QStringList() << i18n("Script Files")); - m_view.scripts_list->setItemDelegate(new RenderScriptDelegate(this)); + m_view.scripts_list->setHeaderLabels(QStringList() << QString() << i18n("Script Files")); + m_view.scripts_list->setItemDelegate(new RenderViewDelegate(this)); + header = m_view.scripts_list->header(); + header->setResizeMode(0, QHeaderView::Fixed); + header->resizeSection(0, 30); focusFirstVisibleItem(); } @@ -200,7 +202,7 @@ void RenderWidget::setDocumentPath(const QString path) { m_projectFolder = path; const QString fileName = m_view.out_file->url().fileName(); - m_view.out_file->setUrl(KUrl(m_projectFolder + '/' + fileName)); + m_view.out_file->setUrl(KUrl(m_projectFolder + fileName)); parseScriptFiles(); } @@ -234,11 +236,14 @@ void RenderWidget::setGuides(QDomElement guidesxml, double duration) m_view.render_guide->setEnabled(false); m_view.create_chapter->setEnabled(false); } + double fps = (double) m_profile.frame_rate_num / m_profile.frame_rate_den; for (int i = 0; i < nodes.count(); i++) { QDomElement e = nodes.item(i).toElement(); if (!e.isNull()) { - m_view.guide_start->addItem(e.attribute("comment"), e.attribute("time").toDouble()); - m_view.guide_end->addItem(e.attribute("comment"), e.attribute("time").toDouble()); + GenTime pos = GenTime(e.attribute("time").toDouble()); + const QString guidePos = Timecode::getStringTimecode(pos.frames(fps), fps); + m_view.guide_start->addItem(e.attribute("comment") + '/' + guidePos, e.attribute("time").toDouble()); + m_view.guide_end->addItem(e.attribute("comment") + '/' + guidePos, e.attribute("time").toDouble()); } } if (nodes.count() > 0) @@ -682,7 +687,7 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut, const renderArgs.append(subsize); } bool resizeProfile = (subsize != currentSize); - QStringList paramsList = renderArgs.split(" "); + QStringList paramsList = renderArgs.split(" ", QString::SkipEmptyParts); for (int i = 0; i < paramsList.count(); i++) { if (paramsList.at(i).startsWith("profile=")) { if (paramsList.at(i).section('=', 1) != m_profile.path) resizeProfile = true; @@ -693,7 +698,7 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut, const if (resizeProfile) render_process_args << "consumer:" + playlistPath; else render_process_args << playlistPath; render_process_args << dest; - render_process_args << renderArgs; + render_process_args << paramsList; QString group = m_view.size_list->currentItem()->data(MetaGroupRole).toString(); @@ -704,12 +709,6 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut, const QString scriptName; if (scriptExport) { - - /*renderParameters << scriptName; - if (group == "dvd") renderParameters << QString::number(m_view.create_chapter->isChecked()); - else renderParameters << QString::number(false); - emit doRender(renderParameters, overlayargs);*/ - // Generate script file QFile file(scriptPath); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { @@ -722,7 +721,10 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut, const outStream << "#! /bin/sh" << "\n" << "\n"; outStream << "SOURCE=" << "\"" + playlistPath + "\"" << "\n"; outStream << "TARGET=" << "\"" + dest + "\"" << "\n"; - outStream << renderer << " " << render_process_args.join(" ") << "\n" << "\n"; + outStream << "RENDERER=" << "\"" + renderer + "\"" << "\n"; + outStream << "MELT=" << "\"" + render_process_args.takeFirst() + "\"" << "\n"; + outStream << "PARAMETERS=" << "\"" + render_process_args.join(" ") + "\"" << "\n"; + outStream << "$RENDERER $MELT $PARAMETERS" << "\n" << "\n"; if (file.error() != QFile::NoError) { KMessageBox::error(this, i18n("Cannot write to file %1", scriptPath)); file.close(); @@ -762,7 +764,6 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut, const // Set rendering type if (group == "dvd") { - renderParameters << QString::number(m_view.create_chapter->isChecked()); if (m_view.open_dvd->isChecked()) { renderItem->setData(0, Qt::UserRole, group); if (renderArgs.contains("profile=")) { @@ -774,7 +775,6 @@ void RenderWidget::slotExport(bool scriptExport, int zoneIn, int zoneOut, const } } } else { - renderParameters << QString::number(false); if (group == "websites" && m_view.open_browser->isChecked()) { renderItem->setData(0, Qt::UserRole, group); // pass the url @@ -791,18 +791,31 @@ void RenderWidget::checkRenderStatus() if (m_blockProcessing) return; QTreeWidgetItem *item = m_view.running_jobs->topLevelItem(0); while (item) { - if (item->data(1, Qt::UserRole + 2).toInt() == RUNNINGJOB) break; - else if (item->data(1, Qt::UserRole + 2).toInt() == WAITINGJOB) { + if (item->data(1, Qt::UserRole + 2).toInt() == RUNNINGJOB) return; + item = m_view.running_jobs->itemBelow(item); + } + item = m_view.running_jobs->topLevelItem(0); + while (item) { + if (item->data(1, Qt::UserRole + 2).toInt() == WAITINGJOB) { item->setData(1, Qt::UserRole + 1, QTime::currentTime()); if (item->data(1, Qt::UserRole + 4).isNull()) { + // Normal render process QString renderer = QCoreApplication::applicationDirPath() + QString("/kdenlive_render"); if (!QFile::exists(renderer)) renderer = "kdenlive_render"; - QProcess::startDetached(renderer, item->data(1, Qt::UserRole + 3).toStringList()); - KNotification::event("RenderStarted", i18n("Rendering %1 started", item->text(1)), QPixmap(), this); - //emit doRender(item->data(1, Qt::UserRole + 3).toStringList(), item->data(1, Qt::UserRole + 2).toStringList()); + if (QProcess::startDetached(renderer, item->data(1, Qt::UserRole + 3).toStringList()) == false) { + item->setData(1, Qt::UserRole + 2, FINISHEDJOB); + item->setData(1, Qt::UserRole, i18n("Rendering crashed")); + item->setIcon(0, KIcon("dialog-close")); + item->setData(2, Qt::UserRole, 100); + } else KNotification::event("RenderStarted", i18n("Rendering %1 started", item->text(1)), QPixmap(), this); } else { // Script item - QProcess::startDetached(item->data(1, Qt::UserRole + 3).toString()); + if (QProcess::startDetached(item->data(1, Qt::UserRole + 3).toString()) == false) { + item->setData(1, Qt::UserRole + 2, FINISHEDJOB); + item->setData(1, Qt::UserRole, i18n("Rendering crashed")); + item->setIcon(0, KIcon("dialog-close")); + item->setData(2, Qt::UserRole, 100); + } } break; } @@ -983,7 +996,7 @@ KUrl RenderWidget::filenameWithExtension(KUrl url, QString extension) else path = path.left(pos) + extension; } else { - path = m_projectFolder + "/untitled." + extension; + path = m_projectFolder + "untitled." + extension; } return KUrl(path); } @@ -1068,8 +1081,8 @@ void RenderWidget::parseProfiles(QString meta, QString group, QString profile) // can also override profiles installed by KNewStuff fileList.removeAll("customprofiles.xml"); foreach(const QString &filename, fileList) - parseFile(exportFolder + '/' + filename, true); - if (QFile::exists(exportFolder + "/customprofiles.xml")) parseFile(exportFolder + "/customprofiles.xml", true); + parseFile(exportFolder + filename, true); + if (QFile::exists(exportFolder + "customprofiles.xml")) parseFile(exportFolder + "customprofiles.xml", true); if (!meta.isEmpty()) { m_view.destination_list->blockSignals(true); @@ -1358,6 +1371,7 @@ void RenderWidget::slotAbortCurrentJob() else { delete current; slotCheckJob(); + checkRenderStatus(); } } } @@ -1396,26 +1410,43 @@ void RenderWidget::parseScriptFiles() QTreeWidgetItem *item; // List the project scripts - QStringList scriptFiles = QDir(m_projectFolder + "/scripts").entryList(scriptsFilter, QDir::Files); + QStringList scriptFiles = QDir(m_projectFolder + "scripts").entryList(scriptsFilter, QDir::Files); for (int i = 0; i < scriptFiles.size(); ++i) { - KUrl scriptpath(m_projectFolder + "/scripts/" + scriptFiles.at(i)); - item = new QTreeWidgetItem(m_view.scripts_list, QStringList() << scriptpath.fileName()); + KUrl scriptpath(m_projectFolder + "scripts/" + scriptFiles.at(i)); QString target; + QString renderer; + QString melt; QFile file(scriptpath.path()); if (file.open(QIODevice::ReadOnly | QIODevice::Text)) { while (!file.atEnd()) { QByteArray line = file.readLine(); if (line.startsWith("TARGET=")) { - target = QString(line).section("TARGET=", 1); + target = QString(line).section("TARGET=", 1).simplified(); target.remove(QChar('"')); - break; + } else if (line.startsWith("RENDERER=")) { + renderer = QString(line).section("RENDERER=", 1).simplified(); + renderer.remove(QChar('"')); + } else if (line.startsWith("MELT=")) { + melt = QString(line).section("MELT=", 1).simplified(); + melt.remove(QChar('"')); } } file.close(); } + if (target.isEmpty()) continue; + item = new QTreeWidgetItem(m_view.scripts_list, QStringList() << QString() << scriptpath.fileName()); + if (!renderer.isEmpty() && renderer.contains('/') && !QFile::exists(renderer)) { + item->setIcon(0, KIcon("dialog-cancel")); + item->setToolTip(1, i18n("Script contains wrong command: %1", renderer)); + item->setData(0, Qt::UserRole, '1'); + } else if (!melt.isEmpty() && melt.contains('/') && !QFile::exists(melt)) { + item->setIcon(0, KIcon("dialog-cancel")); + item->setToolTip(1, i18n("Script contains wrong command: %1", melt)); + item->setData(0, Qt::UserRole, '1'); + } else item->setIcon(0, KIcon("application-x-executable-script")); item->setSizeHint(0, QSize(m_view.scripts_list->columnWidth(0), fontMetrics().height() * 2)); - item->setData(0, Qt::UserRole, target.simplified()); - item->setData(0, Qt::UserRole + 1, scriptpath.path()); + item->setData(1, Qt::UserRole, target.simplified()); + item->setData(1, Qt::UserRole + 1, scriptpath.path()); } bool activate = false; QTreeWidgetItem *script = m_view.scripts_list->topLevelItem(0); @@ -1430,19 +1461,18 @@ void RenderWidget::parseScriptFiles() void RenderWidget::slotCheckScript() { - bool activate = false; - QTreeWidgetItemIterator it(m_view.scripts_list); - if (*it) activate = true; - m_view.start_script->setEnabled(activate); - m_view.delete_script->setEnabled(activate); + QTreeWidgetItem *item = m_view.scripts_list->currentItem(); + if (item == NULL) return; + m_view.start_script->setEnabled(item->data(0, Qt::UserRole).toString().isEmpty()); + m_view.delete_script->setEnabled(true); } void RenderWidget::slotStartScript() { QTreeWidgetItem *item = m_view.scripts_list->currentItem(); if (item) { - QString destination = item->data(0, Qt::UserRole).toString(); - QString path = item->data(0, Qt::UserRole + 1).toString(); + QString destination = item->data(1, Qt::UserRole).toString(); + QString path = item->data(1, Qt::UserRole + 1).toString(); // Insert new job in queue QTreeWidgetItem *renderItem; QList existing = m_view.running_jobs->findItems(destination, Qt::MatchExactly, 1); @@ -1472,7 +1502,7 @@ void RenderWidget::slotDeleteScript() { QTreeWidgetItem *item = m_view.scripts_list->currentItem(); if (item) { - QString path = item->data(0, Qt::UserRole + 1).toString(); + QString path = item->data(1, Qt::UserRole + 1).toString(); KIO::NetAccess::del(path + ".mlt", this); KIO::NetAccess::del(path, this); parseScriptFiles(); @@ -1537,9 +1567,14 @@ bool RenderWidget::startWaitingRenderJobs() QTreeWidgetItem *item = m_view.running_jobs->topLevelItem(0); while (item) { if (item->data(1, Qt::UserRole + 2).toInt() == WAITINGJOB) { - // Add render process for item - const QString params = item->data(1, Qt::UserRole + 3).toStringList().join(" "); - outStream << renderer << " " << params << "\n"; + if (item->data(1, Qt::UserRole + 4).isNull()) { + // Add render process for item + const QString params = item->data(1, Qt::UserRole + 3).toStringList().join(" "); + outStream << renderer << " " << params << "\n"; + } else { + // Script item + outStream << item->data(1, Qt::UserRole + 3).toString() << "\n"; + } } item = m_view.running_jobs->itemBelow(item); } @@ -1548,6 +1583,7 @@ bool RenderWidget::startWaitingRenderJobs() if (file.error() != QFile::NoError) { KMessageBox::error(0, i18n("Cannot write to file %1", autoscriptFile)); file.close(); + m_blockProcessing = false; return false; } file.close(); @@ -1559,7 +1595,7 @@ bool RenderWidget::startWaitingRenderJobs() QString RenderWidget::getFreeScriptName(const QString &prefix) { int ix = 0; - QString scriptsFolder = m_projectFolder + "/scripts/"; + QString scriptsFolder = m_projectFolder + "scripts/"; KStandardDirs::makeDir(scriptsFolder); QString path; while (path.isEmpty() || QFile::exists(path)) {