Updated the rendering dialog:

* add option to disable audio
* Re-organise categories
* Improved info in the "Running jobs" widget, including crash log

svn path=/branches/KDE4/; revision=2927
parent 579e6e7c
......@@ -42,9 +42,10 @@
</group>
<group name="DVD" renderer="avformat" type="av">
<groupname id="dvd">DVD</groupname>
<profile name="PAL 4:3 vob" standard="PAL" extension="vob" args="f=dvd vcodec=mpeg2video acodec=ac3 b=5000k maxrate=8000k minrate=0 bufsize=1835008 mux_packet_s=2048 mux_rate=10080000 ab=192k ar=48000 s=720x576 g=15 me_range=63 trellis=1 profile=dv_pal" />
<profile name="PAL 16:9 vob" standard="PAL" extension="vob" args="f=dvd vcodec=mpeg2video acodec=ac3 b=5000k maxrate=8000k minrate=0 bufsize=1835008 mux_packet_s=2048 mux_rate=10080000 ab=192k ar=48000 s=720x576 g=15 me_range=63 trellis=1 profile=dv_pal_wide" />
<profile name="PAL 16:9 vob" standard="PAL" extension="vob" args="f=dvd vcodec=mpeg2video acodec=ac3 b=5000k maxrate=8000k minrate=0 bufsize=1835008 mux_packet_s=2048 mux_rate=10080000 ab=192k ar=48000 s=720x576 g=15 me_range=63 trellis=1 profile=dv_pal_wide" />
<profile name="NTSC 4:3 vob" standard="NTSC" extension="vob" args="f=dvd vcodec=mpeg2video acodec=ac3 s=720x480 b=6000k maxrate=9000k minrate=0 bufsize=1835008 mux_packet_s=2048 mux_rate=10080000 ab=192k ar=48000 g=18 me_range=63 trellis=1 profile=dv_ntsc" />
<profile name="NTSC 16:9 vob" standard="NTSC" extension="vob" args="f=dvd vcodec=mpeg2video acodec=ac3 s=720x480 b=6000k maxrate=9000k minrate=0 bufsize=1835008 mux_packet_s=2048 mux_rate=10080000 ab=192k ar=48000 g=18 me_range=63 trellis=1 profile=dv_ntsc_wide" />
</group>
......@@ -160,6 +161,7 @@
</group>
<group name="Media players" renderer="avformat" type="av">
<groupname id="mediaplayers">Media players</groupname>
<profile name="Windows Media Player wmv7 400k" extension="avi" args="acodec=libmp3lame ab=128k ar=48000 ac=2 vcodec=wmv1 minrate=0 b=400k s=%widthx%height aspect=%dar" />
<profile name="Windows Media Player wmv7 1000k" extension="avi" args="acodec=libmp3lame ab=128k ar=48000 ac=2 vcodec=wmv1 minrate=0 b=1000k s=%widthx%height aspect=%dar" />
<profile name="Windows Media Player wmv7 2000k" extension="avi" args="acodec=libmp3lame ab=128k ar=48000 ac=2 vcodec=wmv1 minrate=0 b=2000k s=%widthx%height aspect=%dar" />
......@@ -169,6 +171,7 @@
</group>
<group name="Web sites" renderer="avformat" type="av">
<groupname id="websites">Web sites</groupname>
<profile name="Dailymotion 320x240" extension="flv" args="f=flv acodec=libmp3lame ab=128k ar=44100 vcodec=flv minrate=0 b=800k s=320x240 aspect=%dar trellis=1" />
<profile name="Dailymotion 512x384" extension="mp4" args="f=mp4 acodec=libfaac ab=96k ar=44100 vcodec=libx264 minrate=0 b=600k s=512x384 aspect=%dar mbd=2 trellis=1 mv4=1" />
<profile name="Dailymotion 1280x720" extension="mp4" args="f=mp4 acodec=libfaac ab=96k ar=44100 vcodec=libx264 minrate=0 b=1500k s=1280x720 aspect=%dar mbd=2 trellis=1 mv4=1" />
......@@ -181,13 +184,15 @@
<group name="Wav" renderer="avformat" type="audio">
<profile name="22050" extension="wav" args="f=wav ar=22050" />
<profile name="32000" extension="wav" args="f=wav ar=32000" />
<profile name="44100" extension="wav" args="f=wav ar=44100" />
<profile name="48000" extension="wav" args="f=wav ar=48000" />
<groupname id="audioonly">Audio only</groupname>
<profile name="wav 22050" extension="wav" args="f=wav ar=22050" />
<profile name="wav 32000" extension="wav" args="f=wav ar=32000" />
<profile name="wav 44100" extension="wav" args="f=wav ar=44100" />
<profile name="wav 48000" extension="wav" args="f=wav ar=48000" />
</group>
<group name="Lossless/HQ" renderer="avformat" type="av">
<groupname id="lossless">Lossless / HQ</groupname>
<profile name="ffv1 lossless (video) + flac (sound)" extension="mp4" args="f=mp4 acodec=flac acodec=flac ar=48000 ab=1024k ac=2 vcodec=ffv1 qscale=1 s=%widthx%height aspect=%dar" />
<profile name="huffyuv lossless (video) + pcm_s16le (sound)" extension="avi" args="f=avi acodec=pcm_s16le ac=2 vcodec=huffyuv s=%widthx%height aspect=%dar" />
<profile name="MPEG-2 I-frame only (video) + mp2 (sound)" extension="mpg" args="f=mpeg acodec=mp2 ab=384k ar=48000 ac=2 vcodec=mpeg2video qscale=1 qmin=1 s=%widthx%height aspect=%dar intra=1" />
......
......@@ -90,7 +90,8 @@ void RenderJob::slotAbort() {
if (m_kdenliveinterface) {
m_dbusargs[1] = -3;
m_kdenliveinterface->callWithArgumentList(QDBus::NoBlock, "setRenderingProgress", m_dbusargs);
m_dbusargs.append(QString());
m_kdenliveinterface->callWithArgumentList(QDBus::NoBlock, "setRenderingFinished", m_dbusargs);
}
if (m_jobUiserver) m_jobUiserver->call("terminate", QString());
if (m_erase) {
......@@ -107,6 +108,7 @@ void RenderJob::slotAbort() {
void RenderJob::receivedStderr() {
QString result = QString(m_renderProcess->readAllStandardError()).simplified();
if (!result.startsWith("Current Frame")) m_errorMessage.append(result + "<br>");
m_logstream << "ReceivedStderr from inigo: " << result << endl;
result = result.section(" ", -1);
int pro = result.toInt();
......@@ -203,8 +205,9 @@ void RenderJob::slotIsOver(int exitcode, QProcess::ExitStatus status) {
if (status == QProcess::CrashExit) {
// rendering crashed
if (m_kdenliveinterface) {
m_dbusargs[1] = -2;
m_kdenliveinterface->callWithArgumentList(QDBus::NoBlock, "setRenderingProgress", m_dbusargs);
m_dbusargs[1] = (int) - 2;
m_dbusargs.append(m_errorMessage);
m_kdenliveinterface->callWithArgumentList(QDBus::NoBlock, "setRenderingFinished", m_dbusargs);
}
QStringList args;
args << "--error" << tr("Rendering of %1 aborted, resulting video will probably be corrupted.").arg(m_dest);
......@@ -213,8 +216,9 @@ void RenderJob::slotIsOver(int exitcode, QProcess::ExitStatus status) {
QProcess::startDetached("kdialog", args);
} else {
if (m_kdenliveinterface) {
m_dbusargs[1] = -1;
m_kdenliveinterface->callWithArgumentList(QDBus::NoBlock, "setRenderingProgress", m_dbusargs);
m_dbusargs[1] = (int) - 1;
m_dbusargs.append(QString());
m_kdenliveinterface->callWithArgumentList(QDBus::NoBlock, "setRenderingFinished", m_dbusargs);
}
QDBusConnectionInterface* interface = QDBusConnection::sessionBus().interface();
if (interface && interface->isServiceRegistered("org.kde.knotify")) {
......
......@@ -47,6 +47,7 @@ private:
QString m_dest;
int m_progress;
QProcess *m_renderProcess;
QString m_errorMessage;
QString m_prog;
QString m_player;
QStringList m_args;
......
......@@ -417,11 +417,6 @@
<default>false</default>
</entry>
<entry name="experimentalrender" type="Bool">
<label>Show buggy rendering formats.</label>
<default>false</default>
</entry>
<entry name="audiocodecs" type="StringList">
<label>Available avformat audio codecs.</label>
<default></default>
......
......@@ -1443,6 +1443,7 @@ void MainWindow::slotDoRender(const QString &dest, const QString &render, const
}
if (!QFile::exists(KdenliveSettings::rendererpath())) {
KMessageBox::sorry(this, i18n("Cannot find the inigo program required for rendering (part of Mlt)"));
setRenderingProgress(dest, -3);
return;
}
args << KdenliveSettings::rendererpath() << m_activeDocument->profilePath() << render << videoPlayer;
......@@ -1471,6 +1472,10 @@ void MainWindow::setRenderingProgress(const QString &url, int progress) {
if (m_renderWidget) m_renderWidget->setRenderJob(url, progress);
}
void MainWindow::setRenderingFinished(const QString &url, int status, const QString &error) {
if (m_renderWidget) m_renderWidget->setRenderStatus(url, status, error);
}
void MainWindow::slotUpdateMousePosition(int pos) {
if (m_activeDocument)
switch (m_timecodeFormat->currentIndex()) {
......
......@@ -197,6 +197,7 @@ public slots:
void openFile(const KUrl &url);
void slotGotProgressInfo(const QString &message, int progress);
Q_SCRIPTABLE void setRenderingProgress(const QString &url, int progress);
Q_SCRIPTABLE void setRenderingFinished(const QString &url, int status, const QString &error);
private slots:
void newFile(bool showProjectSettings = true);
......
......@@ -8,5 +8,10 @@
<arg name="url" type="s" direction="in"/>
<arg name="progress" type="i" direction="in"/>
</method>
<method name="setRenderingFinished">
<arg name="url" type="s" direction="in"/>
<arg name="status" type="i" direction="in"/>
<arg name="error" type="s" direction="in"/>
</method>
</interface>
</node>
......@@ -38,6 +38,7 @@ const int StandardRole = GroupRole + 2;
const int RenderRole = GroupRole + 3;
const int ParamsRole = GroupRole + 4;
const int EditableRole = GroupRole + 5;
const int MetaGroupRole = GroupRole + 6;
RenderWidget::RenderWidget(QWidget * parent): QDialog(parent) {
m_view.setupUi(this);
......@@ -59,9 +60,7 @@ RenderWidget::RenderWidget(QWidget * parent): QDialog(parent) {
m_view.buttonInfo->setDown(true);
} else m_view.advanced_params->hide();
m_view.experimentalrender->setChecked(KdenliveSettings::experimentalrender());
m_view.experimentalrender->setToolTip(i18n("Changing the size of video when rendering\nis not fully supported, you may have problems\nwith some effects or title clips, so the export\nprofiles that resize your video are marked as\nexperimental"));
parseProfiles();
connect(m_view.buttonInfo, SIGNAL(clicked()), this, SLOT(showInfoPanel()));
......@@ -72,6 +71,8 @@ RenderWidget::RenderWidget(QWidget * parent): QDialog(parent) {
connect(m_view.abort_job, SIGNAL(clicked()), this, SLOT(slotAbortCurrentJob()));
connect(m_view.buttonClose, SIGNAL(clicked()), this, SLOT(hide()));
connect(m_view.buttonClose2, SIGNAL(clicked()), this, SLOT(hide()));
connect(m_view.rescale, SIGNAL(toggled(bool)), m_view.rescale_size, SLOT(setEnabled(bool)));
connect(m_view.destination_list, SIGNAL(activated(int)), this, SLOT(refreshView()));
connect(m_view.out_file, SIGNAL(textChanged(const QString &)), this, SLOT(slotUpdateButtons()));
connect(m_view.format_list, SIGNAL(currentRowChanged(int)), this, SLOT(refreshView()));
connect(m_view.size_list, SIGNAL(currentRowChanged(int)), this, SLOT(refreshParams()));
......@@ -84,11 +85,14 @@ RenderWidget::RenderWidget(QWidget * parent): QDialog(parent) {
connect(m_view.guide_start, SIGNAL(activated(int)), this, SLOT(slotCheckEndGuidePosition()));
connect(m_view.format_selection, SIGNAL(activated(int)), this, SLOT(refreshView()));
connect(m_view.experimentalrender, SIGNAL(stateChanged(int)), this, SLOT(slotUpdateExperimentalRendering()));
m_view.buttonStart->setEnabled(false);
m_view.rescale_size->setEnabled(false);
m_view.guides_box->setVisible(false);
parseProfiles();
m_view.open_dvd->setVisible(false);
m_view.open_browser->setVisible(false);
m_view.error_box->setVisible(false);
m_view.splitter->setStretchFactor(1, 5);
m_view.splitter->setStretchFactor(0, 2);
......@@ -108,12 +112,6 @@ RenderWidget::RenderWidget(QWidget * parent): QDialog(parent) {
focusFirstVisibleItem();
}
void RenderWidget::slotUpdateExperimentalRendering() {
KdenliveSettings::setExperimentalrender(m_view.experimentalrender->isChecked());
refreshView();
}
void RenderWidget::showInfoPanel() {
if (m_view.advanced_params->isVisible()) {
m_view.advanced_params->setVisible(false);
......@@ -396,7 +394,9 @@ void RenderWidget::focusFirstVisibleItem() {
void RenderWidget::slotExport() {
QListWidgetItem *item = m_view.size_list->currentItem();
if (!item) return;
QFile f(m_view.out_file->url().path());
const QString dest = m_view.out_file->url().path();
if (dest.isEmpty()) return;
QFile f(dest);
if (f.exists()) {
if (KMessageBox::warningYesNo(this, i18n("File already exists. Do you want to overwrite it ?")) != KMessageBox::Yes)
return;
......@@ -415,27 +415,50 @@ void RenderWidget::slotExport() {
endPos = m_view.guide_end->itemData(m_view.guide_end->currentIndex()).toDouble();
}
QString renderArgs = m_view.advanced_params->toPlainText();
renderArgs.replace("%width", QString::number(m_profile.width));
renderArgs.replace("%height", QString::number(m_profile.height));
// Adjust frame scale
int width;
int height;
if (m_view.rescale->isChecked() && m_view.rescale->isEnabled()) {
width = m_view.rescale_size->text().section('x', 0, 0).toInt();
height = m_view.rescale_size->text().section('x', 1, 1).toInt();
} else {
width = m_profile.width;
height = m_profile.height;
}
renderArgs.replace("%width", QString::number(width));
renderArgs.replace("%height", QString::number(height));
renderArgs.replace("%dar", "@" + QString::number(m_profile.display_aspect_num) + "/" + QString::number(m_profile.display_aspect_den));
if (m_view.force_progressive->checkState() == Qt::Checked) renderArgs.append(" progressive=1");
else if (m_view.force_progressive->checkState() == Qt::Unchecked) renderArgs.append(" progressive=0");
// Adjust scanning
if (m_view.scanning_list->currentIndex() == 1) renderArgs.append(" progressive=1");
else if (m_view.scanning_list->currentIndex() == 2) renderArgs.append(" progressive=0");
// disable audio if requested
if (!m_view.export_audio->isChecked())
renderArgs.append(" an=1 ");
// Check if the rendering profile is different from project profile,
// in which case we need to use the producer_comsumer from MLT
bool resizeProfile = false;
QString std = item->data(ParamsRole).toString();
QString std = renderArgs;
if (resizeProfile == false && std.contains(" s=")) {
QString subsize = std.section(" s=", 1, 1);
subsize = subsize.section(' ', 0, 0).toLower();
if (subsize != "%widthx%height") {
const QString currentSize = QString::number(m_profile.width) + 'x' + QString::number(m_profile.height);
if (subsize != currentSize) resizeProfile = true;
}
const QString currentSize = QString::number(m_profile.width) + 'x' + QString::number(m_profile.height);
if (subsize != currentSize) resizeProfile = true;
}
emit doRender(m_view.out_file->url().path(), item->data(RenderRole).toString(), overlayargs, renderArgs.simplified().split(' '), m_view.render_zone->isChecked(), m_view.play_after->isChecked(), startPos, endPos, resizeProfile);
// insert item in running jobs list
QTreeWidgetItem *renderItem;
QList<QTreeWidgetItem *> existing = m_view.running_jobs->findItems(dest, Qt::MatchExactly);
if (!existing.isEmpty()) renderItem = existing.at(0);
else renderItem = new QTreeWidgetItem(m_view.running_jobs, QStringList() << dest << QString());
// Set rendering type
renderItem->setData(0, Qt::UserRole, m_view.size_list->currentItem()->data(MetaGroupRole).toString());
emit doRender(dest, item->data(RenderRole).toString(), overlayargs, renderArgs.simplified().split(' '), m_view.render_zone->isChecked(), m_view.play_after->isChecked(), startPos, endPos, resizeProfile);
m_view.tabWidget->setCurrentIndex(1);
}
......@@ -444,25 +467,58 @@ void RenderWidget::setProfile(MltVideoProfile profile) {
//WARNING: this way to tell the video standard is a bit hackish...
if (m_profile.description.contains("pal", Qt::CaseInsensitive) || m_profile.description.contains("25", Qt::CaseInsensitive) || m_profile.description.contains("50", Qt::CaseInsensitive)) m_view.format_selection->setCurrentIndex(0);
else m_view.format_selection->setCurrentIndex(1);
m_view.force_progressive->setCheckState(Qt::PartiallyChecked);
m_view.scanning_list->setCurrentIndex(0);
refreshView();
}
void RenderWidget::refreshView() {
m_view.size_list->blockSignals(true);
QListWidgetItem *item = m_view.format_list->currentItem();
if (!item) {
m_view.format_list->setCurrentRow(0);
QListWidgetItem *sizeItem;
QString destination;
if (m_view.destination_list->currentIndex() > 0)
destination = m_view.destination_list->itemData(m_view.destination_list->currentIndex()).toString();
if (destination == "dvd") m_view.open_dvd->setVisible(true);
else m_view.open_dvd->setVisible(false);
if (destination == "websites") m_view.open_browser->setVisible(true);
else m_view.open_browser->setVisible(false);
if (!destination.isEmpty() && QString("dvd websites audioonly").contains(destination))
m_view.rescale->setEnabled(false);
else m_view.rescale->setEnabled(true);
// hide groups that are not in the correct destination
for (int i = 0; i < m_view.format_list->count(); i++) {
sizeItem = m_view.format_list->item(i);
if (sizeItem->data(MetaGroupRole).toString() == destination)
sizeItem->setHidden(false);
else sizeItem->setHidden(true);
}
// activate first visible item
QListWidgetItem * item = m_view.format_list->currentItem();
if (!item || item->isHidden()) {
for (int i = 0; i < m_view.format_list->count(); i++) {
if (!m_view.format_list->item(i)->isHidden()) {
m_view.format_list->setCurrentRow(i);
break;
}
}
item = m_view.format_list->currentItem();
}
if (!item) return;
int count = 0;
for (int i = 0; i < m_view.format_list->count() && count < 2; i++) {
if (!m_view.format_list->isRowHidden(i)) count++;
}
if (count > 1) m_view.format_list->setVisible(true);
else m_view.format_list->setVisible(false);
QString std;
QString group = item->text();
QListWidgetItem *sizeItem;
bool firstSelected = false;
const QStringList formatsList = KdenliveSettings::supportedformats();
const QStringList vcodecsList = KdenliveSettings::videocodecs();
const QStringList acodecsList = KdenliveSettings::audiocodecs();
for (int i = 0; i < m_view.size_list->count(); i++) {
sizeItem = m_view.size_list->item(i);
if (sizeItem->data(GroupRole) == group) {
......@@ -475,18 +531,7 @@ void RenderWidget::refreshView() {
if (!firstSelected) m_view.size_list->setCurrentItem(sizeItem);
firstSelected = true;
}
if (!KdenliveSettings::experimentalrender() && !sizeItem->isHidden()) {
// hide experimental codecs (which do resize the video)
std = sizeItem->data(ParamsRole).toString();
if (std.contains(" s=")) {
QString subsize = std.section(" s=", 1, 1);
subsize = subsize.section(' ', 0, 0).toLower();
if (subsize != "%widthx%height") {
const QString currentSize = QString::number(m_profile.width) + 'x' + QString::number(m_profile.height);
if (subsize != currentSize) sizeItem->setHidden(true);
}
}
}
if (!sizeItem->isHidden()) {
// Make sure the selected profile uses an installed avformat codec / format
std = sizeItem->data(ParamsRole).toString();
......@@ -571,6 +616,8 @@ void RenderWidget::refreshParams() {
void RenderWidget::parseProfiles(QString group, QString profile) {
m_view.size_list->clear();
m_view.format_list->clear();
m_view.destination_list->clear();
m_view.destination_list->addItem(KIcon("video-x-generic"), i18n("File rendering"));
QString exportFile = KStandardDirs::locate("appdata", "export/profiles.xml");
parseFile(exportFile, false);
exportFile = KStandardDirs::locateLocal("appdata", "export/customprofiles.xml");
......@@ -605,17 +652,39 @@ void RenderWidget::parseFile(QString exportFile, bool editable) {
QString renderer;
QString params;
QString standard;
KIcon icon;
QListWidgetItem *item;
while (!groups.item(i).isNull()) {
documentElement = groups.item(i).toElement();
QDomNode gname = documentElement.elementsByTagName("groupname").at(0);
QString metagroupName;
QString metagroupId;
if (!gname.isNull()) {
metagroupName = gname.firstChild().nodeValue();
metagroupId = gname.toElement().attribute("id");
if (!metagroupName.isEmpty() && !m_view.destination_list->contains(metagroupName)) {
if (metagroupId == "dvd") icon = KIcon("media-optical");
else if (metagroupId == "audioonly") icon = KIcon("audio-x-generic");
else if (metagroupId == "websites") icon = KIcon("applications-internet");
else if (metagroupId == "mediaplayers") icon = KIcon("applications-multimedia");
else if (metagroupId == "lossless") icon = KIcon("drive-harddisk");
m_view.destination_list->addItem(icon, i18n(metagroupName.toUtf8().data()), metagroupId);
}
}
groupName = documentElement.attribute("name", QString::null);
extension = documentElement.attribute("extension", QString::null);
renderer = documentElement.attribute("renderer", QString::null);
if (m_view.format_list->findItems(groupName, Qt::MatchExactly).isEmpty())
new QListWidgetItem(groupName, m_view.format_list);
if (m_view.format_list->findItems(groupName, Qt::MatchExactly).isEmpty()) {
item = new QListWidgetItem(groupName, m_view.format_list);
item->setData(MetaGroupRole, metagroupId);
}
QDomNode n = groups.item(i).firstChild();
while (!n.isNull()) {
if (n.toElement().tagName() != "profile") {
n = n.nextSibling();
continue;
}
profileElement = n.toElement();
profileName = profileElement.attribute("name");
standard = profileElement.attribute("standard");
......@@ -624,6 +693,7 @@ void RenderWidget::parseFile(QString exportFile, bool editable) {
if (!prof_extension.isEmpty()) extension = prof_extension;
item = new QListWidgetItem(profileName, m_view.size_list);
item->setData(GroupRole, groupName);
item->setData(MetaGroupRole, metagroupId);
item->setData(ExtensionRole, extension);
item->setData(RenderRole, renderer);
item->setData(StandardRole, standard);
......@@ -637,38 +707,37 @@ void RenderWidget::parseFile(QString exportFile, bool editable) {
}
void RenderWidget::setRenderJob(const QString &dest, int progress) {
QTreeWidgetItem *item;
QList<QTreeWidgetItem *> existing = m_view.running_jobs->findItems(dest, Qt::MatchExactly);
if (!existing.isEmpty()) {
if (progress == -1) {
// Job finished successfully
existing.at(0)->setIcon(0, KIcon("dialog-ok"));
existing.at(0)->setData(1, Qt::UserRole, 100);
} else if (progress == -2) {
// Rendering crashed
existing.at(0)->setIcon(0, KIcon("dialog-close"));
existing.at(0)->setData(1, Qt::UserRole, 0);
} else if (progress == -3) {
// User aborted job
existing.at(0)->setIcon(0, KIcon("dialog-close"));
existing.at(0)->setData(1, Qt::UserRole, 100);
} else existing.at(0)->setData(1, Qt::UserRole, progress);
return;
}
QTreeWidgetItem *item = new QTreeWidgetItem(m_view.running_jobs, QStringList() << dest << QString());
if (progress == -1) {
if (!existing.isEmpty()) item = existing.at(0);
else item = new QTreeWidgetItem(m_view.running_jobs, QStringList() << dest << QString());
item->setData(1, Qt::UserRole, progress);
if (progress == 0) item->setIcon(0, KIcon("system-run"));
}
void RenderWidget::setRenderStatus(const QString &dest, int status, const QString &error) {
QTreeWidgetItem *item;
QList<QTreeWidgetItem *> existing = m_view.running_jobs->findItems(dest, Qt::MatchExactly);
if (!existing.isEmpty()) item = existing.at(0);
else item = new QTreeWidgetItem(m_view.running_jobs, QStringList() << dest << QString());
if (status == -1) {
// Job finished successfully
item->setIcon(0, KIcon("dialog-ok"));
item->setData(1, Qt::UserRole, 100);
} else if (progress == -2) {
} else if (status == -2) {
// Rendering crashed
item->setIcon(0, KIcon("dialog-close"));
item->setData(1, Qt::UserRole, 0);
} else if (progress == -3) {
m_view.error_log->append(i18n("<strong>Rendering of %1 crashed</strong><br />", dest));
m_view.error_log->append(error);
m_view.error_log->append("<hr />");
m_view.error_box->setVisible(true);
} else if (status == -3) {
// User aborted job
item->setIcon(0, KIcon("dialog-close"));
item->setIcon(0, KIcon("dialog-cancel"));
item->setData(1, Qt::UserRole, 100);
} else item->setData(1, Qt::UserRole, progress);
item->setData(1, Qt::UserRole + 1, i18n("Aborted by user"));
}
}
void RenderWidget::slotAbortCurrentJob() {
......
......@@ -73,6 +73,7 @@ public:
void focusFirstVisibleItem();
void setProfile(MltVideoProfile profile);
void setRenderJob(const QString &dest, int progress = 0);
void setRenderStatus(const QString &dest, int status, const QString &error);
private slots:
void slotUpdateButtons();
......@@ -86,7 +87,6 @@ private slots:
void slotCheckStartGuidePosition();
void slotCheckEndGuidePosition();
void showInfoPanel();
void slotUpdateExperimentalRendering();
void slotAbortCurrentJob();
private:
......
......@@ -5,14 +5,14 @@
<rect>
<x>0</x>
<y>0</y>
<width>444</width>
<height>407</height>
<width>415</width>
<height>512</height>
</rect>
</property>
<property name="windowTitle" >
<string>Dialog</string>
</property>
<layout class="QGridLayout" name="gridLayout_5" >
<layout class="QGridLayout" name="gridLayout_3" >
<property name="margin" >
<number>0</number>
</property>
......@@ -25,142 +25,210 @@
<attribute name="title" >
<string>Render Project</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_3" >
<item row="0" column="0" >
<layout class="QGridLayout" name="gridLayout" >
<item row="0" column="0" colspan="2" >
<widget class="QLabel" name="label_6" >
<property name="text" >
<string>Destination</string>
</property>
</widget>
</item>
<item row="0" column="2" colspan="8" >
<widget class="KComboBox" name="destination_list" />
</item>
<item row="1" column="0" colspan="2" >
<widget class="QLabel" name="label" >
<property name="text" >
<string>Output file</string>
</property>
</widget>
</item>
<item row="0" column="1" colspan="3" >
<item row="1" column="2" colspan="8" >
<widget class="KUrlRequester" name="out_file" />
</item>
<item row="1" column="0" colspan="4" >
<widget class="QGroupBox" name="groupBox" >
<property name="title" >
<item row="2" column="0" >
<widget class="QToolButton" name="buttonInfo" >
<property name="text" >
<string>I</string>
</property>
</widget>
</item>
<item row="2" column="1" >
<widget class="QLabel" name="label_3" >
<property name="text" >
<string>Format</string>
</property>
</widget>
</item>
<item row="2" column="2" colspan="3" >
<spacer name="horizontalSpacer_2" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0" >
<size>
<width>124</width>
<height>23</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="5" colspan="2" >
<widget class="KComboBox" name="format_selection" >
<item>
<property name="text" >
<string>PAL</string>
</property>
</item>
<item>
<property name="text" >
<string>NTSC</string>
</property>
</item>
</widget>
</item>
<item row="2" column="7" >
<widget class="QToolButton" name="buttonEdit" >
<property name="text" >
<string>E</string>
</property>
</widget>
</item>
<item row="2" column="8" >
<widget class="QToolButton" name="buttonSave" >
<property name="text" >
<string>S</string>
</property>
</widget>
</item>
<item row="2" column="9" >
<widget class="QToolButton" name="buttonDelete" >
<property name="text" >
<string>D</string>
</property>
</widget>
</item>
<item row="3" column="0" colspan="10" >
<widget class="QSplitter" name="splitter_3" >
<property name="orientation" >
<enum>Qt::Vertical</enum>
</property>
<widget class="QSplitter" name="splitter" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<widget class="KListWidget" name="format_list" >
<property name="sizePolicy" >
<sizepolicy vsizetype="Expanding" hsizetype="Preferred" >
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>