]> git.sesse.net Git - kdenlive/blob - src/kdenlivesettingsdialog.cpp
Remove support for non-OpenGL main monitor.
[kdenlive] / src / kdenlivesettingsdialog.cpp
1 /***************************************************************************
2  *   Copyright (C) 2008 by Jean-Baptiste Mardelle (jb@kdenlive.org)        *
3  *                                                                         *
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.                                   *
8  *                                                                         *
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.                          *
13  *                                                                         *
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  ***************************************************************************/
19
20 #include "kdenlivesettingsdialog.h"
21 #include "profilesdialog.h"
22 #ifdef USE_V4L
23 #include "v4l/v4lcapture.h"
24 #endif
25 #include "encodingprofilesdialog.h"
26 #include "kdenlivesettings.h"
27 #include "renderer.h"
28
29 #include <KStandardDirs>
30 #include <KDebug>
31 #include <kopenwithdialog.h>
32 #include <KConfigDialogManager>
33 #include <kde_file.h>
34 #include <KIO/NetAccess>
35 #include <kdeversion.h>
36 #include <KMessageBox>
37
38 #include <QDir>
39 #include <QTimer>
40 #include <QTreeWidgetItem>
41 #include <QThread>
42
43 #include <stdlib.h>
44 #include <stdio.h>
45 #include <unistd.h>
46 #include <fcntl.h>
47
48 #ifdef USE_JOGSHUTTLE
49   #include "jogaction.h"
50   #include "jogshuttleconfig.h"
51   #include <linux/input.h>
52 #endif
53
54
55 KdenliveSettingsDialog::KdenliveSettingsDialog(const QMap<QString, QString>& mappable_actions, QWidget * parent) :
56     KConfigDialog(parent, "settings", KdenliveSettings::self()),
57     m_modified(false),
58     m_shuttleModified(false),
59     m_mappable_actions(mappable_actions)
60 {
61     KdenliveSettings::setV4l_format(0);
62     QWidget *p1 = new QWidget;
63     m_configMisc.setupUi(p1);
64     m_page1 = addPage(p1, i18n("Misc"), "configure");
65
66     // Hide multi tab option until Kdenlive really supports it
67     m_configMisc.kcfg_activatetabs->setVisible(false);
68     // Hide avformat-novalidate trick, causes crash (bug #2205 and #2206)
69     m_configMisc.kcfg_projectloading_avformatnovalidate->setVisible(false);
70     
71     m_configMisc.kcfg_use_exiftool->setEnabled(!KStandardDirs::findExe("exiftool").isEmpty());
72
73     QWidget *p8 = new QWidget;
74     m_configProject.setupUi(p8);
75     m_page8 = addPage(p8, i18n("Project Defaults"), "document-new");
76     connect(m_configProject.kcfg_generateproxy, SIGNAL(toggled(bool)), m_configProject.kcfg_proxyminsize, SLOT(setEnabled(bool)));
77     m_configProject.kcfg_proxyminsize->setEnabled(KdenliveSettings::generateproxy());
78     connect(m_configProject.kcfg_generateimageproxy, SIGNAL(toggled(bool)), m_configProject.kcfg_proxyimageminsize, SLOT(setEnabled(bool)));
79     m_configProject.kcfg_proxyimageminsize->setEnabled(KdenliveSettings::generateimageproxy());
80
81     QWidget *p3 = new QWidget;
82     m_configTimeline.setupUi(p3);
83     m_page3 = addPage(p3, i18n("Timeline"), "video-display");
84
85     QWidget *p2 = new QWidget;
86     m_configEnv.setupUi(p2);
87     m_configEnv.mltpathurl->setMode(KFile::Directory);
88     m_configEnv.mltpathurl->lineEdit()->setObjectName("kcfg_mltpath");
89     m_configEnv.rendererpathurl->lineEdit()->setObjectName("kcfg_rendererpath");
90     m_configEnv.ffmpegurl->lineEdit()->setObjectName("kcfg_ffmpegpath");
91     m_configEnv.ffplayurl->lineEdit()->setObjectName("kcfg_ffplaypath");
92     m_configEnv.kcfg_mltthreads->setMaximum( QThread::idealThreadCount() < 4 ? QThread::idealThreadCount() : 3 );
93     m_configEnv.tmppathurl->setMode(KFile::Directory);
94     m_configEnv.tmppathurl->lineEdit()->setObjectName("kcfg_currenttmpfolder");
95     m_configEnv.projecturl->setMode(KFile::Directory);
96     m_configEnv.projecturl->lineEdit()->setObjectName("kcfg_defaultprojectfolder");
97     m_configEnv.capturefolderurl->setMode(KFile::Directory);
98     m_configEnv.capturefolderurl->lineEdit()->setObjectName("kcfg_capturefolder");
99     m_configEnv.capturefolderurl->setEnabled(!KdenliveSettings::capturetoprojectfolder());
100     connect(m_configEnv.kcfg_capturetoprojectfolder, SIGNAL(clicked()), this, SLOT(slotEnableCaptureFolder()));
101     m_page2 = addPage(p2, i18n("Environment"), "application-x-executable-script");
102
103     QWidget *p4 = new QWidget;
104     m_configCapture.setupUi(p4);
105
106 #ifdef USE_V4L
107
108     // Video 4 Linux device detection
109     for (int i = 0; i < 10; ++i) {
110         QString path = QLatin1String("/dev/video") + QString::number(i);
111         if (QFile::exists(path)) {
112             QStringList deviceInfo = V4lCaptureHandler::getDeviceName(path);
113             if (!deviceInfo.isEmpty()) {
114                 m_configCapture.kcfg_detectedv4ldevices->addItem(deviceInfo.at(0), path);
115                 m_configCapture.kcfg_detectedv4ldevices->setItemData(m_configCapture.kcfg_detectedv4ldevices->count() - 1, deviceInfo.at(1), Qt::UserRole + 1);
116             }
117         }
118     }
119     connect(m_configCapture.kcfg_detectedv4ldevices, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdatev4lDevice()));
120     connect(m_configCapture.kcfg_v4l_format, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdatev4lCaptureProfile()));
121     connect(m_configCapture.config_v4l, SIGNAL(clicked()), this, SLOT(slotEditVideo4LinuxProfile()));
122
123     slotUpdatev4lDevice();
124 #endif
125
126     m_page4 = addPage(p4, i18n("Capture"), "media-record");
127     m_configCapture.tabWidget->setCurrentIndex(KdenliveSettings::defaultcapture());
128 #ifdef Q_WS_MAC
129     m_configCapture.tabWidget->setEnabled(false);
130     m_configCapture.kcfg_defaultcapture->setEnabled(false);
131     m_configCapture.label->setText(i18n("Capture is not yet available on Mac OS X."));
132 #endif
133
134     QWidget *p5 = new QWidget;
135     m_configShuttle.setupUi(p5);
136     m_configShuttle.toolBtnReload->setIcon(KIcon("view-refresh"));
137 #ifdef USE_JOGSHUTTLE
138     connect(m_configShuttle.kcfg_enableshuttle, SIGNAL(stateChanged(int)), this, SLOT(slotCheckShuttle(int)));
139     connect(m_configShuttle.shuttledevicelist, SIGNAL(activated(int)), this, SLOT(slotUpdateShuttleDevice(int)));
140     connect(m_configShuttle.toolBtnReload, SIGNAL(clicked(bool)), this, SLOT(slotReloadShuttleDevices()));
141
142     slotCheckShuttle(KdenliveSettings::enableshuttle());
143     m_configShuttle.shuttledisabled->hide();
144
145     // Store the button pointers into an array for easier handling them in the other functions.
146     // TODO: impl enumerator or live with cut and paste :-)))
147     setupJogshuttleBtns(KdenliveSettings::shuttledevice());
148
149 #if 0
150     m_shuttle_buttons.push_back(m_configShuttle.shuttle1);
151     m_shuttle_buttons.push_back(m_configShuttle.shuttle2);
152     m_shuttle_buttons.push_back(m_configShuttle.shuttle3);
153     m_shuttle_buttons.push_back(m_configShuttle.shuttle4);
154     m_shuttle_buttons.push_back(m_configShuttle.shuttle5);
155     m_shuttle_buttons.push_back(m_configShuttle.shuttle6);
156     m_shuttle_buttons.push_back(m_configShuttle.shuttle7);
157     m_shuttle_buttons.push_back(m_configShuttle.shuttle8);
158     m_shuttle_buttons.push_back(m_configShuttle.shuttle9);
159     m_shuttle_buttons.push_back(m_configShuttle.shuttle10);
160     m_shuttle_buttons.push_back(m_configShuttle.shuttle11);
161     m_shuttle_buttons.push_back(m_configShuttle.shuttle12);
162     m_shuttle_buttons.push_back(m_configShuttle.shuttle13);
163     m_shuttle_buttons.push_back(m_configShuttle.shuttle14);
164     m_shuttle_buttons.push_back(m_configShuttle.shuttle15);
165 #endif
166
167 #else /* ! USE_JOGSHUTTLE */
168     m_configShuttle.kcfg_enableshuttle->hide();
169     m_configShuttle.kcfg_enableshuttle->setDisabled(true);
170 #endif /* USE_JOGSHUTTLE */
171     m_page5 = addPage(p5, i18n("JogShuttle"), "input-mouse");
172
173     QWidget *p6 = new QWidget;
174     m_configSdl.setupUi(p6);
175     m_configSdl.reload_blackmagic->setIcon(KIcon("view-refresh"));
176     connect(m_configSdl.reload_blackmagic, SIGNAL(clicked(bool)), this, SLOT(slotReloadBlackMagic()));
177
178     m_page6 = addPage(p6, i18n("Playback"), "media-playback-start");
179
180     QWidget *p7 = new QWidget;
181     m_configTranscode.setupUi(p7);
182     m_page7 = addPage(p7, i18n("Transcode"), "edit-copy");
183     connect(m_configTranscode.button_add, SIGNAL(clicked()), this, SLOT(slotAddTranscode()));
184     connect(m_configTranscode.button_delete, SIGNAL(clicked()), this, SLOT(slotDeleteTranscode()));
185     connect(m_configTranscode.profiles_list, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(slotDialogModified()));
186     connect(m_configTranscode.profiles_list, SIGNAL(currentRowChanged(int)), this, SLOT(slotSetTranscodeProfile()));
187     
188     connect(m_configTranscode.profile_name, SIGNAL(textChanged(QString)), this, SLOT(slotEnableTranscodeUpdate()));
189     connect(m_configTranscode.profile_description, SIGNAL(textChanged(QString)), this, SLOT(slotEnableTranscodeUpdate()));
190     connect(m_configTranscode.profile_extension, SIGNAL(textChanged(QString)), this, SLOT(slotEnableTranscodeUpdate()));
191     connect(m_configTranscode.profile_parameters, SIGNAL(textChanged()), this, SLOT(slotEnableTranscodeUpdate()));
192     connect(m_configTranscode.profile_audioonly, SIGNAL(stateChanged(int)), this, SLOT(slotEnableTranscodeUpdate()));
193     
194     connect(m_configTranscode.button_update, SIGNAL(pressed()), this, SLOT(slotUpdateTranscodingProfile()));
195     
196     m_configTranscode.profile_parameters->setMaximumHeight(QFontMetrics(font()).lineSpacing() * 5);
197
198     connect(m_configEnv.kp_image, SIGNAL(clicked()), this, SLOT(slotEditImageApplication()));
199     connect(m_configEnv.kp_audio, SIGNAL(clicked()), this, SLOT(slotEditAudioApplication()));
200     connect(m_configEnv.kp_player, SIGNAL(clicked()), this, SLOT(slotEditVideoApplication()));
201
202     loadEncodingProfiles();
203     checkProfile();
204
205     slotUpdateDisplay();
206
207     connect(m_configSdl.kcfg_audio_driver, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCheckAlsaDriver()));
208     initDevices();
209     connect(m_configProject.kcfg_profiles_list, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateDisplay()));
210     connect(m_configCapture.kcfg_grab_capture_type, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateGrabRegionStatus()));
211
212     slotUpdateGrabRegionStatus();
213     loadTranscodeProfiles();
214
215
216     //HACK: check dvgrab version, because only dvgrab >= 3.3 supports
217     //   --timestamp option without bug
218
219     if (KdenliveSettings::dvgrab_path().isEmpty() || !QFile::exists(KdenliveSettings::dvgrab_path())) {
220         QString dvgrabpath = KStandardDirs::findExe("dvgrab");
221         KdenliveSettings::setDvgrab_path(dvgrabpath);
222     }
223
224     // decklink profile
225     m_configCapture.decklink_showprofileinfo->setIcon(KIcon("help-about"));
226     m_configCapture.decklink_manageprofile->setIcon(KIcon("configure"));
227     m_configCapture.decklink_parameters->setVisible(false);
228     m_configCapture.decklink_parameters->setMaximumHeight(QFontMetrics(font()).lineSpacing() * 4);
229     m_configCapture.decklink_parameters->setPlainText(KdenliveSettings::decklink_parameters());
230     connect(m_configCapture.decklink_manageprofile, SIGNAL(clicked(bool)), this, SLOT(slotManageEncodingProfile()));
231     connect(m_configCapture.kcfg_decklink_profile, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateDecklinkProfile()));
232     connect(m_configCapture.decklink_showprofileinfo, SIGNAL(clicked(bool)), m_configCapture.decklink_parameters, SLOT(setVisible(bool)));
233
234     // ffmpeg profile
235     m_configCapture.v4l_showprofileinfo->setIcon(KIcon("help-about"));
236     m_configCapture.v4l_manageprofile->setIcon(KIcon("configure"));
237     m_configCapture.v4l_parameters->setVisible(false);
238     m_configCapture.v4l_parameters->setMaximumHeight(QFontMetrics(font()).lineSpacing() * 4);
239     m_configCapture.v4l_parameters->setPlainText(KdenliveSettings::v4l_parameters());
240     connect(m_configCapture.v4l_manageprofile, SIGNAL(clicked(bool)), this, SLOT(slotManageEncodingProfile()));
241     connect(m_configCapture.kcfg_v4l_profile, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateV4lProfile()));
242     connect(m_configCapture.v4l_showprofileinfo, SIGNAL(clicked(bool)), m_configCapture.v4l_parameters, SLOT(setVisible(bool)));
243     
244     // screen grab profile
245     m_configCapture.grab_showprofileinfo->setIcon(KIcon("help-about"));
246     m_configCapture.grab_manageprofile->setIcon(KIcon("configure"));
247     m_configCapture.grab_parameters->setVisible(false);
248     m_configCapture.grab_parameters->setMaximumHeight(QFontMetrics(font()).lineSpacing() * 4);
249     m_configCapture.grab_parameters->setPlainText(KdenliveSettings::grab_parameters());
250     connect(m_configCapture.grab_manageprofile, SIGNAL(clicked(bool)), this, SLOT(slotManageEncodingProfile()));
251     connect(m_configCapture.kcfg_grab_profile, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateGrabProfile()));
252     connect(m_configCapture.grab_showprofileinfo, SIGNAL(clicked(bool)), m_configCapture.grab_parameters, SLOT(setVisible(bool)));
253
254     // proxy profile stuff
255     m_configProject.proxy_showprofileinfo->setIcon(KIcon("help-about"));
256     m_configProject.proxy_manageprofile->setIcon(KIcon("configure"));
257     m_configProject.proxyparams->setVisible(false);
258     m_configProject.proxyparams->setMaximumHeight(QFontMetrics(font()).lineSpacing() * 4);
259     m_configProject.proxyparams->setPlainText(KdenliveSettings::proxyparams());
260     connect(m_configProject.proxy_manageprofile, SIGNAL(clicked(bool)), this, SLOT(slotManageEncodingProfile()));
261     connect(m_configProject.proxy_showprofileinfo, SIGNAL(clicked(bool)), m_configProject.proxyparams, SLOT(setVisible(bool)));
262     connect(m_configProject.kcfg_proxy_profile, SIGNAL(currentIndexChanged(int)), this, SLOT(slotUpdateProxyProfile()));
263
264
265     slotUpdateProxyProfile(-1);
266     slotUpdateV4lProfile(-1);
267     slotUpdateGrabProfile(-1);
268     slotUpdateDecklinkProfile(-1);
269
270     Render::getBlackMagicDeviceList(m_configCapture.kcfg_decklink_capturedevice);
271     if (!Render::getBlackMagicOutputDeviceList(m_configSdl.kcfg_blackmagic_output_device)) {
272         // No blackmagic card found
273         m_configSdl.kcfg_external_display->setEnabled(false);
274     }
275
276     double dvgrabVersion = 0;
277     if (!KdenliveSettings::dvgrab_path().isEmpty()) {
278         QProcess *versionCheck = new QProcess;
279         versionCheck->setProcessChannelMode(QProcess::MergedChannels);
280         versionCheck->start("dvgrab", QStringList() << "--version");
281         if (versionCheck->waitForFinished()) {
282             QString version = QString(versionCheck->readAll()).simplified();
283             if (version.contains(' ')) version = version.section(' ', -1);
284             dvgrabVersion = version.toDouble();
285
286             kDebug() << "// FOUND DVGRAB VERSION: " << dvgrabVersion;
287         }
288         delete versionCheck;
289         if (dvgrabVersion < 3.3) {
290             KdenliveSettings::setFirewiretimestamp(false);
291             m_configCapture.kcfg_firewiretimestamp->setEnabled(false);
292         }
293         m_configCapture.dvgrab_info->setText(i18n("dvgrab version %1 at %2", dvgrabVersion, KdenliveSettings::dvgrab_path()));
294     } else m_configCapture.dvgrab_info->setText(i18n("<strong><em>dvgrab</em> utility not found, please install it for firewire capture</strong>"));
295 }
296
297 void KdenliveSettingsDialog::setupJogshuttleBtns(QString device)
298 {
299     QList<KComboBox*> list;
300     QList<QLabel*> list1;
301
302     list << m_configShuttle.shuttle1;
303     list << m_configShuttle.shuttle2;
304     list << m_configShuttle.shuttle3;
305     list << m_configShuttle.shuttle4;
306     list << m_configShuttle.shuttle5;
307     list << m_configShuttle.shuttle6;
308     list << m_configShuttle.shuttle7;
309     list << m_configShuttle.shuttle8;
310     list << m_configShuttle.shuttle9;
311     list << m_configShuttle.shuttle10;
312     list << m_configShuttle.shuttle11;
313     list << m_configShuttle.shuttle12;
314     list << m_configShuttle.shuttle13;
315     list << m_configShuttle.shuttle14;
316     list << m_configShuttle.shuttle15;
317
318     list1 << m_configShuttle.label_2; // #1
319     list1 << m_configShuttle.label_4; // #2
320     list1 << m_configShuttle.label_3; // #3
321     list1 << m_configShuttle.label_7; // #4
322     list1 << m_configShuttle.label_5; // #5
323     list1 << m_configShuttle.label_6; // #6
324     list1 << m_configShuttle.label_8; // #7
325     list1 << m_configShuttle.label_9; // #8
326     list1 << m_configShuttle.label_10; // #9
327     list1 << m_configShuttle.label_11; // #10
328     list1 << m_configShuttle.label_12; // #11
329     list1 << m_configShuttle.label_13; // #12
330     list1 << m_configShuttle.label_14; // #13
331     list1 << m_configShuttle.label_15; // #14
332     list1 << m_configShuttle.label_16; // #15
333
334
335     for (int i = 0; i < list.count(); i++) {
336         list[i]->hide();
337         list1[i]->hide();
338     }
339
340 #ifdef USE_JOGSHUTTLE
341     int keysCount = JogShuttle::keysCount(device);
342
343     for (int i = 0; i < keysCount; i++) {
344         m_shuttle_buttons.push_back(list[i]);
345         list[i]->show();
346         list1[i]->show();
347     }
348
349     // populate the buttons with the current configuration. The items are sorted
350     // according to the user-selected language, so they do not appear in random order.
351     QMap<QString, QString> mappable_actions(m_mappable_actions);
352     QList<QString> action_names = mappable_actions.keys();
353     QList<QString>::Iterator iter = action_names.begin();
354     kDebug() << "::::::::::::::::";
355     while (iter != action_names.end()) {
356         kDebug() << *iter;
357         ++iter;
358     }
359
360     kDebug() << "::::::::::::::::";
361
362     qSort(action_names);
363     iter = action_names.begin();
364     while (iter != action_names.end()) {
365         kDebug() << *iter;
366         ++iter;
367     }
368     kDebug() << "::::::::::::::::";
369
370     // Here we need to compute the action_id -> index-in-action_names. We iterate over the
371     // action_names, as the sorting may depend on the user-language.
372     QStringList actions_map = JogShuttleConfig::actionMap(KdenliveSettings::shuttlebuttons());
373     QMap<QString, int> action_pos;
374     foreach (const QString& action_id, actions_map) {
375         // This loop find out at what index is the string that would map to the action_id.
376         for (int i = 0; i < action_names.size(); ++i) {
377             if (mappable_actions[action_names.at(i)] == action_id) {
378                 action_pos[action_id] = i;
379                 break;
380             }
381         }
382     }
383
384     int i = 0;
385     foreach (KComboBox* button, m_shuttle_buttons) {
386         button->addItems(action_names);
387         connect(button, SIGNAL(activated(int)), this, SLOT(slotShuttleModified()));
388         ++i;
389         if (i < actions_map.size())
390             button->setCurrentIndex(action_pos[actions_map[i]]);
391     }
392 #endif
393 }
394
395 KdenliveSettingsDialog::~KdenliveSettingsDialog() {}
396
397 void KdenliveSettingsDialog::slotUpdateGrabRegionStatus()
398 {
399     m_configCapture.region_group->setHidden(m_configCapture.kcfg_grab_capture_type->currentIndex() != 1);
400 }
401
402 void KdenliveSettingsDialog::slotEnableCaptureFolder()
403 {
404     m_configEnv.capturefolderurl->setEnabled(!m_configEnv.kcfg_capturetoprojectfolder->isChecked());
405 }
406
407 void KdenliveSettingsDialog::checkProfile()
408 {
409     m_configProject.kcfg_profiles_list->clear();
410     QMap <QString, QString> profilesInfo = ProfilesDialog::getProfilesInfo();
411     QMapIterator<QString, QString> i(profilesInfo);
412     while (i.hasNext()) {
413         i.next();
414         m_configProject.kcfg_profiles_list->addItem(i.key(), i.value());
415     }
416
417     if (!KdenliveSettings::default_profile().isEmpty()) {
418         for (int i = 0; i < m_configProject.kcfg_profiles_list->count(); ++i) {
419             if (m_configProject.kcfg_profiles_list->itemData(i).toString() == KdenliveSettings::default_profile()) {
420                 m_configProject.kcfg_profiles_list->setCurrentIndex(i);
421                 KdenliveSettings::setProfiles_list(i);
422                 break;
423             }
424         }
425     }
426 }
427
428 void KdenliveSettingsDialog::initDevices()
429 {
430     // Fill audio drivers
431     m_configSdl.kcfg_audio_driver->addItem(i18n("Automatic"), QString());
432 #ifndef Q_WS_MAC
433     m_configSdl.kcfg_audio_driver->addItem(i18n("OSS"), "dsp");
434     m_configSdl.kcfg_audio_driver->addItem(i18n("ALSA"), "alsa");
435     m_configSdl.kcfg_audio_driver->addItem(i18n("PulseAudio"), "pulse");
436     m_configSdl.kcfg_audio_driver->addItem(i18n("OSS with DMA access"), "dma");
437     m_configSdl.kcfg_audio_driver->addItem(i18n("Esound daemon"), "esd");
438     m_configSdl.kcfg_audio_driver->addItem(i18n("ARTS daemon"), "artsc");
439 #endif
440
441     if (!KdenliveSettings::audiodrivername().isEmpty())
442         for (int i = 1; i < m_configSdl.kcfg_audio_driver->count(); ++i) {
443             if (m_configSdl.kcfg_audio_driver->itemData(i).toString() == KdenliveSettings::audiodrivername()) {
444                 m_configSdl.kcfg_audio_driver->setCurrentIndex(i);
445                 KdenliveSettings::setAudio_driver((uint) i);
446             }
447         }
448
449     // Fill video drivers
450     m_configSdl.kcfg_video_driver->addItem(i18n("Automatic"), QString());
451 #ifndef Q_WS_MAC
452     m_configSdl.kcfg_video_driver->addItem(i18n("XVideo"), "x11");
453     m_configSdl.kcfg_video_driver->addItem(i18n("X11"), "x11_noaccel");
454     m_configSdl.kcfg_video_driver->addItem(i18n("XFree86 DGA 2.0"), "dga");
455     m_configSdl.kcfg_video_driver->addItem(i18n("Nano X"), "nanox");
456     m_configSdl.kcfg_video_driver->addItem(i18n("Framebuffer console"), "fbcon");
457     m_configSdl.kcfg_video_driver->addItem(i18n("Direct FB"), "directfb");
458     m_configSdl.kcfg_video_driver->addItem(i18n("SVGAlib"), "svgalib");
459     m_configSdl.kcfg_video_driver->addItem(i18n("General graphics interface"), "ggi");
460     m_configSdl.kcfg_video_driver->addItem(i18n("Ascii art library"), "aalib");
461 #endif
462
463     // Fill the list of audio playback / recording devices
464     m_configSdl.kcfg_audio_device->addItem(i18n("Default"), QString());
465     m_configCapture.kcfg_v4l_alsadevice->addItem(i18n("Default"), "default");
466     if (!KStandardDirs::findExe("aplay").isEmpty()) {
467         m_readProcess.setOutputChannelMode(KProcess::OnlyStdoutChannel);
468         m_readProcess.setProgram("aplay", QStringList() << "-l");
469         connect(&m_readProcess, SIGNAL(readyReadStandardOutput()) , this, SLOT(slotReadAudioDevices()));
470         m_readProcess.execute(5000);
471     } else {
472         // If aplay is not installed on the system, parse the /proc/asound/pcm file
473         QFile file("/proc/asound/pcm");
474         if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
475             QTextStream stream(&file);
476             QString line = stream.readLine();
477             QString deviceId;
478             while (!line.isNull()) {
479                 if (line.contains("playback")) {
480                     deviceId = line.section(':', 0, 0);
481                     m_configSdl.kcfg_audio_device->addItem(line.section(':', 1, 1), "plughw:" + QString::number(deviceId.section('-', 0, 0).toInt()) + ',' + QString::number(deviceId.section('-', 1, 1).toInt()));
482                 }
483                 if (line.contains("capture")) {
484                     deviceId = line.section(':', 0, 0);
485                     m_configCapture.kcfg_v4l_alsadevice->addItem(line.section(':', 1, 1).simplified(), "hw:" + QString::number(deviceId.section('-', 0, 0).toInt()) + ',' + QString::number(deviceId.section('-', 1, 1).toInt()));
486                 }
487                 line = stream.readLine();
488             }
489             file.close();
490         } else kDebug()<<" / / / /CANNOT READ PCM";
491     }
492     
493     // Add pulseaudio capture option
494     m_configCapture.kcfg_v4l_alsadevice->addItem(i18n("PulseAudio"), "pulse");
495     
496     if (!KdenliveSettings::audiodevicename().isEmpty()) {
497         // Select correct alsa device
498         int ix = m_configSdl.kcfg_audio_device->findData(KdenliveSettings::audiodevicename());
499         m_configSdl.kcfg_audio_device->setCurrentIndex(ix);
500         KdenliveSettings::setAudio_device(ix);
501     }
502
503     if (!KdenliveSettings::v4l_alsadevicename().isEmpty()) {
504         // Select correct alsa device
505         int ix = m_configCapture.kcfg_v4l_alsadevice->findData(KdenliveSettings::v4l_alsadevicename());
506         m_configCapture.kcfg_v4l_alsadevice->setCurrentIndex(ix);
507         KdenliveSettings::setV4l_alsadevice(ix);
508     }
509
510     loadCurrentV4lProfileInfo();
511 }
512
513
514 void KdenliveSettingsDialog::slotReadAudioDevices()
515 {
516     QString result = QString(m_readProcess.readAllStandardOutput());
517     kDebug() << "// / / / / / READING APLAY: ";
518     kDebug() << result;
519     QStringList lines = result.split('\n');
520     foreach(const QString & data, lines) {
521         //kDebug() << "// READING LINE: " << data;
522         if (!data.startsWith(' ') && data.count(':') > 1) {
523             QString card = data.section(':', 0, 0).section(' ', -1);
524             QString device = data.section(':', 1, 1).section(' ', -1);
525             m_configSdl.kcfg_audio_device->addItem(data.section(':', -1).simplified(), "plughw:" + card + ',' + device);
526             m_configCapture.kcfg_v4l_alsadevice->addItem(data.section(':', -1).simplified(), "hw:" + card + ',' + device);
527         }
528     }
529 }
530
531 void KdenliveSettingsDialog::showPage(int page, int option)
532 {
533     switch (page) {
534     case 1:
535         setCurrentPage(m_page1);
536         break;
537     case 2:
538         setCurrentPage(m_page2);
539         break;
540     case 3:
541         setCurrentPage(m_page3);
542         break;
543     case 4:
544         setCurrentPage(m_page4);
545         m_configCapture.tabWidget->setCurrentIndex(option);
546         break;
547     case 5:
548         setCurrentPage(m_page5);
549         break;
550     case 6:
551         setCurrentPage(m_page6);
552         break;
553     case 7:
554         setCurrentPage(m_page7);
555         break;
556     default:
557         setCurrentPage(m_page1);
558     }
559 }
560
561 void KdenliveSettingsDialog::slotEditVideoApplication()
562 {
563     KService::Ptr service;
564     QPointer<KOpenWithDialog> dlg = new KOpenWithDialog(KUrl::List(), i18n("Select default video player"), m_configEnv.kcfg_defaultplayerapp->text(), this);
565     if (dlg->exec() == QDialog::Accepted) {
566         service = dlg->service();
567         m_configEnv.kcfg_defaultplayerapp->setText(service->exec());
568     }
569
570     delete dlg;
571 }
572
573 void KdenliveSettingsDialog::slotEditAudioApplication()
574 {
575     KService::Ptr service;
576     QPointer<KOpenWithDialog> dlg = new KOpenWithDialog(KUrl::List(), i18n("Select default audio editor"), m_configEnv.kcfg_defaultaudioapp->text(), this);
577     if (dlg->exec() == QDialog::Accepted) {
578         service = dlg->service();
579         m_configEnv.kcfg_defaultaudioapp->setText(service->exec());
580     }
581
582     delete dlg;
583 }
584
585 void KdenliveSettingsDialog::slotEditImageApplication()
586 {
587     KService::Ptr service;
588     QPointer<KOpenWithDialog> dlg = new KOpenWithDialog(KUrl::List(), i18n("Select default image editor"), m_configEnv.kcfg_defaultimageapp->text(), this);
589     if (dlg->exec() == QDialog::Accepted) {
590         service = dlg->service();
591         m_configEnv.kcfg_defaultimageapp->setText(service->exec());
592     }
593     delete dlg;
594 }
595
596 void KdenliveSettingsDialog::slotCheckShuttle(int state)
597 {
598 #ifdef USE_JOGSHUTTLE
599     m_configShuttle.config_group->setEnabled(state);
600     m_configShuttle.shuttledevicelist->clear();
601
602     QStringList devNames = KdenliveSettings::shuttledevicenames();
603     QStringList devPaths = KdenliveSettings::shuttledevicepaths();
604
605     if (devNames.count() != devPaths.count()) {
606         return;
607     }
608     for (int i = 0; i < devNames.count(); i++) {
609         m_configShuttle.shuttledevicelist->addItem(
610                 devNames.at(i), devPaths.at(i));
611     }
612 #endif /* USE_JOGSHUTTLE */
613 }
614
615 void KdenliveSettingsDialog::slotUpdateShuttleDevice(int ix)
616 {
617 #ifdef USE_JOGSHUTTLE
618     QString device = m_configShuttle.shuttledevicelist->itemData(ix).toString();
619     //KdenliveSettings::setShuttledevice(device);
620     setupJogshuttleBtns(device);
621     m_configShuttle.kcfg_shuttledevice->setText(device);
622 #endif /* USE_JOGSHUTTLE */
623 }
624
625 void KdenliveSettingsDialog::updateWidgets()
626 {
627     // Revert widgets to last saved state (for example when user pressed "Cancel")
628     // kDebug() << "// // // KCONFIG Revert called";
629 #ifdef USE_JOGSHUTTLE
630     // revert jog shuttle device
631     if (m_configShuttle.shuttledevicelist->count() > 0) {
632         for (int i = 0; i < m_configShuttle.shuttledevicelist->count(); ++i) {
633             if (m_configShuttle.shuttledevicelist->itemData(i) == KdenliveSettings::shuttledevice()) {
634                 m_configShuttle.shuttledevicelist->setCurrentIndex(i);
635                 break;
636             }
637         }
638     }
639
640     // Revert jog shuttle buttons
641     QList<QString> action_names = m_mappable_actions.keys();
642     qSort(action_names);
643     QStringList actions_map = JogShuttleConfig::actionMap(KdenliveSettings::shuttlebuttons());
644     QMap<QString, int> action_pos;
645     foreach (const QString& action_id, actions_map) {
646         // This loop find out at what index is the string that would map to the action_id.
647         for (int i = 0; i < action_names.size(); ++i) {
648             if (m_mappable_actions[action_names[i]] == action_id) {
649                 action_pos[action_id] = i;
650                 break;
651             }
652         }
653     }
654     int i = 0;
655     foreach (KComboBox* button, m_shuttle_buttons) {
656         ++i;
657         if (i < actions_map.size())
658             button->setCurrentIndex(action_pos[actions_map[i]]);
659     }
660 #endif /* USE_JOGSHUTTLE */
661 }
662
663 void KdenliveSettingsDialog::updateSettings()
664 {
665     // Save changes to settings (for example when user pressed "Apply" or "Ok")
666     // kDebug() << "// // // KCONFIG UPDATE called";
667     m_defaultProfile = m_configProject.kcfg_profiles_list->currentText();
668     KdenliveSettings::setDefault_profile(m_defaultPath);
669
670     bool resetProfile = false;
671     bool updateCapturePath = false;
672
673     /*if (m_configShuttle.shuttledevicelist->count() > 0) {
674     QString device = m_configShuttle.shuttledevicelist->itemData(m_configShuttle.shuttledevicelist->currentIndex()).toString();
675     if (device != KdenliveSettings::shuttledevice()) KdenliveSettings::setShuttledevice(device);
676     }*/
677
678     if (m_configEnv.kcfg_capturetoprojectfolder->isChecked() != KdenliveSettings::capturetoprojectfolder()) {
679         KdenliveSettings::setCapturetoprojectfolder(m_configEnv.kcfg_capturetoprojectfolder->isChecked());
680         updateCapturePath = true;
681     }
682
683     if (m_configEnv.capturefolderurl->url().path() != KdenliveSettings::capturefolder()) {
684         KdenliveSettings::setCapturefolder(m_configEnv.capturefolderurl->url().path());
685         updateCapturePath = true;
686     }
687
688     if (m_configCapture.kcfg_dvgrabfilename->text() != KdenliveSettings::dvgrabfilename()) {
689         KdenliveSettings::setDvgrabfilename(m_configCapture.kcfg_dvgrabfilename->text());
690         updateCapturePath = true;
691     }
692
693     if ((uint) m_configCapture.kcfg_firewireformat->currentIndex() != KdenliveSettings::firewireformat()) {
694         KdenliveSettings::setFirewireformat(m_configCapture.kcfg_firewireformat->currentIndex());
695         updateCapturePath = true;
696     }
697
698     if ((uint) m_configCapture.kcfg_v4l_format->currentIndex() != KdenliveSettings::v4l_format()) {
699         saveCurrentV4lProfile();
700         KdenliveSettings::setV4l_format(0);
701     }
702
703     // Check encoding profiles
704     // FFmpeg
705     QString data = m_configCapture.kcfg_v4l_profile->itemData(m_configCapture.kcfg_v4l_profile->currentIndex()).toString();
706     if (!data.isEmpty() && (data.section(';', 0, 0) != KdenliveSettings::v4l_parameters() || data.section(';', 1, 1) != KdenliveSettings::v4l_extension())) {
707         KdenliveSettings::setV4l_parameters(data.section(';', 0, 0));
708         KdenliveSettings::setV4l_extension(data.section(';', 1, 1));
709     }
710     // screengrab
711     data = m_configCapture.kcfg_grab_profile->itemData(m_configCapture.kcfg_grab_profile->currentIndex()).toString();
712     if (!data.isEmpty() && (data.section(';', 0, 0) != KdenliveSettings::grab_parameters() || data.section(';', 1, 1) != KdenliveSettings::grab_extension())) {
713         KdenliveSettings::setGrab_parameters(data.section(';', 0, 0));
714         KdenliveSettings::setGrab_extension(data.section(';', 1, 1));
715     }
716
717     // decklink
718     data = m_configCapture.kcfg_decklink_profile->itemData(m_configCapture.kcfg_decklink_profile->currentIndex()).toString();
719     if (!data.isEmpty() && (data.section(';', 0, 0) != KdenliveSettings::decklink_parameters() || data.section(';', 1, 1) != KdenliveSettings::decklink_extension())) {
720         KdenliveSettings::setDecklink_parameters(data.section(';', 0, 0));
721         KdenliveSettings::setDecklink_extension(data.section(';', 1, 1));
722     }
723     // proxies
724     data = m_configProject.kcfg_proxy_profile->itemData(m_configProject.kcfg_proxy_profile->currentIndex()).toString();
725     if (!data.isEmpty() && (data.section(';', 0, 0) != KdenliveSettings::proxyparams() || data.section(';', 1, 1) != KdenliveSettings::proxyextension())) {
726         KdenliveSettings::setProxyparams(data.section(';', 0, 0));
727         KdenliveSettings::setProxyextension(data.section(';', 1, 1));
728     }
729
730
731     if (updateCapturePath) emit updateCaptureFolder();
732
733     QString value = m_configCapture.kcfg_v4l_alsadevice->itemData(m_configCapture.kcfg_v4l_alsadevice->currentIndex()).toString();
734     if (value != KdenliveSettings::v4l_alsadevicename()) {
735         KdenliveSettings::setV4l_alsadevicename(value);
736     }
737
738     if (m_configSdl.kcfg_external_display->isChecked() != KdenliveSettings::external_display()) {
739         KdenliveSettings::setExternal_display(m_configSdl.kcfg_external_display->isChecked());
740         resetProfile = true;
741     }
742
743     value = m_configSdl.kcfg_audio_driver->itemData(m_configSdl.kcfg_audio_driver->currentIndex()).toString();
744     if (value != KdenliveSettings::audiodrivername()) {
745         KdenliveSettings::setAudiodrivername(value);
746         resetProfile = true;
747     }
748
749     if (value == "alsa") {
750         // Audio device setting is only valid for alsa driver
751         value = m_configSdl.kcfg_audio_device->itemData(m_configSdl.kcfg_audio_device->currentIndex()).toString();
752         if (value != KdenliveSettings::audiodevicename()) {
753             KdenliveSettings::setAudiodevicename(value);
754             resetProfile = true;
755         }
756     } else if (KdenliveSettings::audiodevicename().isEmpty() == false) {
757         KdenliveSettings::setAudiodevicename(QString::null);
758         resetProfile = true;
759     }
760
761     value = m_configSdl.kcfg_video_driver->itemData(m_configSdl.kcfg_video_driver->currentIndex()).toString();
762     if (value != KdenliveSettings::videodrivername()) {
763         KdenliveSettings::setVideodrivername(value);
764         resetProfile = true;
765     }
766
767     if (m_configSdl.kcfg_window_background->color() != KdenliveSettings::window_background()) {
768         KdenliveSettings::setWindow_background(m_configSdl.kcfg_window_background->color());
769         resetProfile = true;
770     }
771
772     if (m_configSdl.kcfg_volume->value() != KdenliveSettings::volume()) {
773         KdenliveSettings::setVolume(m_configSdl.kcfg_volume->value());
774         resetProfile = true;
775     }
776
777     if (m_modified) {
778         // The transcoding profiles were modified, save.
779         m_modified = false;
780         saveTranscodeProfiles();
781     }
782
783 #ifdef USE_JOGSHUTTLE
784     m_shuttleModified = false;
785
786     QStringList actions;
787     actions << "monitor_pause";  // the Job rest position action.
788     foreach (KComboBox* button, m_shuttle_buttons) {
789         actions << m_mappable_actions[button->currentText()];
790     }
791     QString maps = JogShuttleConfig::actionMap(actions);
792     //fprintf(stderr, "Shuttle config: %s\n", JogShuttleConfig::actionMap(actions).toAscii().constData());
793     if (KdenliveSettings::shuttlebuttons() != maps)
794         KdenliveSettings::setShuttlebuttons(maps);
795 #endif
796
797     KConfigDialog::settingsChangedSlot();
798     //KConfigDialog::updateSettings();
799     if (resetProfile) emit doResetProfile();
800 }
801
802 void KdenliveSettingsDialog::slotUpdateDisplay()
803 {
804     QString currentProfile = m_configProject.kcfg_profiles_list->itemData(m_configProject.kcfg_profiles_list->currentIndex()).toString();
805     QMap< QString, QString > values = ProfilesDialog::getSettingsFromFile(currentProfile);
806     m_configProject.p_size->setText(values.value("width") + 'x' + values.value("height"));
807     m_configProject.p_fps->setText(values.value("frame_rate_num") + '/' + values.value("frame_rate_den"));
808     m_configProject.p_aspect->setText(values.value("sample_aspect_num") + '/' + values.value("sample_aspect_den"));
809     m_configProject.p_display->setText(values.value("display_aspect_num") + '/' + values.value("display_aspect_den"));
810     if (values.value("progressive").toInt() == 0)
811         m_configProject.p_progressive->setText(i18n("Interlaced"));
812     else
813         m_configProject.p_progressive->setText(i18n("Progressive"));
814     m_defaultProfile = m_configProject.kcfg_profiles_list->itemText(m_configProject.kcfg_profiles_list->currentIndex());
815     m_defaultPath = currentProfile;
816 }
817
818 void KdenliveSettingsDialog::slotCheckAlsaDriver()
819 {
820     QString value = m_configSdl.kcfg_audio_driver->itemData(m_configSdl.kcfg_audio_driver->currentIndex()).toString();
821     m_configSdl.kcfg_audio_device->setEnabled(value == "alsa");
822 }
823
824 void KdenliveSettingsDialog::loadTranscodeProfiles()
825 {
826     KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc", KConfig::CascadeConfig);
827     KConfigGroup transConfig(config, "Transcoding");
828     // read the entries
829     m_configTranscode.profiles_list->blockSignals(true);
830     m_configTranscode.profiles_list->clear();
831     QMap< QString, QString > profiles = transConfig.entryMap();
832     QMapIterator<QString, QString> i(profiles);
833     while (i.hasNext()) {
834         i.next();
835         QListWidgetItem *item = new QListWidgetItem(i.key());
836         QString data = i.value();
837         if (data.contains(';')) item->setToolTip(data.section(';', 1, 1));
838         item->setData(Qt::UserRole, data);
839         m_configTranscode.profiles_list->addItem(item);
840         //item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable);
841     }
842     m_configTranscode.profiles_list->blockSignals(false);
843     m_configTranscode.profiles_list->setCurrentRow(0);
844 }
845
846 void KdenliveSettingsDialog::saveTranscodeProfiles()
847 {
848     KSharedConfigPtr config = KSharedConfig::openConfig("kdenlivetranscodingrc", KConfig::CascadeConfig);
849     //KSharedConfigPtr config = KGlobal::config();
850     KConfigGroup transConfig(config, "Transcoding");
851     // read the entries
852     transConfig.deleteGroup();
853     int max = m_configTranscode.profiles_list->count();
854     for (int i = 0; i < max; ++i) {
855         QListWidgetItem *item = m_configTranscode.profiles_list->item(i);
856         transConfig.writeEntry(item->text(), item->data(Qt::UserRole).toString());
857     }
858     config->sync();
859 }
860
861 void KdenliveSettingsDialog::slotAddTranscode()
862 {
863     if (!m_configTranscode.profiles_list->findItems(m_configTranscode.profile_name->text(), Qt::MatchExactly).isEmpty()) {
864         KMessageBox::sorry(this, i18n("A profile with that name already exists"));
865         return;
866     }
867     QListWidgetItem *item = new QListWidgetItem(m_configTranscode.profile_name->text());
868     QString data = m_configTranscode.profile_parameters->toPlainText();
869     data.append(" %1." + m_configTranscode.profile_extension->text());
870     data.append(';');
871     if (!m_configTranscode.profile_description->text().isEmpty())
872         data.append(m_configTranscode.profile_description->text());
873     if (m_configTranscode.profile_audioonly->isChecked()) data.append(";audio");
874     item->setData(Qt::UserRole, data);
875     m_configTranscode.profiles_list->addItem(item);
876     m_configTranscode.profiles_list->setCurrentItem(item);
877     slotDialogModified();
878 }
879
880 void KdenliveSettingsDialog::slotUpdateTranscodingProfile()
881 {
882     QListWidgetItem *item = m_configTranscode.profiles_list->currentItem();
883     if (!item) return;
884     m_configTranscode.button_update->setEnabled(false);
885     item->setText(m_configTranscode.profile_name->text());
886     QString data = m_configTranscode.profile_parameters->toPlainText();
887     data.append(" %1." + m_configTranscode.profile_extension->text());
888     data.append(';');
889     if (!m_configTranscode.profile_description->text().isEmpty())
890         data.append(m_configTranscode.profile_description->text());
891     if (m_configTranscode.profile_audioonly->isChecked()) data.append(";audio");
892     item->setData(Qt::UserRole, data);
893     slotDialogModified();
894 }
895
896 void KdenliveSettingsDialog::slotDeleteTranscode()
897 {
898     QListWidgetItem *item = m_configTranscode.profiles_list->currentItem();
899     if (item == NULL) return;
900     delete item;
901     slotDialogModified();
902 }
903
904 void KdenliveSettingsDialog::slotEnableTranscodeUpdate()
905 {
906     if (!m_configTranscode.profile_box->isEnabled()) return;
907     bool allow = true;
908     if (m_configTranscode.profile_name->text().isEmpty() || m_configTranscode.profile_extension->text().isEmpty()) allow = false;
909     m_configTranscode.button_update->setEnabled(allow);
910 }
911
912 void KdenliveSettingsDialog::slotSetTranscodeProfile()
913 {
914     m_configTranscode.profile_box->setEnabled(false);
915     m_configTranscode.button_update->setEnabled(false);
916     m_configTranscode.profile_name->clear();
917     m_configTranscode.profile_description->clear();
918     m_configTranscode.profile_extension->clear();
919     m_configTranscode.profile_parameters->clear();
920     m_configTranscode.profile_audioonly->setChecked(false);
921     QListWidgetItem *item = m_configTranscode.profiles_list->currentItem();
922     if (!item) {
923         return;
924     }
925     m_configTranscode.profile_name->setText(item->text());
926     QString data = item->data(Qt::UserRole).toString();
927     if (data.contains(';')) {
928         m_configTranscode.profile_description->setText(data.section(';', 1, 1));
929         if (data.section(';', 2, 2) == "audio") m_configTranscode.profile_audioonly->setChecked(true);
930         data = data.section(';', 0, 0).simplified();
931     }
932     m_configTranscode.profile_extension->setText(data.section('.', -1));
933     m_configTranscode.profile_parameters->setPlainText(data.section(' ', 0, -2));
934     m_configTranscode.profile_box->setEnabled(true);
935 }
936
937 void KdenliveSettingsDialog::slotShuttleModified()
938 {
939 #ifdef USE_JOGSHUTTLE
940     QStringList actions;
941     actions << "monitor_pause";  // the Job rest position action.
942     foreach (KComboBox* button, m_shuttle_buttons) {
943         actions << m_mappable_actions[button->currentText()];
944     }
945     QString maps = JogShuttleConfig::actionMap(actions);
946     m_shuttleModified = KdenliveSettings::shuttlebuttons() != maps;
947 #endif
948     KConfigDialog::updateButtons();
949 }
950
951 void KdenliveSettingsDialog::slotDialogModified()
952 {
953     m_modified = true;
954     KConfigDialog::updateButtons();
955 }
956
957 //virtual
958 bool KdenliveSettingsDialog::hasChanged()
959 {
960     if (m_modified || m_shuttleModified) return true;
961     return KConfigDialog::hasChanged();
962 }
963
964 void KdenliveSettingsDialog::slotUpdatev4lDevice()
965 {
966     QString device = m_configCapture.kcfg_detectedv4ldevices->itemData(m_configCapture.kcfg_detectedv4ldevices->currentIndex()).toString();
967     if (!device.isEmpty()) m_configCapture.kcfg_video4vdevice->setText(device);
968     QString info = m_configCapture.kcfg_detectedv4ldevices->itemData(m_configCapture.kcfg_detectedv4ldevices->currentIndex(), Qt::UserRole + 1).toString();
969
970     m_configCapture.kcfg_v4l_format->blockSignals(true);
971     m_configCapture.kcfg_v4l_format->clear();
972
973     QString vl4ProfilePath = KStandardDirs::locateLocal("appdata", "profiles/video4linux");
974     if (QFile::exists(vl4ProfilePath)) {
975         m_configCapture.kcfg_v4l_format->addItem(i18n("Current settings"));
976     }
977
978     QStringList pixelformats = info.split('>', QString::SkipEmptyParts);
979     QString itemSize;
980     QString pixelFormat;
981     QStringList itemRates;
982     for (int i = 0; i < pixelformats.count(); ++i) {
983         QString format = pixelformats.at(i).section(':', 0, 0);
984         QStringList sizes = pixelformats.at(i).split(':', QString::SkipEmptyParts);
985         pixelFormat = sizes.takeFirst();
986         for (int j = 0; j < sizes.count(); j++) {
987             itemSize = sizes.at(j).section('=', 0, 0);
988             itemRates = sizes.at(j).section('=', 1, 1).split(',', QString::SkipEmptyParts);
989             for (int k = 0; k < itemRates.count(); k++) {
990                 m_configCapture.kcfg_v4l_format->addItem('[' + format + "] " + itemSize + " (" + itemRates.at(k) + ')', QStringList() << format << itemSize.section('x', 0, 0) << itemSize.section('x', 1, 1) << itemRates.at(k).section('/', 0, 0) << itemRates.at(k).section('/', 1, 1));
991             }
992         }
993     }
994     m_configCapture.kcfg_v4l_format->blockSignals(false);
995     slotUpdatev4lCaptureProfile();
996 }
997
998 void KdenliveSettingsDialog::slotUpdatev4lCaptureProfile()
999 {
1000     QStringList info = m_configCapture.kcfg_v4l_format->itemData(m_configCapture.kcfg_v4l_format->currentIndex(), Qt::UserRole).toStringList();
1001     if (info.isEmpty()) {
1002         // No auto info, display the current ones
1003         loadCurrentV4lProfileInfo();
1004         return;
1005     }
1006     m_configCapture.p_size->setText(info.at(1) + 'x' + info.at(2));
1007     m_configCapture.p_fps->setText(info.at(3) + '/' + info.at(4));
1008     m_configCapture.p_aspect->setText("1/1");
1009     m_configCapture.p_display->setText(info.at(1) + '/' + info.at(2));
1010     m_configCapture.p_colorspace->setText(ProfilesDialog::getColorspaceDescription(601));
1011     m_configCapture.p_progressive->setText(i18n("Progressive"));
1012
1013     QString vl4ProfilePath = KStandardDirs::locateLocal("appdata", "profiles/video4linux");
1014     if (!QFile::exists(vl4ProfilePath)) saveCurrentV4lProfile();
1015 }
1016
1017 void KdenliveSettingsDialog::loadCurrentV4lProfileInfo()
1018 {
1019     QString vl4ProfilePath = KStandardDirs::locateLocal("appdata", "profiles/video4linux");
1020     MltVideoProfile prof;
1021     if (!QFile::exists(vl4ProfilePath)) {
1022         // No default formats found, build one
1023         prof.width = 320;
1024         prof.height = 200;
1025         prof.frame_rate_num = 15;
1026         prof.frame_rate_den = 1;
1027         prof.display_aspect_num = 4;
1028         prof.display_aspect_den = 3;
1029         prof.sample_aspect_num = 1;
1030         prof.sample_aspect_den = 1;
1031         prof.progressive = 1;
1032         prof.colorspace = 601;
1033         ProfilesDialog::saveProfile(prof, vl4ProfilePath);
1034     }
1035     else prof = ProfilesDialog::getVideoProfile(vl4ProfilePath);
1036     m_configCapture.p_size->setText(QString::number(prof.width) + 'x' + QString::number(prof.height));
1037     m_configCapture.p_fps->setText(QString::number(prof.frame_rate_num) + '/' + QString::number(prof.frame_rate_den));
1038     m_configCapture.p_aspect->setText(QString::number(prof.sample_aspect_num) + '/' + QString::number(prof.sample_aspect_den));
1039     m_configCapture.p_display->setText(QString::number(prof.display_aspect_num) + '/' + QString::number(prof.display_aspect_den));
1040     m_configCapture.p_colorspace->setText(ProfilesDialog::getColorspaceDescription(prof.colorspace));
1041     if (prof.progressive) m_configCapture.p_progressive->setText(i18n("Progressive"));
1042 }
1043
1044 void KdenliveSettingsDialog::saveCurrentV4lProfile()
1045 {
1046     MltVideoProfile profile;
1047     profile.description = "Video4Linux capture";
1048     profile.colorspace = ProfilesDialog::getColorspaceFromDescription(m_configCapture.p_colorspace->text());
1049     profile.width = m_configCapture.p_size->text().section('x', 0, 0).toInt();
1050     profile.height = m_configCapture.p_size->text().section('x', 1, 1).toInt();
1051     profile.sample_aspect_num = m_configCapture.p_aspect->text().section('/', 0, 0).toInt();
1052     profile.sample_aspect_den = m_configCapture.p_aspect->text().section('/', 1, 1).toInt();
1053     profile.display_aspect_num = m_configCapture.p_display->text().section('/', 0, 0).toInt();
1054     profile.display_aspect_den = m_configCapture.p_display->text().section('/', 1, 1).toInt();
1055     profile.frame_rate_num = m_configCapture.p_fps->text().section('/', 0, 0).toInt();
1056     profile.frame_rate_den = m_configCapture.p_fps->text().section('/', 1, 1).toInt();
1057     profile.progressive = m_configCapture.p_progressive->text() == i18n("Progressive");
1058     QString vl4ProfilePath = KStandardDirs::locateLocal("appdata", "profiles/video4linux");
1059     ProfilesDialog::saveProfile(profile, vl4ProfilePath);
1060 }
1061
1062 void KdenliveSettingsDialog::slotManageEncodingProfile()
1063 {
1064     int type = 0;
1065     if (currentPage() == m_page4) {
1066         type = m_configCapture.tabWidget->currentIndex();
1067     }
1068     QPointer<EncodingProfilesDialog> d = new EncodingProfilesDialog(type);
1069     d->exec();
1070     delete d;
1071     loadEncodingProfiles();
1072 }
1073
1074 void KdenliveSettingsDialog::loadEncodingProfiles()
1075 {
1076     KConfig conf("encodingprofiles.rc", KConfig::CascadeConfig, "appdata");
1077
1078     // Load v4l profiles
1079     m_configCapture.kcfg_v4l_profile->blockSignals(true);
1080     QString currentItem = m_configCapture.kcfg_v4l_profile->currentText();
1081     m_configCapture.kcfg_v4l_profile->clear();
1082     KConfigGroup group(&conf, "video4linux");
1083     QMap< QString, QString > values = group.entryMap();
1084     QMapIterator<QString, QString> i(values);
1085     while (i.hasNext()) {
1086         i.next();
1087         if (!i.key().isEmpty()) m_configCapture.kcfg_v4l_profile->addItem(i.key(), i.value());
1088     }
1089     m_configCapture.kcfg_v4l_profile->blockSignals(false);
1090     if (!currentItem.isEmpty()) m_configCapture.kcfg_v4l_profile->setCurrentIndex(m_configCapture.kcfg_v4l_profile->findText(currentItem));
1091     
1092     // Load Screen Grab profiles
1093     m_configCapture.kcfg_grab_profile->blockSignals(true);
1094     currentItem = m_configCapture.kcfg_grab_profile->currentText();
1095     m_configCapture.kcfg_grab_profile->clear();
1096     KConfigGroup group2(&conf, "screengrab");
1097     values = group2.entryMap();
1098     QMapIterator<QString, QString> j(values);
1099     while (j.hasNext()) {
1100         j.next();
1101         if (!j.key().isEmpty()) m_configCapture.kcfg_grab_profile->addItem(j.key(), j.value());
1102     }
1103     m_configCapture.kcfg_grab_profile->blockSignals(false);
1104     if (!currentItem.isEmpty()) m_configCapture.kcfg_grab_profile->setCurrentIndex(m_configCapture.kcfg_grab_profile->findText(currentItem));
1105
1106     // Load Decklink profiles
1107     m_configCapture.kcfg_decklink_profile->blockSignals(true);
1108     currentItem = m_configCapture.kcfg_decklink_profile->currentText();
1109     m_configCapture.kcfg_decklink_profile->clear();
1110     KConfigGroup group3(&conf, "decklink");
1111     values = group3.entryMap();
1112     QMapIterator<QString, QString> k(values);
1113     while (k.hasNext()) {
1114         k.next();
1115         if (!k.key().isEmpty()) m_configCapture.kcfg_decklink_profile->addItem(k.key(), k.value());
1116     }
1117     m_configCapture.kcfg_decklink_profile->blockSignals(false);
1118     if (!currentItem.isEmpty()) m_configCapture.kcfg_decklink_profile->setCurrentIndex(m_configCapture.kcfg_decklink_profile->findText(currentItem));
1119
1120     // Load Proxy profiles
1121     m_configProject.kcfg_proxy_profile->blockSignals(true);
1122     currentItem = m_configProject.kcfg_proxy_profile->currentText();
1123     m_configProject.kcfg_proxy_profile->clear();
1124     KConfigGroup group4(&conf, "proxy");
1125     values = group4.entryMap();
1126     QMapIterator<QString, QString> l(values);
1127     while (l.hasNext()) {
1128         l.next();
1129         if (!l.key().isEmpty()) m_configProject.kcfg_proxy_profile->addItem(l.key(), l.value());
1130     }
1131     if (!currentItem.isEmpty()) m_configProject.kcfg_proxy_profile->setCurrentIndex(m_configProject.kcfg_proxy_profile->findText(currentItem));
1132     m_configProject.kcfg_proxy_profile->blockSignals(false);
1133     slotUpdateProxyProfile();
1134     
1135 }
1136
1137 void KdenliveSettingsDialog::slotUpdateDecklinkProfile(int ix)
1138 {
1139     if (ix == -1) ix = KdenliveSettings::decklink_profile();
1140     else ix = m_configCapture.kcfg_decklink_profile->currentIndex();
1141     QString data = m_configCapture.kcfg_decklink_profile->itemData(ix).toString();
1142     if (data.isEmpty()) return;
1143     m_configCapture.decklink_parameters->setPlainText(data.section(';', 0, 0));
1144     //
1145 }
1146
1147 void KdenliveSettingsDialog::slotUpdateV4lProfile(int ix)
1148 {
1149     if (ix == -1) ix = KdenliveSettings::v4l_profile();
1150     else ix = m_configCapture.kcfg_v4l_profile->currentIndex();
1151     QString data = m_configCapture.kcfg_v4l_profile->itemData(ix).toString();
1152     if (data.isEmpty()) return;
1153     m_configCapture.v4l_parameters->setPlainText(data.section(';', 0, 0));
1154     //
1155 }
1156
1157 void KdenliveSettingsDialog::slotUpdateGrabProfile(int ix)
1158 {
1159     if (ix == -1) ix = KdenliveSettings::grab_profile();
1160     else ix = m_configCapture.kcfg_grab_profile->currentIndex();
1161     QString data = m_configCapture.kcfg_grab_profile->itemData(ix).toString();
1162     if (data.isEmpty()) return;
1163     m_configCapture.grab_parameters->setPlainText(data.section(';', 0, 0));
1164     //
1165 }
1166
1167 void KdenliveSettingsDialog::slotUpdateProxyProfile(int ix)
1168 {
1169     if (ix == -1) ix = KdenliveSettings::v4l_profile();
1170     else ix = m_configProject.kcfg_proxy_profile->currentIndex();
1171     QString data = m_configProject.kcfg_proxy_profile->itemData(ix).toString();
1172     if (data.isEmpty()) return;
1173     m_configProject.proxyparams->setPlainText(data.section(';', 0, 0));
1174     //
1175 }
1176
1177 void KdenliveSettingsDialog::slotEditVideo4LinuxProfile()
1178 {
1179     QString vl4ProfilePath = KStandardDirs::locateLocal("appdata", "profiles/video4linux");
1180     QPointer<ProfilesDialog> w = new ProfilesDialog(vl4ProfilePath);
1181     if (w->exec() == QDialog::Accepted) {
1182         // save and update profile
1183         loadCurrentV4lProfileInfo();
1184     }
1185     delete w;
1186 }
1187
1188 void KdenliveSettingsDialog::slotReloadBlackMagic()
1189 {
1190     Render::getBlackMagicDeviceList(m_configCapture.kcfg_decklink_capturedevice, true);
1191     if (!Render::getBlackMagicOutputDeviceList(m_configSdl.kcfg_blackmagic_output_device), true) {
1192         // No blackmagic card found
1193         m_configSdl.kcfg_external_display->setEnabled(false);
1194     }
1195     m_configSdl.kcfg_external_display->setEnabled(KdenliveSettings::decklink_device_found());
1196 }
1197
1198 void KdenliveSettingsDialog::slotReloadShuttleDevices()
1199 {
1200 #ifdef USE_JOGSHUTTLE
1201     QString devDirStr = "/dev/input/by-id";
1202     QDir devDir(devDirStr);
1203     if (!devDir.exists()) {
1204         devDirStr = "/dev/input";
1205     }
1206
1207     DeviceMap devMap = JogShuttle::enumerateDevices(devDirStr);
1208     if (!devMap.isEmpty()) {
1209         m_configShuttle.shuttledevicelist->clear();
1210     }
1211
1212     QStringList devNamesList;
1213     QStringList devPathList;
1214     DeviceMapIter iter = devMap.begin();
1215     if (iter == devMap.end()) {
1216         KdenliveSettings::shuttledevicenames().clear();
1217         KdenliveSettings::shuttledevicepaths().clear();
1218         m_configShuttle.shuttledevicelist->clear();
1219     }
1220     while (iter != devMap.end()) {
1221         kDebug() << iter.key() << ": " << iter.value();
1222         m_configShuttle.shuttledevicelist->addItem(iter.key(), iter.value());
1223         devNamesList << iter.key();
1224         devPathList << iter.value();
1225         ++iter;
1226     }
1227
1228     KdenliveSettings::setShuttledevicenames(devNamesList);
1229     KdenliveSettings::setShuttledevicepaths(devPathList);
1230     QTimer::singleShot(200, this, SLOT(slotUpdateShuttleDevice()));
1231
1232     kDebug() << "Devices reloaded";
1233
1234 #endif //USE_JOGSHUTTLE
1235 }
1236
1237 #include "kdenlivesettingsdialog.moc"
1238
1239