#include "projectlistview.h"
#include "timecodedisplay.h"
#include "profilesdialog.h"
+#include "clipstabilize.h"
#include "commands/editclipcommand.h"
#include "commands/editclipcutcommand.h"
#include "commands/editfoldercommand.h"
#include <QIcon>
#include <QMenu>
#include <QProcess>
+#include <QScrollBar>
#include <QHeaderView>
#include <QInputDialog>
#include <QtConcurrentRun>
/*QString style = "QToolButton {background-color: %1;border-style: outset;border-width: 2px;
border-radius: 5px;border-color: beige;}";*/
- KColorScheme scheme(palette().currentColorGroup(), KColorScheme::Window, KSharedConfig::openConfig(KdenliveSettings::colortheme()));
+ m_timeLine = new QTimeLine(500, this);
+ QObject::connect(m_timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(slotTimeLineChanged(qreal)));
+ QObject::connect(m_timeLine, SIGNAL(finished()), this, SLOT(slotTimeLineFinished()));
+ hide();
+}
+
+const QString SmallInfoLabel::getStyleSheet(const QPalette &p)
+{
+ KColorScheme scheme(p.currentColorGroup(), KColorScheme::Window, KSharedConfig::openConfig(KdenliveSettings::colortheme()));
QColor bg = scheme.background(KColorScheme::LinkBackground).color();
QColor fg = scheme.foreground(KColorScheme::LinkText).color();
QString style = QString("QPushButton {padding:2px;background-color: rgb(%1, %2, %3);border-radius: 4px;border: none;color: rgb(%4, %5, %6)}").arg(bg.red()).arg(bg.green()).arg(bg.blue()).arg(fg.red()).arg(fg.green()).arg(fg.blue());
fg = scheme.foreground(KColorScheme::ActiveText).color();
style.append(QString("\nQPushButton:hover {padding:2px;background-color: rgb(%1, %2, %3);border-radius: 4px;border: none;color: rgb(%4, %5, %6)}").arg(bg.red()).arg(bg.green()).arg(bg.blue()).arg(fg.red()).arg(fg.green()).arg(fg.blue()));
- setStyleSheet(style);
- m_timeLine = new QTimeLine(500, this);
- QObject::connect(m_timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(slotTimeLineChanged(qreal)));
- QObject::connect(m_timeLine, SIGNAL(finished()), this, SLOT(slotTimeLineFinished()));
- hide();
+ return style;
}
void SmallInfoLabel::slotTimeLineChanged(qreal value)
// small info button for pending jobs
m_infoLabel = new SmallInfoLabel(this);
+ m_infoLabel->setStyleSheet(SmallInfoLabel::getStyleSheet(palette()));
connect(this, SIGNAL(jobCount(int)), m_infoLabel, SLOT(slotSetJobCount(int)));
m_jobsMenu = new QMenu(this);
connect(m_jobsMenu, SIGNAL(aboutToShow()), this, SLOT(slotPrepareJobsMenu()));
frame->setLayout(box);
layout->addWidget(frame);
- m_listView = new ProjectListView;
+ m_listView = new ProjectListView(this);
layout->addWidget(m_listView);
#if KDE_IS_VERSION(4,7,0)
connect(this, SIGNAL(cancelRunningJob(const QString, stringMap )), this, SLOT(slotCancelRunningJob(const QString, stringMap)));
connect(this, SIGNAL(processLog(const QString, int , int, const QString)), this, SLOT(slotProcessLog(const QString, int , int, const QString)));
- connect(this, SIGNAL(updateJobStatus(const QString &, int, int, const QString &, const QString &, const QString)), this, SLOT(slotUpdateJobStatus(const QString &, int, int, const QString &, const QString &, const QString)));
+ connect(this, SIGNAL(updateJobStatus(const QString, int, int, const QString, const QString, const QString)), this, SLOT(slotUpdateJobStatus(const QString, int, int, const QString, const QString, const QString)));
connect(this, SIGNAL(gotProxy(const QString)), this, SLOT(slotGotProxyForId(const QString)));
if (clip->getProperty("transparency").isEmpty() || clip->getProperty("transparency").toInt() == 0) {
if (transparency == "-") {
// first non transparent image
- transparency = "0";
+ transparency = '0';
}
else if (transparency == "1") {
// we have transparent and non transparent clips
else {
if (transparency == "-") {
// first transparent image
- transparency = "1";
+ transparency = '1';
}
else if (transparency == "0") {
// we have transparent and non transparent clips
p.next();
kDebug() << "Result: " << p.key() << " = " << p.value();
}*/
- emit showClipProperties(clipList, commonproperties);
+ if (clipList.isEmpty()) {
+ emit displayMessage(i18n("No available clip selected"), -2);
+ }
+ else emit showClipProperties(clipList, commonproperties);
}
void ProjectList::slotOpenClip()
item->referencedClip()->setPlaceHolder(true);
item->setProperty("file_hash", QString());
} else if (t == IMAGE) {
- clip->getProducer()->set("force_reload", 1);
+ //clip->getProducer() clip->getProducer()->set("force_reload", 1);
}
QDomElement e = item->toXml();
if (item) {
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled);
int height = m_listView->iconSize().height();
+ if (m_render == NULL) {
+ kDebug() << "********* ERROR, NULL RENDR";
+ return;
+ }
int width = (int)(height * m_render->dar());
QPixmap pixmap = qVariantValue<QPixmap>(item->data(0, Qt::DecorationRole));
if (pixmap.isNull()) {
item->setData(0, Qt::DecorationRole, pixmap);
if (item->referencedClip()) {
item->referencedClip()->setPlaceHolder(true);
- if (m_render == NULL) {
- kDebug() << "********* ERROR, NULL RENDR";
- return;
- }
Mlt::Producer *newProd = m_render->invalidProducer(id);
if (item->referencedClip()->getProducer()) {
Mlt::Properties props(newProd->get_properties());
{
m_render = projectRender;
m_listView->setIconSize(QSize((ProjectItem::itemDefaultHeight() - 2) * m_render->dar(), ProjectItem::itemDefaultHeight() - 2));
+ connect(m_render, SIGNAL(requestProxy(QString)), this, SLOT(slotCreateProxy(QString)));
}
void ProjectList::slotClipSelected()
m_proxyAction->setEnabled(false);
return;
}
- m_proxyAction->setEnabled(useProxy());
+ bool enabled = useProxy();
+ if (clip->referencedClip() && !clip->referencedClip()->getProperty("_missingsource").isEmpty()) enabled = false;
+ m_proxyAction->setEnabled(enabled);
m_proxyAction->blockSignals(true);
m_proxyAction->setChecked(clip->hasProxy());
m_proxyAction->blockSignals(false);
emit projectModified();
EditClipCommand *command = new EditClipCommand(this, clip->clipId(), oldprops, newprops, false);
m_commandStack->push(command);
+ QTimer::singleShot(100, this, SLOT(slotCheckScrolling()));
}
}
}
}
+void ProjectList::slotCheckScrolling()
+{
+ m_listView->scrollToItem(m_listView->currentItem());
+}
+
void ProjectList::slotContextMenu(const QPoint &pos, QTreeWidgetItem *item)
{
bool enable = item ? true : false;
} else {
ProjectItem *item = static_cast <ProjectItem *>(selected.at(i));
ids << item->clipId();
- if (item->numReferences() > 0 && KMessageBox::questionYesNo(kapp->activeWindow(), i18np("Delete clip <b>%2</b>?<br />This will also remove the clip in timeline", "Delete clip <b>%2</b>?<br />This will also remove its %1 clips in timeline", item->numReferences(), item->names().at(1)), i18n("Delete Clip"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "DeleteAll") == KMessageBox::No) {
+ if (item->numReferences() > 0 && KMessageBox::questionYesNo(kapp->activeWindow(), i18np("Delete clip <b>%2</b>?<br />This will also remove the clip in timeline", "Delete clip <b>%2</b>?<br />This will also remove its %1 clips in timeline", item->numReferences(), item->text(1)), i18n("Delete Clip"), KStandardGuiItem::yes(), KStandardGuiItem::no(), "DeleteAll") == KMessageBox::No) {
KMessageBox::enableMessage("DeleteAll");
return;
}
m_doc->setModified(true);
}
-void ProjectList::slotAddFolder()
+void ProjectList::slotAddFolder(const QString &name)
{
- AddFolderCommand *command = new AddFolderCommand(this, i18n("Folder"), QString::number(m_doc->clipManager()->getFreeFolderId()), true);
+ AddFolderCommand *command = new AddFolderCommand(this, name.isEmpty() ? i18n("Folder") : name, QString::number(m_doc->clipManager()->getFreeFolderId()), true);
m_commandStack->push(command);
}
//m_listView->setEnabled(false);
const QString parent = clip->getProperty("groupid");
ProjectItem *item = NULL;
+ kDebug()<<"// Adding clip 1";
monitorItemEditing(false);
if (!parent.isEmpty()) {
FolderProjectItem *parentitem = getFolderItemById(parent);
if (item == NULL) {
item = new ProjectItem(m_listView, clip);
}
+ kDebug()<<"// Adding clip 2";
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)));
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";
+ 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()) {
} else {
item = static_cast <ProjectItem *>(*it);
clip = item->referencedClip();
- if (item->referencedClip()->getProducer() == NULL) {
+ if (clip->getProducer() == NULL) {
bool replace = false;
if (brokenClips.contains(item->clipId())) {
// if this is a proxy clip, disable proxy
xml.removeAttribute("file_hash");
xml.removeAttribute("proxy_out");
}
- if (!replace) replace = xml.attribute("replace") == "1";
+ if (!replace) replace = xml.attribute("_replaceproxy") == "1";
+ xml.removeAttribute("_replaceproxy");
if (replace) {
resetThumbsProducer(clip);
}
getCachedThumbnail(item);
}
if (item->data(0, DurationRole).toString().isEmpty()) {
- item->changeDuration(item->referencedClip()->getProducer()->get_playtime());
+ item->changeDuration(clip->getProducer()->get_playtime());
}
if (clip->isPlaceHolder()) {
QPixmap pixmap = qVariantValue<QPixmap>(item->data(0, Qt::DecorationRole));
p.end();
item->setData(0, Qt::DecorationRole, pixmap);
}
+ else if (clip->getProperty("_replaceproxy") == "1") {
+ clip->setProperty("_replaceproxy", QString());
+ slotCreateProxy(clip->getId());
+ }
}
item->setData(0, UsageRole, QString::number(item->numReferences()));
}
QString ProjectList::getExtensions()
{
// Build list of mime types
- QStringList mimeTypes = QStringList() << "application/x-kdenlive" << "application/x-kdenlivetitle" << "video/mlt-playlist" << "text/plain"
- << "video/x-flv" << "application/vnd.rn-realmedia" << "video/x-dv" << "video/dv" << "video/x-msvideo" << "video/x-matroska" << "video/mpeg" << "video/ogg" << "video/x-ms-wmv" << "video/mp4" << "video/quicktime" << "video/webm"
- << "audio/x-flac" << "audio/x-matroska" << "audio/mp4" << "audio/mpeg" << "audio/x-mp3" << "audio/ogg" << "audio/x-wav" << "audio/x-aiff" << "audio/aiff" << "application/ogg" << "application/mxf" << "application/x-shockwave-flash"
- << "image/gif" << "image/jpeg" << "image/png" << "image/x-tga" << "image/x-bmp" << "image/svg+xml" << "image/tiff" << "image/x-xcf" << "image/x-xcf-gimp" << "image/x-vnd.adobe.photoshop" << "image/x-pcx" << "image/x-exr";
+ QStringList mimeTypes = QStringList() << "application/x-kdenlive" << "application/x-kdenlivetitle" << "video/mlt-playlist" << "text/plain";
+
+ // Video mimes
+ mimeTypes << "video/x-flv" << "application/vnd.rn-realmedia" << "video/x-dv" << "video/dv" << "video/x-msvideo" << "video/x-matroska" << "video/mpeg" << "video/ogg" << "video/x-ms-wmv" << "video/mp4" << "video/quicktime" << "video/webm" << "video/3gpp";
+
+ // Audio mimes
+ mimeTypes << "audio/x-flac" << "audio/x-matroska" << "audio/mp4" << "audio/mpeg" << "audio/x-mp3" << "audio/ogg" << "audio/x-wav" << "audio/x-aiff" << "audio/aiff" << "application/ogg" << "application/mxf" << "application/x-shockwave-flash" << "audio/ac3";
+
+ // Image mimes
+ mimeTypes << "image/gif" << "image/jpeg" << "image/png" << "image/x-tga" << "image/x-bmp" << "image/svg+xml" << "image/tiff" << "image/x-xcf" << "image/x-xcf-gimp" << "image/x-vnd.adobe.photoshop" << "image/x-pcx" << "image/x-exr";
QString allExtensions;
foreach(const QString & mimeType, mimeTypes) {
l->addWidget(c);
l->addStretch(5);
f->setLayout(l);
- KFileDialog *d = new KFileDialog(KUrl("kfiledialog:///clipfolder"), dialogFilter, kapp->activeWindow(), f);
+ QPointer<KFileDialog> d = new KFileDialog(KUrl("kfiledialog:///clipfolder"), dialogFilter, kapp->activeWindow(), f);
d->setOperationMode(KFileDialog::Opening);
d->setMode(KFile::Files);
if (d->exec() == QDialog::Accepted) {
while (fileName.at(fileName.size() - 1).isDigit()) {
fileName.chop(1);
}
-
- m_doc->slotCreateSlideshowClipFile(fileName, pattern, count, m_timecode.reformatSeparators(KdenliveSettings::sequence_duration()),
- false, false, false,
- m_timecode.getTimecodeFromFrames(int(ceil(m_timecode.fps()))), QString(), 0,
- QString(), groupInfo.at(0), groupInfo.at(1));
+ QMap <QString, QString> properties;
+ properties.insert("name", fileName);
+ properties.insert("resource", pattern);
+ properties.insert("in", "0");
+ QString duration = m_timecode.reformatSeparators(KdenliveSettings::sequence_duration());
+ properties.insert("out", QString::number(m_doc->getFramePos(duration) * count));
+ properties.insert("ttl", QString::number(m_doc->getFramePos(duration)));
+ properties.insert("loop", QString::number(false));
+ properties.insert("crop", QString::number(false));
+ properties.insert("fade", QString::number(false));
+ properties.insert("luma_duration", QString::number(m_doc->getFramePos(m_timecode.getTimecodeFromFrames(int(ceil(m_timecode.fps()))))));
+ m_doc->slotCreateSlideshowClipFile(properties, groupInfo.at(0), groupInfo.at(1));
return;
}
}
for (int i = 0; i < givenList.count(); i++)
list << givenList.at(i);
}
+ QList <KUrl::List> foldersList;
foreach(const KUrl & file, list) {
// Check there is no folder here
KMimeType::Ptr type = KMimeType::findByUrl(file);
if (type->is("inode/directory")) {
- // user dropped a folder
+ // user dropped a folder, import its files
list.removeAll(file);
+ QDir dir(file.path());
+ QStringList result = dir.entryList(QDir::Files);
+ KUrl::List folderFiles;
+ folderFiles << file;
+ foreach(const QString & path, result) {
+ KUrl newFile = file;
+ newFile.addPath(path);
+ folderFiles.append(newFile);
+ }
+ if (folderFiles.count() > 1) foldersList.append(folderFiles);
}
}
- if (list.isEmpty())
- return;
-
- if (givenList.isEmpty()) {
+ if (givenList.isEmpty() && !list.isEmpty()) {
QStringList groupInfo = getGroup();
m_doc->slotAddClipList(list, groupInfo.at(0), groupInfo.at(1));
- } else {
+ } else if (!list.isEmpty()) {
m_doc->slotAddClipList(list, groupName, groupId);
}
+
+ if (!foldersList.isEmpty()) {
+ // create folders
+ for (int i = 0; i < foldersList.count(); i++) {
+ KUrl::List urls = foldersList.at(i);
+ KUrl folderUrl = urls.takeFirst();
+ QString folderName = folderUrl.fileName();
+ FolderProjectItem *folder = NULL;
+ if (!folderName.isEmpty()) {
+ folder = getFolderItemByName(folderName);
+ if (folder == NULL) {
+ slotAddFolder(folderName);
+ folder = getFolderItemByName(folderName);
+ }
+ }
+ if (folder)
+ m_doc->slotAddClipList(urls, folder->groupName(), folder->clipId());
+ else m_doc->slotAddClipList(urls);
+ }
+ }
}
void ProjectList::slotRemoveInvalidClip(const QString &id, bool replace)
if (!m_commandStack)
kDebug() << "!!!!!!!!!!!!!!!! NO CMD STK";
- QDialog *dia = new QDialog(this);
+ QPointer<QDialog> dia = new QDialog(this);
Ui::ColorClip_UI dia_ui;
dia_ui.setupUi(dia);
dia->setWindowTitle(i18n("Color Clip"));
if (dia->exec() == QDialog::Accepted) {
QStringList groupInfo = getGroup();
- m_doc->slotCreateSlideshowClipFile(dia->clipName(), dia->selectedPath(), dia->imageCount(), dia->clipDuration(),
- dia->loop(), dia->crop(), dia->fade(),
- dia->lumaDuration(), dia->lumaFile(), dia->softness(),
- dia->animation(), groupInfo.at(0), groupInfo.at(1));
+
+ QMap <QString, QString> properties;
+ properties.insert("name", dia->clipName());
+ properties.insert("resource", dia->selectedPath());
+ properties.insert("in", "0");
+ properties.insert("out", QString::number(m_doc->getFramePos(dia->clipDuration()) * dia->imageCount()));
+ properties.insert("ttl", QString::number(m_doc->getFramePos(dia->clipDuration())));
+ properties.insert("loop", QString::number(dia->loop()));
+ properties.insert("crop", QString::number(dia->crop()));
+ properties.insert("fade", QString::number(dia->fade()));
+ properties.insert("luma_duration", dia->lumaDuration());
+ properties.insert("luma_file", dia->lumaFile());
+ properties.insert("softness", QString::number(dia->softness()));
+ properties.insert("animation", dia->animation());
+
+ m_doc->slotCreateSlideshowClipFile(properties, groupInfo.at(0), groupInfo.at(1));
}
delete dia;
}
const QString path = m_doc->projectFolder().path(KUrl::AddTrailingSlash) + "titles/";
QStringList templateFiles = QDir(path).entryList(filter, QDir::Files);
- QDialog *dia = new QDialog(this);
+ QPointer<QDialog> dia = new QDialog(this);
Ui::TemplateClip_UI dia_ui;
dia_ui.setupUi(dia);
for (int i = 0; i < templateFiles.size(); ++i)
void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Producer *producer, const stringMap &properties, const stringMap &metadata, bool replace)
{
QString toReload;
+ kDebug()<<"// CLIP LOADED 1;";
ProjectItem *item = getItemById(clipId);
int queue = m_render->processingItems();
if (item && producer) {
if (clip->getProperty("proxy").isEmpty()) {
KUrl proxyPath = m_doc->projectFolder();
proxyPath.addPath("proxy/");
- proxyPath.addPath(clip->getClipHash() + "." + (t == IMAGE ? "png" : m_doc->getDocumentProperty("proxyextension")));
+ proxyPath.addPath(clip->getClipHash() + '.' + (t == IMAGE ? "png" : m_doc->getDocumentProperty("proxyextension")));
QMap <QString, QString> newProps;
// insert required duration for proxy
if (t != IMAGE) newProps.insert("proxy_out", clip->producerProperty("out"));
if (queue == 0) {
monitorItemEditing(true);
if (item && m_thumbnailQueue.isEmpty()) {
+ kDebug()<<"// CLIP LOADED;";
if (!item->hasProxy() || m_render->activeClipId() == item->clipId())
m_listView->setCurrentItem(item);
bool updatedProfile = false;
return NULL;
}
+FolderProjectItem *ProjectList::getFolderItemByName(const QString &name)
+{
+ FolderProjectItem *item = NULL;
+ QList <QTreeWidgetItem *> hits = m_listView->findItems(name, Qt::MatchExactly, 0);
+ for (int i = 0; i < hits.count(); i++) {
+ if (hits.at(i)->type() == PROJECTFOLDERTYPE) {
+ item = static_cast<FolderProjectItem *>(hits.at(i));
+ break;
+ }
+ }
+ return item;
+}
+
FolderProjectItem *ProjectList::getFolderItemById(const QString &id)
{
FolderProjectItem *item;
} else {
// Create sequence
QStringList groupInfo = getGroup();
- m_doc->slotCreateSlideshowClipFile(fileName, pattern, count, m_timecode.reformatSeparators(KdenliveSettings::sequence_duration()),
- false, false, false,
- m_timecode.getTimecodeFromFrames(int(ceil(m_timecode.fps()))), QString(), 0,
- QString(), groupInfo.at(0), groupInfo.at(1));
+ QMap <QString, QString> properties;
+ properties.insert("name", fileName);
+ properties.insert("resource", pattern);
+ properties.insert("in", "0");
+ QString duration = m_timecode.reformatSeparators(KdenliveSettings::sequence_duration());
+ properties.insert("out", QString::number(m_doc->getFramePos(duration) * count));
+ properties.insert("ttl", QString::number(m_doc->getFramePos(duration)));
+ properties.insert("loop", QString::number(false));
+ properties.insert("crop", QString::number(false));
+ properties.insert("fade", QString::number(false));
+ properties.insert("luma_duration", m_timecode.getTimecodeFromFrames(int(ceil(m_timecode.fps()))));
+
+ m_doc->slotCreateSlideshowClipFile(properties, groupInfo.at(0), groupInfo.at(1));
}
} else emit displayMessage(i18n("Sequence not found"), -2);
}
slotUpdateJobStatus(item, PROXYJOB, JOBCRASHED, i18n("Failed to create proxy, empty path."));
return;
}
-
- ProxyJob *job = new ProxyJob(item->clipType(), id, QStringList() << path << item->clipUrl().path() << item->referencedClip()->producerProperty("_exif_orientation") << m_doc->getDocumentProperty("proxyparams").simplified() << QString::number(m_render->frameRenderWidth()) << QString::number(m_render->renderHeight()));
- if (job->isExclusive() && hasPendingJob(item, job->jobType)) {
- delete job;
- return;
- }
-
+
if (QFileInfo(path).size() > 0) {
// Proxy already created
setJobStatus(item, PROXYJOB, JOBDONE);
return;
}
+ ProxyJob *job = new ProxyJob(item->clipType(), id, QStringList() << path << item->clipUrl().path() << item->referencedClip()->producerProperty("_exif_orientation") << m_doc->getDocumentProperty("proxyparams").simplified() << QString::number(m_render->frameRenderWidth()) << QString::number(m_render->renderHeight()));
+ if (job->isExclusive() && hasPendingJob(item, job->jobType)) {
+ delete job;
+ return;
+ }
+
m_jobList.append(job);
setJobStatus(item, job->jobType, JOBWAITING, 0, job->statusMessage());
slotCheckJobProcess();
if (!item|| item->referencedClip()->isPlaceHolder()) return;
QString source = item->clipUrl().path();
QString ext = source.section('.', -1);
- QString dest = source.section('.', 0, -2) + "_" + QString::number(zone.x()) + "." + ext;
+ QString dest = source.section('.', 0, -2) + '_' + QString::number(zone.x()) + '.' + ext;
double clipFps = item->referencedClip()->getProperty("fps").toDouble();
if (clipFps == 0) clipFps = m_fps;
QString timeIn = Timecode::getStringTimecode(in, clipFps, true);
QString timeOut = Timecode::getStringTimecode(duration, clipFps, true);
- QDialog *d = new QDialog(this);
+ QPointer<QDialog> d = new QDialog(this);
Ui::CutJobDialog_UI ui;
ui.setupUi(d);
ui.extra_params->setVisible(false);
slotCheckJobProcess();
}
-void ProjectList::slotTranscodeClipJob(QStringList ids, QString params, QString desc)
+void ProjectList::slotTranscodeClipJob(const QString &condition, QString params, QString desc)
{
QStringList existingFiles;
+ QStringList ids = getConditionalIds(condition);
+ QStringList destinations;
foreach(const QString &id, ids) {
ProjectItem *item = getItemById(id);
if (!item) continue;
QString newFile = params.section(' ', -1).replace("%1", item->clipUrl().path());
+ destinations << newFile;
if (QFile::exists(newFile)) existingFiles << newFile;
}
if (!existingFiles.isEmpty()) {
Ui::CutJobDialog_UI ui;
ui.setupUi(d);
d->setWindowTitle(i18n("Transcoding"));
- ui.destination_label->setVisible(false);
ui.extra_params->setMaximumHeight(QFontMetrics(font()).lineSpacing() * 5);
- ui.file_url->setVisible(false);
+ if (ids.count() == 1) {
+ ui.file_url->setUrl(KUrl(destinations.first()));
+ }
+ else {
+ ui.destination_label->setVisible(false);
+ ui.file_url->setVisible(false);
+ }
ui.extra_params->setVisible(false);
+ d->adjustSize();
ui.button_more->setIcon(KIcon("configure"));
ui.add_clip->setChecked(KdenliveSettings::add_clip_cut());
- ui.extra_params->setPlainText(params.simplified());
+ ui.extra_params->setPlainText(params.simplified().section(' ', 0, -2));
QString mess = desc;
- mess.append(" " + i18np("(%1 clip)", "(%1 clips)", ids.count()));
+ mess.append(' ' + i18np("(%1 clip)", "(%1 clips)", ids.count()));
ui.info_label->setText(mess);
- d->adjustSize();
if (d->exec() != QDialog::Accepted) {
delete d;
return;
}
params = ui.extra_params->toPlainText().simplified();
KdenliveSettings::setAdd_clip_cut(ui.add_clip->isChecked());
- delete d;
foreach(const QString &id, ids) {
ProjectItem *item = getItemById(id);
if (!item || !item->referencedClip()) continue;
QString src = item->clipUrl().path();
- QString dest = params.section(' ', -1).replace("%1", src);
+ QString dest;
+ if (ids.count() > 1) dest = params.section(' ', -1).replace("%1", src);
+ else dest = ui.file_url->url().path();
QStringList jobParams;
jobParams << dest << src << QString() << QString();
double clipFps = item->referencedClip()->getProperty("fps").toDouble();
QString duration = QString::number(max);
jobParams << duration;
jobParams << QString::number(KdenliveSettings::add_clip_cut());
- jobParams << params.section(' ', 0, -2);
+ jobParams << params;
CutClipJob *job = new CutClipJob(item->clipType(), id, jobParams);
if (job->isExclusive() && hasPendingJob(item, job->jobType)) {
delete job;
m_jobList.append(job);
setJobStatus(item, job->jobType, JOBWAITING, 0, job->statusMessage());
}
+ delete d;
slotCheckJobProcess();
}
-
-
void ProjectList::slotCheckJobProcess()
{
if (!m_jobThreads.futures().isEmpty()) {
void ProjectList::slotAbortProxy(const QString id, const QString path)
{
+ Q_UNUSED(path)
+
ProjectItem *item = getItemById(id);
if (!item) return;
if (!item->isProxyRunning()) slotGotProxy(item);
break;
}
QString destination = job->destination();
-
// Check if the clip is still here
- ProjectItem *processingItem = getItemById(job->clipId());
- if (processingItem == NULL) {
+ DocClipBase *currentClip = m_doc->clipManager()->getClipById(job->clipId());
+ //ProjectItem *processingItem = getItemById(job->clipId());
+ if (currentClip == NULL) {
job->setStatus(JOBDONE);
continue;
}
if (job->jobType == MLTJOB) {
MeltJob *jb = static_cast<MeltJob *> (job);
- jb->setProducer(processingItem->referencedClip()->getProducer());
+ jb->setProducer(currentClip->getProducer());
}
job->startJob();
if (job->jobStatus == 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) {
+ if (job->addClipToProject()) {
emit addClip(destination, QString(), QString());
}
- }
- else if (job->jobStatus == JOBCRASHED) {
- emit updateJobStatus(job->clipId(), job->jobType, JOBCRASHED, job->errorMessage());
+ } else if (job->jobStatus == JOBCRASHED || job->jobStatus == JOBABORTED) {
+ emit updateJobStatus(job->clipId(), job->jobType, job->jobStatus, job->errorMessage(), QString(), job->logDetails());
}
}
// Thread finished, cleanup & update count
QMap <QString, QString> oldProps;// = clip->properties();
oldProps.insert("proxy", QString());
QMap <QString, QString> newProps;
- newProps.insert("proxy", proxydir + item->referencedClip()->getClipHash() + "." + m_doc->getDocumentProperty("proxyextension"));
+ newProps.insert("proxy", proxydir + item->referencedClip()->getClipHash() + '.' + m_doc->getDocumentProperty("proxyextension"));
new EditClipCommand(this, clip->getId(), oldProps, newProps, true, command);
}
}
// remove proxy
QMap <QString, QString> newProps;
newProps.insert("proxy", QString());
- newProps.insert("replace", "1");
// insert required duration for proxy
newProps.insert("proxy_out", item->referencedClip()->producerProperty("out"));
new EditClipCommand(this, item->clipId(), item->referencedClip()->currentProperties(newProps), newProps, true, command);
// remove proxy
QMap <QString, QString> newProps;
newProps.insert("proxy", QString());
- newProps.insert("replace", "1");
new EditClipCommand(this, item->clipId(), item->referencedClip()->properties(), newProps, true, command);
}
}
//oldProps = clip->properties();
if (doProxy) {
newProps.clear();
- QString path = proxydir + clip->getClipHash() + "." + (t == IMAGE ? "png" : m_doc->getDocumentProperty("proxyextension"));
+ QString path = proxydir + clip->getClipHash() + '.' + (t == IMAGE ? "png" : m_doc->getDocumentProperty("proxyextension"));
// insert required duration for proxy
newProps.insert("proxy_out", clip->producerProperty("out"));
newProps.insert("proxy", path);
{
if (item->hasProxy()) {
QPainter p(&pix);
- QColor c = QPalette().base().color();
- c.setAlpha(160);
- QBrush br(c);
- p.setBrush(br);
- p.setPen(Qt::NoPen);
- QRect r(1, 1, 10, 10);
- p.drawRect(r);
- p.setPen(QPalette().text().color());
+ QColor c(220, 220, 10, 200);
+ QRect r(0, 0, 12, 12);
+ p.fillRect(r, c);
+ QFont font = p.font();
+ font.setBold(true);
+ p.setFont(font);
+ p.setPen(Qt::black);
p.drawText(r, Qt::AlignCenter, i18nc("The first letter of Proxy, used as abbreviation", "P"));
}
}
command->setText(i18np("Cancel job", "Cancel jobs", m_jobList.count()));
m_jobMutex.lock();
for (int i = 0; i < m_jobList.count(); i++) {
- ProjectItem *item = getItemById(m_jobList.at(i)->clipId());
- if (!item || !item->referencedClip()) continue;
+ DocClipBase *currentClip = m_doc->clipManager()->getClipById(m_jobList.at(i)->clipId());
+ if (!currentClip) continue;
QMap <QString, QString> newProps = m_jobList.at(i)->cancelProperties();
if (newProps.isEmpty()) continue;
- QMap <QString, QString> oldProps = item->referencedClip()->currentProperties(newProps);
+ QMap <QString, QString> oldProps = currentClip->currentProperties(newProps);
new EditClipCommand(this, m_jobList.at(i)->clipId(), oldProps, newProps, true, command);
}
m_jobMutex.unlock();
void ProjectList::slotCancelRunningJob(const QString id, stringMap newProps)
{
if (newProps.isEmpty() || m_closing) return;
- ProjectItem *item = getItemById(id);
- if (!item || !item->referencedClip()) return;
- QMap <QString, QString> oldProps = item->referencedClip()->currentProperties(newProps);
+ DocClipBase *currentClip = m_doc->clipManager()->getClipById(id);
+ if (!currentClip) return;
+ QMap <QString, QString> oldProps = currentClip->currentProperties(newProps);
if (newProps == oldProps) return;
QMapIterator<QString, QString> i(oldProps);
EditClipCommand *command = new EditClipCommand(this, id, oldProps, newProps, true);
}
}
-void ProjectList::slotUpdateJobStatus(const QString &id, int type, int status, const QString &label, const QString &actionName, const QString details)
+void ProjectList::slotUpdateJobStatus(const QString id, int type, int status, const QString label, const QString actionName, const QString details)
{
ProjectItem *item = getItemById(id);
if (!item) return;
if (!item) return;
QStringList jobParams;
jobParams << QString::number(info.cropStart.frames(m_fps)) << QString::number((info.cropStart + info.cropDuration).frames(m_fps));
- jobParams << filterName << filterParams << consumer << consumerParams << properties << QString::number(info.startPos.frames(m_fps)) << QString::number(info.track) << finalFilterName;
+ jobParams << QString() << filterName << filterParams << consumer << consumerParams << properties << QString::number(info.startPos.frames(m_fps)) << QString::number(info.track) << finalFilterName;
MeltJob *job = new MeltJob(item->clipType(), id, jobParams);
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();
+ }
+ QPointer<ClipStabilize> d = new ClipStabilize(destination, ids.count(), filterName);
+ if (d->exec() == QDialog::Accepted) {
+ processClipJob(ids, d->destination(), d->autoAddClip(), d->params(), d->desc());
+ }
+ delete d;
+}
+
+void ProjectList::processClipJob(QStringList ids, const QString&destination, bool autoAdd, QStringList jobParams, const QString &description)
+{
+ 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;
+ if (ids.count() == 1) {
+ consumer += ':' + destination;
+ }
+ else {
+ consumer += ':' + destination + item->clipUrl().fileName() + ".mlt";
+ }
+ preParams << consumer << jobParams;
+
+ MeltJob *job = new MeltJob(item->clipType(), id, preParams);
+ 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;
discardJobs(id);
}
+void ProjectList::updatePalette()
+{
+ m_infoLabel->setStyleSheet(SmallInfoLabel::getStyleSheet(QApplication::palette()));
+ m_listView->updateStyleSheet();
+}
+
#include "projectlist.moc"