X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fprojectlist.cpp;h=698a16f2919d7da0638833791276656e6020e94c;hb=31e84d6bd7f7b1ac64d942a9171d98ad8d0f7d62;hp=5092babf5db5b5fba09c08eddd0b0ac1e205c167;hpb=1dd4e9ce2f4ad2b7b7b5ab42f6c01ad414bc41ea;p=kdenlive diff --git a/src/projectlist.cpp b/src/projectlist.cpp index 5092babf..698a16f2 100644 --- a/src/projectlist.cpp +++ b/src/projectlist.cpp @@ -33,7 +33,7 @@ #include "projectlistview.h" #include "editclipcommand.h" #include "editfoldercommand.h" - +#include "ui_templateclip_ui.h" #include #include @@ -94,7 +94,7 @@ ProjectList::ProjectList(QWidget *parent) : connect(m_listView, SIGNAL(pauseMonitor()), this, SLOT(slotPauseMonitor())); connect(m_listView, SIGNAL(requestMenu(const QPoint &, QTreeWidgetItem *)), this, SLOT(slotContextMenu(const QPoint &, QTreeWidgetItem *))); connect(m_listView, SIGNAL(addClip()), this, SLOT(slotAddClip())); - connect(m_listView, SIGNAL(addClip(const QList , const QString &)), this, SLOT(slotAddClip(const QList , const QString &))); + connect(m_listView, SIGNAL(addClip(const QList , const QString &, const QString &)), this, SLOT(slotAddClip(const QList , const QString &, const QString &))); connect(m_listView, SIGNAL(itemChanged(QTreeWidgetItem *, int)), this, SLOT(slotItemEdited(QTreeWidgetItem *, int))); connect(m_listView, SIGNAL(showProperties(DocClipBase *)), this, SIGNAL(showClipProperties(DocClipBase *))); @@ -205,12 +205,19 @@ void ProjectList::slotOpenClip() void ProjectList::slotReloadClip() { - ProjectItem *item = static_cast (m_listView->currentItem()); - if (item && !item->isGroup()) { - if (item->clipType() == IMAGE) { - item->referencedClip()->producer()->set("force_reload", 1); + QList selected = m_listView->selectedItems(); + ProjectItem *item; + for (int i = 0; i < selected.count(); i++) { + item = static_cast (selected.at(i)); + if (item && !item->isGroup()) { + if (item->clipType() == IMAGE) { + item->referencedClip()->producer()->set("force_reload", 1); + } else if (item->clipType() == TEXT) { + if (!item->referencedClip()->getProperty("xmltemplate").isEmpty()) regenerateTemplate(item); + } + //requestClipInfo(item->toXml(), item->clipId(), true); + emit getFileProperties(item->toXml(), item->clipId(), true); } - emit getFileProperties(item->toXml(), item->clipId(), false); } } @@ -257,7 +264,10 @@ void ProjectList::slotUpdateClipProperties(const QString &id, QMap changeDuration(properties.value("out").toInt()); } } @@ -266,6 +276,7 @@ void ProjectList::slotUpdateClipProperties(ProjectItem *clip, QMap isGroup()) clip->setProperties(properties); + if (properties.contains("xmldata")) regenerateTemplateImage(clip); if (properties.contains("name")) { m_listView->blockSignals(true); clip->setText(1, properties.value("name")); @@ -295,7 +306,14 @@ void ProjectList::slotItemEdited(QTreeWidgetItem *item, int column) QMap newprops; oldprops["description"] = clip->referencedClip()->getProperty("description"); newprops["description"] = item->text(2); - slotUpdateClipProperties(clip, newprops); + + if (clip->clipType() == TEXT && !clip->referencedClip()->getProperty("xmltemplate").isEmpty()) { + // This is a text template clip, update the image + oldprops.insert("xmldata", clip->referencedClip()->getProperty("xmldata")); + newprops.insert("xmldata", generateTemplateXml(clip->referencedClip()->getProperty("xmltemplate"), item->text(2)).toString()); + } + + slotUpdateClipProperties(clip->clipId(), newprops); EditClipCommand *command = new EditClipCommand(this, clip->clipId(), oldprops, newprops, false); m_commandStack->push(command); } @@ -436,7 +454,7 @@ void ProjectList::slotAddFolder(const QString foldername, const QString &clipId, QStringList text; text << QString() << foldername; m_listView->blockSignals(true); - (void) new ProjectItem(m_listView, text, clipId); + m_listView->setCurrentItem(new ProjectItem(m_listView, text, clipId)); m_doc->clipManager()->addFolder(clipId, foldername); m_listView->blockSignals(false); } @@ -480,7 +498,6 @@ void ProjectList::slotAddClip(DocClipBase *clip, bool getProperties) if (parentitem) item = new ProjectItem(parentitem, clip); } if (item == NULL) item = new ProjectItem(m_listView, clip); - KUrl url = clip->fileURL(); if (!url.isEmpty() && KdenliveSettings::activate_nepomuk()) { // if file has Nepomuk comment, use it @@ -520,7 +537,7 @@ void ProjectList::slotProcessNextClipInQueue() const QDomElement dom = i.value(); const QString id = i.key(); m_infoQueue.remove(i.key()); - emit getFileProperties(dom, id, true); + emit getFileProperties(dom, id, false); } if (m_infoQueue.isEmpty()) m_listView->setEnabled(true); } @@ -578,13 +595,13 @@ void ProjectList::updateAllClips() QTimer::singleShot(500, this, SLOT(slotCheckForEmptyQueue())); } -void ProjectList::slotAddClip(const QList givenList, QString group) +void ProjectList::slotAddClip(const QList givenList, const QString &groupName, const QString &groupId) { if (!m_commandStack) kDebug() << "!!!!!!!!!!!!!!!! NO CMD STK"; KUrl::List list; if (givenList.isEmpty()) { // Build list of mime types - QStringList mimeTypes = QStringList() << "application/x-kdenlive" << "video/x-flv" << "application/vnd.rn-realmedia" << "video/x-dv" << "video/dv" << "video/x-msvideo" << "video/mpeg" << "video/x-ms-wmv" << "audio/mpeg" << "audio/x-mp3" << "audio/x-wav" << "application/ogg" << "video/mp4" << "video/quicktime" << "image/gif" << "image/jpeg" << "image/png" << "image/x-tga" << "image/x-bmp" << "image/svg+xml" << "image/tiff" << "image/x-xcf-gimp" << "image/x-vnd.adobe.photoshop" << "image/x-pcx" << "image/x-exr" << "video/mlt-playlist" << "audio/x-flac" << "audio/mp4" << "video/x-matroska" << "audio/x-matroska"; + QStringList mimeTypes = QStringList() << "application/x-kdenlive" << "video/x-flv" << "application/vnd.rn-realmedia" << "video/x-dv" << "video/dv" << "video/x-msvideo" << "video/mpeg" << "video/x-ms-wmv" << "audio/mpeg" << "audio/x-mp3" << "audio/x-wav" << "application/ogg" << "video/mp4" << "video/quicktime" << "image/gif" << "image/jpeg" << "image/png" << "image/x-tga" << "image/x-bmp" << "image/svg+xml" << "image/tiff" << "image/x-xcf-gimp" << "image/x-vnd.adobe.photoshop" << "image/x-pcx" << "image/x-exr" << "video/mlt-playlist" << "audio/x-flac" << "audio/mp4" << "video/x-matroska" << "audio/x-matroska" << "video/ogg" << "audio/ogg"; QString allExtensions; foreach(const QString& mimeType, mimeTypes) { @@ -604,21 +621,10 @@ void ProjectList::slotAddClip(const QList givenList, QString group) } if (list.isEmpty()) return; - QString groupId; - if (group.isEmpty()) { - ProjectItem *item = static_cast (m_listView->currentItem()); - if (item && !item->isGroup()) { - while (item->parent()) { - item = static_cast (item->parent()); - if (item->isGroup()) break; - } - } - if (item && item->isGroup()) { - group = item->groupName(); - groupId = item->clipId(); - } - } - m_doc->slotAddClipList(list, group, groupId); + if (givenList.isEmpty()) { + QStringList groupInfo = getGroup(); + m_doc->slotAddClipList(list, groupInfo.at(0), groupInfo.at(1)); + } else m_doc->slotAddClipList(list, groupName, groupId); } void ProjectList::slotRemoveInvalidClip(const QString &id, bool replace) @@ -644,32 +650,16 @@ void ProjectList::slotAddColorClip() { if (!m_commandStack) kDebug() << "!!!!!!!!!!!!!!!! NO CMD STK"; QDialog *dia = new QDialog(this); - Ui::ColorClip_UI *dia_ui = new Ui::ColorClip_UI(); - dia_ui->setupUi(dia); - dia_ui->clip_name->setText(i18n("Color Clip")); - dia_ui->clip_duration->setText(KdenliveSettings::color_duration()); + Ui::ColorClip_UI dia_ui; + dia_ui.setupUi(dia); + dia_ui.clip_name->setText(i18n("Color Clip")); + dia_ui.clip_duration->setText(KdenliveSettings::color_duration()); if (dia->exec() == QDialog::Accepted) { - QString color = dia_ui->clip_color->color().name(); + QString color = dia_ui.clip_color->color().name(); color = color.replace(0, 1, "0x") + "ff"; - - QString group; - QString groupId; - ProjectItem *item = static_cast (m_listView->currentItem()); - if (item && !item->isGroup()) { - while (item->parent()) { - item = static_cast (item->parent()); - if (item->isGroup()) break; - } - } - if (item && item->isGroup()) { - group = item->groupName(); - groupId = item->clipId(); - } - - m_doc->clipManager()->slotAddColorClipFile(dia_ui->clip_name->text(), color, dia_ui->clip_duration->text(), group, groupId); - m_doc->setModified(true); + QStringList groupInfo = getGroup(); + m_doc->slotCreateColorClip(dia_ui.clip_name->text(), color, dia_ui.clip_duration->text(), groupInfo.at(0), groupInfo.at(1)); } - delete dia_ui; delete dia; } @@ -677,34 +667,60 @@ void ProjectList::slotAddColorClip() void ProjectList::slotAddSlideshowClip() { if (!m_commandStack) kDebug() << "!!!!!!!!!!!!!!!! NO CMD STK"; - SlideshowClip *dia = new SlideshowClip(this); + SlideshowClip *dia = new SlideshowClip(m_timecode, this); if (dia->exec() == QDialog::Accepted) { + QStringList groupInfo = getGroup(); + m_doc->slotCreateSlideshowClipFile(dia->clipName(), dia->selectedPath(), dia->imageCount(), dia->clipDuration(), dia->loop(), dia->fade(), dia->lumaDuration(), dia->lumaFile(), dia->softness(), groupInfo.at(0), groupInfo.at(1)); + } + delete dia; +} - QString group; - QString groupId; - ProjectItem *item = static_cast (m_listView->currentItem()); - if (item && !item->isGroup()) { - while (item->parent()) { - item = static_cast (item->parent()); - if (item->isGroup()) break; - } - } - if (item && item->isGroup()) { - group = item->groupName(); - groupId = item->clipId(); - } +void ProjectList::slotAddTitleClip() +{ + QStringList groupInfo = getGroup(); + m_doc->slotCreateTextClip(groupInfo.at(0), groupInfo.at(1)); +} - m_doc->clipManager()->slotAddSlideshowClipFile(dia->clipName(), dia->selectedPath(), dia->imageCount(), dia->clipDuration(), dia->loop(), dia->fade(), dia->lumaDuration(), dia->lumaFile(), dia->softness(), group, groupId); - m_doc->setModified(true); +void ProjectList::slotAddTitleTemplateClip() +{ + QStringList groupInfo = getGroup(); + if (!m_commandStack) kDebug() << "!!!!!!!!!!!!!!!! NO CMD STK"; + + // Get the list of existing templates + QStringList filter; + filter << "*.kdenlivetitle"; + const QString path = m_doc->projectFolder().path() + "/titles/"; + QStringList templateFiles = QDir(path).entryList(filter, QDir::Files); + + QDialog *dia = new QDialog(this); + Ui::TemplateClip_UI dia_ui; + dia_ui.setupUi(dia); + for (int i = 0; i < templateFiles.size(); ++i) { + dia_ui.template_list->comboBox()->addItem(templateFiles.at(i), path + templateFiles.at(i)); + } + dia_ui.template_list->fileDialog()->setFilter("*.kdenlivetitle"); + //warning: setting base directory doesn't work?? + KUrl startDir(path); + dia_ui.template_list->fileDialog()->setUrl(startDir); + dia_ui.description->setHidden(true); + if (dia->exec() == QDialog::Accepted) { + QString textTemplate = dia_ui.template_list->comboBox()->itemData(dia_ui.template_list->comboBox()->currentIndex()).toString(); + if (textTemplate.isEmpty()) textTemplate = dia_ui.template_list->comboBox()->currentText(); + if (dia_ui.normal_clip->isChecked()) { + // Create a normal title clip + m_doc->slotCreateTextClip(groupInfo.at(0), groupInfo.at(1), textTemplate); + } else { + // Create a cloned template clip + m_doc->slotCreateTextTemplateClip(groupInfo.at(0), groupInfo.at(1), KUrl(textTemplate)); + } } delete dia; } -void ProjectList::slotAddTitleClip() +QStringList ProjectList::getGroup() const { - QString group; - QString groupId; + QStringList result; ProjectItem *item = static_cast (m_listView->currentItem()); if (item && !item->isGroup()) { while (item->parent()) { @@ -713,11 +729,10 @@ void ProjectList::slotAddTitleClip() } } if (item && item->isGroup()) { - group = item->groupName(); - groupId = item->clipId(); - } - - m_doc->slotCreateTextClip(group, groupId); + result << item->groupName(); + result << item->clipId(); + } else result << QString() << QString(); + return result; } void ProjectList::setDocument(KdenliveDoc *doc) @@ -773,6 +788,18 @@ void ProjectList::slotCheckForEmptyQueue() } else QTimer::singleShot(500, this, SLOT(slotCheckForEmptyQueue())); } +void ProjectList::reloadClipThumbnails() +{ + m_thumbnailQueue.clear(); + QTreeWidgetItemIterator it(m_listView); + while (*it) { + if (!((ProjectItem *)(*it))->isGroup()) + m_thumbnailQueue << ((ProjectItem *)(*it))->clipId(); + ++it; + } + QTimer::singleShot(300, this, SLOT(slotProcessNextThumbnail())); +} + void ProjectList::requestClipThumbnail(const QString &id) { m_thumbnailQueue.append(id); @@ -821,12 +848,18 @@ void ProjectList::slotReplyGetFileProperties(const QString &clipId, Mlt::Produce m_listView->blockSignals(true); item->setProperties(properties, metadata); Q_ASSERT_X(item->referencedClip(), "void ProjectList::slotReplyGetFileProperties", QString("Item with groupName %1 does not have a clip associated").arg(item->groupName()).toLatin1()); - if (replace) item->referencedClip()->setProducer(producer); - else { + item->referencedClip()->setProducer(producer, replace); + emit receivedClipDuration(clipId); + if (replace) { + // update clip in clip monitor + emit clipSelected(NULL); + emit clipSelected(item->referencedClip()); + } + /*else { // Check if duration changed. emit receivedClipDuration(clipId); delete producer; - } + }*/ m_listView->blockSignals(false); } else kDebug() << "//////// COULD NOT FIND CLIP TO UPDATE PRPS..."; if (!m_infoQueue.isEmpty()) QTimer::singleShot(300, this, SLOT(slotProcessNextClipInQueue())); @@ -896,4 +929,59 @@ QString ProjectList::currentClipUrl() const return item->clipUrl().path(); } +void ProjectList::regenerateTemplate(const QString &id) +{ + ProjectItem *clip = getItemById(id); + if (clip) regenerateTemplate(clip); +} + +void ProjectList::regenerateTemplate(ProjectItem *clip) +{ + // Generate image for template clip + const QString comment = clip->referencedClip()->getProperty("description"); + const QString path = clip->referencedClip()->getProperty("xmltemplate"); + QDomDocument doc = generateTemplateXml(path, comment); + TitleWidget *dia_ui = new TitleWidget(KUrl(), QString(), m_render, this); + dia_ui->setXml(doc); + QImage pix = dia_ui->renderedPixmap(); + pix.save(clip->clipUrl().path()); + delete dia_ui; + clip->referencedClip()->producer()->set("force_reload", 1); +} + +void ProjectList::regenerateTemplateImage(ProjectItem *clip) +{ + // Generate image for template clip + TitleWidget *dia_ui = new TitleWidget(KUrl(), QString(), m_render, this); + QDomDocument doc; + doc.setContent(clip->referencedClip()->getProperty("xmldata")); + dia_ui->setXml(doc); + QImage pix = dia_ui->renderedPixmap(); + pix.save(clip->clipUrl().path()); + delete dia_ui; +} + +QDomDocument ProjectList::generateTemplateXml(QString path, const QString &replaceString) +{ + QDomDocument doc; + QFile file(path); + if (!file.open(QIODevice::ReadOnly)) { + kWarning() << "ERROR, CANNOT READ: " << path; + return doc; + } + if (!doc.setContent(&file)) { + kWarning() << "ERROR, CANNOT READ: " << path; + file.close(); + return doc; + } + file.close(); + QDomNodeList texts = doc.elementsByTagName("content"); + for (int i = 0; i < texts.count(); i++) { + QString data = texts.item(i).firstChild().nodeValue(); + data.replace("%s", replaceString); + texts.item(i).firstChild().setNodeValue(data); + } + return doc; +} + #include "projectlist.moc"