1 /***************************************************************************
2 * Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org) *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
18 ***************************************************************************/
20 #include "profilesdialog.h"
21 #include "kdenlivesettings.h"
23 #include <KStandardDirs>
25 #include <KMessageBox>
26 #include <KIO/NetAccess>
29 #include <QCloseEvent>
31 ProfilesDialog::ProfilesDialog(QWidget * parent): QDialog(parent), m_isCustomProfile(false), m_profileIsModified(false)
35 QStringList profilesFilter;
36 profilesFilter << "*";
38 m_view.button_delete->setIcon(KIcon("trash-empty"));
39 m_view.button_delete->setToolTip(i18n("Delete profile"));
40 m_view.button_save->setIcon(KIcon("document-save"));
41 m_view.button_save->setToolTip(i18n("Save profile"));
42 m_view.button_create->setIcon(KIcon("document-new"));
43 m_view.button_create->setToolTip(i18n("Create new profile"));
47 connect(m_view.profiles_list, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateDisplay()));
48 connect(m_view.button_create, SIGNAL(clicked()), this, SLOT(slotCreateProfile()));
49 connect(m_view.button_save, SIGNAL(clicked()), this, SLOT(slotSaveProfile()));
50 connect(m_view.button_delete, SIGNAL(clicked()), this, SLOT(slotDeleteProfile()));
51 connect(m_view.button_default, SIGNAL(clicked()), this, SLOT(slotSetDefaultProfile()));
53 connect(m_view.description, SIGNAL(textChanged(const QString &)), this, SLOT(slotProfileEdited()));
54 connect(m_view.frame_num, SIGNAL(valueChanged(int)), this, SLOT(slotProfileEdited()));
55 connect(m_view.frame_den, SIGNAL(valueChanged(int)), this, SLOT(slotProfileEdited()));
56 connect(m_view.aspect_num, SIGNAL(valueChanged(int)), this, SLOT(slotProfileEdited()));
57 connect(m_view.aspect_den, SIGNAL(valueChanged(int)), this, SLOT(slotProfileEdited()));
58 connect(m_view.display_num, SIGNAL(valueChanged(int)), this, SLOT(slotProfileEdited()));
59 connect(m_view.display_den, SIGNAL(valueChanged(int)), this, SLOT(slotProfileEdited()));
60 connect(m_view.progressive, SIGNAL(stateChanged(int)), this, SLOT(slotProfileEdited()));
61 connect(m_view.size_h, SIGNAL(valueChanged(int)), this, SLOT(slotProfileEdited()));
62 connect(m_view.size_w, SIGNAL(valueChanged(int)), this, SLOT(slotProfileEdited()));
65 void ProfilesDialog::slotProfileEdited()
67 m_profileIsModified = true;
70 void ProfilesDialog::fillList(const QString selectedProfile)
72 // List the Mlt profiles
73 m_view.profiles_list->clear();
74 QMap <QString, QString> profilesInfo = ProfilesDialog::getProfilesInfo();
75 QMapIterator<QString, QString> i(profilesInfo);
78 m_view.profiles_list->addItem(i.key(), i.value());
81 if (!KdenliveSettings::default_profile().isEmpty()) {
82 for (int i = 0; i < m_view.profiles_list->count(); i++) {
83 if (m_view.profiles_list->itemData(i).toString() == KdenliveSettings::default_profile()) {
84 m_view.profiles_list->setCurrentIndex(i);
89 int ix = m_view.profiles_list->findText(selectedProfile);
90 if (ix != -1) m_view.profiles_list->setCurrentIndex(ix);
91 m_selectedProfileIndex = m_view.profiles_list->currentIndex();
94 void ProfilesDialog::accept()
96 if (askForSave()) QDialog::accept();
99 void ProfilesDialog::closeEvent(QCloseEvent *event)
108 bool ProfilesDialog::askForSave()
110 if (!m_profileIsModified) return true;
111 if (KMessageBox::questionYesNo(this, i18n("The custom profile was modified, do you want to save it?")) != KMessageBox::Yes) return true;
112 return slotSaveProfile();
115 void ProfilesDialog::slotCreateProfile()
117 m_view.button_delete->setEnabled(false);
118 m_view.button_create->setEnabled(false);
119 m_view.button_save->setEnabled(true);
120 m_view.properties->setEnabled(true);
123 void ProfilesDialog::slotSetDefaultProfile()
125 int ix = m_view.profiles_list->currentIndex();
126 QString path = m_view.profiles_list->itemData(ix).toString();
127 if (!path.isEmpty()) KdenliveSettings::setDefault_profile(path);
130 bool ProfilesDialog::slotSaveProfile()
132 const QString profileDesc = m_view.description->text();
133 int ix = m_view.profiles_list->findText(profileDesc);
135 // this profile name already exists
136 const QString path = m_view.profiles_list->itemData(ix).toString();
137 if (!path.contains('/')) {
138 KMessageBox::sorry(this, i18n("A profile with same name already exists in MLT's default profiles, please choose another description for your custom profile."));
144 QString customName = "profiles/customprofile";
145 QString profilePath = KStandardDirs::locateLocal("appdata", customName + QString::number(i));
146 kDebug() << " TYING PROFILE FILE: " << profilePath;
147 while (KIO::NetAccess::exists(KUrl(profilePath), KIO::NetAccess::SourceSide, this)) {
149 profilePath = KStandardDirs::locateLocal("appdata", customName + QString::number(i));
151 saveProfile(profilePath);
153 m_profileIsModified = false;
154 fillList(profileDesc);
155 m_view.button_create->setEnabled(true);
159 void ProfilesDialog::saveProfile(const QString path)
162 if (!file.open(QIODevice::WriteOnly)) {
163 KMessageBox::sorry(this, i18n("Cannot write to file %1", path));
166 QTextStream out(&file);
167 out << "description=" << m_view.description->text() << "\n" << "frame_rate_num=" << m_view.frame_num->value() << "\n" << "frame_rate_den=" << m_view.frame_den->value() << "\n" << "width=" << m_view.size_w->value() << "\n" << "height=" << m_view.size_h->value() << "\n" << "progressive=" << m_view.progressive->isChecked() << "\n" << "sample_aspect_num=" << m_view.aspect_num->value() << "\n" << "sample_aspect_den=" << m_view.aspect_den->value() << "\n" << "display_aspect_num=" << m_view.display_num->value() << "\n" << "display_aspect_den=" << m_view.display_den->value() << "\n";
168 if (file.error() != QFile::NoError) {
169 KMessageBox::error(this, i18n("Cannot write to file %1", path));
174 void ProfilesDialog::slotDeleteProfile()
176 const QString path = m_view.profiles_list->itemData(m_view.profiles_list->currentIndex()).toString();
177 if (path.contains('/')) {
178 KIO::NetAccess::del(KUrl(path), this);
180 } else kDebug() << "//// Cannot delete profile " << path << ", does not seem to be custom one";
184 MltVideoProfile ProfilesDialog::getVideoProfile(QString name)
186 MltVideoProfile result;
187 QStringList profilesNames;
188 QStringList profilesFiles;
189 QStringList profilesFilter;
190 profilesFilter << "*";
192 bool isCustom = false;
193 if (name.contains('/')) isCustom = true;
196 // List the Mlt profiles
197 profilesFiles = QDir(KdenliveSettings::mltpath()).entryList(profilesFilter, QDir::Files);
198 if (profilesFiles.contains(name)) path = KdenliveSettings::mltpath() + '/' + name;
200 if (isCustom || path.isEmpty()) {
204 if (path.isEmpty() || !QFile::exists(path)) {
205 if (name == "dv_pal") {
206 kDebug() << "!!! WARNING, COULD NOT FIND DEFAULT MLT PROFILE";
209 if (name == KdenliveSettings::default_profile()) KdenliveSettings::setDefault_profile("dv_pal");
210 kDebug() << "// WARNING, COULD NOT FIND PROFILE " << name;
211 return getVideoProfile("dv_pal");
213 KConfig confFile(path, KConfig::SimpleConfig);
215 result.description = confFile.entryMap().value("description");
216 result.frame_rate_num = confFile.entryMap().value("frame_rate_num").toInt();
217 result.frame_rate_den = confFile.entryMap().value("frame_rate_den").toInt();
218 result.width = confFile.entryMap().value("width").toInt();
219 result.height = confFile.entryMap().value("height").toInt();
220 result.progressive = confFile.entryMap().value("progressive").toInt();
221 result.sample_aspect_num = confFile.entryMap().value("sample_aspect_num").toInt();
222 result.sample_aspect_den = confFile.entryMap().value("sample_aspect_den").toInt();
223 result.display_aspect_num = confFile.entryMap().value("display_aspect_num").toInt();
224 result.display_aspect_den = confFile.entryMap().value("display_aspect_den").toInt();
229 QString ProfilesDialog::getProfileDescription(QString name)
231 QStringList profilesNames;
232 QStringList profilesFiles;
233 QStringList profilesFilter;
234 profilesFilter << "*";
236 // List the Mlt profiles
237 profilesFiles = QDir(KdenliveSettings::mltpath()).entryList(profilesFilter, QDir::Files);
238 if (profilesFiles.contains(name)) {
239 KConfig confFile(KdenliveSettings::mltpath() + '/' + name, KConfig::SimpleConfig);
240 return confFile.entryMap().value("description");
243 // List custom profiles
244 QStringList customProfiles = KGlobal::dirs()->findDirs("appdata", "profiles");
245 for (int i = 0; i < customProfiles.size(); ++i) {
246 profilesFiles = QDir(customProfiles.at(i)).entryList(profilesFilter, QDir::Files);
247 if (profilesFiles.contains(name)) {
248 KConfig confFile(customProfiles.at(i) + '/' + name, KConfig::SimpleConfig);
249 return confFile.entryMap().value("description");
257 QMap <QString, QString> ProfilesDialog::getProfilesInfo()
259 QMap <QString, QString> result;
260 QStringList profilesFilter;
261 profilesFilter << "*";
263 // List the Mlt profiles
264 QStringList profilesFiles = QDir(KdenliveSettings::mltpath()).entryList(profilesFilter, QDir::Files);
265 for (int i = 0; i < profilesFiles.size(); ++i) {
266 KConfig confFile(KdenliveSettings::mltpath() + '/' + profilesFiles.at(i), KConfig::SimpleConfig);
267 QString desc = confFile.entryMap().value("description");
268 if (!desc.isEmpty()) result.insert(desc, profilesFiles.at(i));
271 // List custom profiles
272 QStringList customProfiles = KGlobal::dirs()->findDirs("appdata", "profiles");
273 for (int i = 0; i < customProfiles.size(); ++i) {
274 profilesFiles = QDir(customProfiles.at(i)).entryList(profilesFilter, QDir::Files);
275 for (int j = 0; j < profilesFiles.size(); ++j) {
276 KConfig confFile(customProfiles.at(i) + '/' + profilesFiles.at(j), KConfig::SimpleConfig);
277 QString desc = confFile.entryMap().value("description");
278 if (!desc.isEmpty()) result.insert(desc, customProfiles.at(i) + '/' + profilesFiles.at(j));
285 QMap< QString, QString > ProfilesDialog::getSettingsFromFile(const QString path)
287 QStringList profilesNames;
288 QStringList profilesFiles;
289 QStringList profilesFilter;
290 profilesFilter << "*";
292 if (!path.contains('/')) {
293 // This is an MLT profile
294 KConfig confFile(KdenliveSettings::mltpath() + '/' + path, KConfig::SimpleConfig);
295 return confFile.entryMap();
297 // This is a custom profile
298 KConfig confFile(path, KConfig::SimpleConfig);
299 return confFile.entryMap();
304 QMap< QString, QString > ProfilesDialog::getSettingsForProfile(const QString profileName)
306 QStringList profilesNames;
307 QStringList profilesFiles;
308 QStringList profilesFilter;
309 profilesFilter << "*";
311 // List the Mlt profiles
312 profilesFiles = QDir(KdenliveSettings::mltpath()).entryList(profilesFilter, QDir::Files);
313 for (int i = 0; i < profilesFiles.size(); ++i) {
314 KConfig confFile(KdenliveSettings::mltpath() + '/' + profilesFiles.at(i), KConfig::SimpleConfig);
315 QMap< QString, QString > values = confFile.entryMap();
316 if (values.value("description") == profileName) {
317 values.insert("path", profilesFiles.at(i));
322 // List custom profiles
323 QStringList customProfiles = KGlobal::dirs()->findDirs("appdata", "profiles");
324 for (int i = 0; i < customProfiles.size(); ++i) {
325 QStringList profiles = QDir(customProfiles.at(i)).entryList(profilesFilter, QDir::Files);
326 for (int i = 0; i < profiles.size(); ++i) {
327 KConfig confFile(customProfiles.at(i) + '/' + profiles.at(i), KConfig::SimpleConfig);
328 QMap< QString, QString > values = confFile.entryMap();
329 if (values.value("description") == profileName) {
330 values.insert("path", customProfiles.at(i) + '/' + profiles.at(i));
335 return QMap< QString, QString >();
339 QString ProfilesDialog::getPathFromDescription(const QString profileDesc)
341 QStringList profilesNames;
342 QStringList profilesFiles;
343 QStringList profilesFilter;
344 profilesFilter << "*";
346 // List the Mlt profiles
347 profilesFiles = QDir(KdenliveSettings::mltpath()).entryList(profilesFilter, QDir::Files);
348 for (int i = 0; i < profilesFiles.size(); ++i) {
349 KConfig confFile(KdenliveSettings::mltpath() + '/' + profilesFiles.at(i), KConfig::SimpleConfig);
350 QMap< QString, QString > values = confFile.entryMap();
351 if (values.value("description") == profileDesc) return profilesFiles.at(i);
354 // List custom profiles
355 QStringList customProfiles = KGlobal::dirs()->findDirs("appdata", "profiles");
356 for (int i = 0; i < customProfiles.size(); ++i) {
357 QStringList profiles = QDir(customProfiles.at(i)).entryList(profilesFilter, QDir::Files);
358 for (int i = 0; i < profiles.size(); ++i) {
359 KConfig confFile(customProfiles.at(i) + '/' + profiles.at(i), KConfig::SimpleConfig);
360 QMap< QString, QString > values = confFile.entryMap();
361 if (values.value("description") == profileDesc) return customProfiles.at(i) + '/' + profiles.at(i);
368 void ProfilesDialog::slotUpdateDisplay()
370 if (askForSave() == false) {
371 m_view.profiles_list->blockSignals(true);
372 m_view.profiles_list->setCurrentIndex(m_selectedProfileIndex);
373 m_view.profiles_list->blockSignals(false);
377 m_selectedProfileIndex = m_view.profiles_list->currentIndex();
378 QString currentProfile = m_view.profiles_list->itemData(m_view.profiles_list->currentIndex()).toString();
379 m_isCustomProfile = currentProfile.contains('/');
380 m_view.button_delete->setEnabled(m_isCustomProfile);
381 m_view.properties->setEnabled(m_isCustomProfile);
382 m_view.button_save->setEnabled(m_isCustomProfile);
383 QMap< QString, QString > values = ProfilesDialog::getSettingsFromFile(currentProfile);
384 m_view.description->setText(values.value("description"));
385 m_view.size_w->setValue(values.value("width").toInt());
386 m_view.size_h->setValue(values.value("height").toInt());
387 m_view.aspect_num->setValue(values.value("sample_aspect_num").toInt());
388 m_view.aspect_den->setValue(values.value("sample_aspect_den").toInt());
389 m_view.display_num->setValue(values.value("display_aspect_num").toInt());
390 m_view.display_den->setValue(values.value("display_aspect_den").toInt());
391 m_view.frame_num->setValue(values.value("frame_rate_num").toInt());
392 m_view.frame_den->setValue(values.value("frame_rate_den").toInt());
393 m_view.progressive->setChecked(values.value("progressive").toInt());
394 m_profileIsModified = false;
398 #include "profilesdialog.moc"