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