rbutil: correct another instance of incorrect modelname.
[kugel-rb.git] / rbutil / rbutilqt / rbutilqt.cpp
blob1000302186cf6337b7098a4f60c297d3a322f114
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
9 * Copyright (C) 2007 by Dominik Riebeling
10 * $Id$
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 ****************************************************************************/
20 #include <QtGui>
22 #include "version.h"
23 #include "rbutilqt.h"
24 #include "ui_rbutilqtfrm.h"
25 #include "ui_aboutbox.h"
26 #include "configure.h"
27 #include "install.h"
28 #include "installtalkwindow.h"
29 #include "createvoicewindow.h"
30 #include "httpget.h"
31 #include "installthemes.h"
32 #include "uninstallwindow.h"
33 #include "utils.h"
34 #include "rbzip.h"
35 #include "sysinfo.h"
36 #include "detect.h"
38 #include "progressloggerinterface.h"
40 #include "bootloaderinstallbase.h"
41 #include "bootloaderinstallmi4.h"
42 #include "bootloaderinstallhex.h"
43 #include "bootloaderinstallipod.h"
44 #include "bootloaderinstallsansa.h"
45 #include "bootloaderinstallfile.h"
47 #if defined(Q_OS_LINUX)
48 #include <stdio.h>
49 #endif
50 #if defined(Q_OS_WIN32)
51 #if defined(UNICODE)
52 #define _UNICODE
53 #endif
54 #include <stdio.h>
55 #include <tchar.h>
56 #include <windows.h>
57 #endif
59 RbUtilQt::RbUtilQt(QWidget *parent) : QMainWindow(parent)
61 absolutePath = qApp->applicationDirPath();
63 settings = new RbSettings();
64 settings->open();
65 HttpGet::setGlobalUserAgent("rbutil/"VERSION);
66 // init startup & autodetection
67 ui.setupUi(this);
68 updateSettings();
69 downloadInfo();
71 m_gotInfo = false;
72 m_auto = false;
74 // manual tab
75 ui.radioPdf->setChecked(true);
77 // info tab
78 ui.treeInfo->setAlternatingRowColors(true);
79 ui.treeInfo->setHeaderLabels(QStringList() << tr("File") << tr("Version"));
80 ui.treeInfo->expandAll();
81 ui.treeInfo->setColumnCount(2);
82 // disable quick install until version info is available
83 ui.buttonSmall->setEnabled(false);
84 ui.buttonComplete->setEnabled(false);
86 connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(updateTabs(int)));
87 connect(ui.actionAbout_Qt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
88 connect(ui.action_About, SIGNAL(triggered()), this, SLOT(about()));
89 connect(ui.action_Help, SIGNAL(triggered()), this, SLOT(help()));
90 connect(ui.action_Configure, SIGNAL(triggered()), this, SLOT(configDialog()));
91 connect(ui.buttonChangeDevice, SIGNAL(clicked()), this, SLOT(configDialog()));
92 connect(ui.buttonRockbox, SIGNAL(clicked()), this, SLOT(installBtn()));
93 connect(ui.buttonBootloader, SIGNAL(clicked()), this, SLOT(installBootloaderBtn()));
94 connect(ui.buttonFonts, SIGNAL(clicked()), this, SLOT(installFontsBtn()));
95 connect(ui.buttonGames, SIGNAL(clicked()), this, SLOT(installDoomBtn()));
96 connect(ui.buttonTalk, SIGNAL(clicked()), this, SLOT(createTalkFiles()));
97 connect(ui.buttonCreateVoice, SIGNAL(clicked()), this, SLOT(createVoiceFile()));
98 connect(ui.buttonVoice, SIGNAL(clicked()), this, SLOT(installVoice()));
99 connect(ui.buttonThemes, SIGNAL(clicked()), this, SLOT(installThemes()));
100 connect(ui.buttonRemoveRockbox, SIGNAL(clicked()), this, SLOT(uninstall()));
101 connect(ui.buttonRemoveBootloader, SIGNAL(clicked()), this, SLOT(uninstallBootloader()));
102 connect(ui.buttonDownloadManual, SIGNAL(clicked()), this, SLOT(downloadManual()));
103 connect(ui.buttonSmall, SIGNAL(clicked()), this, SLOT(smallInstall()));
104 connect(ui.buttonComplete, SIGNAL(clicked()), this, SLOT(completeInstall()));
106 // actions accessible from the menu
107 connect(ui.actionComplete_Installation, SIGNAL(triggered()), this, SLOT(completeInstall()));
108 connect(ui.actionSmall_Installation, SIGNAL(triggered()), this, SLOT(smallInstall()));
109 connect(ui.actionInstall_Bootloader, SIGNAL(triggered()), this, SLOT(installBootloaderBtn()));
110 connect(ui.actionInstall_Rockbox, SIGNAL(triggered()), this, SLOT(installBtn()));
111 connect(ui.actionFonts_Package, SIGNAL(triggered()), this, SLOT(installFontsBtn()));
112 connect(ui.actionInstall_Themes, SIGNAL(triggered()), this, SLOT(installThemes()));
113 connect(ui.actionInstall_Game_Files, SIGNAL(triggered()), this, SLOT(installDoomBtn()));
114 connect(ui.actionInstall_Voice_File, SIGNAL(triggered()), this, SLOT(installVoice()));
115 connect(ui.actionCreate_Voice_File, SIGNAL(triggered()), this, SLOT(createVoiceFile()));
116 connect(ui.actionCreate_Talk_Files, SIGNAL(triggered()), this, SLOT(createTalkFiles()));
117 connect(ui.actionRemove_bootloader, SIGNAL(triggered()), this, SLOT(uninstallBootloader()));
118 connect(ui.actionUninstall_Rockbox, SIGNAL(triggered()), this, SLOT(uninstall()));
119 connect(ui.action_System_Info, SIGNAL(triggered()), this, SLOT(sysinfo()));
121 #if !defined(STATIC)
122 ui.actionInstall_Rockbox_Utility_on_player->setEnabled(false);
123 #else
124 connect(ui.actionInstall_Rockbox_Utility_on_player, SIGNAL(triggered()), this, SLOT(installPortable()));
125 #endif
130 void RbUtilQt::sysinfo(void)
132 Sysinfo *info = new Sysinfo(this);
133 info->show();
136 void RbUtilQt::updateTabs(int count)
138 switch(count) {
139 case 6:
140 updateInfo();
141 break;
142 default:
143 break;
148 void RbUtilQt::downloadInfo()
150 // make sure the version map is repopulated correctly later.
151 versmap.clear();
152 // try to get the current build information
153 daily = new HttpGet(this);
154 connect(daily, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
155 connect(daily, SIGNAL(requestFinished(int, bool)), this, SLOT(downloadDone(int, bool)));
156 connect(qApp, SIGNAL(lastWindowClosed()), daily, SLOT(abort()));
157 if(settings->cacheOffline())
158 daily->setCache(true);
159 else
160 daily->setCache(false);
161 qDebug() << "downloading build info";
162 daily->setFile(&buildInfo);
163 daily->getFile(QUrl(settings->serverConfUrl()));
167 void RbUtilQt::downloadDone(bool error)
169 if(error) {
170 qDebug() << "network error:" << daily->error();
171 QMessageBox::critical(this, tr("Network error"),
172 tr("Can't get version information."));
173 return;
175 qDebug() << "network status:" << daily->error();
177 buildInfo.open();
178 QSettings info(buildInfo.fileName(), QSettings::IniFormat, this);
179 buildInfo.close();
180 versmap.insert("arch_rev", info.value("dailies/rev").toString());
181 versmap.insert("arch_date", info.value("dailies/date").toString());
183 info.beginGroup("release");
184 versmap.insert("rel_rev", info.value(settings->curBuildserver_Modelname()).toString());
185 info.endGroup();
187 if(versmap.value("rel_rev").isEmpty()) {
188 ui.buttonSmall->setEnabled(false);
189 ui.buttonComplete->setEnabled(false);
191 else {
192 ui.buttonSmall->setEnabled(true);
193 ui.buttonComplete->setEnabled(true);
196 bleeding = new HttpGet(this);
197 connect(bleeding, SIGNAL(done(bool)), this, SLOT(downloadBleedingDone(bool)));
198 connect(bleeding, SIGNAL(requestFinished(int, bool)), this, SLOT(downloadDone(int, bool)));
199 connect(qApp, SIGNAL(lastWindowClosed()), daily, SLOT(abort()));
200 if(settings->cacheOffline())
201 bleeding->setCache(true);
202 bleeding->setFile(&bleedingInfo);
203 bleeding->getFile(QUrl(settings->bleedingInfo()));
205 if(settings->curVersion() != PUREVERSION) {
206 QApplication::processEvents();
207 QMessageBox::information(this, tr("New installation"),
208 tr("This is a new installation of Rockbox Utility, or a new version. "
209 "The configuration dialog will now open to allow you to setup the program, "
210 " or review your settings."));
211 configDialog();
213 else if(chkConfig(false)) {
214 QApplication::processEvents();
215 QMessageBox::critical(this, tr("Configuration error"),
216 tr("Your configuration is invalid. This is most likely due "
217 "to a changed device path. The configuration dialog will "
218 "now open to allow you to correct the problem."));
219 configDialog();
224 void RbUtilQt::downloadBleedingDone(bool error)
226 if(error) qDebug() << "network error:" << bleeding->error();
228 bleedingInfo.open();
229 QSettings info(bleedingInfo.fileName(), QSettings::IniFormat, this);
230 bleedingInfo.close();
231 versmap.insert("bleed_rev", info.value("bleeding/rev").toString());
232 versmap.insert("bleed_date", info.value("bleeding/timestamp").toString());
233 qDebug() << "versmap =" << versmap;
235 m_gotInfo = true;
239 void RbUtilQt::downloadDone(int id, bool error)
241 QString errorString;
242 errorString = tr("Network error: %1. Please check your network and proxy settings.")
243 .arg(daily->errorString());
244 if(error) {
245 QMessageBox::about(this, "Network Error", errorString);
246 m_networkerror = daily->errorString();
248 qDebug() << "downloadDone:" << id << "error:" << error;
252 void RbUtilQt::about()
254 QDialog *window = new QDialog(this);
255 Ui::aboutBox about;
256 about.setupUi(window);
257 window->setModal(true);
259 QFile licence(":/docs/gpl-2.0.html");
260 licence.open(QIODevice::ReadOnly);
261 QTextStream c(&licence);
262 QString cline = c.readAll();
263 about.browserLicense->insertHtml(cline);
264 about.browserLicense->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
265 QFile credits(":/docs/CREDITS");
266 credits.open(QIODevice::ReadOnly);
267 QTextStream r(&credits);
268 r.setCodec(QTextCodec::codecForName("UTF-8"));
269 QString rline = r.readAll();
270 about.browserCredits->insertPlainText(rline);
271 about.browserCredits->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
272 QString title = QString("<b>The Rockbox Utility</b><br/>Version %1").arg(FULLVERSION);
273 about.labelTitle->setText(title);
274 about.labelHomepage->setText("<a href='http://www.rockbox.org'>http://www.rockbox.org</a>");
276 window->show();
281 void RbUtilQt::help()
283 QUrl helpurl("http://www.rockbox.org/wiki/RockboxUtility");
284 QDesktopServices::openUrl(helpurl);
288 void RbUtilQt::configDialog()
290 Config *cw = new Config(this);
291 cw->setSettings(settings);
292 connect(cw, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
293 connect(cw, SIGNAL(settingsUpdated()), this, SLOT(downloadInfo()));
294 cw->show();
298 void RbUtilQt::updateSettings()
300 qDebug() << "updateSettings()";
301 updateDevice();
302 updateManual();
303 if(settings->proxyType() == "system") {
304 HttpGet::setGlobalProxy(Detect::systemProxy());
306 else if(settings->proxyType() == "manual") {
307 HttpGet::setGlobalProxy(settings->proxy());
309 else {
310 HttpGet::setGlobalProxy(QUrl(""));
312 HttpGet::setGlobalCache(settings->cachePath());
313 HttpGet::setGlobalDumbCache(settings->cacheOffline());
317 void RbUtilQt::updateDevice()
319 if(settings->curBootloaderMethod() == "none" ) {
320 ui.buttonBootloader->setEnabled(false);
321 ui.buttonRemoveBootloader->setEnabled(false);
322 ui.labelBootloader->setEnabled(false);
323 ui.labelRemoveBootloader->setEnabled(false);
325 else {
326 ui.buttonBootloader->setEnabled(true);
327 ui.labelBootloader->setEnabled(true);
328 if(settings->curBootloaderMethod() == "fwpatcher") {
329 ui.labelRemoveBootloader->setEnabled(false);
330 ui.buttonRemoveBootloader->setEnabled(false);
332 else {
333 ui.labelRemoveBootloader->setEnabled(true);
334 ui.buttonRemoveBootloader->setEnabled(true);
338 // displayed device info
339 QString mountpoint = settings->mountpoint();
340 QString brand = settings->curBrand();
341 QString name = settings->curName();
342 if(name.isEmpty()) name = "&lt;none&gt;";
343 if(mountpoint.isEmpty()) mountpoint = "&lt;invalid&gt;";
344 ui.labelDevice->setText(tr("<b>%1 %2</b> at <b>%3</b>")
345 .arg(brand, name, QDir::toNativeSeparators(mountpoint)));
349 void RbUtilQt::updateManual()
351 if(settings->curPlatform() != "")
353 QString manual= settings->curManual();
355 if(manual == "")
356 manual = "rockbox-" + settings->curPlatform();
357 QString pdfmanual;
358 pdfmanual = settings->manualUrl() + "/" + manual + ".pdf";
359 QString htmlmanual;
360 htmlmanual = settings->manualUrl() + "/" + manual + "/rockbox-build.html";
361 ui.labelPdfManual->setText(tr("<a href='%1'>PDF Manual</a>")
362 .arg(pdfmanual));
363 ui.labelHtmlManual->setText(tr("<a href='%1'>HTML Manual (opens in browser)</a>")
364 .arg(htmlmanual));
366 else {
367 ui.labelPdfManual->setText(tr("Select a device for a link to the correct manual"));
368 ui.labelHtmlManual->setText(tr("<a href='%1'>Manual Overview</a>")
369 .arg("http://www.rockbox.org/manual.shtml"));
374 void RbUtilQt::completeInstall()
376 if(chkConfig(true)) return;
377 if(QMessageBox::question(this, tr("Confirm Installation"),
378 tr("Do you really want to perform a complete installation?\n\n"
379 "This will install Rockbox %1. To install the most recent "
380 "development build available press \"Cancel\" and "
381 "use the \"Installation\" tab.")
382 .arg(versmap.value("rel_rev")),
383 QMessageBox::Ok | QMessageBox::Cancel) != QMessageBox::Ok)
384 return;
385 // create logger
386 logger = new ProgressLoggerGui(this);
387 logger->show();
389 if(smallInstallInner())
390 return;
391 logger->undoAbort();
392 // Fonts
393 m_error = false;
394 m_installed = false;
395 if(!installFontsAuto())
396 return;
397 else
399 // wait for installation finished
400 while(!m_installed)
401 QApplication::processEvents();
403 if(m_error) return;
404 logger->undoAbort();
406 // Doom
407 if(hasDoom())
409 m_error = false;
410 m_installed = false;
411 if(!installDoomAuto())
412 return;
413 else
415 // wait for installation finished
416 while(!m_installed)
417 QApplication::processEvents();
419 if(m_error) return;
422 // theme
423 // this is a window
424 // it has its own logger window,so close our.
425 logger->close();
426 installThemes();
430 void RbUtilQt::smallInstall()
432 if(chkConfig(true)) return;
433 if(QMessageBox::question(this, tr("Confirm Installation"),
434 tr("Do you really want to perform a minimal installation? "
435 "A minimal installation will contain only the absolutely "
436 "necessary parts to run Rockbox.\n\n"
437 "This will install Rockbox %1. To install the most recent "
438 "development build available press \"Cancel\" and "
439 "use the \"Installation\" tab.")
440 .arg(versmap.value("rel_rev")),
441 QMessageBox::Ok | QMessageBox::Cancel) != QMessageBox::Ok)
442 return;
444 // create logger
445 logger = new ProgressLoggerGui(this);
446 logger->show();
448 smallInstallInner();
451 bool RbUtilQt::smallInstallInner()
453 QString mountpoint = settings->mountpoint();
454 // show dialog with error if mount point is wrong
455 if(!QFileInfo(mountpoint).isDir()) {
456 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
457 logger->abort();
458 return true;
460 // Bootloader
461 if(settings->curBootloaderMethod() != "none")
463 m_error = false;
464 m_installed = false;
465 m_auto = true;
466 if(!installBootloaderAuto()) {
467 logger->abort();
468 return true;
470 else
472 // wait for boot loader installation finished
473 while(!m_installed)
474 QApplication::processEvents();
476 m_auto = false;
477 if(m_error) return true;
478 logger->undoAbort();
481 // Rockbox
482 m_error = false;
483 m_installed = false;
484 if(!installAuto())
485 return true;
486 else
488 // wait for installation finished
489 while(!m_installed)
490 QApplication::processEvents();
493 installBootloaderPost(false);
494 return false;
497 void RbUtilQt::installdone(bool error)
499 qDebug() << "install done";
500 m_installed = true;
501 m_error = error;
504 void RbUtilQt::installBtn()
506 if(chkConfig(true)) return;
507 install();
510 bool RbUtilQt::installAuto()
512 QString file = QString("%1/%2/rockbox-%3-%4.zip")
513 .arg(settings->releaseUrl(), versmap.value("rel_rev"),
514 settings->curBuildserver_Modelname(), versmap.value("rel_rev"));
515 buildInfo.open();
516 QSettings info(buildInfo.fileName(), QSettings::IniFormat, this);
517 buildInfo.close();
519 // check installed Version and Target
520 QString rbVersion = Detect::installedVersion(settings->mountpoint());
521 QString warning = Detect::check(settings, false);
523 if(!warning.isEmpty())
525 if(QMessageBox::warning(this, tr("Really continue?"), warning,
526 QMessageBox::Ok | QMessageBox::Abort, QMessageBox::Abort) == QMessageBox::Abort)
528 logger->addItem(tr("Aborted!"), LOGERROR);
529 logger->abort();
530 return false;
534 // check version
535 if(rbVersion != "")
537 if(QMessageBox::question(this, tr("Installed Rockbox detected"),
538 tr("Rockbox installation detected. Do you want to backup first?"),
539 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
541 logger->addItem(tr("Starting backup..."),LOGINFO);
542 QString backupName = settings->mountpoint()
543 + "/.backup/rockbox-backup-" + rbVersion + ".zip";
545 //! create dir, if it doesnt exist
546 QFileInfo backupFile(backupName);
547 if(!QDir(backupFile.path()).exists())
549 QDir a;
550 a.mkpath(backupFile.path());
553 //! create backup
554 RbZip backup;
555 connect(&backup,SIGNAL(zipProgress(int,int)),logger, SLOT(setProgress(int,int)));
556 if(backup.createZip(backupName,settings->mountpoint() + "/.rockbox") == Zip::Ok)
558 logger->addItem(tr("Backup successful"),LOGOK);
560 else
562 logger->addItem(tr("Backup failed!"),LOGERROR);
563 logger->abort();
564 return false;
569 //! install current build
570 ZipInstaller* installer = new ZipInstaller(this);
571 installer->setUrl(file);
572 installer->setLogSection("Rockbox (Base)");
573 installer->setLogVersion(versmap.value("rel_rev"));
574 if(!settings->cacheDisabled())
575 installer->setCache(true);
576 installer->setMountPoint(settings->mountpoint());
578 connect(installer, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
580 installer->install(logger);
581 return true;
585 void RbUtilQt::install()
587 Install *installWindow = new Install(settings,this);
589 buildInfo.open();
590 QSettings info(buildInfo.fileName(), QSettings::IniFormat, this);
591 buildInfo.close();
592 installWindow->setVersionStrings(versmap);
594 installWindow->show();
597 bool RbUtilQt::installBootloaderAuto()
599 installBootloader();
600 return !m_error;
603 void RbUtilQt::installBootloaderBtn()
605 if(chkConfig(true)) return;
606 if(QMessageBox::question(this, tr("Confirm Installation"),
607 tr("Do you really want to install the Bootloader?"),
608 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
610 // create logger
611 logger = new ProgressLoggerGui(this);
613 installBootloader();
616 void RbUtilQt::installBootloader()
618 QString platform = settings->curPlatform();
619 QString backupDestination = "";
620 m_error = false;
622 // create installer
623 BootloaderInstallBase *bl;
624 QString type = settings->curBootloaderMethod();
625 if(type == "mi4") {
626 bl = new BootloaderInstallMi4(this);
628 else if(type == "hex") {
629 bl = new BootloaderInstallHex(this);
631 else if(type == "sansa") {
632 bl = new BootloaderInstallSansa(this);
634 else if(type == "ipod") {
635 bl = new BootloaderInstallIpod(this);
637 else if(type == "file") {
638 bl = new BootloaderInstallFile(this);
640 else {
641 logger->addItem(tr("No install method known."), LOGERROR);
642 logger->abort();
643 return;
646 // set bootloader filename. Do this now as installed() needs it.
647 QString blfile;
648 blfile = settings->mountpoint() + settings->curBootloaderFile();
649 // special case for H10 pure: this player can have a different
650 // bootloader file filename. This is handled here to keep the install
651 // class clean, though having it here is also not the nicest solution.
652 if(platform == "h10_ums"
653 || platform == "h10_mtp") {
654 if(resolvePathCase(blfile).isEmpty())
655 blfile = settings->mountpoint()
656 + settings->curBootloaderName().replace("H10",
657 "H10EMP", Qt::CaseInsensitive);
659 bl->setBlFile(blfile);
660 QUrl url(settings->bootloaderUrl() + settings->curBootloaderName());
661 bl->setBlUrl(url);
662 bl->setLogfile(settings->mountpoint() + "/.rockbox/rbutil.log");
664 if(bl->installed() == BootloaderInstallBase::BootloaderRockbox) {
665 if(QMessageBox::question(this, tr("Bootloader detected"),
666 tr("Bootloader already installed. Do you want to reinstall the bootloader?"),
667 QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
668 if(m_auto) {
669 // keep logger open for auto installs.
670 // don't consider abort as error in auto-mode.
671 logger->addItem(tr("Bootloader installation skipped"), LOGINFO);
672 installBootloaderPost(false);
674 else {
675 logger->close();
676 installBootloaderPost(true);
678 return;
681 else if(bl->installed() == BootloaderInstallBase::BootloaderOther
682 && bl->capabilities() & BootloaderInstallBase::Backup)
684 QString targetFolder = settings->curPlatform() + " Firmware Backup";
685 // remove invalid character(s)
686 targetFolder.remove(QRegExp("[:/]"));
687 if(QMessageBox::question(this, tr("Create Bootloader backup"),
688 tr("You can create a backup of the original bootloader "
689 "file. Press \"Yes\" to select an output folder on your "
690 "computer to save the file to. The file will get placed "
691 "in a new folder \"%1\" created below the selected folder.\n"
692 "Press \"No\" to skip this step.").arg(targetFolder),
693 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
694 BrowseDirtree tree(this, tr("Browse backup folder"));
695 tree.setDir(QDir::home());
696 tree.exec();
698 backupDestination = tree.getSelected() + "/" + targetFolder;
699 qDebug() << backupDestination;
700 // backup needs to be done after the logger has been set up.
704 if(bl->capabilities() & BootloaderInstallBase::NeedsFlashing)
706 int ret;
707 ret = QMessageBox::information(this, tr("Prerequisites"),
708 tr("Bootloader installation requires you to provide "
709 "a firmware file of the original firmware (hex file). "
710 "You need to download this file yourself due to legal "
711 "reasons. Please refer to the "
712 "<a href='http://www.rockbox.org/manual.shtml'>manual</a> and the "
713 "<a href='http://www.rockbox.org/wiki/IriverBoot"
714 "#Download_and_extract_a_recent_ve'>IriverBoot</a> wiki page on "
715 "how to obtain this file.<br/>"
716 "Press Ok to continue and browse your computer for the firmware "
717 "file."),
718 QMessageBox::Ok | QMessageBox::Abort);
719 if(ret != QMessageBox::Ok) {
720 // consider aborting an error to close window / abort automatic
721 // installation.
722 m_error = true;
723 logger->addItem(tr("Bootloader installation aborted"), LOGINFO);
724 return;
726 // open dialog to browse to hex file
727 QString hexfile;
728 hexfile = QFileDialog::getOpenFileName(this,
729 tr("Select firmware file"), QDir::homePath(), "*.hex");
730 if(!QFileInfo(hexfile).isReadable()) {
731 logger->addItem(tr("Error opening firmware file"), LOGERROR);
732 m_error = true;
733 return;
735 ((BootloaderInstallHex*)bl)->setHexfile(hexfile);
738 // the bootloader install class does NOT use any GUI stuff.
739 // All messages are passed via signals.
740 connect(bl, SIGNAL(done(bool)), logger, SLOT(abort()));
741 connect(bl, SIGNAL(done(bool)), this, SLOT(installBootloaderPost(bool)));
742 connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
743 connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
745 // show logger and start install.
746 logger->show();
747 if(!backupDestination.isEmpty()) {
748 if(!bl->backup(backupDestination)) {
749 if(QMessageBox::warning(this, tr("Backup error"),
750 tr("Could not create backup file. Continue?"),
751 QMessageBox::No | QMessageBox::Yes)
752 == QMessageBox::No) {
753 logger->abort();
754 return;
758 bl->install();
761 void RbUtilQt::installBootloaderPost(bool error)
763 qDebug() << __func__ << error;
764 // if an error occured don't perform post install steps.
765 if(error) {
766 m_error = true;
767 return;
769 else
770 m_error = false;
772 m_installed = true;
773 // end here if automated install
774 if(m_auto)
775 return;
777 QString msg = BootloaderInstallBase::postinstallHints(settings->curPlatform());
778 if(!msg.isEmpty()) {
779 QMessageBox::information(this, tr("Manual steps required"), msg);
780 logger->close();
785 void RbUtilQt::installFontsBtn()
787 if(chkConfig(true)) return;
788 if(QMessageBox::question(this, tr("Confirm Installation"),
789 tr("Do you really want to install the fonts package?"),
790 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
791 // create logger
792 logger = new ProgressLoggerGui(this);
793 logger->show();
794 installFonts();
797 bool RbUtilQt::installFontsAuto()
799 installFonts();
801 return !m_error;
804 void RbUtilQt::installFonts()
806 // create zip installer
807 installer = new ZipInstaller(this);
809 installer->setUrl(settings->fontUrl());
810 installer->setLogSection("Fonts");
811 installer->setLogVersion(versmap.value("arch_date"));
812 installer->setMountPoint(settings->mountpoint());
813 if(!settings->cacheDisabled())
814 installer->setCache(true);
816 connect(installer, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
817 installer->install(logger);
821 void RbUtilQt::installVoice()
823 if(chkConfig(true)) return;
825 if(m_gotInfo == false)
827 QMessageBox::warning(this, tr("Warning"),
828 tr("The Application is still downloading Information about new Builds."
829 " Please try again shortly."));
830 return;
833 if(QMessageBox::question(this, tr("Confirm Installation"),
834 tr("Do you really want to install the voice file?"),
835 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
836 // create logger
837 logger = new ProgressLoggerGui(this);
838 logger->show();
840 // create zip installer
841 installer = new ZipInstaller(this);
843 QString voiceurl = settings->voiceUrl();
845 voiceurl += settings->curConfigure_Modelname() + "-" +
846 versmap.value("arch_date") + "-english.zip";
847 qDebug() << voiceurl;
849 installer->setUrl(voiceurl);
850 installer->setLogSection("Voice");
851 installer->setLogVersion(versmap.value("arch_date"));
852 installer->setMountPoint(settings->mountpoint());
853 if(!settings->cacheDisabled())
854 installer->setCache(true);
855 installer->install(logger);
859 void RbUtilQt::installDoomBtn()
861 if(chkConfig(true)) return;
862 if(!hasDoom()){
863 QMessageBox::critical(this, tr("Error"),
864 tr("Your device doesn't have a doom plugin. Aborting."));
865 return;
868 if(QMessageBox::question(this, tr("Confirm Installation"),
869 tr("Do you really want to install the game addon files?"),
870 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
871 // create logger
872 logger = new ProgressLoggerGui(this);
873 logger->show();
875 installDoom();
877 bool RbUtilQt::installDoomAuto()
879 installDoom();
880 return !m_error;
883 bool RbUtilQt::hasDoom()
885 QFile doomrock(settings->mountpoint() +"/.rockbox/rocks/games/doom.rock");
886 return doomrock.exists();
889 void RbUtilQt::installDoom()
891 // create zip installer
892 installer = new ZipInstaller(this);
894 installer->setUrl(settings->doomUrl());
895 installer->setLogSection("Game Addons");
896 installer->setLogVersion(versmap.value("arch_date"));
897 installer->setMountPoint(settings->mountpoint());
898 if(!settings->cacheDisabled())
899 installer->setCache(true);
900 connect(installer, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
901 installer->install(logger);
905 void RbUtilQt::installThemes()
907 if(chkConfig(true)) return;
908 ThemesInstallWindow* tw = new ThemesInstallWindow(this);
909 tw->setSettings(settings);
910 tw->setModal(true);
911 tw->show();
914 void RbUtilQt::createTalkFiles(void)
916 if(chkConfig(true)) return;
917 InstallTalkWindow *installWindow = new InstallTalkWindow(this);
918 installWindow->setSettings(settings);
920 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(downloadInfo()));
921 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
922 installWindow->show();
926 void RbUtilQt::createVoiceFile(void)
928 if(chkConfig(true)) return;
929 CreateVoiceWindow *installWindow = new CreateVoiceWindow(this);
930 installWindow->setSettings(settings);
932 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(downloadInfo()));
933 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
934 installWindow->show();
937 void RbUtilQt::uninstall(void)
939 if(chkConfig(true)) return;
940 UninstallWindow *uninstallWindow = new UninstallWindow(this);
941 uninstallWindow->setSettings(settings);
942 uninstallWindow->show();
946 void RbUtilQt::uninstallBootloader(void)
948 if(chkConfig(true)) return;
949 if(QMessageBox::question(this, tr("Confirm Uninstallation"),
950 tr("Do you really want to uninstall the Bootloader?"),
951 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
952 // create logger
953 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
954 logger->setProgressVisible(false);
955 logger->show();
957 QString platform = settings->curPlatform();
959 // create installer
960 BootloaderInstallBase *bl;
961 QString type = settings->curBootloaderMethod();
962 if(type == "mi4") {
963 bl = new BootloaderInstallMi4();
965 else if(type == "hex") {
966 bl = new BootloaderInstallHex();
968 else if(type == "sansa") {
969 bl = new BootloaderInstallSansa();
971 else if(type == "ipod") {
972 bl = new BootloaderInstallIpod();
974 else if(type == "file") {
975 bl = new BootloaderInstallFile();
977 else {
978 logger->addItem(tr("No uninstall method known."), LOGERROR);
979 logger->abort();
980 return;
983 QString blfile = settings->mountpoint() + settings->curBootloaderFile();
984 if(settings->curPlatform() == "h10_ums"
985 || settings->curPlatform() == "h10_mtp") {
986 if(resolvePathCase(blfile).isEmpty())
987 blfile = settings->mountpoint()
988 + settings->curBootloaderName().replace("H10",
989 "H10EMP", Qt::CaseInsensitive);
991 bl->setBlFile(blfile);
993 connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
994 connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
996 int result;
997 result = bl->uninstall();
999 logger->abort();
1004 void RbUtilQt::downloadManual(void)
1006 if(chkConfig(true)) return;
1007 if(QMessageBox::question(this, tr("Confirm download"),
1008 tr("Do you really want to download the manual? The manual will be saved "
1009 "to the root folder of your player."),
1010 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
1011 return;
1013 buildInfo.open();
1014 QSettings info(buildInfo.fileName(), QSettings::IniFormat, this);
1015 buildInfo.close();
1017 QString manual = settings->curManual();
1019 QString date = (info.value("dailies/date").toString());
1021 QString manualurl;
1022 QString target;
1023 QString section;
1024 if(ui.radioPdf->isChecked()) {
1025 target = "/" + manual + ".pdf";
1026 section = "Manual (PDF)";
1028 else {
1029 target = "/" + manual + "-" + date + "-html.zip";
1030 section = "Manual (HTML)";
1032 manualurl = settings->manualUrl() + "/" + target;
1033 qDebug() << "manualurl =" << manualurl;
1035 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
1036 logger->show();
1037 installer = new ZipInstaller(this);
1038 installer->setMountPoint(settings->mountpoint());
1039 if(!settings->cacheDisabled())
1040 installer->setCache(true);
1041 installer->setLogSection(section);
1042 installer->setLogVersion(date);
1043 installer->setUrl(manualurl);
1044 installer->setUnzip(false);
1045 installer->setTarget(target);
1046 installer->install(logger);
1050 void RbUtilQt::installPortable(void)
1052 if(QMessageBox::question(this, tr("Confirm installation"),
1053 tr("Do you really want to install Rockbox Utility to your player? "
1054 "After installation you can run it from the players hard drive."),
1055 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
1056 return;
1058 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
1059 logger->setProgressMax(0);
1060 logger->setProgressValue(0);
1061 logger->show();
1062 logger->addItem(tr("Installing Rockbox Utility"), LOGINFO);
1064 // check mountpoint
1065 if(!QFileInfo(settings->mountpoint()).isDir()) {
1066 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
1067 logger->abort();
1068 return;
1071 // remove old files first.
1072 QFile::remove(settings->mountpoint() + "/RockboxUtility.exe");
1073 QFile::remove(settings->mountpoint() + "/RockboxUtility.ini");
1074 // copy currently running binary and currently used settings file
1075 if(!QFile::copy(qApp->applicationFilePath(), settings->mountpoint()
1076 + "/RockboxUtility.exe")) {
1077 logger->addItem(tr("Error installing Rockbox Utility"), LOGERROR);
1078 logger->abort();
1079 return;
1081 logger->addItem(tr("Installing user configuration"), LOGINFO);
1082 if(!QFile::copy(settings->userSettingFilename(), settings->mountpoint()
1083 + "/RockboxUtility.ini")) {
1084 logger->addItem(tr("Error installing user configuration"), LOGERROR);
1085 logger->abort();
1086 return;
1088 logger->addItem(tr("Successfully installed Rockbox Utility."), LOGOK);
1089 logger->abort();
1090 logger->setProgressMax(1);
1091 logger->setProgressValue(1);
1096 void RbUtilQt::updateInfo()
1098 qDebug() << "RbUtilQt::updateInfo()";
1100 QSettings log(settings->mountpoint() + "/.rockbox/rbutil.log",
1101 QSettings::IniFormat, this);
1102 QStringList groups = log.childGroups();
1103 QList<QTreeWidgetItem *> items;
1104 QTreeWidgetItem *w, *w2;
1105 QString min, max;
1106 int olditems = 0;
1108 // remove old list entries (if any)
1109 int l = ui.treeInfo->topLevelItemCount();
1110 while(l--) {
1111 QTreeWidgetItem *m;
1112 m = ui.treeInfo->takeTopLevelItem(l);
1113 // delete childs (single level deep, no recursion here)
1114 int n = m->childCount();
1115 while(n--)
1116 delete m->child(n);
1118 // get and populate new items
1119 for(int a = 0; a < groups.size(); a++) {
1120 log.beginGroup(groups.at(a));
1121 QStringList keys = log.allKeys();
1122 w = new QTreeWidgetItem;
1123 w->setFlags(Qt::ItemIsEnabled);
1124 w->setText(0, groups.at(a));
1125 items.append(w);
1126 // get minimum and maximum version information so we can hilight old files
1127 min = max = log.value(keys.at(0)).toString();
1128 for(int b = 0; b < keys.size(); b++) {
1129 if(log.value(keys.at(b)).toString() > max)
1130 max = log.value(keys.at(b)).toString();
1131 if(log.value(keys.at(b)).toString() < min)
1132 min = log.value(keys.at(b)).toString();
1135 for(int b = 0; b < keys.size(); b++) {
1136 QString file;
1137 file = settings->mountpoint() + "/" + keys.at(b);
1138 if(QFileInfo(file).isDir())
1139 continue;
1140 w2 = new QTreeWidgetItem(w, QStringList() << "/"
1141 + keys.at(b) << log.value(keys.at(b)).toString());
1142 if(log.value(keys.at(b)).toString() != max) {
1143 w2->setForeground(0, QBrush(QColor(255, 0, 0)));
1144 w2->setForeground(1, QBrush(QColor(255, 0, 0)));
1145 olditems++;
1147 items.append(w2);
1149 log.endGroup();
1150 if(min != max)
1151 w->setData(1, Qt::DisplayRole, QString("%1 / %2").arg(min, max));
1152 else
1153 w->setData(1, Qt::DisplayRole, max);
1155 ui.treeInfo->insertTopLevelItems(0, items);
1156 ui.treeInfo->resizeColumnToContents(0);
1160 QUrl RbUtilQt::proxy()
1162 if(settings->proxyType() == "manual")
1163 return QUrl(settings->proxy());
1164 else if(settings->proxy() == "system")
1165 return Detect::systemProxy();
1166 return QUrl("");
1170 bool RbUtilQt::chkConfig(bool warn)
1172 bool error = false;
1173 if(settings->curPlatform().isEmpty()
1174 || settings->mountpoint().isEmpty()
1175 || !QFileInfo(settings->mountpoint()).isWritable()) {
1176 error = true;
1178 if(warn) QMessageBox::critical(this, tr("Configuration error"),
1179 tr("Your configuration is invalid. Please go to the configuration "
1180 "dialog and make sure the selected values are correct."));
1182 return error;