Correct beast manual install instructions in Windows.
[kugel-rb.git] / rbutil / rbutilqt / rbutilqt.cpp
blob18534029a586c20e79c15025d43dce1229edf6cf
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 "themesinstallwindow.h"
32 #include "uninstallwindow.h"
33 #include "utils.h"
34 #include "rbzip.h"
35 #include "sysinfo.h"
36 #include "system.h"
37 #include "systrace.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)
54 #include <stdio.h>
55 #endif
56 #if defined(Q_OS_WIN32)
57 #if defined(UNICODE)
58 #define _UNICODE
59 #endif
60 #include <stdio.h>
61 #include <tchar.h>
62 #include <windows.h>
63 #endif
65 RbUtilQt::RbUtilQt(QWidget *parent) : QMainWindow(parent)
67 // startup log
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
77 ui.setupUi(this);
78 updateSettings();
79 downloadInfo();
81 m_gotInfo = false;
82 m_auto = false;
84 // manual tab
85 ui.radioPdf->setChecked(true);
87 // info tab
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()));
135 #if !defined(STATIC)
136 ui.actionInstall_Rockbox_Utility_on_player->setEnabled(false);
137 #else
138 connect(ui.actionInstall_Rockbox_Utility_on_player, SIGNAL(triggered()), this, SLOT(installPortable()));
139 #endif
144 void RbUtilQt::trace(void)
146 SysTrace wnd(this);
147 wnd.exec();
150 void RbUtilQt::sysinfo(void)
152 Sysinfo info(this);
153 info.exec();
156 void RbUtilQt::updateTabs(int count)
158 switch(count) {
159 case 6:
160 updateInfo();
161 break;
162 default:
163 break;
168 void RbUtilQt::downloadInfo()
170 // make sure the version map is repopulated correctly later.
171 versmap.clear();
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);
179 else
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)
190 if(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."));
195 return;
197 qDebug() << "[RbUtil] network status:" << daily->error();
199 buildInfo.open();
200 QSettings info(buildInfo.fileName(), QSettings::IniFormat, this);
201 buildInfo.close();
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());
207 info.endGroup();
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."));
232 configDialog();
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."));
240 configDialog();
245 void RbUtilQt::downloadBleedingDone(bool error)
247 if(error) {
248 qDebug() << "[RbUtil] network error:" << bleeding->error();
250 else {
251 bleedingInfo.open();
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);
259 m_gotInfo = true;
261 //start check for updates
262 checkUpdate();
267 void RbUtilQt::downloadDone(int id, bool error)
269 QString errorString;
270 errorString = tr("Network error: %1. Please check your network and proxy settings.")
271 .arg(daily->errorString());
272 if(error) {
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);
283 Ui::aboutBox about;
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);
304 window->show();
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()));
321 cw->show();
325 void RbUtilQt::updateSettings()
327 qDebug() << "[RbUtil] updating current settings";
328 updateDevice();
329 updateManual();
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());
336 else {
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 = "&lt;none&gt;";
373 if(mountpoint.isEmpty()) mountpoint = "&lt;invalid&gt;";
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();
385 if(manual == "")
386 manual = "rockbox-" + RbSettings::value(RbSettings::Platform).toString();
387 QString pdfmanual;
388 pdfmanual = RbSettings::value(RbSettings::ManualUrl).toString()
389 + "/" + manual + ".pdf";
390 QString htmlmanual;
391 htmlmanual = RbSettings::value(RbSettings::ManualUrl).toString()
392 + "/" + manual + "/rockbox-build.html";
393 ui.labelPdfManual->setText(tr("<a href='%1'>PDF Manual</a>")
394 .arg(pdfmanual));
395 ui.labelHtmlManual->setText(tr("<a href='%1'>HTML Manual (opens in browser)</a>")
396 .arg(htmlmanual));
398 else {
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)
416 return;
417 // create logger
418 logger = new ProgressLoggerGui(this);
419 logger->show();
421 if(smallInstallInner())
422 return;
423 logger->setRunning();
424 // Fonts
425 m_error = false;
426 m_installed = false;
427 if(!installFontsAuto())
428 return;
429 else
431 // wait for installation finished
432 while(!m_installed)
433 QApplication::processEvents();
435 if(m_error) return;
436 logger->setRunning();
438 // Doom
439 if(hasDoom())
441 m_error = false;
442 m_installed = false;
443 if(!installDoomAuto())
444 return;
445 else
447 // wait for installation finished
448 while(!m_installed)
449 QApplication::processEvents();
451 if(m_error) return;
454 // theme
455 // this is a window
456 // it has its own logger window,so close our.
457 logger->close();
458 installThemes();
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)
474 return;
476 // create logger
477 logger = new ProgressLoggerGui(this);
478 logger->show();
480 smallInstallInner();
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();
490 return true;
492 // Bootloader
493 if(RbSettings::value(RbSettings::CurBootloaderMethod) != "none")
495 m_error = false;
496 m_installed = false;
497 m_auto = true;
498 if(!installBootloaderAuto()) {
499 logger->setFinished();
500 return true;
502 else
504 // wait for boot loader installation finished
505 while(!m_installed)
506 QApplication::processEvents();
508 m_auto = false;
509 if(m_error) return true;
510 logger->setRunning();
513 // Rockbox
514 m_error = false;
515 m_installed = false;
516 if(!installAuto())
517 return true;
518 else
520 // wait for installation finished
521 while(!m_installed)
522 QApplication::processEvents();
525 installBootloaderPost(false);
526 return false;
529 void RbUtilQt::installdone(bool error)
531 qDebug() << "[RbUtil] install done";
532 m_installed = true;
533 m_error = error;
536 void RbUtilQt::installBtn()
538 if(chkConfig(true)) return;
539 install();
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"));
547 buildInfo.open();
548 QSettings info(buildInfo.fileName(), QSettings::IniFormat, this);
549 buildInfo.close();
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();
561 return false;
565 // check version
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())
581 QDir a;
582 a.mkpath(backupFile.path());
585 //! create backup
586 RbZip backup;
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);
593 else
595 logger->addItem(tr("Backup failed!"),LOGERROR);
596 logger->setFinished();
597 return false;
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();
617 return true;
621 void RbUtilQt::install()
623 Install *installWindow = new Install(this);
625 buildInfo.open();
626 QSettings info(buildInfo.fileName(), QSettings::IniFormat, this);
627 buildInfo.close();
628 installWindow->setVersionStrings(versmap);
630 installWindow->show();
633 bool RbUtilQt::installBootloaderAuto()
635 installBootloader();
636 return !m_error;
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;
646 // create logger
647 logger = new ProgressLoggerGui(this);
648 logger->show();
649 installBootloader();
652 void RbUtilQt::installBootloader()
654 QString platform = RbSettings::value(RbSettings::Platform).toString();
655 QString backupDestination = "";
656 m_error = false;
658 // create installer
659 BootloaderInstallBase *bl;
660 QString type = RbSettings::value(RbSettings::CurBootloaderMethod).toString();
661 if(type == "mi4") {
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);
685 else {
686 logger->addItem(tr("No install method known."), LOGERROR);
687 logger->setFinished();
688 return;
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()
696 + blfile.at(a));
698 bl->setBlFile(blfilepath);
699 QUrl url(RbSettings::value(RbSettings::BootloaderUrl).toString()
700 + RbSettings::value(RbSettings::CurBootloaderName).toString());
701 bl->setBlUrl(url);
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) {
709 if(m_auto) {
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);
715 else {
716 logger->close();
717 installBootloaderPost(true);
719 delete bl;
720 return;
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());
739 tree.exec();
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)
749 int ret;
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
754 // installation.
755 m_error = true;
756 logger->addItem(tr("Bootloader installation aborted"), LOGINFO);
757 logger->setFinished();
758 return;
760 // open dialog to browse to of file
761 QString offile;
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();
767 m_error = true;
768 return;
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)));
780 // start install.
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();
788 return;
792 bl->install();
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.
799 if(error) {
800 m_error = true;
801 return;
803 else
804 m_error = false;
806 m_installed = true;
807 // end here if automated install
808 if(m_auto)
809 return;
811 QString msg = BootloaderInstallBase::postinstallHints(
812 RbSettings::value(RbSettings::Platform).toString());
813 if(!msg.isEmpty()) {
814 QMessageBox::information(this, tr("Manual steps required"), msg);
815 logger->close();
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;
826 // create logger
827 logger = new ProgressLoggerGui(this);
828 logger->show();
829 installFonts();
832 bool RbUtilQt::installFontsAuto()
834 installFonts();
836 return !m_error;
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."));
869 return;
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;
875 // create logger
876 logger = new ProgressLoggerGui(this);
877 logger->show();
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;
905 if(!hasDoom()){
906 QMessageBox::critical(this, tr("Error"),
907 tr("Your device doesn't have a doom plugin. Aborting."));
908 return;
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;
914 // create logger
915 logger = new ProgressLoggerGui(this);
916 logger->show();
918 installDoom();
920 bool RbUtilQt::installDoomAuto()
922 installDoom();
923 return !m_error;
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);
957 tw->setModal(true);
958 tw->show();
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;
996 // create logger
997 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
998 logger->setProgressVisible(false);
999 logger->show();
1001 QString platform = RbSettings::value(RbSettings::Platform).toString();
1003 // create installer
1004 BootloaderInstallBase *bl;
1005 QString type = RbSettings::value(RbSettings::CurBootloaderMethod).toString();
1006 if(type == "mi4") {
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);
1021 else {
1022 logger->addItem(tr("No uninstall method known."), LOGERROR);
1023 logger->setFinished();
1024 return;
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()
1031 + blfile.at(a));
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)));
1038 int result;
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)
1053 return;
1055 buildInfo.open();
1056 QSettings info(buildInfo.fileName(), QSettings::IniFormat, this);
1057 buildInfo.close();
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());
1065 QString manualurl;
1066 QString target;
1067 QString section;
1068 if(ui.radioPdf->isChecked()) {
1069 target = "/" + manual + ".pdf";
1070 section = "Manual (PDF)";
1072 else {
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);
1080 logger->show();
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)
1104 return;
1106 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
1107 logger->setProgressMax(0);
1108 logger->setProgressValue(0);
1109 logger->show();
1110 logger->addItem(tr("Installing Rockbox Utility"), LOGINFO);
1112 // check mountpoint
1113 if(!QFileInfo(RbSettings::value(RbSettings::Mountpoint).toString()).isDir()) {
1114 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
1115 logger->setFinished();
1116 return;
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();
1130 return;
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();
1138 return;
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;
1157 QString min, max;
1158 int olditems = 0;
1160 // remove old list entries (if any)
1161 int l = ui.treeInfo->topLevelItemCount();
1162 while(l--) {
1163 QTreeWidgetItem *m;
1164 m = ui.treeInfo->takeTopLevelItem(l);
1165 // delete childs (single level deep, no recursion here)
1166 int n = m->childCount();
1167 while(n--)
1168 delete m->child(n);
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));
1177 items.append(w);
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++) {
1188 QString file;
1189 file = RbSettings::value(RbSettings::Mountpoint).toString() + "/" + keys.at(b);
1190 if(QFileInfo(file).isDir())
1191 continue;
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)));
1197 olditems++;
1199 items.append(w2);
1201 log.endGroup();
1202 if(min != max)
1203 w->setData(1, Qt::DisplayRole, QString("%1 / %2").arg(min, max));
1204 else
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();
1218 return QUrl("");
1222 bool RbUtilQt::chkConfig(bool warn)
1224 bool error = false;
1225 if(RbSettings::value(RbSettings::Platform).toString().isEmpty()
1226 || RbSettings::value(RbSettings::Mountpoint).toString().isEmpty()
1227 || !QFileInfo(RbSettings::value(RbSettings::Mountpoint).toString()).isWritable()) {
1228 error = true;
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."));
1234 return error;
1237 void RbUtilQt::checkUpdate(void)
1239 QString url = RbSettings::value(RbSettings::RbutilUrl).toString();
1240 #if defined(Q_OS_WIN32)
1241 url += "win32/";
1242 #elif defined(Q_OS_LINUX)
1243 url += "linux/";
1244 #elif defined(Q_OS_MACX)
1245 url += "macosx/";
1246 #endif
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)
1260 if(error) {
1261 qDebug() << "[RbUtil] network error:" << update->error();
1263 else {
1264 QString toParse(update->readAll());
1266 QRegExp searchString("<a[^>]*>(rbutilqt[^<]*)</a>");
1267 QStringList rbutilList;
1268 int pos = 0;
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"))
1284 continue;
1285 #else
1286 //skip if it is a 64bit build
1287 if(rbutilList.at(i).contains("64bit"))
1288 continue;
1289 #endif
1290 #endif
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)
1306 url += "win32/";
1307 #elif defined(Q_OS_LINUX)
1308 url += "linux/";
1309 #elif defined(Q_OS_MACX)
1310 url += "macosx/";
1311 #endif
1312 url += newVersion;
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
1360 return true;
1361 else if(newPartInt < oldPartInt) //this section int is lower -> false
1362 return false;
1363 else if(newPartChar > oldPartChar) //ints are the same, chars is higher -> true
1364 return true;
1365 else if(newPartChar < oldPartChar) //ints are the same, chars is lower -> false
1366 return false;
1367 //all the same, next section
1369 // all the same -> false
1370 return false;