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 ****************************************************************************/
24 #include "ui_rbutilqtfrm.h"
25 #include "ui_aboutbox.h"
26 #include "configure.h"
28 #include "installtalkwindow.h"
29 #include "createvoicewindow.h"
31 #include "themesinstallwindow.h"
32 #include "uninstallwindow.h"
38 #include "rbsettings.h"
40 #include "progressloggerinterface.h"
42 #include "bootloaderinstallbase.h"
43 #include "bootloaderinstallmi4.h"
44 #include "bootloaderinstallhex.h"
45 #include "bootloaderinstallipod.h"
46 #include "bootloaderinstallsansa.h"
47 #include "bootloaderinstallfile.h"
48 #include "bootloaderinstallchinachip.h"
49 #include "bootloaderinstallams.h"
50 #include "bootloaderinstalltcc.h"
53 #if defined(Q_OS_LINUX)
56 #if defined(Q_OS_WIN32)
65 RbUtilQt::RbUtilQt(QWidget
*parent
) : QMainWindow(parent
)
68 qDebug() << "======================================";
69 qDebug() << "[System] Rockbox Utility " VERSION
;
70 qDebug() << "[System] Qt version:" << qVersion();
71 qDebug() << "======================================";
73 absolutePath
= qApp
->applicationDirPath();
75 HttpGet::setGlobalUserAgent("rbutil/"VERSION
);
76 // init startup & autodetection
85 ui
.radioPdf
->setChecked(true);
88 ui
.treeInfo
->setAlternatingRowColors(true);
89 ui
.treeInfo
->setHeaderLabels(QStringList() << tr("File") << tr("Version"));
90 ui
.treeInfo
->expandAll();
91 ui
.treeInfo
->setColumnCount(2);
92 ui
.treeInfo
->setLayoutDirection(Qt::LeftToRight
);
93 // disable quick install until version info is available
94 ui
.buttonSmall
->setEnabled(false);
95 ui
.buttonComplete
->setEnabled(false);
96 ui
.actionSmall_Installation
->setEnabled(false);
97 ui
.actionComplete_Installation
->setEnabled(false);
99 connect(ui
.tabWidget
, SIGNAL(currentChanged(int)), this, SLOT(updateTabs(int)));
100 connect(ui
.actionAbout_Qt
, SIGNAL(triggered()), qApp
, SLOT(aboutQt()));
101 connect(ui
.action_About
, SIGNAL(triggered()), this, SLOT(about()));
102 connect(ui
.action_Help
, SIGNAL(triggered()), this, SLOT(help()));
103 connect(ui
.action_Configure
, SIGNAL(triggered()), this, SLOT(configDialog()));
104 connect(ui
.buttonChangeDevice
, SIGNAL(clicked()), this, SLOT(configDialog()));
105 connect(ui
.buttonRockbox
, SIGNAL(clicked()), this, SLOT(installBtn()));
106 connect(ui
.buttonBootloader
, SIGNAL(clicked()), this, SLOT(installBootloaderBtn()));
107 connect(ui
.buttonFonts
, SIGNAL(clicked()), this, SLOT(installFontsBtn()));
108 connect(ui
.buttonGames
, SIGNAL(clicked()), this, SLOT(installDoomBtn()));
109 connect(ui
.buttonTalk
, SIGNAL(clicked()), this, SLOT(createTalkFiles()));
110 connect(ui
.buttonCreateVoice
, SIGNAL(clicked()), this, SLOT(createVoiceFile()));
111 connect(ui
.buttonVoice
, SIGNAL(clicked()), this, SLOT(installVoice()));
112 connect(ui
.buttonThemes
, SIGNAL(clicked()), this, SLOT(installThemes()));
113 connect(ui
.buttonRemoveRockbox
, SIGNAL(clicked()), this, SLOT(uninstall()));
114 connect(ui
.buttonRemoveBootloader
, SIGNAL(clicked()), this, SLOT(uninstallBootloader()));
115 connect(ui
.buttonDownloadManual
, SIGNAL(clicked()), this, SLOT(downloadManual()));
116 connect(ui
.buttonSmall
, SIGNAL(clicked()), this, SLOT(smallInstall()));
117 connect(ui
.buttonComplete
, SIGNAL(clicked()), this, SLOT(completeInstall()));
119 // actions accessible from the menu
120 connect(ui
.actionComplete_Installation
, SIGNAL(triggered()), this, SLOT(completeInstall()));
121 connect(ui
.actionSmall_Installation
, SIGNAL(triggered()), this, SLOT(smallInstall()));
122 connect(ui
.actionInstall_Bootloader
, SIGNAL(triggered()), this, SLOT(installBootloaderBtn()));
123 connect(ui
.actionInstall_Rockbox
, SIGNAL(triggered()), this, SLOT(installBtn()));
124 connect(ui
.actionFonts_Package
, SIGNAL(triggered()), this, SLOT(installFontsBtn()));
125 connect(ui
.actionInstall_Themes
, SIGNAL(triggered()), this, SLOT(installThemes()));
126 connect(ui
.actionInstall_Game_Files
, SIGNAL(triggered()), this, SLOT(installDoomBtn()));
127 connect(ui
.actionInstall_Voice_File
, SIGNAL(triggered()), this, SLOT(installVoice()));
128 connect(ui
.actionCreate_Voice_File
, SIGNAL(triggered()), this, SLOT(createVoiceFile()));
129 connect(ui
.actionCreate_Talk_Files
, SIGNAL(triggered()), this, SLOT(createTalkFiles()));
130 connect(ui
.actionRemove_bootloader
, SIGNAL(triggered()), this, SLOT(uninstallBootloader()));
131 connect(ui
.actionUninstall_Rockbox
, SIGNAL(triggered()), this, SLOT(uninstall()));
132 connect(ui
.action_System_Info
, SIGNAL(triggered()), this, SLOT(sysinfo()));
133 connect(ui
.action_Trace
, SIGNAL(triggered()), this, SLOT(trace()));
136 ui
.actionInstall_Rockbox_Utility_on_player
->setEnabled(false);
138 connect(ui
.actionInstall_Rockbox_Utility_on_player
, SIGNAL(triggered()), this, SLOT(installPortable()));
144 void RbUtilQt::trace(void)
150 void RbUtilQt::sysinfo(void)
156 void RbUtilQt::updateTabs(int count
)
168 void RbUtilQt::downloadInfo()
170 // make sure the version map is repopulated correctly later.
172 // try to get the current build information
173 daily
= new HttpGet(this);
174 connect(daily
, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
175 connect(daily
, SIGNAL(requestFinished(int, bool)), this, SLOT(downloadDone(int, bool)));
176 connect(qApp
, SIGNAL(lastWindowClosed()), daily
, SLOT(abort()));
177 if(RbSettings::value(RbSettings::CacheOffline
).toBool())
178 daily
->setCache(true);
180 daily
->setCache(false);
181 ui
.statusbar
->showMessage(tr("Downloading build information, please wait ..."));
182 qDebug() << "[RbUtil] downloading build info";
183 daily
->setFile(&buildInfo
);
184 daily
->getFile(QUrl(RbSettings::value(RbSettings::ServerConfUrl
).toString()));
188 void RbUtilQt::downloadDone(bool error
)
191 qDebug() << "[RbUtil] network error:" << daily
->error();
192 ui
.statusbar
->showMessage(tr("Can't get version information!"));
193 QMessageBox::critical(this, tr("Network error"),
194 tr("Can't get version information."));
197 qDebug() << "[RbUtil] network status:" << daily
->error();
200 QSettings
info(buildInfo
.fileName(), QSettings::IniFormat
, this);
202 versmap
.insert("arch_rev", info
.value("dailies/rev").toString());
203 versmap
.insert("arch_date", info
.value("dailies/date").toString());
205 info
.beginGroup("release");
206 versmap
.insert("rel_rev", info
.value(RbSettings::value(RbSettings::CurBuildserverModel
).toString()).toString());
209 bool installable
= !versmap
.value("rel_rev").isEmpty();
211 ui
.buttonSmall
->setEnabled(installable
);
212 ui
.buttonComplete
->setEnabled(installable
);
213 ui
.actionSmall_Installation
->setEnabled(installable
);
214 ui
.actionComplete_Installation
->setEnabled(installable
);
216 bleeding
= new HttpGet(this);
217 connect(bleeding
, SIGNAL(done(bool)), this, SLOT(downloadBleedingDone(bool)));
218 connect(bleeding
, SIGNAL(requestFinished(int, bool)), this, SLOT(downloadDone(int, bool)));
219 connect(qApp
, SIGNAL(lastWindowClosed()), bleeding
, SLOT(abort()));
220 if(RbSettings::value(RbSettings::CacheOffline
).toBool())
221 bleeding
->setCache(true);
222 bleeding
->setFile(&bleedingInfo
);
223 bleeding
->getFile(QUrl(RbSettings::value(RbSettings::BleedingInfo
).toString()));
224 ui
.statusbar
->showMessage(tr("Downloading build information, please wait ..."));
226 if(RbSettings::value(RbSettings::RbutilVersion
) != PUREVERSION
) {
227 QApplication::processEvents();
228 QMessageBox::information(this, tr("New installation"),
229 tr("This is a new installation of Rockbox Utility, or a new version. "
230 "The configuration dialog will now open to allow you to setup the program, "
231 " or review your settings."));
234 else if(chkConfig(false)) {
235 QApplication::processEvents();
236 QMessageBox::critical(this, tr("Configuration error"),
237 tr("Your configuration is invalid. This is most likely due "
238 "to a changed device path. The configuration dialog will "
239 "now open to allow you to correct the problem."));
245 void RbUtilQt::downloadBleedingDone(bool error
)
248 qDebug() << "[RbUtil] network error:" << bleeding
->error();
252 QSettings
info(bleedingInfo
.fileName(), QSettings::IniFormat
, this);
253 bleedingInfo
.close();
254 versmap
.insert("bleed_rev", info
.value("bleeding/rev").toString());
255 versmap
.insert("bleed_date", info
.value("bleeding/timestamp").toString());
256 qDebug() << "[RbUtil] version map:" << versmap
;
257 ui
.statusbar
->showMessage(tr("Download build information finished."), 5000);
261 //start check for updates
267 void RbUtilQt::downloadDone(int id
, bool error
)
270 errorString
= tr("Network error: %1. Please check your network and proxy settings.")
271 .arg(daily
->errorString());
273 QMessageBox::about(this, "Network Error", errorString
);
274 m_networkerror
= daily
->errorString();
276 qDebug() << "[RbUtil] downloadDone:" << id
<< "error:" << error
;
280 void RbUtilQt::about()
282 QDialog
*window
= new QDialog(this);
284 about
.setupUi(window
);
285 window
->setLayoutDirection(Qt::LeftToRight
);
286 window
->setModal(true);
288 QFile
licence(":/docs/gpl-2.0.html");
289 licence
.open(QIODevice::ReadOnly
);
290 QTextStream
c(&licence
);
291 QString cline
= c
.readAll();
292 about
.browserLicense
->insertHtml(cline
);
293 about
.browserLicense
->moveCursor(QTextCursor::Start
, QTextCursor::MoveAnchor
);
294 QFile
credits(":/docs/CREDITS");
295 credits
.open(QIODevice::ReadOnly
);
296 QTextStream
r(&credits
);
297 r
.setCodec(QTextCodec::codecForName("UTF-8"));
298 QString rline
= r
.readAll();
299 about
.browserCredits
->insertPlainText(rline
);
300 about
.browserCredits
->moveCursor(QTextCursor::Start
, QTextCursor::MoveAnchor
);
301 QString title
= QString("<b>The Rockbox Utility</b><br/>Version %1").arg(FULLVERSION
);
302 about
.labelTitle
->setText(title
);
309 void RbUtilQt::help()
311 QUrl
helpurl("http://www.rockbox.org/wiki/RockboxUtility");
312 QDesktopServices::openUrl(helpurl
);
316 void RbUtilQt::configDialog()
318 Config
*cw
= new Config(this);
319 connect(cw
, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
320 connect(cw
, SIGNAL(settingsUpdated()), this, SLOT(downloadInfo()));
325 void RbUtilQt::updateSettings()
327 qDebug() << "[RbUtil] updating current settings";
330 if(RbSettings::value(RbSettings::ProxyType
) == "system") {
331 HttpGet::setGlobalProxy(System::systemProxy());
333 else if(RbSettings::value(RbSettings::ProxyType
) == "manual") {
334 HttpGet::setGlobalProxy(RbSettings::value(RbSettings::Proxy
).toString());
337 HttpGet::setGlobalProxy(QUrl(""));
339 HttpGet::setGlobalCache(RbSettings::value(RbSettings::CachePath
).toString());
340 HttpGet::setGlobalDumbCache(RbSettings::value(RbSettings::CacheOffline
).toBool());
344 void RbUtilQt::updateDevice()
346 /* TODO: We should check the flags of the bootloaderinstall classes, and not
347 * just check if its != none or != "fwpatcher" */
349 /* Enable bootloader installation, if possible */
350 bool bootloaderInstallable
=
351 RbSettings::value(RbSettings::CurBootloaderMethod
) != "none";
352 ui
.buttonBootloader
->setEnabled(bootloaderInstallable
);
353 ui
.labelBootloader
->setEnabled(bootloaderInstallable
);
354 ui
.actionInstall_Bootloader
->setEnabled(bootloaderInstallable
);
356 /* Enable bootloader uninstallation, if possible */
357 bool bootloaderUninstallable
= bootloaderInstallable
&&
358 RbSettings::value(RbSettings::CurBootloaderMethod
) != "fwpatcher";
359 ui
.labelRemoveBootloader
->setEnabled(bootloaderUninstallable
);
360 ui
.buttonRemoveBootloader
->setEnabled(bootloaderUninstallable
);
361 ui
.actionRemove_bootloader
->setEnabled(bootloaderUninstallable
);
363 /* Disable the whole tab widget if configuration is invalid */
364 bool configurationValid
= !chkConfig(false);
365 ui
.tabWidget
->setEnabled(configurationValid
);
366 ui
.menuA_ctions
->setEnabled(configurationValid
);
368 // displayed device info
369 QString mountpoint
= RbSettings::value(RbSettings::Mountpoint
).toString();
370 QString brand
= RbSettings::value(RbSettings::CurBrand
).toString();
371 QString name
= RbSettings::value(RbSettings::CurName
).toString();
372 if(name
.isEmpty()) name
= "<none>";
373 if(mountpoint
.isEmpty()) mountpoint
= "<invalid>";
374 ui
.labelDevice
->setText(tr("<b>%1 %2</b> at <b>%3</b>")
375 .arg(brand
, name
, QDir::toNativeSeparators(mountpoint
)));
379 void RbUtilQt::updateManual()
381 if(RbSettings::value(RbSettings::Platform
) != "")
383 QString manual
= RbSettings::value(RbSettings::CurManual
).toString();
386 manual
= "rockbox-" + RbSettings::value(RbSettings::Platform
).toString();
388 pdfmanual
= RbSettings::value(RbSettings::ManualUrl
).toString()
389 + "/" + manual
+ ".pdf";
391 htmlmanual
= RbSettings::value(RbSettings::ManualUrl
).toString()
392 + "/" + manual
+ "/rockbox-build.html";
393 ui
.labelPdfManual
->setText(tr("<a href='%1'>PDF Manual</a>")
395 ui
.labelHtmlManual
->setText(tr("<a href='%1'>HTML Manual (opens in browser)</a>")
399 ui
.labelPdfManual
->setText(tr("Select a device for a link to the correct manual"));
400 ui
.labelHtmlManual
->setText(tr("<a href='%1'>Manual Overview</a>")
401 .arg("http://www.rockbox.org/manual.shtml"));
406 void RbUtilQt::completeInstall()
408 if(chkConfig(true)) return;
409 if(QMessageBox::question(this, tr("Confirm Installation"),
410 tr("Do you really want to perform a complete installation?\n\n"
411 "This will install Rockbox %1. To install the most recent "
412 "development build available press \"Cancel\" and "
413 "use the \"Installation\" tab.")
414 .arg(versmap
.value("rel_rev")),
415 QMessageBox::Ok
| QMessageBox::Cancel
) != QMessageBox::Ok
)
418 logger
= new ProgressLoggerGui(this);
421 if(smallInstallInner())
423 logger
->setRunning();
427 if(!installFontsAuto())
431 // wait for installation finished
433 QApplication::processEvents();
436 logger
->setRunning();
443 if(!installDoomAuto())
447 // wait for installation finished
449 QApplication::processEvents();
456 // it has its own logger window,so close our.
462 void RbUtilQt::smallInstall()
464 if(chkConfig(true)) return;
465 if(QMessageBox::question(this, tr("Confirm Installation"),
466 tr("Do you really want to perform a minimal installation? "
467 "A minimal installation will contain only the absolutely "
468 "necessary parts to run Rockbox.\n\n"
469 "This will install Rockbox %1. To install the most recent "
470 "development build available press \"Cancel\" and "
471 "use the \"Installation\" tab.")
472 .arg(versmap
.value("rel_rev")),
473 QMessageBox::Ok
| QMessageBox::Cancel
) != QMessageBox::Ok
)
477 logger
= new ProgressLoggerGui(this);
483 bool RbUtilQt::smallInstallInner()
485 QString mountpoint
= RbSettings::value(RbSettings::Mountpoint
).toString();
486 // show dialog with error if mount point is wrong
487 if(!QFileInfo(mountpoint
).isDir()) {
488 logger
->addItem(tr("Mount point is wrong!"),LOGERROR
);
489 logger
->setFinished();
493 if(RbSettings::value(RbSettings::CurBootloaderMethod
) != "none")
498 if(!installBootloaderAuto()) {
499 logger
->setFinished();
504 // wait for boot loader installation finished
506 QApplication::processEvents();
509 if(m_error
) return true;
510 logger
->setRunning();
520 // wait for installation finished
522 QApplication::processEvents();
525 installBootloaderPost(false);
529 void RbUtilQt::installdone(bool error
)
531 qDebug() << "[RbUtil] install done";
536 void RbUtilQt::installBtn()
538 if(chkConfig(true)) return;
542 bool RbUtilQt::installAuto()
544 QString file
= RbSettings::value(RbSettings::ReleaseUrl
).toString();
545 file
.replace("%MODEL%", RbSettings::value(RbSettings::CurBuildserverModel
).toString());
546 file
.replace("%RELVERSION%", versmap
.value("rel_rev"));
548 QSettings
info(buildInfo
.fileName(), QSettings::IniFormat
, this);
551 // check installed Version and Target
552 QString warning
= check(false);
553 if(!warning
.isEmpty())
555 if(QMessageBox::warning(this, tr("Really continue?"), warning
,
556 QMessageBox::Ok
| QMessageBox::Abort
, QMessageBox::Abort
)
557 == QMessageBox::Abort
)
559 logger
->addItem(tr("Aborted!"), LOGERROR
);
560 logger
->setFinished();
566 RockboxInfo
rbinfo(RbSettings::value(RbSettings::Mountpoint
).toString());
567 if(rbinfo
.version() != "")
569 if(QMessageBox::question(this, tr("Installed Rockbox detected"),
570 tr("Rockbox installation detected. Do you want to backup first?"),
571 QMessageBox::Yes
| QMessageBox::No
) == QMessageBox::Yes
)
573 logger
->addItem(tr("Starting backup..."),LOGINFO
);
574 QString backupName
= RbSettings::value(RbSettings::Mountpoint
).toString()
575 + "/.backup/rockbox-backup-" + rbinfo
.version() + ".zip";
577 //! create dir, if it doesnt exist
578 QFileInfo
backupFile(backupName
);
579 if(!QDir(backupFile
.path()).exists())
582 a
.mkpath(backupFile
.path());
587 connect(&backup
,SIGNAL(zipProgress(int,int)),logger
, SLOT(setProgress(int,int)));
588 if(backup
.createZip(backupName
,
589 RbSettings::value(RbSettings::Mountpoint
).toString() + "/.rockbox") == Zip::Ok
)
591 logger
->addItem(tr("Backup successful"),LOGOK
);
595 logger
->addItem(tr("Backup failed!"),LOGERROR
);
596 logger
->setFinished();
602 //! install current build
603 ZipInstaller
* installer
= new ZipInstaller(this);
604 installer
->setUrl(file
);
605 installer
->setLogSection("Rockbox (Base)");
606 installer
->setLogVersion(versmap
.value("rel_rev"));
607 if(!RbSettings::value(RbSettings::CacheDisabled
).toBool())
608 installer
->setCache(true);
609 installer
->setMountPoint(RbSettings::value(RbSettings::Mountpoint
).toString());
611 connect(installer
, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
612 connect(installer
, SIGNAL(logItem(QString
, int)), logger
, SLOT(addItem(QString
, int)));
613 connect(installer
, SIGNAL(logProgress(int, int)), logger
, SLOT(setProgress(int, int)));
614 connect(installer
, SIGNAL(done(bool)), logger
, SLOT(setFinished()));
615 connect(logger
, SIGNAL(aborted()), installer
, SLOT(abort()));
616 installer
->install();
621 void RbUtilQt::install()
623 Install
*installWindow
= new Install(this);
626 QSettings
info(buildInfo
.fileName(), QSettings::IniFormat
, this);
628 installWindow
->setVersionStrings(versmap
);
630 installWindow
->show();
633 bool RbUtilQt::installBootloaderAuto()
639 void RbUtilQt::installBootloaderBtn()
641 if(chkConfig(true)) return;
642 if(QMessageBox::question(this, tr("Confirm Installation"),
643 tr("Do you really want to install the Bootloader?"),
644 QMessageBox::Yes
| QMessageBox::No
) != QMessageBox::Yes
) return;
647 logger
= new ProgressLoggerGui(this);
652 void RbUtilQt::installBootloader()
654 QString platform
= RbSettings::value(RbSettings::Platform
).toString();
655 QString backupDestination
= "";
659 BootloaderInstallBase
*bl
;
660 QString type
= RbSettings::value(RbSettings::CurBootloaderMethod
).toString();
662 bl
= new BootloaderInstallMi4(this);
664 else if(type
== "hex") {
665 bl
= new BootloaderInstallHex(this);
667 else if(type
== "sansa") {
668 bl
= new BootloaderInstallSansa(this);
670 else if(type
== "ipod") {
671 bl
= new BootloaderInstallIpod(this);
673 else if(type
== "file") {
674 bl
= new BootloaderInstallFile(this);
676 else if(type
== "chinachip") {
677 bl
= new BootloaderInstallChinaChip(this);
679 else if(type
== "ams") {
680 bl
= new BootloaderInstallAms(this);
682 else if(type
== "tcc") {
683 bl
= new BootloaderInstallTcc(this);
686 logger
->addItem(tr("No install method known."), LOGERROR
);
687 logger
->setFinished();
691 // set bootloader filename. Do this now as installed() needs it.
692 QStringList blfile
= RbSettings::value(RbSettings::CurBootloaderFile
).toStringList();
693 QStringList blfilepath
;
694 for(int a
= 0; a
< blfile
.size(); a
++) {
695 blfilepath
.append(RbSettings::value(RbSettings::Mountpoint
).toString()
698 bl
->setBlFile(blfilepath
);
699 QUrl
url(RbSettings::value(RbSettings::BootloaderUrl
).toString()
700 + RbSettings::value(RbSettings::CurBootloaderName
).toString());
702 bl
->setLogfile(RbSettings::value(RbSettings::Mountpoint
).toString()
703 + "/.rockbox/rbutil.log");
705 if(bl
->installed() == BootloaderInstallBase::BootloaderRockbox
) {
706 if(QMessageBox::question(this, tr("Bootloader detected"),
707 tr("Bootloader already installed. Do you want to reinstall the bootloader?"),
708 QMessageBox::Yes
| QMessageBox::No
) == QMessageBox::No
) {
710 // keep logger open for auto installs.
711 // don't consider abort as error in auto-mode.
712 logger
->addItem(tr("Bootloader installation skipped"), LOGINFO
);
713 installBootloaderPost(false);
717 installBootloaderPost(true);
723 else if(bl
->installed() == BootloaderInstallBase::BootloaderOther
724 && bl
->capabilities() & BootloaderInstallBase::Backup
)
726 QString targetFolder
= RbSettings::value(RbSettings::CurPlatformName
).toString()
727 + " Firmware Backup";
728 // remove invalid character(s)
729 targetFolder
.remove(QRegExp("[:/]"));
730 if(QMessageBox::question(this, tr("Create Bootloader backup"),
731 tr("You can create a backup of the original bootloader "
732 "file. Press \"Yes\" to select an output folder on your "
733 "computer to save the file to. The file will get placed "
734 "in a new folder \"%1\" created below the selected folder.\n"
735 "Press \"No\" to skip this step.").arg(targetFolder
),
736 QMessageBox::Yes
| QMessageBox::No
) == QMessageBox::Yes
) {
737 BrowseDirtree
tree(this, tr("Browse backup folder"));
738 tree
.setDir(QDir::home());
741 backupDestination
= tree
.getSelected() + "/" + targetFolder
;
742 qDebug() << "[RbUtil] backing up to" << backupDestination
;
743 // backup needs to be done after the logger has been set up.
747 if(bl
->capabilities() & BootloaderInstallBase::NeedsOf
)
750 ret
= QMessageBox::information(this, tr("Prerequisites"),
751 bl
->ofHint(),QMessageBox::Ok
| QMessageBox::Abort
);
752 if(ret
!= QMessageBox::Ok
) {
753 // consider aborting an error to close window / abort automatic
756 logger
->addItem(tr("Bootloader installation aborted"), LOGINFO
);
757 logger
->setFinished();
760 // open dialog to browse to of file
762 offile
= QFileDialog::getOpenFileName(this,
763 tr("Select firmware file"), QDir::homePath());
764 if(!QFileInfo(offile
).isReadable()) {
765 logger
->addItem(tr("Error opening firmware file"), LOGERROR
);
766 logger
->setFinished();
770 bl
->setOfFile(offile
);
773 // the bootloader install class does NOT use any GUI stuff.
774 // All messages are passed via signals.
775 connect(bl
, SIGNAL(done(bool)), logger
, SLOT(setFinished()));
776 connect(bl
, SIGNAL(done(bool)), this, SLOT(installBootloaderPost(bool)));
777 connect(bl
, SIGNAL(logItem(QString
, int)), logger
, SLOT(addItem(QString
, int)));
778 connect(bl
, SIGNAL(logProgress(int, int)), logger
, SLOT(setProgress(int, int)));
781 if(!backupDestination
.isEmpty()) {
782 if(!bl
->backup(backupDestination
)) {
783 if(QMessageBox::warning(this, tr("Backup error"),
784 tr("Could not create backup file. Continue?"),
785 QMessageBox::No
| QMessageBox::Yes
)
786 == QMessageBox::No
) {
787 logger
->setFinished();
795 void RbUtilQt::installBootloaderPost(bool error
)
797 qDebug() << "[RbUtil] Bootloader Post-Installation, error state:" << error
;
798 // if an error occured don't perform post install steps.
807 // end here if automated install
811 QString msg
= BootloaderInstallBase::postinstallHints(
812 RbSettings::value(RbSettings::Platform
).toString());
814 QMessageBox::information(this, tr("Manual steps required"), msg
);
820 void RbUtilQt::installFontsBtn()
822 if(chkConfig(true)) return;
823 if(QMessageBox::question(this, tr("Confirm Installation"),
824 tr("Do you really want to install the fonts package?"),
825 QMessageBox::Yes
| QMessageBox::No
) != QMessageBox::Yes
) return;
827 logger
= new ProgressLoggerGui(this);
832 bool RbUtilQt::installFontsAuto()
839 void RbUtilQt::installFonts()
841 // create zip installer
842 installer
= new ZipInstaller(this);
844 installer
->setUrl(RbSettings::value(RbSettings::FontUrl
).toString());
845 installer
->setLogSection("Fonts");
846 installer
->setLogVersion(versmap
.value("arch_date"));
847 installer
->setMountPoint(RbSettings::value(RbSettings::Mountpoint
).toString());
848 if(!RbSettings::value(RbSettings::CacheDisabled
).toBool())
849 installer
->setCache(true);
851 connect(installer
, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
852 connect(installer
, SIGNAL(logItem(QString
, int)), logger
, SLOT(addItem(QString
, int)));
853 connect(installer
, SIGNAL(logProgress(int, int)), logger
, SLOT(setProgress(int, int)));
854 connect(installer
, SIGNAL(done(bool)), logger
, SLOT(setFinished()));
855 connect(logger
, SIGNAL(aborted()), installer
, SLOT(abort()));
856 installer
->install();
860 void RbUtilQt::installVoice()
862 if(chkConfig(true)) return;
864 if(m_gotInfo
== false)
866 QMessageBox::warning(this, tr("Warning"),
867 tr("The Application is still downloading Information about new Builds."
868 " Please try again shortly."));
872 if(QMessageBox::question(this, tr("Confirm Installation"),
873 tr("Do you really want to install the voice file?"),
874 QMessageBox::Yes
| QMessageBox::No
) != QMessageBox::Yes
) return;
876 logger
= new ProgressLoggerGui(this);
879 // create zip installer
880 installer
= new ZipInstaller(this);
882 QString voiceurl
= RbSettings::value(RbSettings::VoiceUrl
).toString();
884 voiceurl
+= RbSettings::value(RbSettings::CurBuildserverModel
).toString() + "-" +
885 versmap
.value("arch_date") + "-english.zip";
886 qDebug() << "[RbUtil] voicefile URL:" << voiceurl
;
888 installer
->setUrl(voiceurl
);
889 installer
->setLogSection("Voice");
890 installer
->setLogVersion(versmap
.value("arch_date"));
891 installer
->setMountPoint(RbSettings::value(RbSettings::Mountpoint
).toString());
892 if(!RbSettings::value(RbSettings::CacheDisabled
).toBool())
893 installer
->setCache(true);
894 connect(installer
, SIGNAL(logItem(QString
, int)), logger
, SLOT(addItem(QString
, int)));
895 connect(installer
, SIGNAL(logProgress(int, int)), logger
, SLOT(setProgress(int, int)));
896 connect(installer
, SIGNAL(done(bool)), logger
, SLOT(setFinished()));
897 connect(logger
, SIGNAL(aborted()), installer
, SLOT(abort()));
898 installer
->install();
902 void RbUtilQt::installDoomBtn()
904 if(chkConfig(true)) return;
906 QMessageBox::critical(this, tr("Error"),
907 tr("Your device doesn't have a doom plugin. Aborting."));
911 if(QMessageBox::question(this, tr("Confirm Installation"),
912 tr("Do you really want to install the game addon files?"),
913 QMessageBox::Yes
| QMessageBox::No
) != QMessageBox::Yes
) return;
915 logger
= new ProgressLoggerGui(this);
920 bool RbUtilQt::installDoomAuto()
926 bool RbUtilQt::hasDoom()
928 QFile
doomrock(RbSettings::value(RbSettings::Mountpoint
).toString()
929 +"/.rockbox/rocks/games/doom.rock");
930 return doomrock
.exists();
933 void RbUtilQt::installDoom()
935 // create zip installer
936 installer
= new ZipInstaller(this);
938 installer
->setUrl(RbSettings::value(RbSettings::DoomUrl
).toString());
939 installer
->setLogSection("Game Addons");
940 installer
->setLogVersion(versmap
.value("arch_date"));
941 installer
->setMountPoint(RbSettings::value(RbSettings::Mountpoint
).toString());
942 if(!RbSettings::value(RbSettings::CacheDisabled
).toBool())
943 installer
->setCache(true);
944 connect(installer
, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
945 connect(installer
, SIGNAL(logItem(QString
, int)), logger
, SLOT(addItem(QString
, int)));
946 connect(installer
, SIGNAL(logProgress(int, int)), logger
, SLOT(setProgress(int, int)));
947 connect(installer
, SIGNAL(done(bool)), logger
, SLOT(setFinished()));
948 connect(logger
, SIGNAL(aborted()), installer
, SLOT(abort()));
949 installer
->install();
953 void RbUtilQt::installThemes()
955 if(chkConfig(true)) return;
956 ThemesInstallWindow
* tw
= new ThemesInstallWindow(this);
961 void RbUtilQt::createTalkFiles(void)
963 if(chkConfig(true)) return;
964 InstallTalkWindow
*installWindow
= new InstallTalkWindow(this);
966 connect(installWindow
, SIGNAL(settingsUpdated()), this, SLOT(downloadInfo()));
967 connect(installWindow
, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
968 installWindow
->show();
972 void RbUtilQt::createVoiceFile(void)
974 if(chkConfig(true)) return;
975 CreateVoiceWindow
*installWindow
= new CreateVoiceWindow(this);
977 connect(installWindow
, SIGNAL(settingsUpdated()), this, SLOT(downloadInfo()));
978 connect(installWindow
, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
979 installWindow
->show();
982 void RbUtilQt::uninstall(void)
984 if(chkConfig(true)) return;
985 UninstallWindow
*uninstallWindow
= new UninstallWindow(this);
986 uninstallWindow
->show();
990 void RbUtilQt::uninstallBootloader(void)
992 if(chkConfig(true)) return;
993 if(QMessageBox::question(this, tr("Confirm Uninstallation"),
994 tr("Do you really want to uninstall the Bootloader?"),
995 QMessageBox::Yes
| QMessageBox::No
) != QMessageBox::Yes
) return;
997 ProgressLoggerGui
* logger
= new ProgressLoggerGui(this);
998 logger
->setProgressVisible(false);
1001 QString platform
= RbSettings::value(RbSettings::Platform
).toString();
1004 BootloaderInstallBase
*bl
;
1005 QString type
= RbSettings::value(RbSettings::CurBootloaderMethod
).toString();
1007 bl
= new BootloaderInstallMi4(this);
1009 else if(type
== "hex") {
1010 bl
= new BootloaderInstallHex(this);
1012 else if(type
== "sansa") {
1013 bl
= new BootloaderInstallSansa(this);
1015 else if(type
== "ipod") {
1016 bl
= new BootloaderInstallIpod(this);
1018 else if(type
== "file") {
1019 bl
= new BootloaderInstallFile(this);
1022 logger
->addItem(tr("No uninstall method known."), LOGERROR
);
1023 logger
->setFinished();
1027 QStringList blfile
= RbSettings::value(RbSettings::CurBootloaderFile
).toStringList();
1028 QStringList blfilepath
;
1029 for(int a
= 0; a
< blfile
.size(); a
++) {
1030 blfilepath
.append(RbSettings::value(RbSettings::Mountpoint
).toString()
1033 bl
->setBlFile(blfilepath
);
1035 connect(bl
, SIGNAL(logItem(QString
, int)), logger
, SLOT(addItem(QString
, int)));
1036 connect(bl
, SIGNAL(logProgress(int, int)), logger
, SLOT(setProgress(int, int)));
1039 result
= bl
->uninstall();
1041 logger
->setFinished();
1046 void RbUtilQt::downloadManual(void)
1048 if(chkConfig(true)) return;
1049 if(QMessageBox::question(this, tr("Confirm download"),
1050 tr("Do you really want to download the manual? The manual will be saved "
1051 "to the root folder of your player."),
1052 QMessageBox::Yes
| QMessageBox::No
) != QMessageBox::Yes
)
1056 QSettings
info(buildInfo
.fileName(), QSettings::IniFormat
, this);
1059 QString manual
= RbSettings::value(RbSettings::CurManual
).toString();
1060 if(manual
.isEmpty())
1061 manual
= "rockbox-" + RbSettings::value(RbSettings::Platform
).toString();
1063 QString date
= (info
.value("dailies/date").toString());
1068 if(ui
.radioPdf
->isChecked()) {
1069 target
= "/" + manual
+ ".pdf";
1070 section
= "Manual (PDF)";
1073 target
= "/" + manual
+ "-" + date
+ "-html.zip";
1074 section
= "Manual (HTML)";
1076 manualurl
= RbSettings::value(RbSettings::ManualUrl
).toString() + "/" + target
;
1077 qDebug() << "[RbUtil] Manual URL:" << manualurl
;
1079 ProgressLoggerGui
* logger
= new ProgressLoggerGui(this);
1081 installer
= new ZipInstaller(this);
1082 installer
->setMountPoint(RbSettings::value(RbSettings::Mountpoint
).toString());
1083 if(!RbSettings::value(RbSettings::CacheDisabled
).toBool())
1084 installer
->setCache(true);
1085 installer
->setLogSection(section
);
1086 installer
->setLogVersion(date
);
1087 installer
->setUrl(manualurl
);
1088 installer
->setUnzip(false);
1089 installer
->setTarget(target
);
1090 connect(installer
, SIGNAL(logItem(QString
, int)), logger
, SLOT(addItem(QString
, int)));
1091 connect(installer
, SIGNAL(logProgress(int, int)), logger
, SLOT(setProgress(int, int)));
1092 connect(installer
, SIGNAL(done(bool)), logger
, SLOT(setFinished()));
1093 connect(logger
, SIGNAL(aborted()), installer
, SLOT(abort()));
1094 installer
->install();
1098 void RbUtilQt::installPortable(void)
1100 if(QMessageBox::question(this, tr("Confirm installation"),
1101 tr("Do you really want to install Rockbox Utility to your player? "
1102 "After installation you can run it from the players hard drive."),
1103 QMessageBox::Yes
| QMessageBox::No
) != QMessageBox::Yes
)
1106 ProgressLoggerGui
* logger
= new ProgressLoggerGui(this);
1107 logger
->setProgressMax(0);
1108 logger
->setProgressValue(0);
1110 logger
->addItem(tr("Installing Rockbox Utility"), LOGINFO
);
1113 if(!QFileInfo(RbSettings::value(RbSettings::Mountpoint
).toString()).isDir()) {
1114 logger
->addItem(tr("Mount point is wrong!"),LOGERROR
);
1115 logger
->setFinished();
1119 // remove old files first.
1120 QFile::remove(RbSettings::value(RbSettings::Mountpoint
).toString()
1121 + "/RockboxUtility.exe");
1122 QFile::remove(RbSettings::value(RbSettings::Mountpoint
).toString()
1123 + "/RockboxUtility.ini");
1124 // copy currently running binary and currently used settings file
1125 if(!QFile::copy(qApp
->applicationFilePath(),
1126 RbSettings::value(RbSettings::Mountpoint
).toString()
1127 + "/RockboxUtility.exe")) {
1128 logger
->addItem(tr("Error installing Rockbox Utility"), LOGERROR
);
1129 logger
->setFinished();
1132 logger
->addItem(tr("Installing user configuration"), LOGINFO
);
1133 if(!QFile::copy(RbSettings::userSettingFilename(),
1134 RbSettings::value(RbSettings::Mountpoint
).toString()
1135 + "/RockboxUtility.ini")) {
1136 logger
->addItem(tr("Error installing user configuration"), LOGERROR
);
1137 logger
->setFinished();
1140 logger
->addItem(tr("Successfully installed Rockbox Utility."), LOGOK
);
1141 logger
->setFinished();
1142 logger
->setProgressMax(1);
1143 logger
->setProgressValue(1);
1148 void RbUtilQt::updateInfo()
1150 qDebug() << "[RbUtil] updating server info";
1152 QSettings
log(RbSettings::value(RbSettings::Mountpoint
).toString()
1153 + "/.rockbox/rbutil.log", QSettings::IniFormat
, this);
1154 QStringList groups
= log
.childGroups();
1155 QList
<QTreeWidgetItem
*> items
;
1156 QTreeWidgetItem
*w
, *w2
;
1160 // remove old list entries (if any)
1161 int l
= ui
.treeInfo
->topLevelItemCount();
1164 m
= ui
.treeInfo
->takeTopLevelItem(l
);
1165 // delete childs (single level deep, no recursion here)
1166 int n
= m
->childCount();
1170 // get and populate new items
1171 for(int a
= 0; a
< groups
.size(); a
++) {
1172 log
.beginGroup(groups
.at(a
));
1173 QStringList keys
= log
.allKeys();
1174 w
= new QTreeWidgetItem
;
1175 w
->setFlags(Qt::ItemIsEnabled
);
1176 w
->setText(0, groups
.at(a
));
1178 // get minimum and maximum version information so we can hilight old files
1179 min
= max
= log
.value(keys
.at(0)).toString();
1180 for(int b
= 0; b
< keys
.size(); b
++) {
1181 if(log
.value(keys
.at(b
)).toString() > max
)
1182 max
= log
.value(keys
.at(b
)).toString();
1183 if(log
.value(keys
.at(b
)).toString() < min
)
1184 min
= log
.value(keys
.at(b
)).toString();
1187 for(int b
= 0; b
< keys
.size(); b
++) {
1189 file
= RbSettings::value(RbSettings::Mountpoint
).toString() + "/" + keys
.at(b
);
1190 if(QFileInfo(file
).isDir())
1192 w2
= new QTreeWidgetItem(w
, QStringList() << "/"
1193 + keys
.at(b
) << log
.value(keys
.at(b
)).toString());
1194 if(log
.value(keys
.at(b
)).toString() != max
) {
1195 w2
->setForeground(0, QBrush(QColor(255, 0, 0)));
1196 w2
->setForeground(1, QBrush(QColor(255, 0, 0)));
1203 w
->setData(1, Qt::DisplayRole
, QString("%1 / %2").arg(min
, max
));
1205 w
->setData(1, Qt::DisplayRole
, max
);
1207 ui
.treeInfo
->insertTopLevelItems(0, items
);
1208 ui
.treeInfo
->resizeColumnToContents(0);
1212 QUrl
RbUtilQt::proxy()
1214 if(RbSettings::value(RbSettings::ProxyType
) == "manual")
1215 return QUrl(RbSettings::value(RbSettings::Proxy
).toString());
1216 else if(RbSettings::value(RbSettings::ProxyType
) == "system")
1217 return System::systemProxy();
1222 bool RbUtilQt::chkConfig(bool warn
)
1225 if(RbSettings::value(RbSettings::Platform
).toString().isEmpty()
1226 || RbSettings::value(RbSettings::Mountpoint
).toString().isEmpty()
1227 || !QFileInfo(RbSettings::value(RbSettings::Mountpoint
).toString()).isWritable()) {
1230 if(warn
) QMessageBox::critical(this, tr("Configuration error"),
1231 tr("Your configuration is invalid. Please go to the configuration "
1232 "dialog and make sure the selected values are correct."));
1237 void RbUtilQt::checkUpdate(void)
1239 QString url
= RbSettings::value(RbSettings::RbutilUrl
).toString();
1240 #if defined(Q_OS_WIN32)
1242 #elif defined(Q_OS_LINUX)
1244 #elif defined(Q_OS_MACX)
1248 update
= new HttpGet(this);
1249 connect(update
, SIGNAL(done(bool)), this, SLOT(downloadUpdateDone(bool)));
1250 connect(update
, SIGNAL(requestFinished(int, bool)), this, SLOT(downloadDone(int, bool)));
1251 connect(qApp
, SIGNAL(lastWindowClosed()), update
, SLOT(abort()));
1252 if(RbSettings::value(RbSettings::CacheOffline
).toBool())
1253 update
->setCache(true);
1255 update
->getFile(QUrl(url
));
1258 void RbUtilQt::downloadUpdateDone(bool error
)
1261 qDebug() << "[RbUtil] network error:" << update
->error();
1264 QString
toParse(update
->readAll());
1266 QRegExp
searchString("<a[^>]*>(rbutilqt[^<]*)</a>");
1267 QStringList rbutilList
;
1269 while ((pos
= searchString
.indexIn(toParse
, pos
)) != -1)
1271 rbutilList
<< searchString
.cap(1);
1272 pos
+= searchString
.matchedLength();
1274 qDebug() << "[Checkupdate] " << rbutilList
;
1276 QString newVersion
="";
1277 //check if there is a binary with higher version in this list
1278 for(int i
=0; i
< rbutilList
.size(); i
++)
1280 #if defined(Q_OS_LINUX)
1281 #if defined(__amd64__)
1282 //skip if it isnt a 64bit build
1283 if( !rbutilList
.at(i
).contains("64bit"))
1286 //skip if it is a 64bit build
1287 if(rbutilList
.at(i
).contains("64bit"))
1291 //check if it is newer, and remember newest
1292 if(newerVersion(VERSION
,rbutilList
.at(i
)))
1294 if(newVersion
== "" || newerVersion(newVersion
,rbutilList
.at(i
)))
1296 newVersion
= rbutilList
.at(i
);
1301 // if we found something newer, display info
1302 if(newVersion
!= "")
1304 QString url
= RbSettings::value(RbSettings::RbutilUrl
).toString();
1305 #if defined(Q_OS_WIN32)
1307 #elif defined(Q_OS_LINUX)
1309 #elif defined(Q_OS_MACX)
1314 QMessageBox::information(this,tr("RockboxUtility Update available"),
1315 tr("<b>New RockboxUtility Version available.</b> <br><br>"
1316 "Download it from here: <a href='%1'>%2</a>").arg(url
).arg(newVersion
) );
1321 bool RbUtilQt::newerVersion(QString versionOld
,QString versionNew
)
1323 QRegExp
chars("\\d*(\\D)");
1325 //strip non-number from beginning
1326 versionOld
= versionOld
.remove(0,versionOld
.indexOf(QRegExp("\\d")));
1327 versionNew
= versionNew
.remove(0,versionNew
.indexOf(QRegExp("\\d")));
1329 // split versions by "."
1330 QStringList versionListOld
= versionOld
.split(".");
1331 QStringList versionListNew
= versionNew
.split(".");
1333 QStringListIterator
iteratorOld(versionListOld
);
1334 QStringListIterator
iteratorNew(versionListNew
);
1336 //check every section
1337 while(iteratorOld
.hasNext() && iteratorNew
.hasNext())
1339 QString newPart
= iteratorNew
.next();
1340 QString oldPart
= iteratorOld
.next();
1341 QString newPartChar
= "", oldPartChar
= "";
1342 int newPartInt
= 0, oldPartInt
=0;
1344 //convert to int, if it contains chars, put into seperated variable
1345 if(newPart
.contains(chars
))
1347 newPartChar
= chars
.cap(1);
1348 newPart
= newPart
.remove(newPartChar
);
1350 newPartInt
= newPart
.toInt();
1351 //convert to int, if it contains chars, put into seperated variable
1352 if(oldPart
.contains(chars
))
1354 oldPartChar
= chars
.cap(1);
1355 oldPart
= oldPart
.remove(oldPartChar
);
1357 oldPartInt
= oldPart
.toInt();
1359 if(newPartInt
> oldPartInt
) // this section int is higher -> true
1361 else if(newPartInt
< oldPartInt
) //this section int is lower -> false
1363 else if(newPartChar
> oldPartChar
) //ints are the same, chars is higher -> true
1365 else if(newPartChar
< oldPartChar
) //ints are the same, chars is lower -> false
1367 //all the same, next section
1369 // all the same -> false