1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
9 * Copyright (C) 2007 by Dominik Riebeling
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
23 #include "configure.h"
24 #include "autodetection.h"
25 #include "ui_configurefrm.h"
26 #include "browsedirtree.h"
30 #include "encttscfggui.h"
33 #if defined(Q_OS_WIN32)
41 #define DEFAULT_LANG "English (en)"
42 #define DEFAULT_LANG_CODE "en"
44 Config::Config(QWidget
*parent
,int index
) : QDialog(parent
)
46 programPath
= qApp
->applicationDirPath() + "/";
48 ui
.tabConfiguration
->setCurrentIndex(index
);
49 ui
.radioManualProxy
->setChecked(true);
50 QRegExpValidator
*proxyValidator
= new QRegExpValidator(this);
51 QRegExp
validate("[0-9]*");
52 proxyValidator
->setRegExp(validate
);
53 ui
.proxyPort
->setValidator(proxyValidator
);
54 #if !defined(Q_OS_LINUX) && !defined(Q_OS_WIN32)
55 ui
.radioSystemProxy
->setEnabled(false); // not on macox for now
57 // build language list and sort alphabetically
58 QStringList langs
= findLanguageFiles();
59 for(int i
= 0; i
< langs
.size(); ++i
)
60 lang
.insert(languageName(langs
.at(i
))
61 + QString(" (%1)").arg(langs
.at(i
)), langs
.at(i
));
62 lang
.insert(DEFAULT_LANG
, DEFAULT_LANG_CODE
);
63 QMap
<QString
, QString
>::const_iterator i
= lang
.constBegin();
64 while (i
!= lang
.constEnd()) {
65 ui
.listLanguages
->addItem(i
.key());
68 ui
.listLanguages
->setSelectionMode(QAbstractItemView::SingleSelection
);
69 ui
.proxyPass
->setEchoMode(QLineEdit::Password
);
70 ui
.treeDevices
->setAlternatingRowColors(true);
71 ui
.listLanguages
->setAlternatingRowColors(true);
75 connect(ui
.buttonOk
, SIGNAL(clicked()), this, SLOT(accept()));
76 connect(ui
.buttonCancel
, SIGNAL(clicked()), this, SLOT(abort()));
77 connect(ui
.radioNoProxy
, SIGNAL(toggled(bool)), this, SLOT(setNoProxy(bool)));
78 connect(ui
.radioSystemProxy
, SIGNAL(toggled(bool)), this, SLOT(setSystemProxy(bool)));
79 connect(ui
.browseMountPoint
, SIGNAL(clicked()), this, SLOT(browseFolder()));
80 connect(ui
.buttonAutodetect
,SIGNAL(clicked()),this,SLOT(autodetect()));
81 connect(ui
.buttonCacheBrowse
, SIGNAL(clicked()), this, SLOT(browseCache()));
82 connect(ui
.buttonCacheClear
, SIGNAL(clicked()), this, SLOT(cacheClear()));
83 connect(ui
.configTts
, SIGNAL(clicked()), this, SLOT(configTts()));
84 connect(ui
.configEncoder
, SIGNAL(clicked()), this, SLOT(configEnc()));
85 connect(ui
.comboTts
, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTtsState(int)));
86 connect(ui
.treeDevices
, SIGNAL(itemSelectionChanged()), this, SLOT(updateEncState()));
94 qDebug() << "Config::accept()";
95 QString errormsg
= tr("The following errors occurred:") + "<ul>";
98 // proxy: save entered proxy values, not displayed.
99 if(ui
.radioManualProxy
->isChecked()) {
100 proxy
.setScheme("http");
101 proxy
.setUserName(ui
.proxyUser
->text());
102 proxy
.setPassword(ui
.proxyPass
->text());
103 proxy
.setHost(ui
.proxyHost
->text());
104 proxy
.setPort(ui
.proxyPort
->text().toInt());
107 settings
->setValue(RbSettings::Proxy
, proxy
.toString());
108 qDebug() << "new proxy:" << proxy
;
111 if(ui
.radioNoProxy
->isChecked()) proxyType
= "none";
112 else if(ui
.radioSystemProxy
->isChecked()) proxyType
= "system";
113 else proxyType
= "manual";
114 settings
->setValue(RbSettings::ProxyType
, proxyType
);
117 if(settings
->value(RbSettings::Language
).toString() != language
&& !language
.isEmpty()) {
118 QMessageBox::information(this, tr("Language changed"),
119 tr("You need to restart the application for the changed language to take effect."));
120 settings
->setValue(RbSettings::Language
, language
);
124 QString mp
= ui
.mountPoint
->text();
126 errormsg
+= "<li>" + tr("No mountpoint given") + "</li>";
129 else if(!QFileInfo(mp
).exists()) {
130 errormsg
+= "<li>" + tr("Mountpoint does not exist") + "</li>";
133 else if(!QFileInfo(mp
).isDir()) {
134 errormsg
+= "<li>" + tr("Mountpoint is not a directory.") + "</li>";
137 else if(!QFileInfo(mp
).isWritable()) {
138 errormsg
+= "<li>" + tr("Mountpoint is not writeable") + "</li>";
142 settings
->setValue(RbSettings::Mountpoint
, QDir::fromNativeSeparators(mp
));
147 if(ui
.treeDevices
->selectedItems().size() != 0) {
148 nplat
= ui
.treeDevices
->selectedItems().at(0)->data(0, Qt::UserRole
).toString();
149 settings
->setValue(RbSettings::Platform
, nplat
);
152 errormsg
+= "<li>" + tr("No player selected") + "</li>";
157 if(QFileInfo(ui
.cachePath
->text()).isDir()) {
158 if(!QFileInfo(ui
.cachePath
->text()).isWritable()) {
159 errormsg
+= "<li>" + tr("Cache path not writeable. Leave path empty "
160 "to default to systems temporary path.") + "</li>";
164 settings
->setValue(RbSettings::CachePath
, ui
.cachePath
->text());
166 else // default to system temp path
167 settings
->setValue(RbSettings::CachePath
, QDir::tempPath());
168 settings
->setValue(RbSettings::CacheDisabled
, ui
.cacheDisable
->isChecked());
169 settings
->setValue(RbSettings::CacheOffline
, ui
.cacheOfflineMode
->isChecked());
172 int i
= ui
.comboTts
->currentIndex();
173 settings
->setValue(RbSettings::Tts
, ui
.comboTts
->itemData(i
).toString());
175 settings
->setValue(RbSettings::RbutilVersion
, PUREVERSION
);
178 errormsg
+= tr("You need to fix the above errors before you can continue.");
181 QMessageBox::critical(this, tr("Configuration error"), errormsg
);
187 emit
settingsUpdated();
194 qDebug() << "Config::abort()";
198 void Config::setSettings(RbSettings
* sett
)
206 void Config::setUserSettings()
209 proxy
= settings
->value(RbSettings::Proxy
).toString();
212 ui
.proxyPort
->setText(QString("%1").arg(proxy
.port()));
213 else ui
.proxyPort
->setText("");
214 ui
.proxyHost
->setText(proxy
.host());
215 ui
.proxyUser
->setText(proxy
.userName());
216 ui
.proxyPass
->setText(proxy
.password());
218 QString proxyType
= settings
->value(RbSettings::ProxyType
).toString();
219 if(proxyType
== "manual") ui
.radioManualProxy
->setChecked(true);
220 else if(proxyType
== "system") ui
.radioSystemProxy
->setChecked(true);
221 else ui
.radioNoProxy
->setChecked(true);
223 // set language selection
224 QList
<QListWidgetItem
*> a
;
226 // find key for lang value
227 QMap
<QString
, QString
>::const_iterator i
= lang
.constBegin();
228 QString l
= settings
->value(RbSettings::Language
).toString();
230 l
= QLocale::system().name();
231 while (i
!= lang
.constEnd()) {
236 else if(l
.startsWith(i
.value(), Qt::CaseInsensitive
)) {
237 // check if there is a base language (en -> en_US, etc.)
243 a
= ui
.listLanguages
->findItems(b
, Qt::MatchExactly
);
245 ui
.listLanguages
->setCurrentItem(a
.at(0));
246 // don't connect before language list has been set up to prevent
247 // triggering the signal by selecting the saved language.
248 connect(ui
.listLanguages
, SIGNAL(itemSelectionChanged()), this, SLOT(updateLanguage()));
251 ui
.mountPoint
->setText(QDir::toNativeSeparators(settings
->value(RbSettings::Mountpoint
).toString()));
254 if(!QFileInfo(settings
->value(RbSettings::CachePath
).toString()).isDir())
255 settings
->setValue(RbSettings::CachePath
, QDir::tempPath());
256 ui
.cachePath
->setText(QDir::toNativeSeparators(settings
->value(RbSettings::CachePath
).toString()));
257 ui
.cacheDisable
->setChecked(settings
->value(RbSettings::CacheDisabled
).toBool());
258 ui
.cacheOfflineMode
->setChecked(settings
->value(RbSettings::CacheOffline
).toBool());
259 updateCacheInfo(settings
->value(RbSettings::CachePath
).toString());
263 void Config::updateCacheInfo(QString path
)
266 fs
= QDir(path
+ "/rbutil-cache/").entryInfoList(QDir::Files
| QDir::NoDotAndDotDot
);
268 for(int i
= 0; i
< fs
.size(); i
++) {
269 sz
+= fs
.at(i
).size();
270 qDebug() << fs
.at(i
).fileName() << fs
.at(i
).size();
272 ui
.cacheSize
->setText(tr("Current cache size is %L1 kiB.")
277 void Config::setDevices()
280 // setup devices table
281 qDebug() << "Config::setDevices()";
283 QStringList platformList
= settings
->platforms();
285 QMap
<QString
, QString
> manuf
;
286 QMap
<QString
, QString
> devcs
;
287 for(int it
= 0; it
< platformList
.size(); it
++)
289 QString curname
= settings
->name(platformList
.at(it
));
290 QString curbrand
= settings
->brand(platformList
.at(it
));
291 manuf
.insertMulti(curbrand
, platformList
.at(it
));
292 devcs
.insert(platformList
.at(it
), curname
);
296 platform
= devcs
.value(settings
->value(RbSettings::Platform
).toString());
298 // set up devices table
299 ui
.treeDevices
->header()->hide();
300 ui
.treeDevices
->expandAll();
301 ui
.treeDevices
->setColumnCount(1);
302 QList
<QTreeWidgetItem
*> items
;
305 QStringList brands
= manuf
.uniqueKeys();
308 QTreeWidgetItem
*w3
= 0;
309 for(int c
= 0; c
< brands
.size(); c
++) {
310 qDebug() << brands
.at(c
);
311 w
= new QTreeWidgetItem();
312 w
->setFlags(Qt::ItemIsEnabled
);
313 w
->setText(0, brands
.at(c
));
316 // go through platforms again for sake of order
317 for(int it
= 0; it
< platformList
.size(); it
++) {
319 QString curname
= settings
->name(platformList
.at(it
));
320 QString curbrand
= settings
->brand(platformList
.at(it
));
322 if(curbrand
!= brands
.at(c
)) continue;
323 qDebug() << "adding:" << brands
.at(c
) << curname
;
324 w2
= new QTreeWidgetItem(w
, QStringList(curname
));
325 w2
->setData(0, Qt::UserRole
, platformList
.at(it
));
327 if(platform
.contains(curname
)) {
328 w2
->setSelected(true);
329 w
->setExpanded(true);
330 w3
= w2
; // save pointer to hilight old selection
335 ui
.treeDevices
->insertTopLevelItems(0, items
);
337 ui
.treeDevices
->setCurrentItem(w3
); // hilight old selection
345 QStringList ttslist
= TTSBase::getTTSList();
346 for(int a
= 0; a
< ttslist
.size(); a
++)
347 ui
.comboTts
->addItem(TTSBase::getTTSName(ttslist
.at(a
)), ttslist
.at(a
));
348 //update index of combobox
349 int index
= ui
.comboTts
->findData(settings
->value(RbSettings::Tts
).toString());
350 if(index
< 0) index
= 0;
351 ui
.comboTts
->setCurrentIndex(index
);
352 updateTtsState(index
);
357 void Config::updateTtsState(int index
)
359 QString ttsName
= ui
.comboTts
->itemData(index
).toString();
360 TTSBase
* tts
= TTSBase::getTTS(this,ttsName
);
361 tts
->setCfg(settings
);
365 ui
.configTTSstatus
->setText(tr("Configuration OK"));
366 ui
.configTTSstatusimg
->setPixmap(QPixmap(QString::fromUtf8(":/icons/go-next.png")));
370 ui
.configTTSstatus
->setText(tr("Configuration INVALID"));
371 ui
.configTTSstatusimg
->setPixmap(QPixmap(QString::fromUtf8(":/icons/dialog-error.png")));
375 void Config::updateEncState()
377 // FIXME: this is a workaround to make the encoder follow the device selection
378 // even with the settings (and thus the device) being saved. Needs to be redone
379 // properly later by extending the settings object
380 if(ui
.treeDevices
->selectedItems().size() == 0)
383 QString devname
= ui
.treeDevices
->selectedItems().at(0)->data(0, Qt::UserRole
).toString();
384 QString olddevice
= settings
->value(RbSettings::Platform
).toString();
385 settings
->setValue(RbSettings::Platform
, devname
);
386 QString encoder
= settings
->value(RbSettings::CurEncoder
).toString();
387 ui
.encoderName
->setText(EncBase::getEncoderName(settings
->value(RbSettings::CurEncoder
).toString()));
388 settings
->setValue(RbSettings::Platform
, olddevice
);
390 EncBase
* enc
= EncBase::getEncoder(this,encoder
);
391 enc
->setCfg(settings
);
395 ui
.configEncstatus
->setText(tr("Configuration OK"));
396 ui
.configEncstatusimg
->setPixmap(QPixmap(QString::fromUtf8(":/icons/go-next.png")));
400 ui
.configEncstatus
->setText(tr("Configuration INVALID"));
401 ui
.configEncstatusimg
->setPixmap(QPixmap(QString::fromUtf8(":/icons/dialog-error.png")));
405 void Config::setNoProxy(bool checked
)
408 ui
.proxyPort
->setEnabled(i
);
409 ui
.proxyHost
->setEnabled(i
);
410 ui
.proxyUser
->setEnabled(i
);
411 ui
.proxyPass
->setEnabled(i
);
415 void Config::setSystemProxy(bool checked
)
418 ui
.proxyPort
->setEnabled(i
);
419 ui
.proxyHost
->setEnabled(i
);
420 ui
.proxyUser
->setEnabled(i
);
421 ui
.proxyPass
->setEnabled(i
);
423 // save values in input box
424 proxy
.setScheme("http");
425 proxy
.setUserName(ui
.proxyUser
->text());
426 proxy
.setPassword(ui
.proxyPass
->text());
427 proxy
.setHost(ui
.proxyHost
->text());
428 proxy
.setPort(ui
.proxyPort
->text().toInt());
429 // show system values in input box
430 QUrl envproxy
= Detect::systemProxy();
432 ui
.proxyHost
->setText(envproxy
.host());
434 ui
.proxyPort
->setText(QString("%1").arg(envproxy
.port()));
435 ui
.proxyUser
->setText(envproxy
.userName());
436 ui
.proxyPass
->setText(envproxy
.password());
440 ui
.proxyHost
->setText(proxy
.host());
442 ui
.proxyPort
->setText(QString("%1").arg(proxy
.port()));
443 else ui
.proxyPort
->setText("");
444 ui
.proxyUser
->setText(proxy
.userName());
445 ui
.proxyPass
->setText(proxy
.password());
451 QStringList
Config::findLanguageFiles()
453 QDir
dir(programPath
);
454 QStringList fileNames
;
456 fileNames
= dir
.entryList(QStringList("*.qm"), QDir::Files
, QDir::Name
);
458 QDir
resDir(":/lang");
459 fileNames
+= resDir
.entryList(QStringList("*.qm"), QDir::Files
, QDir::Name
);
461 QRegExp
exp("^rbutil_(.*)\\.qm");
462 for(int i
= 0; i
< fileNames
.size(); i
++) {
463 QString a
= fileNames
.at(i
);
464 a
.replace(exp
, "\\1");
468 qDebug() << "Config::findLanguageFiles()" << langs
;
474 QString
Config::languageName(const QString
&qmFile
)
476 QTranslator translator
;
478 QString file
= "rbutil_" + qmFile
;
479 if(!translator
.load(file
, programPath
))
480 translator
.load(file
, ":/lang");
482 return translator
.translate("Configure", "English",
483 "This is the localized language name, i.e. your language.");
487 void Config::updateLanguage()
489 qDebug() << "updateLanguage()";
490 QList
<QListWidgetItem
*> a
= ui
.listLanguages
->selectedItems();
492 language
= lang
.value(a
.at(0)->text());
493 qDebug() << language
;
497 void Config::browseFolder()
499 browser
= new BrowseDirtree(this,tr("Select your device"));
500 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
501 browser
->setFilter(QDir::AllDirs
| QDir::NoDotAndDotDot
| QDir::NoSymLinks
);
502 #elif defined(Q_OS_WIN32)
503 browser
->setFilter(QDir::Drives
);
505 #if defined(Q_OS_MACX)
506 browser
->setRoot("/Volumes");
507 #elif defined(Q_OS_LINUX)
508 browser
->setDir("/media");
510 if( ui
.mountPoint
->text() != "" )
512 browser
->setDir(ui
.mountPoint
->text());
515 connect(browser
, SIGNAL(itemChanged(QString
)), this, SLOT(setMountpoint(QString
)));
519 void Config::browseCache()
521 cbrowser
= new BrowseDirtree(this);
522 #if defined(Q_OS_LINUX) || defined(Q_OS_MACX)
523 cbrowser
->setFilter(QDir::AllDirs
| QDir::NoDotAndDotDot
| QDir::NoSymLinks
);
524 #elif defined(Q_OS_WIN32)
525 cbrowser
->setFilter(QDir::Drives
| QDir::AllDirs
| QDir::NoDotAndDotDot
);
527 cbrowser
->setDir(ui
.cachePath
->text());
528 connect(cbrowser
, SIGNAL(itemChanged(QString
)), this, SLOT(setCache(QString
)));
533 void Config::setMountpoint(QString m
)
535 ui
.mountPoint
->setText(m
);
539 void Config::setCache(QString c
)
541 ui
.cachePath
->setText(c
);
546 void Config::autodetect()
548 Autodetection
detector(this);
549 detector
.setSettings(settings
);
550 // disable tree during detection as "working" feedback.
551 // TODO: replace the tree view with a splash screen during this time.
552 ui
.treeDevices
->setEnabled(false);
553 this->setCursor(Qt::WaitCursor
);
554 QCoreApplication::processEvents();
556 if(detector
.detect()) //let it detect
558 QString devicename
= detector
.getDevice();
559 // deexpand all items
560 for(int a
= 0; a
< ui
.treeDevices
->topLevelItemCount(); a
++)
561 ui
.treeDevices
->topLevelItem(a
)->setExpanded(false);
562 //deselect the selected item(s)
563 for(int a
= 0; a
< ui
.treeDevices
->selectedItems().size(); a
++)
564 ui
.treeDevices
->selectedItems().at(a
)->setSelected(false);
567 // enumerate all platform items
568 QList
<QTreeWidgetItem
*> itmList
= ui
.treeDevices
->findItems("*",Qt::MatchWildcard
);
569 for(int i
=0; i
< itmList
.size();i
++)
571 //enumerate device items
572 for(int j
=0;j
< itmList
.at(i
)->childCount();j
++)
574 QString data
= itmList
.at(i
)->child(j
)->data(0, Qt::UserRole
).toString();
576 if(devicename
== data
) // item found
578 itmList
.at(i
)->child(j
)->setSelected(true); //select the item
579 itmList
.at(i
)->setExpanded(true); //expand the platform item
580 //ui.treeDevices->indexOfTopLevelItem(itmList.at(i)->child(j));
587 if(!detector
.errdev().isEmpty()) {
589 if(detector
.errdev() == "sansae200")
590 text
= tr("Sansa e200 in MTP mode found!\n"
591 "You need to change your player to MSC mode for installation. ");
592 if(detector
.errdev() == "h10")
593 text
= tr("H10 20GB in MTP mode found!\n"
594 "You need to change your player to UMS mode for installation. ");
595 text
+= tr("Unless you changed this installation will fail!");
597 QMessageBox::critical(this, tr("Fatal error"), text
, QMessageBox::Ok
);
600 if(!detector
.incompatdev().isEmpty()) {
602 // we need to set the platform here to get the brand from the
604 settings
->setValue(RbSettings::Platform
, detector
.incompatdev());
605 text
= tr("Detected an unsupported %1 player variant. Sorry, "
606 "Rockbox doesn't run on your player.")
607 .arg(settings
->value(RbSettings::CurBrand
).toString());
609 QMessageBox::critical(this, tr("Fatal error: incompatible player found"),
610 text
, QMessageBox::Ok
);
614 if(detector
.getMountPoint() != "" )
616 ui
.mountPoint
->setText(QDir::toNativeSeparators(detector
.getMountPoint()));
620 QMessageBox::warning(this, tr("Autodetection"),
621 tr("Could not detect a Mountpoint.\n"
622 "Select your Mountpoint manually."),
623 QMessageBox::Ok
,QMessageBox::Ok
);
629 QMessageBox::warning(this, tr("Autodetection"),
630 tr("Could not detect a device.\n"
631 "Select your device and Mountpoint manually."),
632 QMessageBox::Ok
,QMessageBox::Ok
);
635 ui
.treeDevices
->setEnabled(true);
638 void Config::cacheClear()
640 if(QMessageBox::critical(this, tr("Really delete cache?"),
641 tr("Do you really want to delete the cache? "
642 "Make absolutely sure this setting is correct as it will "
643 "remove <b>all</b> files in this folder!").arg(ui
.cachePath
->text()),
644 QMessageBox::Yes
| QMessageBox::No
) != QMessageBox::Yes
)
647 QString cache
= ui
.cachePath
->text() + "/rbutil-cache/";
648 if(!QFileInfo(cache
).isDir()) {
649 QMessageBox::critical(this, tr("Path wrong!"),
650 tr("The cache path is invalid. Aborting."), QMessageBox::Ok
);
655 fn
= dir
.entryList(QStringList("*"), QDir::Files
, QDir::Name
);
658 for(int i
= 0; i
< fn
.size(); i
++) {
659 QString f
= cache
+ fn
.at(i
);
661 qDebug() << "removed:" << f
;
663 updateCacheInfo(settings
->value(RbSettings::CachePath
).toString());
667 void Config::configTts()
669 int index
= ui
.comboTts
->currentIndex();
670 TTSBase
* tts
= TTSBase::getTTS(this,ui
.comboTts
->itemData(index
).toString());
672 tts
->setCfg(settings
);
673 EncTtsCfgGui
gui(this,tts
,TTSBase::getTTSName(settings
->value(RbSettings::Tts
).toString()));
675 updateTtsState(ui
.comboTts
->currentIndex());
679 void Config::configEnc()
681 // FIXME: this is a workaround to make the encoder follow the device selection
682 // even with the settings (and thus the device) being saved. Needs to be redone
683 // properly later by extending the settings object
684 if(ui
.treeDevices
->selectedItems().size() == 0)
687 QString devname
= ui
.treeDevices
->selectedItems().at(0)->data(0, Qt::UserRole
).toString();
688 QString olddevice
= settings
->value(RbSettings::CurrentPlatform
).toString();
689 settings
->setValue(RbSettings::CurrentPlatform
,devname
);
690 QString encoder
= settings
->value(RbSettings::CurEncoder
).toString();
691 ui
.encoderName
->setText(EncBase::getEncoderName(settings
->value(RbSettings::CurEncoder
).toString()));
692 settings
->setValue(RbSettings::CurrentPlatform
,olddevice
);
695 EncBase
* enc
= EncBase::getEncoder(this,encoder
);
697 enc
->setCfg(settings
);
698 EncTtsCfgGui
gui(this,enc
,EncBase::getEncoderName(encoder
));