X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fprojectsettings.cpp;h=848a0718c87c92f1d7fa6b12b89404e4f2d2fb0b;hb=c24658bd34221d735f0641c924b890e1a6be7101;hp=41deae0fc5c6976c2d68c703e42a3178a854d220;hpb=a1bec067bd32e1b489c8be5d3968b45b4645d659;p=kdenlive diff --git a/src/projectsettings.cpp b/src/projectsettings.cpp index 41deae0f..848a0718 100644 --- a/src/projectsettings.cpp +++ b/src/projectsettings.cpp @@ -21,7 +21,7 @@ #include "kdenlivesettings.h" #include "profilesdialog.h" #include "docclipbase.h" -#include "titlewidget.h" +#include "widgets/titlewidget.h" #include "effectslist.h" #include @@ -35,7 +35,7 @@ #include #include -ProjectSettings::ProjectSettings(ProjectList *projectlist, QStringList lumas, int videotracks, int audiotracks, const QString projectPath, bool readOnlyTracks, bool savedProject, QWidget * parent) : +ProjectSettings::ProjectSettings(ProjectList *projectlist, QMap metadata, const QStringList &lumas, int videotracks, int audiotracks, const QString &projectPath, bool readOnlyTracks, bool savedProject, QWidget * parent) : QDialog(parent), m_savedProject(savedProject), m_projectList(projectlist), m_lumas(lumas) { setupUi(this); @@ -52,7 +52,7 @@ ProjectSettings::ProjectSettings(ProjectList *projectlist, QStringList lumas, in project_folder->setUrl(KUrl(projectPath)); QString currentProf = KdenliveSettings::current_profile(); - for (int i = 0; i < profiles_list->count(); i++) { + for (int i = 0; i < profiles_list->count(); ++i) { if (profiles_list->itemData(i).toString() == currentProf) { profiles_list->setCurrentIndex(i); break; @@ -94,8 +94,7 @@ ProjectSettings::ProjectSettings(ProjectList *projectlist, QStringList lumas, in // load proxy profiles - QString profileFile = KStandardDirs::locateLocal("appdata", "encodingprofiles.rc"); - KConfig conf(profileFile, KConfig::SimpleConfig); + KConfig conf("encodingprofiles.rc", KConfig::CascadeConfig, "appdata"); KConfigGroup group(&conf, "proxy"); QMap values = group.entryMap(); QMapIterator k(values); @@ -105,7 +104,7 @@ ProjectSettings::ProjectSettings(ProjectList *projectlist, QStringList lumas, in if (!k.key().isEmpty()) { QString params = k.value().section(';', 0, 0); QString extension = k.value().section(';', 1, 1); - if (params == proxyparameters && extension == proxyextension) { + if (ix == -1 && ((params == proxyparameters && extension == proxyextension) || (proxyparameters.isEmpty() || proxyextension.isEmpty()))) { // this is the current profile ix = proxy_profile->count(); } @@ -131,6 +130,64 @@ ProjectSettings::ProjectSettings(ProjectList *projectlist, QStringList lumas, in video_tracks->setEnabled(false); audio_tracks->setEnabled(false); } + + + // Metadata list + QTreeWidgetItem *item = new QTreeWidgetItem(metadata_list, QStringList() << i18n("Title")); + item->setData(0, Qt::UserRole, QString("meta.attr.title.markup")); + if (metadata.contains("meta.attr.title.markup")) { + item->setText(1, metadata.value("meta.attr.title.markup")); + metadata.remove("meta.attr.title.markup"); + } + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); + item = new QTreeWidgetItem(metadata_list, QStringList() << i18n("Author")); + item->setData(0, Qt::UserRole, QString("meta.attr.author.markup")); + if (metadata.contains("meta.attr.author.markup")) { + item->setText(1, metadata.value("meta.attr.author.markup")); + metadata.remove("meta.attr.author.markup"); + } + else if (metadata.contains("meta.attr.artist.markup")) { + item->setText(0, i18n("Artist")); + item->setData(0, Qt::UserRole, QString("meta.attr.artist.markup")); + item->setText(1, metadata.value("meta.attr.artist.markup")); + metadata.remove("meta.attr.artist.markup"); + } + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); + item = new QTreeWidgetItem(metadata_list, QStringList() << i18n("Copyright")); + item->setData(0, Qt::UserRole, QString("meta.attr.copyright.markup")); + if (metadata.contains("meta.attr.copyright.markup")) { + item->setText(1, metadata.value("meta.attr.copyright.markup")); + metadata.remove("meta.attr.copyright.markup"); + } + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); + item = new QTreeWidgetItem(metadata_list, QStringList() << i18n("Year")); + item->setData(0, Qt::UserRole, QString("meta.attr.year.markup")); + if (metadata.contains("meta.attr.year.markup")) { + item->setText(1, metadata.value("meta.attr.year.markup")); + metadata.remove("meta.attr.year.markup"); + } + else if (metadata.contains("meta.attr.date.markup")) { + item->setText(0, i18n("Date")); + item->setData(0, Qt::UserRole, QString("meta.attr.date.markup")); + item->setText(1, metadata.value("meta.attr.date.markup")); + metadata.remove("meta.attr.date.markup"); + } + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); + + QMap::const_iterator meta = metadata.constBegin(); + while (meta != metadata.constEnd()) { + item = new QTreeWidgetItem(metadata_list, QStringList() << meta.key().section('.', 2,2)); + item->setData(0, Qt::UserRole, meta.key()); + item->setText(1, meta.value()); + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); + ++meta; + } + + connect(add_metadata, SIGNAL(clicked()), this, SLOT(slotAddMetadataField())); + connect(delete_metadata, SIGNAL(clicked()), this, SLOT(slotDeleteMetadataField())); + add_metadata->setIcon(KIcon("list-add")); + delete_metadata->setIcon(KIcon("list-remove")); + slotUpdateDisplay(); if (m_projectList != NULL) { slotUpdateFiles(); @@ -139,7 +196,7 @@ ProjectSettings::ProjectSettings(ProjectList *projectlist, QStringList lumas, in connect(delete_proxies, SIGNAL(clicked()), this, SLOT(slotDeleteProxies())); } else tabWidget->widget(1)->setEnabled(false); connect(profiles_list, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateDisplay())); - connect(project_folder, SIGNAL(textChanged(const QString &)), this, SLOT(slotUpdateButton(const QString &))); + connect(project_folder, SIGNAL(textChanged(QString)), this, SLOT(slotUpdateButton(QString))); connect(button_export, SIGNAL(clicked()), this, SLOT(slotExportToText())); } @@ -147,16 +204,16 @@ void ProjectSettings::slotDeleteUnused() { QStringList toDelete; QList list = m_projectList->documentClipList(); - for (int i = 0; i < list.count(); i++) { + for (int i = 0; i < list.count(); ++i) { DocClipBase *clip = list.at(i); - if (clip->numReferences() == 0 && clip->clipType() != SLIDESHOW) { + if (clip->numReferences() == 0 && clip->clipType() != SlideShow) { KUrl url = clip->fileURL(); if (!url.isEmpty() && !toDelete.contains(url.path())) toDelete << url.path(); } } // make sure our urls are not used in another clip - for (int i = 0; i < list.count(); i++) { + for (int i = 0; i < list.count(); ++i) { DocClipBase *clip = list.at(i); if (clip->numReferences() > 0) { KUrl url = clip->fileURL(); @@ -187,8 +244,10 @@ void ProjectSettings::slotClearCache() void ProjectSettings::slotDeleteProxies() { + if (KMessageBox::warningContinueCancel(this, i18n("Deleting proxy clips will disable proxies for this project.")) != KMessageBox::Continue) return; buttonBox->setEnabled(false); - + enable_proxy->setChecked(false); + emit disableProxies(); KIO::NetAccess::del(KUrl(project_folder->url().path(KUrl::AddTrailingSlash) + "proxy/"), this); KStandardDirs::makeDir(project_folder->url().path(KUrl::AddTrailingSlash) + "proxy/"); buttonBox->setEnabled(true); @@ -216,7 +275,7 @@ void ProjectSettings::slotUpdateFiles(bool cacheOnly) // List all files that are used in the project. That also means: // images included in slideshow and titles, files in playlist clips - // TODO: images used in luma transitions, files used for LADSPA effects? + // TODO: images used in luma transitions? // Setup categories QTreeWidgetItem *videos = new QTreeWidgetItem(files_list, QStringList() << i18n("Video clips")); @@ -234,6 +293,9 @@ void ProjectSettings::slotUpdateFiles(bool cacheOnly) QTreeWidgetItem *texts = new QTreeWidgetItem(files_list, QStringList() << i18n("Text clips")); texts->setIcon(0, KIcon("text-plain")); texts->setExpanded(true); + QTreeWidgetItem *playlists = new QTreeWidgetItem(files_list, QStringList() << i18n("Playlist clips")); + playlists->setIcon(0, KIcon("video-mlt-playlist")); + playlists->setExpanded(true); QTreeWidgetItem *others = new QTreeWidgetItem(files_list, QStringList() << i18n("Other clips")); others->setIcon(0, KIcon("unknown")); others->setExpanded(true); @@ -244,9 +306,9 @@ void ProjectSettings::slotUpdateFiles(bool cacheOnly) new QTreeWidgetItem(images, QStringList() << file); } - for (int i = 0; i < list.count(); i++) { + for (int i = 0; i < list.count(); ++i) { DocClipBase *clip = list.at(i); - if (clip->clipType() == SLIDESHOW) { + if (clip->clipType() == SlideShow) { QStringList subfiles = extractSlideshowUrls(clip->fileURL()); foreach(const QString & file, subfiles) { count++; @@ -255,16 +317,19 @@ void ProjectSettings::slotUpdateFiles(bool cacheOnly) } else if (!clip->fileURL().isEmpty()) { //allFiles.append(clip->fileURL().path()); switch (clip->clipType()) { - case TEXT: + case Text: new QTreeWidgetItem(texts, QStringList() << clip->fileURL().path()); break; - case AUDIO: + case Audio: new QTreeWidgetItem(sounds, QStringList() << clip->fileURL().path()); break; - case IMAGE: + case Image: new QTreeWidgetItem(images, QStringList() << clip->fileURL().path()); break; - case UNKNOWN: + case Playlist: + new QTreeWidgetItem(playlists, QStringList() << clip->fileURL().path()); + break; + case Unknown: new QTreeWidgetItem(others, QStringList() << clip->fileURL().path()); break; default: @@ -273,7 +338,7 @@ void ProjectSettings::slotUpdateFiles(bool cacheOnly) } count++; } - if (clip->clipType() == TEXT) { + if (clip->clipType() == Text) { QStringList imagefiles = TitleWidget::extractImageList(clip->getProperty("xmldata")); QStringList fonts = TitleWidget::extractFontList(clip->getProperty("xmldata")); foreach(const QString & file, imagefiles) { @@ -281,7 +346,7 @@ void ProjectSettings::slotUpdateFiles(bool cacheOnly) new QTreeWidgetItem(images, QStringList() << file); } allFonts << fonts; - } else if (clip->clipType() == PLAYLIST) { + } else if (clip->clipType() == Playlist) { QStringList files = extractPlaylistUrls(clip->fileURL().path()); foreach(const QString & file, files) { count++; @@ -297,11 +362,9 @@ void ProjectSettings::slotUpdateFiles(bool cacheOnly) usedSize += clip->fileSize(); } } -#if QT_VERSION >= 0x040500 allFonts.removeDuplicates(); -#endif // Hide unused categories - for (int i = 0; i < files_list->topLevelItemCount(); i++) { + for (int i = 0; i < files_list->topLevelItemCount(); ++i) { if (files_list->topLevelItem(i)->childCount() == 0) { files_list->topLevelItem(i)->setHidden(true); } @@ -328,6 +391,7 @@ void ProjectSettings::accept() void ProjectSettings::slotUpdateDisplay() { + QLocale locale; QString currentProfile = profiles_list->itemData(profiles_list->currentIndex()).toString(); QMap< QString, QString > values = ProfilesDialog::getSettingsFromFile(currentProfile); p_size->setText(values.value("width") + 'x' + values.value("height")); @@ -336,7 +400,7 @@ void ProjectSettings::slotUpdateDisplay() p_display->setText(values.value("display_aspect_num") + '/' + values.value("display_aspect_den")); if (values.value("progressive").toInt() == 0) { p_progressive->setText(i18n("Interlaced (%1 fields per second)", - QString::number((double)2 * values.value("frame_rate_num").toInt() / values.value("frame_rate_den").toInt(), 'f', 2))); + locale.toString((double)2 * values.value("frame_rate_num").toInt() / values.value("frame_rate_den").toInt(), 'f', 2))); } else { p_progressive->setText(i18n("Progressive")); } @@ -362,7 +426,7 @@ KUrl ProjectSettings::selectedFolder() const return project_folder->url(); } -QPoint ProjectSettings::tracks() +QPoint ProjectSettings::tracks() const { QPoint p; p.setX(video_tracks->value()); @@ -418,7 +482,7 @@ QString ProjectSettings::proxyExtension() const } //static -QStringList ProjectSettings::extractPlaylistUrls(QString path) +QStringList ProjectSettings::extractPlaylistUrls(const QString &path) { QStringList urls; QDomDocument doc; @@ -433,11 +497,14 @@ QStringList ProjectSettings::extractPlaylistUrls(QString path) QString root = doc.documentElement().attribute("root"); if (!root.isEmpty() && !root.endsWith('/')) root.append('/'); QDomNodeList files = doc.elementsByTagName("producer"); - for (int i = 0; i < files.count(); i++) { + for (int i = 0; i < files.count(); ++i) { QDomElement e = files.at(i).toElement(); QString type = EffectsList::property(e, "mlt_service"); if (type != "colour") { QString url = EffectsList::property(e, "resource"); + if (type == "framebuffer") { + url = url.section('?', 0, 0); + } if (!url.isEmpty()) { if (!url.startsWith('/')) url.prepend(root); if (url.section('.', 0, -2).endsWith("/.all")) { @@ -454,7 +521,7 @@ QStringList ProjectSettings::extractPlaylistUrls(QString path) // luma files for transitions files = doc.elementsByTagName("transition"); - for (int i = 0; i < files.count(); i++) { + for (int i = 0; i < files.count(); ++i) { QDomElement e = files.at(i).toElement(); QString url = EffectsList::property(e, "luma"); if (!url.isEmpty()) { @@ -468,7 +535,7 @@ QStringList ProjectSettings::extractPlaylistUrls(QString path) //static -QStringList ProjectSettings::extractSlideshowUrls(KUrl url) +QStringList ProjectSettings::extractSlideshowUrls(const KUrl &url) { QStringList urls; QString path = url.directory(KUrl::AppendTrailingSlash); @@ -480,20 +547,20 @@ QStringList ProjectSettings::extractSlideshowUrls(KUrl url) filters << "*." + ext; dir.setNameFilters(filters); QStringList result = dir.entryList(QDir::Files); - urls.append(path + filters.at(0) + " (" + i18np("1 image found", "%1 images found", result.count()) + ")"); + urls.append(path + filters.at(0) + " (" + i18np("1 image found", "%1 images found", result.count()) + ')'); } else { // this is a pattern slideshow, like sequence%4d.jpg QString filter = url.fileName(); QString ext = filter.section('.', -1); filter = filter.section('%', 0, -2); - QString regexp = "^" + filter + "\\d+\\." + ext + "$"; + QString regexp = '^' + filter + "\\d+\\." + ext + '$'; QRegExp rx(regexp); int count = 0; QStringList result = dir.entryList(QDir::Files); foreach(const QString & path, result) { if (rx.exactMatch(path)) count++; } - urls.append(url.path() + " (" + i18np("1 image found", "%1 images found", count) + ")"); + urls.append(url.path() + " (" + i18np("1 image found", "%1 images found", count) + ')'); } return urls; } @@ -503,14 +570,14 @@ void ProjectSettings::slotExportToText() QString savePath = KFileDialog::getSaveFileName(project_folder->url(), "text/plain", this); if (savePath.isEmpty()) return; QString data; - data.append(i18n("Project folder: %1", project_folder->url().path()) + "\n"); - data.append(i18n("Project profile: %1", profiles_list->currentText()) + "\n"); + data.append(i18n("Project folder: %1", project_folder->url().path()) + '\n'); + data.append(i18n("Project profile: %1", profiles_list->currentText()) + '\n'); data.append(i18n("Total clips: %1 (%2 used in timeline).", files_count->text(), used_count->text()) + "\n\n"); - for (int i = 0; i < files_list->topLevelItemCount(); i++) { + for (int i = 0; i < files_list->topLevelItemCount(); ++i) { if (files_list->topLevelItem(i)->childCount() > 0) { - data.append("\n" + files_list->topLevelItem(i)->text(0) + ":\n\n"); + data.append('\n' + files_list->topLevelItem(i)->text(0) + ":\n\n"); for (int j = 0; j < files_list->topLevelItem(i)->childCount(); j++) { - data.append(files_list->topLevelItem(i)->child(j)->text(0) + "\n"); + data.append(files_list->topLevelItem(i)->child(j)->text(0) + '\n'); } } } @@ -520,7 +587,8 @@ void ProjectSettings::slotExportToText() return; } QFile xmlf(tmpfile.fileName()); - xmlf.open(QIODevice::WriteOnly); + if (!xmlf.open(QIODevice::WriteOnly)) + return; xmlf.write(data.toUtf8()); if (xmlf.error() != QFile::NoError) { xmlf.close(); @@ -536,6 +604,35 @@ void ProjectSettings::slotUpdateProxyParams() proxyparams->setPlainText(params.section(';', 0, 0)); } +const QMap ProjectSettings::metadata() const +{ + QMap metadata; + for (int i = 0; i < metadata_list->topLevelItemCount(); ++i) + { + QTreeWidgetItem *item = metadata_list->topLevelItem(i); + if (!item->text(1).simplified().isEmpty()) { + // Insert metadata entry + QString key = item->data(0, Qt::UserRole).toString(); + if (key.isEmpty()) key = "meta.attr." + item->text(0).simplified() + ".markup"; + QString value = item->text(1); + metadata.insert(key, value); + } + } + return metadata; +} + +void ProjectSettings::slotAddMetadataField() +{ + QTreeWidgetItem *item = new QTreeWidgetItem(metadata_list, QStringList() << i18n("field_name")); + item->setFlags(Qt::ItemIsEditable | Qt::ItemIsSelectable | Qt::ItemIsEnabled); +} + +void ProjectSettings::slotDeleteMetadataField() +{ + QTreeWidgetItem *item = metadata_list->currentItem(); + if (item) delete item; +} + #include "projectsettings.moc"