1 /*
2 Copyright (C) 2007-2009 Remon Sijrier
3 
4 This file is part of Traverso
5 
6 Traverso is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA.
19 
20 */
21 
22 #include <QDir>
23 #include <QFile>
24 #include <QFileDialog>
25 #include <QMessageBox>
26 #include <QStyle>
27 #include <QStyleFactory>
28 
29 #include "Pages.h"
30 #include <AudioDevice.h>
31 #if defined (ALSA_SUPPORT)
32 #include <AlsaDriver.h>
33 #endif
34 #include <Config.h>
35 #include <Utils.h>
36 #include <Themer.h>
37 #include <InputEngine.h>
38 #include "Interface.h"
39 #include <QDomDocument>
40 #include <QtPrintSupport/QPrinter>
41 #include <QtPrintSupport/QPrintDialog>
42 #include <QTextEdit>
43 
44 #if defined (JACK_SUPPORT)
45 RELAYTOOL_JACK
46 #endif
47 
48 
49 /****************************************/
50 /*            AudioDriver               */
51 /****************************************/
52 
53 
AudioDriverConfigPage(QWidget * parent)54 AudioDriverConfigPage::AudioDriverConfigPage(QWidget *parent)
55     : ConfigPage(parent)
56 {
57 	setupUi(this);
58 	periodBufferSizesList << 16 << 32 << 64 << 128 << 256 << 512 << 1024 << 2048 << 4096;
59 
60 	m_mainLayout = qobject_cast<QVBoxLayout*>(layout());
61 
62 	QStringList drivers = audiodevice().get_available_drivers();
63 	foreach(const QString &name, drivers) {
64 		driverCombo->addItem(name);
65 	}
66 
67 
68 	m_portaudiodrivers = new PaDriverPage(this);
69 	m_mainLayout->addWidget(m_portaudiodrivers);
70 
71 	m_alsadevices = new AlsaDevicesPage(this);
72 	m_alsadevices->layout()->setMargin(0);
73 	m_mainLayout->addWidget(m_alsadevices);
74 
75 	connect(driverCombo, SIGNAL(currentIndexChanged(QString)), this, SLOT(driver_combobox_index_changed(QString)));
76 	connect(restartDriverButton, SIGNAL(clicked()), this, SLOT(restart_driver_button_clicked()));
77 	connect(rateComboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(rate_combobox_index_changed(QString)));
78 
79 	load_config();
80 }
81 
save_config()82 void AudioDriverConfigPage::save_config()
83 {
84 	config().set_property("Hardware", "samplerate", rateComboBox->currentText());
85 	int bufferindex = latencyComboBox->currentIndex();
86 	int buffersize = 1024;
87 	if (bufferindex >= 0) {
88 		buffersize = periodBufferSizesList.at(bufferindex);
89 	}
90 	config().set_property("Hardware", "buffersize", buffersize);
91 
92 	config().set_property("Hardware", "drivertype", driverCombo->currentText());
93 
94 	int playback=1, capture=1;
95 	if(duplexComboBox->currentIndex() == 1) {
96 		capture = 0;
97 	}
98 
99 	if(duplexComboBox->currentIndex() == 2) {
100 		playback = 0;
101 	}
102 
103 	config().set_property("Hardware", "capture", capture);
104 	config().set_property("Hardware", "playback", playback);
105 
106 
107 #if defined (ALSA_SUPPORT)
108 	int periods = m_alsadevices->periodsCombo->currentText().toInt();
109 	config().set_property("Hardware", "numberofperiods", periods);
110 	int index = m_alsadevices->devicesCombo->currentIndex();
111 	config().set_property("Hardware", "carddevice", m_alsadevices->devicesCombo->itemData(index));
112 	config().set_property("Hardware", "DitherShape", m_alsadevices->ditherShapeComboBox->currentText());
113 
114 #endif
115 
116 
117 #if defined (PORTAUDIO_SUPPORT)
118 	int paindex = m_portaudiodrivers->driverCombo->currentIndex();
119 	config().set_property("Hardware", "pahostapi", m_portaudiodrivers->driverCombo->itemData(paindex));
120 #endif
121 
122 	config().set_property("Hardware", "jackslave", jackTransportCheckBox->isChecked());
123 }
124 
reset_default_config()125 void AudioDriverConfigPage::reset_default_config()
126 {
127 	config().set_property("Hardware", "samplerate", 44100);
128 	config().set_property("Hardware", "buffersize", 512);
129 #if defined (ALSA_SUPPORT)
130 	config().set_property("Hardware", "drivertype", "ALSA");
131         config().set_property("Hardware", "carddevice", "default");
132 	config().set_property("Hardware", "numberofperiods", 3);
133 	config().set_property("Hardware", "DitherShape", "None");
134 #elif defined (JACK_SUPPORT)
135 	if (libjack_is_present)
136 		config().set_property("Hardware", "drivertype", "Jack");
137 #else
138 	config().set_property("Hardware", "drivertype", "Null Driver");
139 #endif
140 
141 #if defined (PORTAUDIO_SUPPORT)
142 #if defined (Q_WS_X11)
143 	config().set_property("Hardware", "pahostapi", "alsa");
144 #endif
145 #if defined (Q_WS_MAC)
146 	config().set_property("Hardware", "pahostapi", "coreaudio");
147 #endif
148 #if defined (Q_WS_WIN)
149 	config().set_property("Hardware", "pahostapi", "wmme");
150 #endif
151 #endif //end PORTAUDIO_SUPPORT
152 
153 	config().set_property("Hardware", "capture", 1);
154 	config().set_property("Hardware", "playback", 1);
155 
156 	config().set_property("Hardware", "jackslave", false);
157 
158 	load_config();
159 }
160 
load_config()161 void AudioDriverConfigPage::load_config( )
162 {
163 	int samplerate = config().get_property("Hardware", "samplerate", 44100).toInt();
164 	int buffersize = config().get_property("Hardware", "buffersize", 512).toInt();
165 #if defined (Q_WS_X11)
166 	QString driverType = config().get_property("Hardware", "drivertype", "ALSA").toString();
167 #else
168 	QString driverType = config().get_property("Hardware", "drivertype", "PortAudio").toString();
169 #endif
170 	bool capture = config().get_property("Hardware", "capture", 1).toInt();
171 	bool playback = config().get_property("Hardware", "playback", 1).toInt();
172 
173 
174 	int driverTypeIndex = driverCombo->findText(driverType);
175 	if (driverTypeIndex >= 0) {
176 		driverCombo->setCurrentIndex(driverTypeIndex);
177 	}
178 
179 	driver_combobox_index_changed(driverType);
180 
181 	int buffersizeIndex = periodBufferSizesList.indexOf(buffersize);
182 	int samplerateIndex = rateComboBox->findText(QString::number(samplerate));
183 
184 	rateComboBox->setCurrentIndex(samplerateIndex);
185 	latencyComboBox->setCurrentIndex(buffersizeIndex);
186 
187 
188 	if (capture && playback) {
189 		duplexComboBox->setCurrentIndex(0);
190 	} else if (playback) {
191 		duplexComboBox->setCurrentIndex(1);
192 	} else {
193 		duplexComboBox->setCurrentIndex(2);
194 	}
195 
196 	int index;
197 
198 #if defined (ALSA_SUPPORT)
199 	m_alsadevices->devicesCombo->clear();
200 	int periodsIndex = config().get_property("Hardware", "numberofperiods", 3).toInt();
201 	QString ditherShape = config().get_property("Hardware", "DitherShape", "None").toString();
202 	m_alsadevices->periodsCombo->setCurrentIndex(periodsIndex - 2);
203 
204 	int shapeIndex = m_alsadevices->ditherShapeComboBox->findText(ditherShape);
205 	if (shapeIndex >=0) {
206 		m_alsadevices->ditherShapeComboBox->setCurrentIndex(shapeIndex);
207 	}
208 
209 	// Always add the 'default' device
210 	m_alsadevices->devicesCombo->addItem(tr("System default"), "default");
211 
212 	// Iterate over the maximum number of devices that can be in a system
213 	// according to alsa, and add them to the devices list.
214 	QString name;
215 	for (int i=0; i<6; ++i) {
216 		name = AlsaDriver::alsa_device_name(false, i);
217 		if (name != "") {
218 			QString card = "Card " + QString::number(i+1) + ":  ";
219 			QString device = "hw:" + QString::number(i);
220 			m_alsadevices->devicesCombo->addItem(card + name, device);
221 		}
222 	}
223 
224         QString defaultdevice =  config().get_property("Hardware", "carddevice", "default").toString();
225 	index = m_alsadevices->devicesCombo->findData(defaultdevice);
226 	if (index >= 0) {
227 		m_alsadevices->devicesCombo->setCurrentIndex(index);
228 	}
229 #endif
230 
231 #if defined (PORTAUDIO_SUPPORT)
232 	m_portaudiodrivers->driverCombo->clear();
233 	QString defaulthostapi = "";
234 
235 #if defined (Q_WS_X11)
236 	m_portaudiodrivers->driverCombo->addItem("ALSA", "alsa");
237 	m_portaudiodrivers->driverCombo->addItem("Jack", "jack");
238 	m_portaudiodrivers->driverCombo->addItem("OSS", "oss");
239 	defaulthostapi = "jack";
240 #endif
241 
242 #if defined (Q_WS_MAC)
243 	m_portaudiodrivers->driverCombo->addItem("Core Audio", "coreaudio");
244 	m_portaudiodrivers->driverCombo->addItem("Jack", "jack");
245 	defaulthostapi = "coreaudio";
246 #endif
247 
248 #if defined (Q_WS_WIN)
249 	m_portaudiodrivers->driverCombo->addItem("MME", "wmme");
250 	m_portaudiodrivers->driverCombo->addItem("Direct Sound", "directsound");
251 	m_portaudiodrivers->driverCombo->addItem("ASIO", "asio");
252 	defaulthostapi = "wmme";
253 #endif
254 
255 	QString hostapi = config().get_property("Hardware", "pahostapi", defaulthostapi).toString();
256 	index = m_portaudiodrivers->driverCombo->findData(hostapi);
257 	if (index >= 0) {
258 		m_portaudiodrivers->driverCombo->setCurrentIndex(index);
259 	}
260 
261 	update_latency_combobox();
262 
263 #endif //end PORTAUDIO_SUPPORT
264 
265 	bool usetransport = config().get_property("Hardware", "jackslave", false).toBool();
266 	jackTransportCheckBox->setChecked(usetransport);
267 }
268 
269 
restart_driver_button_clicked()270 void AudioDriverConfigPage::restart_driver_button_clicked()
271 {
272 	QString driver = driverCombo->currentText();
273 	int rate = rateComboBox->currentText().toInt();
274 	int buffersize =  periodBufferSizesList.at(latencyComboBox->currentIndex());
275 
276 	int playback=1, capture=1;
277 	if(duplexComboBox->currentIndex() == 1) {
278 		capture = 0;
279 	}
280 
281 	if(duplexComboBox->currentIndex() == 2) {
282 		playback = 0;
283 	}
284 
285 
286 	QString cardDevice = "";
287 	QString dithershape = "None";
288 
289 
290 #if defined (ALSA_SUPPORT)
291 	int periods = m_alsadevices->periodsCombo->currentText().toInt();
292 	dithershape = m_alsadevices->ditherShapeComboBox->currentText();
293 	// The AlsaDriver retrieves it's periods number directly from config()
294 	// So there is no way to use the current selected one, other then
295 	// setting it now, and restoring it afterwards...
296 	int currentperiods = config().get_property("Hardware", "numberofperiods", 3).toInt();
297 	config().set_property("Hardware", "numberofperiods", periods);
298 
299 	if (driver == "ALSA") {
300 		int index = m_alsadevices->devicesCombo->currentIndex();
301 		cardDevice = m_alsadevices->devicesCombo->itemData(index).toString();
302 	}
303 #endif
304 
305 #if defined (PORTAUDIO_SUPPORT)
306 	if (driver == "PortAudio") {
307 		int index = m_portaudiodrivers->driverCombo->currentIndex();
308 		cardDevice = m_portaudiodrivers->driverCombo->itemData(index).toString();
309 	}
310 #endif
311 
312 	audiodevice().set_parameters(rate, buffersize, driver, capture, playback, cardDevice, dithershape);
313 
314 #if defined (ALSA_SUPPORT)
315 	config().set_property("Hardware", "numberofperiods", currentperiods);
316 #endif
317 
318 	config().set_property("Hardware", "jackslave", jackTransportCheckBox->isChecked());
319 }
320 
321 
322 
driver_combobox_index_changed(QString driver)323 void AudioDriverConfigPage::driver_combobox_index_changed(QString driver)
324 {
325 	m_mainLayout->removeWidget(m_alsadevices);
326 	m_mainLayout->removeWidget(m_portaudiodrivers);
327 	m_mainLayout->removeWidget(jackGroupBox);
328 
329 	if (driver == "ALSA") {
330 		m_alsadevices->show();
331 		m_mainLayout->insertWidget(m_mainLayout->indexOf(driverConfigGroupBox) + 1, m_alsadevices);
332 	} else {
333 		m_alsadevices->hide();
334 		m_mainLayout->removeWidget(m_alsadevices);
335 	}
336 
337 	if (driver == "PortAudio") {
338 		m_portaudiodrivers->show();
339 		m_mainLayout->insertWidget(m_mainLayout->indexOf(driverConfigGroupBox) + 1, m_portaudiodrivers);
340 	} else {
341 		m_portaudiodrivers->hide();
342 		m_mainLayout->removeWidget(m_portaudiodrivers);
343 	}
344 
345 	if (driver == "Jack") {
346 		jackGroupBox->show();
347 		m_mainLayout->insertWidget(m_mainLayout->indexOf(driverConfigGroupBox) + 1, jackGroupBox);
348 	} else {
349 		jackGroupBox->hide();
350 		m_mainLayout->removeWidget(jackGroupBox);
351 	}
352 }
353 
354 
update_latency_combobox()355 void AudioDriverConfigPage::update_latency_combobox( )
356 {
357 	latencyComboBox->clear();
358 	int rate = rateComboBox->currentText().toInt();
359 	int buffersize = audiodevice().get_buffer_size();
360 
361 	for (int i=0; i<periodBufferSizesList.size(); ++i) {
362 		QString latency = QString::number( ((float)(periodBufferSizesList.at(i)) / rate) * 1000 * 2, 'f', 2);
363 		latencyComboBox->addItem(latency);
364 	}
365 
366 	int index = periodBufferSizesList.indexOf(buffersize);
367 	latencyComboBox->setCurrentIndex(index);
368 }
369 
rate_combobox_index_changed(QString)370 void AudioDriverConfigPage::rate_combobox_index_changed(QString )
371 {
372 	update_latency_combobox();
373 }
374 
375 
376 
377 /****************************************/
378 /*            Appearance                */
379 /****************************************/
380 
381 
save_config()382 void AppearenceConfigPage::save_config()
383 {
384 	config().set_property("Themer", "themepath", themePathLineEdit->text());
385 	config().set_property("Themer", "currenttheme", themeSelecterCombo->currentText());
386 	config().set_property("Themer", "coloradjust", colorAdjustBox->value());
387 	config().set_property("Themer", "style", styleCombo->currentText());
388 	config().set_property("Themer", "usestylepallet", useStylePalletCheckBox->isChecked());
389 	config().set_property("Themer", "paintaudiorectified", rectifiedCheckBox->isChecked());
390 	config().set_property("Themer", "paintstereoaudioasmono", mergedCheckBox->isChecked());
391 	config().set_property("Themer", "drawdbgrid", dbGridCheckBox->isChecked());
392 	config().set_property("Themer", "paintwavewithoutline", paintAudioWithOutlineCheckBox->isChecked());
393 	config().set_property("Themer", "iconsize", iconSizeCombo->currentText());
394 	config().set_property("Themer", "toolbuttonstyle", toolbarStyleCombo->currentIndex());
395 	config().set_property("Themer", "supportediconsizes", supportedIconSizes);
396 	config().set_property("Themer", "transportconsolesize", transportConsoleCombo->currentText());
397 	config().set_property("Interface", "LanguageFile", languageComboBox->itemData(languageComboBox->currentIndex()));
398 }
399 
load_config()400 void AppearenceConfigPage::load_config()
401 {
402 	QIcon icon = QApplication::style()->standardIcon(QStyle::SP_DirClosedIcon);
403 	pathSelectButton->setIcon(icon);
404 	QString themepath = config().get_property("Themer", "themepath",
405 				   QString(QDir::homePath()).append(".traverso/themes")).toString();
406 
407 
408 	QStringList keys = QStyleFactory::keys();
409 	keys.sort();
410 	foreach(const QString &key, keys) {
411 		styleCombo->addItem(key);
412 	}
413 
414 	update_theme_combobox(themepath);
415 
416 
417 	// Hmm, there seems no way to get the name of the current
418 	// used style, using the classname minus Q and Style seems to do the trick.
419 	QString systemstyle = QString(QApplication::style()->metaObject()->className()).remove("Q").remove("Style");
420 	QString style = config().get_property("Themer", "style", systemstyle).toString();
421 	QString theme  = config().get_property("Themer", "currenttheme", "TraversoLight").toString();
422 	int coloradjust = config().get_property("Themer", "coloradjust", 100).toInt();
423 	bool usestylepallete = config().get_property("Themer", "usestylepallet", "").toBool();
424 	bool paintRectified = config().get_property("Themer", "paintaudiorectified", false).toBool();
425 	bool paintStereoAsMono = config().get_property("Themer", "paintstereoaudioasmono", false).toBool();
426 	bool paintWaveWithLines = config().get_property("Themer", "paintwavewithoutline", true).toBool();
427 	bool dbGrid = config().get_property("Themer", "drawdbgrid", false).toBool();
428 
429 	QString interfaceLanguage = config().get_property("Interface", "LanguageFile", "").toString();
430 
431 	int index = styleCombo->findText(style);
432 	styleCombo->setCurrentIndex(index);
433 	index = themeSelecterCombo->findText(theme);
434 	themeSelecterCombo->setCurrentIndex(index);
435 	colorAdjustBox->setValue(coloradjust);
436 	useStylePalletCheckBox->setChecked(usestylepallete);
437 	themePathLineEdit->setText(themepath);
438 	rectifiedCheckBox->setChecked(paintRectified);
439 	mergedCheckBox->setChecked(paintStereoAsMono);
440 	dbGridCheckBox->setChecked(dbGrid);
441 	paintAudioWithOutlineCheckBox->setChecked(paintWaveWithLines);
442 
443 	toolbarStyleCombo->clear();
444 	toolbarStyleCombo->addItem(tr("Icons only"));
445 	toolbarStyleCombo->addItem(tr("Text only"));
446 	toolbarStyleCombo->addItem(tr("Text beside Icons"));
447 	toolbarStyleCombo->addItem(tr("Text below Icons"));
448 	int tbstyle = config().get_property("Themer", "toolbuttonstyle", 0).toInt();
449 	toolbarStyleCombo->setCurrentIndex(tbstyle);
450 
451 	// icon sizes of the toolbars
452 	QString iconsize = config().get_property("Themer", "iconsize", "22").toString();
453 	supportedIconSizes = config().get_property("Themer", "supportediconsizes", "16;22;32;48").toString();
454 
455 	// if the list is empty, we should offer some default values. (The list can only be
456 	// empty if someone deleted the values, but not the whole entry, in the config file.)
457 	if (supportedIconSizes.isEmpty()) {
458 		supportedIconSizes = "16;22;32;48";
459 	}
460 
461 	QStringList iconSizesList = supportedIconSizes.split(";", QString::SkipEmptyParts);
462 
463 	// check if the current icon size occurs in the list, if not, add it
464 	if (iconSizesList.lastIndexOf(iconsize) == -1) {
465 		iconSizesList << iconsize;
466 		iconSizesList.sort();
467 	}
468 
469 	iconSizeCombo->clear();
470 	iconSizeCombo->addItems(iconSizesList);
471 	int iconsizeindex = iconSizeCombo->findText(iconsize);
472 	iconSizeCombo->setCurrentIndex(iconsizeindex);
473 
474 	// and the same again for the icons size of the transport console
475 	QString trspsize = config().get_property("Themer", "transportconsolesize", "22").toString();
476 	iconSizesList = supportedIconSizes.split(";", QString::SkipEmptyParts);
477 
478 	if (iconSizesList.lastIndexOf(iconsize) == -1) {
479 		iconSizesList << trspsize;
480 		iconSizesList.sort();
481 	}
482 
483 	transportConsoleCombo->clear();
484 	transportConsoleCombo->addItems(iconSizesList);
485 	int trspsizeindex = iconSizeCombo->findText(trspsize);
486 	transportConsoleCombo->setCurrentIndex(trspsizeindex);
487 
488 
489 	int langIndex = languageComboBox->findData(interfaceLanguage);
490 	if (langIndex >= 0) {
491 		languageComboBox->setCurrentIndex(langIndex);
492 	}
493 }
494 
reset_default_config()495 void AppearenceConfigPage::reset_default_config()
496 {
497 	styleCombo->clear();
498 
499 	config().set_property("Themer", "themepath", QString(QDir::homePath()).append("/.traverso/themes"));
500 	config().set_property("Themer", "currenttheme", "TraversoLight");
501 	config().set_property("Themer", "coloradjust", 100);
502 	QString systemstyle = QString(QApplication::style()->metaObject()->className()).remove("Q").remove("Style");
503 	config().set_property("Themer", "style", systemstyle);
504 	config().set_property("Themer", "usestylepallet", false);
505 	config().set_property("Themer", "paintaudiorectified", false);
506 	config().set_property("Themer", "paintstereoaudioasmono", false);
507 	config().set_property("Themer", "drawdbgrid", false);
508 	config().set_property("Themer", "paintwavewithoutline", true);
509 	config().set_property("Themer", "supportediconsizes", "16;22;32;48");
510 	config().set_property("Themer", "iconsize", "22");
511 	config().set_property("Themer", "toolbuttonstyle", 0);
512 	config().set_property("Interface", "LanguageFile", "");
513 
514 	load_config();
515 }
516 
517 
AppearenceConfigPage(QWidget * parent)518 AppearenceConfigPage::AppearenceConfigPage(QWidget * parent)
519 	: ConfigPage(parent)
520 {
521 	setupUi(this);
522 
523 	themeSelecterCombo->setInsertPolicy(QComboBox::InsertAlphabetically);
524 
525 	languageComboBox->addItem(tr("Default Language"), "");
526 	foreach(const QString &lang, find_qm_files()) {
527 		languageComboBox->addItem(language_name_from_qm_file(lang), lang);
528 	}
529 
530 	load_config();
531 	create_connections();
532 }
533 
create_connections()534 void AppearenceConfigPage::create_connections()
535 {
536 	connect(styleCombo, SIGNAL(currentIndexChanged(const QString)), this, SLOT(style_index_changed(const QString)));
537 	connect(themeSelecterCombo, SIGNAL(currentIndexChanged(const QString)), this, SLOT(theme_index_changed(const QString)));
538 	connect(useStylePalletCheckBox, SIGNAL(toggled(bool)), this, SLOT(use_selected_styles_pallet_checkbox_toggled(bool)));
539 	connect(pathSelectButton, SIGNAL(clicked()), this, SLOT(dirselect_button_clicked()));
540 	connect(colorAdjustBox, SIGNAL(valueChanged(int)), this, SLOT(color_adjustbox_changed(int)));
541 	connect(rectifiedCheckBox, SIGNAL(toggled(bool)), this, SLOT(theme_option_changed()));
542 	connect(mergedCheckBox, SIGNAL(toggled(bool)), this, SLOT(theme_option_changed()));
543 	connect(dbGridCheckBox, SIGNAL(toggled(bool)), this, SLOT(theme_option_changed()));
544 	connect(paintAudioWithOutlineCheckBox, SIGNAL(toggled(bool)), this, SLOT(theme_option_changed()));
545 }
546 
style_index_changed(const QString & text)547 void AppearenceConfigPage::style_index_changed(const QString& text)
548 {
549 	QApplication::setStyle(text);
550 	QIcon icon = QApplication::style()->standardIcon(QStyle::SP_DirClosedIcon);
551 	pathSelectButton->setIcon(icon);
552 	use_selected_styles_pallet_checkbox_toggled(useStylePalletCheckBox->isChecked());
553 }
554 
theme_index_changed(const QString & theme)555 void AppearenceConfigPage::theme_index_changed(const QString & theme)
556 {
557 	int index = themeSelecterCombo->findText(theme);
558 	QString data = themeSelecterCombo->itemData(index).toString();
559 	QString path = config().get_property("Themer", "themepath", "").toString();
560 
561 	if (data == "builtintheme") {
562 		themer()->use_builtin_theme(theme);
563 	} else {
564 		themer()->set_path_and_theme(path, theme);
565 	}
566 }
567 
use_selected_styles_pallet_checkbox_toggled(bool checked)568 void AppearenceConfigPage::use_selected_styles_pallet_checkbox_toggled(bool checked)
569 {
570 	if (checked) {
571 		QApplication::setPalette(QApplication::style()->standardPalette());
572 	} else {
573 		QApplication::setPalette(themer()->system_palette());
574 	}
575 }
576 
color_adjustbox_changed(int value)577 void AppearenceConfigPage::color_adjustbox_changed(int value)
578 {
579 	themer()->set_color_adjust_value(value);
580 }
581 
dirselect_button_clicked()582 void AppearenceConfigPage::dirselect_button_clicked()
583 {
584 	QString path = themePathLineEdit->text();
585 	if (path.isEmpty()) {
586 		path = QDir::homePath();
587 	}
588 	QString dirName = QFileDialog::getExistingDirectory(this,
589 			tr("Select default project dir"), path);
590 
591 	if (!dirName.isEmpty()) {
592 		themePathLineEdit->setText(dirName);
593 		update_theme_combobox(dirName);
594 	}
595 }
596 
update_theme_combobox(const QString & path)597 void AppearenceConfigPage::update_theme_combobox(const QString& path)
598 {
599 	themeSelecterCombo->clear();
600 
601 	foreach(QString key, themer()->get_builtin_themes()) {
602 		themeSelecterCombo->insertItem(0, key, "builtintheme");
603 	}
604 
605 	QDir themedir(path);
606 	foreach (QString dirName, themedir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
607 		QString filename = path + "/" + dirName + "/" + "traversotheme.xml";
608 		if (QFile::exists(filename) ) {
609 			themeSelecterCombo->insertItem(0, dirName);
610 		}
611 	}
612 
613 }
614 
theme_option_changed()615 void AppearenceConfigPage::theme_option_changed()
616 {
617 	config().set_property("Themer", "paintaudiorectified", rectifiedCheckBox->isChecked());
618 	config().set_property("Themer", "paintstereoaudioasmono", mergedCheckBox->isChecked());
619 	config().set_property("Themer", "drawdbgrid", dbGridCheckBox->isChecked());
620 	config().set_property("Themer", "paintwavewithoutline", paintAudioWithOutlineCheckBox->isChecked());
621 	themer()->load();
622 }
623 
624 
625 
626 
627 
628 /****************************************/
629 /*            Behavior                  */
630 /****************************************/
631 
BehaviorConfigPage(QWidget * parent)632 BehaviorConfigPage::BehaviorConfigPage(QWidget * parent)
633 	: ConfigPage(parent)
634 {
635 	setupUi(this);
636 
637 	connect(&config(), SIGNAL(configChanged()), this, SLOT(update_follow()));
638 
639 	load_config();
640 }
641 
642 
save_config()643 void BehaviorConfigPage::save_config()
644 {
645 	config().set_property("Project", "loadLastUsed", loadLastProjectCheckBox->isChecked());
646 	config().set_property("Sheet", "trackCreationCount", numberOfTrackSpinBox->value());
647 	config().set_property("PlayHead", "Follow", keepCursorVisibleCheckBox->isChecked());
648 	config().set_property("PlayHead", "Scrollmode", scrollModeComboBox->currentIndex());
649 	config().set_property("AudioClip", "SyncDuringDrag", resyncAudioCheckBox->isChecked());
650 	config().set_property("AudioClip", "LockByDefault", lockClipsCheckBox->isChecked());
651 
652 	QString oncloseaction;
653 	if (saveRadioButton->isChecked()) {
654 		config().set_property("Project", "onclose", "save");
655 	} else if (askRadioButton->isChecked()) {
656 		config().set_property("Project", "onclose", "ask");
657 	} else {
658 		config().set_property("Project", "onclose", "dontsave");
659 	}
660 }
661 
load_config()662 void BehaviorConfigPage::load_config()
663 {
664 	bool loadLastUsedProject = config().get_property("Project", "loadLastUsed", 1).toBool();
665 	QString oncloseaction = config().get_property("Project", "onclose", "save").toString();
666 	int defaultNumTracks = config().get_property("Sheet", "trackCreationCount", 6).toInt();
667 	int scrollMode = config().get_property("PlayHead", "Scrollmode", 2).toInt();
668 	bool resyncAudio = config().get_property("AudioClip", "SyncDuringDrag", false).toBool();
669 	bool lockClips = config().get_property("AudioClip", "LockByDefault", false).toBool();
670 
671 	loadLastProjectCheckBox->setChecked(loadLastUsedProject);
672 	numberOfTrackSpinBox->setValue(defaultNumTracks);
673 	scrollModeComboBox->setCurrentIndex(scrollMode);
674 	resyncAudioCheckBox->setChecked(resyncAudio);
675 	lockClipsCheckBox->setChecked(lockClips);
676 
677 	if (oncloseaction == "save") {
678 		saveRadioButton->setChecked(true);
679 	} else if (oncloseaction == "ask") {
680 		askRadioButton->setChecked(true);
681 	} else {
682 		neverRadioButton->setChecked(true);
683 	}
684 
685 	update_follow();
686 
687 }
688 
689 
update_follow()690 void BehaviorConfigPage::update_follow()
691 {
692 	bool keepCursorVisible = config().get_property("PlayHead", "Follow", true).toBool();
693 	keepCursorVisibleCheckBox->setChecked(keepCursorVisible);
694 	scrollModeComboBox->setEnabled(keepCursorVisible);
695 }
696 
reset_default_config()697 void BehaviorConfigPage::reset_default_config()
698 {
699 	config().set_property("Project", "loadLastUsed", true);
700 	config().set_property("Project", "onclose", "save");
701 	config().set_property("Sheet", "trackCreationCount", 6);
702 	config().set_property("PlayHead", "Follow", 0);
703 	config().set_property("PlayHead", "Scrollmode", 2);
704 	config().set_property("AudioClip", "SyncDuringDrag", false);
705 	config().set_property("AudioClip", "LockByDefault", false);
706 
707 	load_config();
708 }
709 
710 
711 
712 
713 /****************************************/
714 /*            Keyboard                  */
715 /****************************************/
716 
717 
KeyboardConfigPage(QWidget * parent)718 KeyboardConfigPage::KeyboardConfigPage(QWidget * parent)
719 	: ConfigPage(parent)
720 {
721 	setupUi(this);
722 	connect(keymapComboBox, SIGNAL(currentIndexChanged(const QString)),
723 		this, SLOT(keymap_index_changed(const QString)));
724 
725 	load_config();
726 
727 	update_keymap_combo();
728 }
729 
load_config()730 void KeyboardConfigPage::load_config()
731 {
732 	int doubleFactTimeout = config().get_property("CCE", "doublefactTimeout", 180).toInt();
733 	int holdTimeout = config().get_property("CCE", "holdTimeout", 150).toInt();
734 
735 	doubleFactTimeoutSpinBox->setValue(doubleFactTimeout);
736 	holdTimeoutSpinBox->setValue(holdTimeout);
737 
738 	QString defaultkeymap = config().get_property("CCE", "keymap", "default").toString();
739 	int index = keymapComboBox->findText(defaultkeymap);
740 	if (index >= 0) {
741 		keymapComboBox->setCurrentIndex(index);
742 	}
743 }
744 
save_config()745 void KeyboardConfigPage::save_config()
746 {
747 	QString currentkeymap = config().get_property("CCE", "keymap", "default").toString();
748 	QString newkeymap = keymapComboBox->currentText();
749 
750 	config().set_property("CCE", "doublefactTimeout", doubleFactTimeoutSpinBox->value());
751 	config().set_property("CCE", "holdTimeout", holdTimeoutSpinBox->value());
752 	config().set_property("CCE", "keymap", newkeymap);
753 
754 	ie().set_double_fact_interval(doubleFactTimeoutSpinBox->value());
755 	ie().set_hold_sensitiveness(holdTimeoutSpinBox->value());
756 	if (currentkeymap != newkeymap) {
757 		ie().init_map(newkeymap);
758 	}
759 }
760 
reset_default_config()761 void KeyboardConfigPage::reset_default_config()
762 {
763 	config().set_property("CCE", "doublefactTimeout", 180);
764 	config().set_property("CCE", "holdTimeout", 150);
765 	config().set_property("CCE", "keymap", "default");
766 	load_config();
767 }
768 
769 
keymap_index_changed(const QString & keymap)770 void KeyboardConfigPage::keymap_index_changed(const QString& keymap)
771 {
772 	QString filename = ":/keymaps/" + keymap + ".xml";
773 	if ( ! QFile::exists(filename)) {
774 		filename = QDir::homePath() + "/.traverso/keymaps/" + keymap + ".xml";
775 	}
776 
777 	QDomDocument doc("keymap");
778 	QFile file(filename);
779 	if (!file.open(QIODevice::ReadOnly))
780 		return;
781 	if (!doc.setContent(&file)) {
782 		file.close();
783 		return;
784 	}
785 	file.close();
786 
787 	QDomElement root = doc.documentElement();
788 	QDomNode mapinfo = root.firstChildElement("KeymapInfo");
789 	QDomElement e = mapinfo.toElement();
790 	QString description = e.attribute("description", tr("No description set for this keymap"));
791 
792 	descriptionTextEdit->setHtml(description);
793 }
794 
update_keymap_combo()795 void KeyboardConfigPage::update_keymap_combo()
796 {
797 	keymapComboBox->clear();
798 
799 	QDir keymapdir(":/keymaps");
800 	foreach (QString filename, keymapdir.entryList(QDir::Files)) {
801 		keymapComboBox->insertItem(0, filename.remove(".xml"));
802 	}
803 
804 	keymapdir.setPath(QDir::homePath() + "/.traverso/keymaps");
805 	foreach (QString filename, keymapdir.entryList(QDir::Files)) {
806 		keymapComboBox->insertItem(0, filename.remove(".xml"));
807 	}
808 }
809 
on_exportButton_clicked()810 void KeyboardConfigPage::on_exportButton_clicked()
811 {
812 	Interface::instance()->export_keymap();
813 	QMessageBox::information( Interface::instance(), tr("KeyMap Export"),
814 		     tr("The exported keymap can be found here:\n\n %1").arg(QDir::homePath() + "/traversokeymap.html"),
815 		     QMessageBox::Ok);
816 }
817 
on_printButton_clicked()818 void KeyboardConfigPage::on_printButton_clicked()
819 {
820 	QString kmap;
821 	Interface::instance()->get_keymap(kmap);
822 
823 //	QPrinter printer(QPrinter::ScreenResolution);
824 //	QPrintDialog printDialog(&printer, Interface::instance());
825 //	if (printDialog.exec() == QDialog::Accepted) {
826 //		QTextEdit edit;
827 //		edit.insertHtml(kmap);
828 //		edit.document()->print(&printer);
829 //	}
830 }
831 
832 
833 
834 
PerformanceConfigPage(QWidget * parent)835 PerformanceConfigPage::PerformanceConfigPage(QWidget* parent)
836 	: ConfigPage(parent)
837 {
838 	delete layout();
839 	setupUi(this);
840 
841 	load_config();
842 
843 
844 	// don't show it for now, it's not making sense with current opengl support
845 	useOpenGLCheckBox->hide();
846 #if defined (QT_OPENGL_SUPPORT)
847 	useOpenGLCheckBox->setEnabled(true);
848 #else
849 	useOpenGLCheckBox->setEnabled(false);
850 #endif
851 	QIcon icon = QApplication::style()->standardIcon(QStyle::SP_MessageBoxInformation);
852 	reloadWarningLabel->setPixmap(icon.pixmap(22, 22));
853 }
854 
855 
load_config()856 void PerformanceConfigPage::load_config()
857 {
858 	int jogUpdateInterval = config().get_property("CCE", "jogupdateinterval", 28).toInt();
859 	bool useOpenGL = config().get_property("Interface", "OpenGL", false).toBool();
860 
861 	jogUpdateIntervalSpinBox->setValue(1000 / jogUpdateInterval);
862 	useOpenGLCheckBox->setChecked(useOpenGL);
863 
864 
865 	double buffertime = config().get_property("Hardware", "readbuffersize", 1.0).toDouble();
866 	bufferTimeSpinBox->setValue(buffertime);
867 }
868 
save_config()869 void PerformanceConfigPage::save_config()
870 {
871 	config().set_property("Interface", "OpenGL", useOpenGLCheckBox->isChecked());
872 	config().set_property("CCE", "jogupdateinterval", 1000 / jogUpdateIntervalSpinBox->value());
873 	double buffertime = bufferTimeSpinBox->value();
874 	config().set_property("Hardware", "readbuffersize", buffertime);
875 }
876 
reset_default_config()877 void PerformanceConfigPage::reset_default_config()
878 {
879 	config().set_property("CCE", "jogupdateinterval", 28);
880 	config().set_property("Interface", "OpenGL", false);
881 	config().set_property("Hardware", "readbuffersize", 1.0);
882 	load_config();
883 }
884 
885 
886 /****************************************/
887 /*            Recording                 */
888 /****************************************/
889 
RecordingConfigPage(QWidget * parent)890 RecordingConfigPage::RecordingConfigPage(QWidget * parent)
891 	: ConfigPage(parent)
892 {
893 	setupUi(this);
894 
895 	encodingComboBox->addItem("WAV", "wav");
896 	encodingComboBox->addItem("WavPack", "wavpack");
897 	encodingComboBox->addItem("WAV64", "w64");
898 	wavpackCompressionComboBox->addItem("Very high", "very_high");
899 	wavpackCompressionComboBox->addItem("High", "high");
900 	wavpackCompressionComboBox->addItem("Fast", "fast");
901 
902 	connect(encodingComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(encoding_index_changed(int)));
903 	connect(useResamplingCheckBox, SIGNAL(stateChanged(int)),
904 		this, SLOT(use_onthefly_resampling_checkbox_changed(int)));
905 
906 	load_config();
907 }
908 
load_config()909 void RecordingConfigPage::load_config()
910 {
911 	bool useResampling = config().get_property("Conversion", "DynamicResampling", true).toBool();
912 	if (useResampling) {
913 		use_onthefly_resampling_checkbox_changed(Qt::Checked);
914 	} else {
915 		use_onthefly_resampling_checkbox_changed(Qt::Unchecked);
916 	}
917 
918 	QString recordFormat = config().get_property("Recording", "FileFormat", "wav").toString();
919 	if (recordFormat == "wavpack") {
920 		encoding_index_changed(1);
921 	} else if (recordFormat == "w64") {
922 		encoding_index_changed(2);
923 	} else {
924 		encoding_index_changed(0);
925 	}
926 
927 	QString wavpackcompression = config().get_property("Recording", "WavpackCompressionType", "fast").toString();
928 	if (wavpackcompression == "very_high") {
929 		wavpackCompressionComboBox->setCurrentIndex(0);
930 	} else if (wavpackcompression == "high") {
931 		wavpackCompressionComboBox->setCurrentIndex(1);
932 	} else {
933 		wavpackCompressionComboBox->setCurrentIndex(2);
934 	}
935 
936 	int index = config().get_property("Conversion", "RTResamplingConverterType", DEFAULT_RESAMPLE_QUALITY).toInt();
937 	ontheflyResampleComboBox->setCurrentIndex(index);
938 
939 	index = config().get_property("Conversion", "ExportResamplingConverterType", 1).toInt();
940 	exportDefaultResampleQualityComboBox->setCurrentIndex(index);
941 }
942 
save_config()943 void RecordingConfigPage::save_config()
944 {
945 	config().set_property("Conversion", "DynamicResampling", useResamplingCheckBox->isChecked());
946 	config().set_property("Conversion", "RTResamplingConverterType", ontheflyResampleComboBox->currentIndex());
947 	config().set_property("Conversion", "ExportResamplingConverterType", exportDefaultResampleQualityComboBox->currentIndex());
948 	config().set_property("Recording", "FileFormat", encodingComboBox->itemData(encodingComboBox->currentIndex()).toString());
949 	config().set_property("Recording", "WavpackCompressionType", wavpackCompressionComboBox->itemData(wavpackCompressionComboBox->currentIndex()).toString());
950 	QString skipwvx = wavpackUseAlmostLosslessCheckBox->isChecked() ? "true" : "false";
951 	config().set_property("Recording", "WavpackSkipWVX", skipwvx);
952 }
953 
reset_default_config()954 void RecordingConfigPage::reset_default_config()
955 {
956 	config().set_property("Conversion", "DynamicResampling", true);
957 	config().set_property("Conversion", "RTResamplingConverterType", DEFAULT_RESAMPLE_QUALITY);
958 	config().set_property("Conversion", "ExportResamplingConverterType", 1);
959 	config().set_property("Recording", "FileFormat", "wav");
960 	config().set_property("Recording", "WavpackCompressionType", "fast");
961 	config().set_property("Recording", "WavpackSkipWVX", "false");
962 
963 	load_config();
964 }
965 
966 
encoding_index_changed(int index)967 void RecordingConfigPage::encoding_index_changed(int index)
968 {
969 	encodingComboBox->setCurrentIndex(index);
970 	if (index != 1) {
971 		wacpackGroupBox->hide();
972 	} else {
973 		wacpackGroupBox->show();
974 	}
975 }
976 
use_onthefly_resampling_checkbox_changed(int state)977 void RecordingConfigPage::use_onthefly_resampling_checkbox_changed(int state)
978 {
979 	if (state == Qt::Checked) {
980 		useResamplingCheckBox->setChecked(true);
981 		ontheflyResampleComboBox->setEnabled(true);
982 	} else {
983 		useResamplingCheckBox->setChecked(false);
984 		ontheflyResampleComboBox->setEnabled(false);
985 	}
986 }
987 
988