Fix wpsbuild to properly generate "-" for theme related settings (to get the default...
[kugel-rb.git] / rbutil / rbutilqt / rbutilqt.cpp
bloba721183fbd9b0fd6343689f9bfb48ead136af53f
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 "installwindow.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"
39 #include "serverinfo.h"
40 #include "systeminfo.h"
42 #include "progressloggerinterface.h"
44 #include "bootloaderinstallbase.h"
45 #include "bootloaderinstallmi4.h"
46 #include "bootloaderinstallhex.h"
47 #include "bootloaderinstallipod.h"
48 #include "bootloaderinstallsansa.h"
49 #include "bootloaderinstallfile.h"
50 #include "bootloaderinstallchinachip.h"
51 #include "bootloaderinstallams.h"
52 #include "bootloaderinstalltcc.h"
55 #if defined(Q_OS_LINUX)
56 #include <stdio.h>
57 #endif
58 #if defined(Q_OS_WIN32)
59 #if defined(UNICODE)
60 #define _UNICODE
61 #endif
62 #include <stdio.h>
63 #include <tchar.h>
64 #include <windows.h>
65 #endif
67 RbUtilQt::RbUtilQt(QWidget *parent) : QMainWindow(parent)
69 // startup log
70 qDebug() << "======================================";
71 qDebug() << "[System] Rockbox Utility " VERSION;
72 qDebug() << "[System] Qt version:" << qVersion();
73 qDebug() << "======================================";
75 absolutePath = qApp->applicationDirPath();
77 HttpGet::setGlobalUserAgent("rbutil/"VERSION);
78 // init startup & autodetection
79 ui.setupUi(this);
80 downloadInfo();
82 m_gotInfo = false;
83 m_auto = false;
85 // manual tab
86 ui.radioPdf->setChecked(true);
88 // info tab
89 ui.treeInfo->setAlternatingRowColors(true);
90 ui.treeInfo->setHeaderLabels(QStringList() << tr("File") << tr("Version"));
91 ui.treeInfo->expandAll();
92 ui.treeInfo->setColumnCount(2);
93 ui.treeInfo->setLayoutDirection(Qt::LeftToRight);
94 // disable quick install until version info is available
95 ui.buttonSmall->setEnabled(false);
96 ui.buttonComplete->setEnabled(false);
97 ui.actionSmall_Installation->setEnabled(false);
98 ui.actionComplete_Installation->setEnabled(false);
100 connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(updateTabs(int)));
101 connect(ui.actionAbout_Qt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
102 connect(ui.action_About, SIGNAL(triggered()), this, SLOT(about()));
103 connect(ui.action_Help, SIGNAL(triggered()), this, SLOT(help()));
104 connect(ui.action_Configure, SIGNAL(triggered()), this, SLOT(configDialog()));
105 connect(ui.actionE_xit, SIGNAL(triggered()), this, SLOT(shutdown()));
106 connect(ui.buttonChangeDevice, SIGNAL(clicked()), this, SLOT(configDialog()));
107 connect(ui.buttonRockbox, SIGNAL(clicked()), this, SLOT(installBtn()));
108 connect(ui.buttonBootloader, SIGNAL(clicked()), this, SLOT(installBootloaderBtn()));
109 connect(ui.buttonFonts, SIGNAL(clicked()), this, SLOT(installFontsBtn()));
110 connect(ui.buttonGames, SIGNAL(clicked()), this, SLOT(installDoomBtn()));
111 connect(ui.buttonTalk, SIGNAL(clicked()), this, SLOT(createTalkFiles()));
112 connect(ui.buttonCreateVoice, SIGNAL(clicked()), this, SLOT(createVoiceFile()));
113 connect(ui.buttonVoice, SIGNAL(clicked()), this, SLOT(installVoice()));
114 connect(ui.buttonThemes, SIGNAL(clicked()), this, SLOT(installThemes()));
115 connect(ui.buttonRemoveRockbox, SIGNAL(clicked()), this, SLOT(uninstall()));
116 connect(ui.buttonRemoveBootloader, SIGNAL(clicked()), this, SLOT(uninstallBootloader()));
117 connect(ui.buttonDownloadManual, SIGNAL(clicked()), this, SLOT(downloadManual()));
118 connect(ui.buttonSmall, SIGNAL(clicked()), this, SLOT(smallInstall()));
119 connect(ui.buttonComplete, SIGNAL(clicked()), this, SLOT(completeInstall()));
121 // actions accessible from the menu
122 connect(ui.actionComplete_Installation, SIGNAL(triggered()), this, SLOT(completeInstall()));
123 connect(ui.actionSmall_Installation, SIGNAL(triggered()), this, SLOT(smallInstall()));
124 connect(ui.actionInstall_Bootloader, SIGNAL(triggered()), this, SLOT(installBootloaderBtn()));
125 connect(ui.actionInstall_Rockbox, SIGNAL(triggered()), this, SLOT(installBtn()));
126 connect(ui.actionFonts_Package, SIGNAL(triggered()), this, SLOT(installFontsBtn()));
127 connect(ui.actionInstall_Themes, SIGNAL(triggered()), this, SLOT(installThemes()));
128 connect(ui.actionInstall_Game_Files, SIGNAL(triggered()), this, SLOT(installDoomBtn()));
129 connect(ui.actionInstall_Voice_File, SIGNAL(triggered()), this, SLOT(installVoice()));
130 connect(ui.actionCreate_Voice_File, SIGNAL(triggered()), this, SLOT(createVoiceFile()));
131 connect(ui.actionCreate_Talk_Files, SIGNAL(triggered()), this, SLOT(createTalkFiles()));
132 connect(ui.actionRemove_bootloader, SIGNAL(triggered()), this, SLOT(uninstallBootloader()));
133 connect(ui.actionUninstall_Rockbox, SIGNAL(triggered()), this, SLOT(uninstall()));
134 connect(ui.action_System_Info, SIGNAL(triggered()), this, SLOT(sysinfo()));
135 connect(ui.action_Trace, SIGNAL(triggered()), this, SLOT(trace()));
137 #if !defined(STATIC)
138 ui.actionInstall_Rockbox_Utility_on_player->setEnabled(false);
139 #else
140 connect(ui.actionInstall_Rockbox_Utility_on_player, SIGNAL(triggered()), this, SLOT(installPortable()));
141 #endif
146 void RbUtilQt::shutdown(void)
148 // restore default message handler to prevent trace accesses during
149 // object destruction -- the trace object could already be destroyed.
150 // Fixes segfaults on exit.
151 qInstallMsgHandler(0);
152 this->close();
156 void RbUtilQt::trace(void)
158 SysTrace wnd(this);
159 wnd.exec();
162 void RbUtilQt::sysinfo(void)
164 Sysinfo info(this);
165 info.exec();
168 void RbUtilQt::updateTabs(int count)
170 switch(count) {
171 case 6:
172 updateInfo();
173 break;
174 default:
175 break;
180 void RbUtilQt::downloadInfo()
182 // try to get the current build information
183 daily = new HttpGet(this);
184 connect(daily, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
185 connect(daily, SIGNAL(requestFinished(int, bool)), this, SLOT(downloadDone(int, bool)));
186 connect(qApp, SIGNAL(lastWindowClosed()), daily, SLOT(abort()));
187 if(RbSettings::value(RbSettings::CacheOffline).toBool())
188 daily->setCache(true);
189 else
190 daily->setCache(false);
191 ui.statusbar->showMessage(tr("Downloading build information, please wait ..."));
192 qDebug() << "[RbUtil] downloading build info";
193 daily->setFile(&buildInfo);
194 daily->getFile(QUrl(SystemInfo::value(SystemInfo::ServerConfUrl).toString()));
198 void RbUtilQt::downloadDone(bool error)
200 if(error) {
201 qDebug() << "[RbUtil] network error:" << daily->error();
202 ui.statusbar->showMessage(tr("Can't get version information!"));
203 QMessageBox::critical(this, tr("Network error"),
204 tr("Can't get version information."));
205 return;
207 qDebug() << "[RbUtil] network status:" << daily->error();
209 // read info into ServerInfo object
210 buildInfo.open();
211 ServerInfo::readBuildInfo(buildInfo.fileName());
212 buildInfo.close();
214 //start bleeding info download
215 bleeding = new HttpGet(this);
216 connect(bleeding, SIGNAL(done(bool)), this, SLOT(downloadBleedingDone(bool)));
217 connect(bleeding, SIGNAL(requestFinished(int, bool)), this, SLOT(downloadDone(int, bool)));
218 connect(qApp, SIGNAL(lastWindowClosed()), bleeding, SLOT(abort()));
219 if(RbSettings::value(RbSettings::CacheOffline).toBool())
220 bleeding->setCache(true);
221 bleeding->setFile(&bleedingInfo);
222 bleeding->getFile(QUrl(SystemInfo::value(SystemInfo::BleedingInfo).toString()));
223 ui.statusbar->showMessage(tr("Downloading build information, please wait ..."));
228 void RbUtilQt::downloadBleedingDone(bool error)
230 if(error) {
231 qDebug() << "[RbUtil] network error:" << bleeding->error();
233 else {
234 bleedingInfo.open();
235 ServerInfo::readBleedingInfo(bleedingInfo.fileName());
236 bleedingInfo.close();
238 ui.statusbar->showMessage(tr("Download build information finished."), 5000);
239 updateSettings();
240 m_gotInfo = true;
242 //start check for updates
243 checkUpdate();
248 void RbUtilQt::downloadDone(int id, bool error)
250 QString errorString;
251 errorString = tr("Network error: %1. Please check your network and proxy settings.")
252 .arg(daily->errorString());
253 if(error) {
254 QMessageBox::about(this, "Network Error", errorString);
255 m_networkerror = daily->errorString();
257 qDebug() << "[RbUtil] downloadDone:" << id << "error:" << error;
261 void RbUtilQt::about()
263 QDialog *window = new QDialog(this);
264 Ui::aboutBox about;
265 about.setupUi(window);
266 window->setLayoutDirection(Qt::LeftToRight);
267 window->setModal(true);
269 QFile licence(":/docs/gpl-2.0.html");
270 licence.open(QIODevice::ReadOnly);
271 QTextStream c(&licence);
272 QString cline = c.readAll();
273 about.browserLicense->insertHtml(cline);
274 about.browserLicense->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
275 QFile credits(":/docs/CREDITS");
276 credits.open(QIODevice::ReadOnly);
277 QTextStream r(&credits);
278 r.setCodec(QTextCodec::codecForName("UTF-8"));
279 while(!r.atEnd()) {
280 QString line = r.readLine();
281 // filter out header.
282 line.remove(QRegExp("^[^A-Z]+.*"));
283 line.remove(QRegExp("^People.*"));
284 about.browserCredits->append(line);
286 about.browserCredits->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
287 QString title = QString("<b>The Rockbox Utility</b><br/>Version %1").arg(FULLVERSION);
288 about.labelTitle->setText(title);
290 window->show();
295 void RbUtilQt::help()
297 QUrl helpurl("http://www.rockbox.org/wiki/RockboxUtility");
298 QDesktopServices::openUrl(helpurl);
302 void RbUtilQt::configDialog()
304 Config *cw = new Config(this);
305 connect(cw, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
306 cw->show();
310 void RbUtilQt::updateSettings()
312 qDebug() << "[RbUtil] updating current settings";
313 updateDevice();
314 updateManual();
315 if(RbSettings::value(RbSettings::ProxyType) == "system") {
316 HttpGet::setGlobalProxy(System::systemProxy());
318 else if(RbSettings::value(RbSettings::ProxyType) == "manual") {
319 HttpGet::setGlobalProxy(RbSettings::value(RbSettings::Proxy).toString());
321 else {
322 HttpGet::setGlobalProxy(QUrl(""));
324 HttpGet::setGlobalCache(RbSettings::value(RbSettings::CachePath).toString());
325 HttpGet::setGlobalDumbCache(RbSettings::value(RbSettings::CacheOffline).toBool());
327 if(RbSettings::value(RbSettings::RbutilVersion) != PUREVERSION) {
328 QApplication::processEvents();
329 QMessageBox::information(this, tr("New installation"),
330 tr("This is a new installation of Rockbox Utility, or a new version. "
331 "The configuration dialog will now open to allow you to setup the program, "
332 " or review your settings."));
333 configDialog();
335 else if(chkConfig(false)) {
336 QApplication::processEvents();
337 QMessageBox::critical(this, tr("Configuration error"),
338 tr("Your configuration is invalid. This is most likely due "
339 "to a changed device path. The configuration dialog will "
340 "now open to allow you to correct the problem."));
341 configDialog();
346 void RbUtilQt::updateDevice()
348 /* TODO: We should check the flags of the bootloaderinstall classes, and not
349 * just check if its != none or != "fwpatcher" */
351 /* Enable bootloader installation, if possible */
352 bool bootloaderInstallable =
353 SystemInfo::value(SystemInfo::CurBootloaderMethod) != "none";
354 ui.buttonBootloader->setEnabled(bootloaderInstallable);
355 ui.labelBootloader->setEnabled(bootloaderInstallable);
356 ui.actionInstall_Bootloader->setEnabled(bootloaderInstallable);
358 /* Enable bootloader uninstallation, if possible */
359 bool bootloaderUninstallable = bootloaderInstallable &&
360 SystemInfo::value(SystemInfo::CurBootloaderMethod) != "fwpatcher";
361 ui.labelRemoveBootloader->setEnabled(bootloaderUninstallable);
362 ui.buttonRemoveBootloader->setEnabled(bootloaderUninstallable);
363 ui.actionRemove_bootloader->setEnabled(bootloaderUninstallable);
365 /* Disable the whole tab widget if configuration is invalid */
366 bool configurationValid = !chkConfig(false);
367 ui.tabWidget->setEnabled(configurationValid);
368 ui.menuA_ctions->setEnabled(configurationValid);
370 // displayed device info
371 QString mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
372 QString brand = SystemInfo::value(SystemInfo::CurBrand).toString();
373 QString name = SystemInfo::value(SystemInfo::CurName).toString() +
374 " (" + ServerInfo::value(ServerInfo::CurStatus).toString() + ")";
375 if(name.isEmpty()) name = "&lt;none&gt;";
376 if(mountpoint.isEmpty()) mountpoint = "&lt;invalid&gt;";
377 ui.labelDevice->setText(tr("<b>%1 %2</b> at <b>%3</b>")
378 .arg(brand, name, QDir::toNativeSeparators(mountpoint)));
380 // hide quickstart buttons if no release available
381 bool installable = !ServerInfo::value(ServerInfo::CurReleaseVersion).toString().isEmpty();
382 ui.buttonSmall->setEnabled(installable);
383 ui.buttonComplete->setEnabled(installable);
384 ui.actionSmall_Installation->setEnabled(installable);
385 ui.actionComplete_Installation->setEnabled(installable);
389 void RbUtilQt::updateManual()
391 if(RbSettings::value(RbSettings::Platform) != "")
393 QString manual= SystemInfo::value(SystemInfo::CurManual).toString();
395 if(manual == "")
396 manual = "rockbox-" + RbSettings::value(RbSettings::Platform).toString();
397 QString pdfmanual;
398 pdfmanual = SystemInfo::value(SystemInfo::ManualUrl).toString()
399 + "/" + manual + ".pdf";
400 QString htmlmanual;
401 htmlmanual = SystemInfo::value(SystemInfo::ManualUrl).toString()
402 + "/" + manual + "/rockbox-build.html";
403 ui.labelPdfManual->setText(tr("<a href='%1'>PDF Manual</a>")
404 .arg(pdfmanual));
405 ui.labelHtmlManual->setText(tr("<a href='%1'>HTML Manual (opens in browser)</a>")
406 .arg(htmlmanual));
408 else {
409 ui.labelPdfManual->setText(tr("Select a device for a link to the correct manual"));
410 ui.labelHtmlManual->setText(tr("<a href='%1'>Manual Overview</a>")
411 .arg("http://www.rockbox.org/manual.shtml"));
416 void RbUtilQt::completeInstall()
418 if(chkConfig(true)) return;
419 if(QMessageBox::question(this, tr("Confirm Installation"),
420 tr("Do you really want to perform a complete installation?\n\n"
421 "This will install Rockbox %1. To install the most recent "
422 "development build available press \"Cancel\" and "
423 "use the \"Installation\" tab.")
424 .arg(ServerInfo::value(ServerInfo::CurReleaseVersion).toString()),
425 QMessageBox::Ok | QMessageBox::Cancel) != QMessageBox::Ok)
426 return;
427 // create logger
428 logger = new ProgressLoggerGui(this);
429 logger->show();
431 if(smallInstallInner())
432 return;
433 logger->setRunning();
434 // Fonts
435 m_error = false;
436 m_installed = false;
437 if(!installFontsAuto())
438 return;
439 else
441 // wait for installation finished
442 while(!m_installed)
443 QApplication::processEvents();
445 if(m_error) return;
446 logger->setRunning();
448 // Doom
449 if(hasDoom())
451 m_error = false;
452 m_installed = false;
453 if(!installDoomAuto())
454 return;
455 else
457 // wait for installation finished
458 while(!m_installed)
459 QApplication::processEvents();
461 if(m_error) return;
464 // theme
465 // this is a window
466 // it has its own logger window,so close our.
467 logger->close();
468 installThemes();
472 void RbUtilQt::smallInstall()
474 if(chkConfig(true)) return;
475 if(QMessageBox::question(this, tr("Confirm Installation"),
476 tr("Do you really want to perform a minimal installation? "
477 "A minimal installation will contain only the absolutely "
478 "necessary parts to run Rockbox.\n\n"
479 "This will install Rockbox %1. To install the most recent "
480 "development build available press \"Cancel\" and "
481 "use the \"Installation\" tab.")
482 .arg(ServerInfo::value(ServerInfo::CurReleaseVersion).toString()),
483 QMessageBox::Ok | QMessageBox::Cancel) != QMessageBox::Ok)
484 return;
486 // create logger
487 logger = new ProgressLoggerGui(this);
488 logger->show();
490 smallInstallInner();
493 bool RbUtilQt::smallInstallInner()
495 QString mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
496 // show dialog with error if mount point is wrong
497 if(!QFileInfo(mountpoint).isDir()) {
498 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
499 logger->setFinished();
500 return true;
502 // Bootloader
503 if(SystemInfo::value(SystemInfo::CurBootloaderMethod) != "none")
505 m_error = false;
506 m_installed = false;
507 m_auto = true;
508 if(!installBootloaderAuto()) {
509 logger->setFinished();
510 return true;
512 else
514 // wait for boot loader installation finished
515 while(!m_installed)
516 QApplication::processEvents();
518 m_auto = false;
519 if(m_error) return true;
520 logger->setRunning();
523 // Rockbox
524 m_error = false;
525 m_installed = false;
526 if(!installAuto())
527 return true;
528 else
530 // wait for installation finished
531 while(!m_installed)
532 QApplication::processEvents();
535 installBootloaderPost(false);
536 return false;
539 void RbUtilQt::installdone(bool error)
541 qDebug() << "[RbUtil] install done";
542 m_installed = true;
543 m_error = error;
546 void RbUtilQt::installBtn()
548 if(chkConfig(true)) return;
549 install();
552 bool RbUtilQt::installAuto()
554 QString file = SystemInfo::value(SystemInfo::ReleaseUrl).toString();
555 file.replace("%MODEL%", SystemInfo::value(SystemInfo::CurBuildserverModel).toString());
556 file.replace("%RELVERSION%", ServerInfo::value(ServerInfo::CurReleaseVersion).toString());
558 // check installed Version and Target
559 QString warning = check(false);
560 if(!warning.isEmpty())
562 if(QMessageBox::warning(this, tr("Really continue?"), warning,
563 QMessageBox::Ok | QMessageBox::Abort, QMessageBox::Abort)
564 == QMessageBox::Abort)
566 logger->addItem(tr("Aborted!"), LOGERROR);
567 logger->setFinished();
568 return false;
572 // check version
573 RockboxInfo rbinfo(RbSettings::value(RbSettings::Mountpoint).toString());
574 if(rbinfo.version() != "")
576 if(QMessageBox::question(this, tr("Installed Rockbox detected"),
577 tr("Rockbox installation detected. Do you want to backup first?"),
578 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
580 logger->addItem(tr("Starting backup..."),LOGINFO);
581 QString backupName = RbSettings::value(RbSettings::Mountpoint).toString()
582 + "/.backup/rockbox-backup-" + rbinfo.version() + ".zip";
584 //! create dir, if it doesnt exist
585 QFileInfo backupFile(backupName);
586 if(!QDir(backupFile.path()).exists())
588 QDir a;
589 a.mkpath(backupFile.path());
592 //! create backup
593 RbZip backup;
594 connect(&backup,SIGNAL(zipProgress(int,int)),logger, SLOT(setProgress(int,int)));
595 if(backup.createZip(backupName,
596 RbSettings::value(RbSettings::Mountpoint).toString() + "/.rockbox") == Zip::Ok)
598 logger->addItem(tr("Backup successful"),LOGOK);
600 else
602 logger->addItem(tr("Backup failed!"),LOGERROR);
603 logger->setFinished();
604 return false;
609 //! install current build
610 ZipInstaller* installer = new ZipInstaller(this);
611 installer->setUrl(file);
612 installer->setLogSection("Rockbox (Base)");
613 installer->setLogVersion(ServerInfo::value(ServerInfo::CurReleaseVersion).toString());
614 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
615 installer->setCache(true);
616 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
618 connect(installer, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
619 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
620 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
621 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
622 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
623 installer->install();
624 return true;
628 void RbUtilQt::install()
630 InstallWindow *installWindow = new InstallWindow(this);
631 installWindow->show();
634 bool RbUtilQt::installBootloaderAuto()
636 installBootloader();
637 return !m_error;
640 void RbUtilQt::installBootloaderBtn()
642 if(chkConfig(true)) return;
643 if(QMessageBox::question(this, tr("Confirm Installation"),
644 tr("Do you really want to install the Bootloader?"),
645 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
647 // create logger
648 logger = new ProgressLoggerGui(this);
649 logger->show();
650 installBootloader();
653 void RbUtilQt::installBootloader()
655 QString platform = RbSettings::value(RbSettings::Platform).toString();
656 QString backupDestination = "";
657 m_error = false;
659 // create installer
660 BootloaderInstallBase *bl;
661 QString type = SystemInfo::value(SystemInfo::CurBootloaderMethod).toString();
662 if(type == "mi4") {
663 bl = new BootloaderInstallMi4(this);
665 else if(type == "hex") {
666 bl = new BootloaderInstallHex(this);
668 else if(type == "sansa") {
669 bl = new BootloaderInstallSansa(this);
671 else if(type == "ipod") {
672 bl = new BootloaderInstallIpod(this);
674 else if(type == "file") {
675 bl = new BootloaderInstallFile(this);
677 else if(type == "chinachip") {
678 bl = new BootloaderInstallChinaChip(this);
680 else if(type == "ams") {
681 bl = new BootloaderInstallAms(this);
683 else if(type == "tcc") {
684 bl = new BootloaderInstallTcc(this);
686 else {
687 logger->addItem(tr("No install method known."), LOGERROR);
688 logger->setFinished();
689 return;
692 // set bootloader filename. Do this now as installed() needs it.
693 QStringList blfile = SystemInfo::value(SystemInfo::CurBootloaderFile).toStringList();
694 QStringList blfilepath;
695 for(int a = 0; a < blfile.size(); a++) {
696 blfilepath.append(RbSettings::value(RbSettings::Mountpoint).toString()
697 + blfile.at(a));
699 bl->setBlFile(blfilepath);
700 QUrl url(SystemInfo::value(SystemInfo::BootloaderUrl).toString()
701 + SystemInfo::value(SystemInfo::CurBootloaderName).toString());
702 bl->setBlUrl(url);
703 bl->setLogfile(RbSettings::value(RbSettings::Mountpoint).toString()
704 + "/.rockbox/rbutil.log");
706 if(bl->installed() == BootloaderInstallBase::BootloaderRockbox) {
707 if(QMessageBox::question(this, tr("Bootloader detected"),
708 tr("Bootloader already installed. Do you want to reinstall the bootloader?"),
709 QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
710 if(m_auto) {
711 // keep logger open for auto installs.
712 // don't consider abort as error in auto-mode.
713 logger->addItem(tr("Bootloader installation skipped"), LOGINFO);
714 installBootloaderPost(false);
716 else {
717 logger->close();
718 installBootloaderPost(true);
720 delete bl;
721 return;
724 else if(bl->installed() == BootloaderInstallBase::BootloaderOther
725 && bl->capabilities() & BootloaderInstallBase::Backup)
727 QString targetFolder = SystemInfo::value(SystemInfo::CurPlatformName).toString()
728 + " Firmware Backup";
729 // remove invalid character(s)
730 targetFolder.remove(QRegExp("[:/]"));
731 if(QMessageBox::question(this, tr("Create Bootloader backup"),
732 tr("You can create a backup of the original bootloader "
733 "file. Press \"Yes\" to select an output folder on your "
734 "computer to save the file to. The file will get placed "
735 "in a new folder \"%1\" created below the selected folder.\n"
736 "Press \"No\" to skip this step.").arg(targetFolder),
737 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
738 backupDestination = QFileDialog::getExistingDirectory(this,
739 tr("Browse backup folder"), QDir::homePath());
740 if(!backupDestination.isEmpty())
741 backupDestination += "/" + targetFolder;
743 qDebug() << "[RbUtil] backing up to" << backupDestination;
744 // backup needs to be done after the logger has been set up.
748 if(bl->capabilities() & BootloaderInstallBase::NeedsOf)
750 int ret;
751 ret = QMessageBox::information(this, tr("Prerequisites"),
752 bl->ofHint(),QMessageBox::Ok | QMessageBox::Abort);
753 if(ret != QMessageBox::Ok) {
754 // consider aborting an error to close window / abort automatic
755 // installation.
756 m_error = true;
757 logger->addItem(tr("Bootloader installation aborted"), LOGINFO);
758 logger->setFinished();
759 return;
761 // open dialog to browse to of file
762 QString offile;
763 offile = QFileDialog::getOpenFileName(this,
764 tr("Select firmware file"), QDir::homePath());
765 if(!QFileInfo(offile).isReadable()) {
766 logger->addItem(tr("Error opening firmware file"), LOGERROR);
767 logger->setFinished();
768 m_error = true;
769 return;
771 bl->setOfFile(offile);
774 // the bootloader install class does NOT use any GUI stuff.
775 // All messages are passed via signals.
776 connect(bl, SIGNAL(done(bool)), logger, SLOT(setFinished()));
777 connect(bl, SIGNAL(done(bool)), this, SLOT(installBootloaderPost(bool)));
778 connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
779 connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
781 // start install.
782 if(!backupDestination.isEmpty()) {
783 if(!bl->backup(backupDestination)) {
784 if(QMessageBox::warning(this, tr("Backup error"),
785 tr("Could not create backup file. Continue?"),
786 QMessageBox::No | QMessageBox::Yes)
787 == QMessageBox::No) {
788 logger->setFinished();
789 return;
793 bl->install();
796 void RbUtilQt::installBootloaderPost(bool error)
798 qDebug() << "[RbUtil] Bootloader Post-Installation, error state:" << error;
799 // if an error occured don't perform post install steps.
800 if(error) {
801 m_error = true;
802 return;
804 else
805 m_error = false;
807 m_installed = true;
808 // end here if automated install
809 if(m_auto)
810 return;
812 QString msg = BootloaderInstallBase::postinstallHints(
813 RbSettings::value(RbSettings::Platform).toString());
814 if(!msg.isEmpty()) {
815 QMessageBox::information(this, tr("Manual steps required"), msg);
816 logger->close();
821 void RbUtilQt::installFontsBtn()
823 if(chkConfig(true)) return;
824 if(QMessageBox::question(this, tr("Confirm Installation"),
825 tr("Do you really want to install the fonts package?"),
826 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
827 // create logger
828 logger = new ProgressLoggerGui(this);
829 logger->show();
830 installFonts();
833 bool RbUtilQt::installFontsAuto()
835 installFonts();
837 return !m_error;
840 void RbUtilQt::installFonts()
842 // create zip installer
843 installer = new ZipInstaller(this);
845 installer->setUrl(SystemInfo::value(SystemInfo::FontUrl).toString());
846 installer->setLogSection("Fonts");
847 installer->setLogVersion(ServerInfo::value(ServerInfo::DailyDate).toString());
848 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
849 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
850 installer->setCache(true);
852 connect(installer, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
853 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
854 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
855 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
856 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
857 installer->install();
861 void RbUtilQt::installVoice()
863 if(chkConfig(true)) return;
865 if(m_gotInfo == false)
867 QMessageBox::warning(this, tr("Warning"),
868 tr("The Application is still downloading Information about new Builds."
869 " Please try again shortly."));
870 return;
873 if(QMessageBox::question(this, tr("Confirm Installation"),
874 tr("Do you really want to install the voice file?"),
875 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
876 // create logger
877 logger = new ProgressLoggerGui(this);
878 logger->show();
880 // create zip installer
881 installer = new ZipInstaller(this);
883 QString voiceurl = SystemInfo::value(SystemInfo::VoiceUrl).toString();
884 QDate date = QDate::fromString(ServerInfo::value(ServerInfo::DailyDate).toString(),Qt::ISODate);
885 voiceurl += SystemInfo::value(SystemInfo::CurBuildserverModel).toString() + "-" +
886 date.toString("yyyyMMdd") + "-english.zip";
887 qDebug() << "[RbUtil] voicefile URL:" << voiceurl;
889 installer->setUrl(voiceurl);
890 installer->setLogSection("Voice");
891 installer->setLogVersion(ServerInfo::value(ServerInfo::DailyDate).toString());
892 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
893 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
894 installer->setCache(true);
895 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
896 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
897 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
898 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
899 installer->install();
903 void RbUtilQt::installDoomBtn()
905 if(chkConfig(true)) return;
906 if(!hasDoom()){
907 QMessageBox::critical(this, tr("Error"),
908 tr("Your device doesn't have a doom plugin. Aborting."));
909 return;
912 if(QMessageBox::question(this, tr("Confirm Installation"),
913 tr("Do you really want to install the game addon files?"),
914 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
915 // create logger
916 logger = new ProgressLoggerGui(this);
917 logger->show();
919 installDoom();
921 bool RbUtilQt::installDoomAuto()
923 installDoom();
924 return !m_error;
927 bool RbUtilQt::hasDoom()
929 QFile doomrock(RbSettings::value(RbSettings::Mountpoint).toString()
930 +"/.rockbox/rocks/games/doom.rock");
931 return doomrock.exists();
934 void RbUtilQt::installDoom()
936 // create zip installer
937 installer = new ZipInstaller(this);
939 installer->setUrl(SystemInfo::value(SystemInfo::DoomUrl).toString());
940 installer->setLogSection("Game Addons");
941 installer->setLogVersion(ServerInfo::value(ServerInfo::DailyDate).toString());
942 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
943 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
944 installer->setCache(true);
945 connect(installer, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
946 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
947 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
948 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
949 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
950 installer->install();
954 void RbUtilQt::installThemes()
956 if(chkConfig(true)) return;
957 ThemesInstallWindow* tw = new ThemesInstallWindow(this);
958 tw->setModal(true);
959 tw->show();
962 void RbUtilQt::createTalkFiles(void)
964 if(chkConfig(true)) return;
965 InstallTalkWindow *installWindow = new InstallTalkWindow(this);
966 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
967 installWindow->show();
971 void RbUtilQt::createVoiceFile(void)
973 if(chkConfig(true)) return;
974 CreateVoiceWindow *installWindow = new CreateVoiceWindow(this);
976 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
977 installWindow->show();
980 void RbUtilQt::uninstall(void)
982 if(chkConfig(true)) return;
983 UninstallWindow *uninstallWindow = new UninstallWindow(this);
984 uninstallWindow->show();
988 void RbUtilQt::uninstallBootloader(void)
990 if(chkConfig(true)) return;
991 if(QMessageBox::question(this, tr("Confirm Uninstallation"),
992 tr("Do you really want to uninstall the Bootloader?"),
993 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
994 // create logger
995 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
996 logger->setProgressVisible(false);
997 logger->show();
999 QString platform = RbSettings::value(RbSettings::Platform).toString();
1001 // create installer
1002 BootloaderInstallBase *bl;
1003 QString type = SystemInfo::value(SystemInfo::CurBootloaderMethod).toString();
1004 if(type == "mi4") {
1005 bl = new BootloaderInstallMi4(this);
1007 else if(type == "hex") {
1008 bl = new BootloaderInstallHex(this);
1010 else if(type == "sansa") {
1011 bl = new BootloaderInstallSansa(this);
1013 else if(type == "ipod") {
1014 bl = new BootloaderInstallIpod(this);
1016 else if(type == "file") {
1017 bl = new BootloaderInstallFile(this);
1019 else {
1020 logger->addItem(tr("No uninstall method known."), LOGERROR);
1021 logger->setFinished();
1022 return;
1025 QStringList blfile = SystemInfo::value(SystemInfo::CurBootloaderFile).toStringList();
1026 QStringList blfilepath;
1027 for(int a = 0; a < blfile.size(); a++) {
1028 blfilepath.append(RbSettings::value(RbSettings::Mountpoint).toString()
1029 + blfile.at(a));
1031 bl->setBlFile(blfilepath);
1033 connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
1034 connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
1036 int result;
1037 result = bl->uninstall();
1039 logger->setFinished();
1044 void RbUtilQt::downloadManual(void)
1046 if(chkConfig(true)) return;
1047 if(QMessageBox::question(this, tr("Confirm download"),
1048 tr("Do you really want to download the manual? The manual will be saved "
1049 "to the root folder of your player."),
1050 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
1051 return;
1053 QString manual = SystemInfo::value(SystemInfo::CurManual).toString();
1054 if(manual.isEmpty())
1055 manual = "rockbox-" + RbSettings::value(RbSettings::Platform).toString();
1057 QString date = ServerInfo::value(ServerInfo::DailyDate).toString();
1059 QString manualurl;
1060 QString target;
1061 QString section;
1062 if(ui.radioPdf->isChecked()) {
1063 target = "/" + manual + ".pdf";
1064 section = "Manual (PDF)";
1066 else {
1067 target = "/" + manual + "-" + date + "-html.zip";
1068 section = "Manual (HTML)";
1070 manualurl = SystemInfo::value(SystemInfo::ManualUrl).toString() + "/" + target;
1071 qDebug() << "[RbUtil] Manual URL:" << manualurl;
1073 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
1074 logger->show();
1075 installer = new ZipInstaller(this);
1076 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
1077 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
1078 installer->setCache(true);
1079 installer->setLogSection(section);
1080 installer->setLogVersion(date);
1081 installer->setUrl(manualurl);
1082 installer->setUnzip(false);
1083 installer->setTarget(target);
1084 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
1085 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
1086 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
1087 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
1088 installer->install();
1092 void RbUtilQt::installPortable(void)
1094 if(QMessageBox::question(this, tr("Confirm installation"),
1095 tr("Do you really want to install Rockbox Utility to your player? "
1096 "After installation you can run it from the players hard drive."),
1097 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
1098 return;
1100 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
1101 logger->setProgressMax(0);
1102 logger->setProgressValue(0);
1103 logger->show();
1104 logger->addItem(tr("Installing Rockbox Utility"), LOGINFO);
1106 // check mountpoint
1107 if(!QFileInfo(RbSettings::value(RbSettings::Mountpoint).toString()).isDir()) {
1108 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
1109 logger->setFinished();
1110 return;
1113 // remove old files first.
1114 QFile::remove(RbSettings::value(RbSettings::Mountpoint).toString()
1115 + "/RockboxUtility.exe");
1116 QFile::remove(RbSettings::value(RbSettings::Mountpoint).toString()
1117 + "/RockboxUtility.ini");
1118 // copy currently running binary and currently used settings file
1119 if(!QFile::copy(qApp->applicationFilePath(),
1120 RbSettings::value(RbSettings::Mountpoint).toString()
1121 + "/RockboxUtility.exe")) {
1122 logger->addItem(tr("Error installing Rockbox Utility"), LOGERROR);
1123 logger->setFinished();
1124 return;
1126 logger->addItem(tr("Installing user configuration"), LOGINFO);
1127 if(!QFile::copy(RbSettings::userSettingFilename(),
1128 RbSettings::value(RbSettings::Mountpoint).toString()
1129 + "/RockboxUtility.ini")) {
1130 logger->addItem(tr("Error installing user configuration"), LOGERROR);
1131 logger->setFinished();
1132 return;
1134 logger->addItem(tr("Successfully installed Rockbox Utility."), LOGOK);
1135 logger->setFinished();
1136 logger->setProgressMax(1);
1137 logger->setProgressValue(1);
1142 void RbUtilQt::updateInfo()
1144 qDebug() << "[RbUtil] updating server info";
1146 QSettings log(RbSettings::value(RbSettings::Mountpoint).toString()
1147 + "/.rockbox/rbutil.log", QSettings::IniFormat, this);
1148 QStringList groups = log.childGroups();
1149 QList<QTreeWidgetItem *> items;
1150 QTreeWidgetItem *w, *w2;
1151 QString min, max;
1152 int olditems = 0;
1154 // remove old list entries (if any)
1155 int l = ui.treeInfo->topLevelItemCount();
1156 while(l--) {
1157 QTreeWidgetItem *m;
1158 m = ui.treeInfo->takeTopLevelItem(l);
1159 // delete childs (single level deep, no recursion here)
1160 int n = m->childCount();
1161 while(n--)
1162 delete m->child(n);
1164 // get and populate new items
1165 for(int a = 0; a < groups.size(); a++) {
1166 log.beginGroup(groups.at(a));
1167 QStringList keys = log.allKeys();
1168 w = new QTreeWidgetItem;
1169 w->setFlags(Qt::ItemIsEnabled);
1170 w->setText(0, groups.at(a));
1171 items.append(w);
1172 // get minimum and maximum version information so we can hilight old files
1173 min = max = log.value(keys.at(0)).toString();
1174 for(int b = 0; b < keys.size(); b++) {
1175 if(log.value(keys.at(b)).toString() > max)
1176 max = log.value(keys.at(b)).toString();
1177 if(log.value(keys.at(b)).toString() < min)
1178 min = log.value(keys.at(b)).toString();
1181 for(int b = 0; b < keys.size(); b++) {
1182 QString file;
1183 file = RbSettings::value(RbSettings::Mountpoint).toString() + "/" + keys.at(b);
1184 if(QFileInfo(file).isDir())
1185 continue;
1186 w2 = new QTreeWidgetItem(w, QStringList() << "/"
1187 + keys.at(b) << log.value(keys.at(b)).toString());
1188 if(log.value(keys.at(b)).toString() != max) {
1189 w2->setForeground(0, QBrush(QColor(255, 0, 0)));
1190 w2->setForeground(1, QBrush(QColor(255, 0, 0)));
1191 olditems++;
1193 items.append(w2);
1195 log.endGroup();
1196 if(min != max)
1197 w->setData(1, Qt::DisplayRole, QString("%1 / %2").arg(min, max));
1198 else
1199 w->setData(1, Qt::DisplayRole, max);
1201 ui.treeInfo->insertTopLevelItems(0, items);
1202 ui.treeInfo->resizeColumnToContents(0);
1206 QUrl RbUtilQt::proxy()
1208 if(RbSettings::value(RbSettings::ProxyType) == "manual")
1209 return QUrl(RbSettings::value(RbSettings::Proxy).toString());
1210 else if(RbSettings::value(RbSettings::ProxyType) == "system")
1211 return System::systemProxy();
1212 return QUrl("");
1216 bool RbUtilQt::chkConfig(bool warn)
1218 bool error = false;
1219 if(RbSettings::value(RbSettings::Platform).toString().isEmpty()
1220 || RbSettings::value(RbSettings::Mountpoint).toString().isEmpty()
1221 || !QFileInfo(RbSettings::value(RbSettings::Mountpoint).toString()).isWritable()) {
1222 error = true;
1224 if(warn) QMessageBox::critical(this, tr("Configuration error"),
1225 tr("Your configuration is invalid. Please go to the configuration "
1226 "dialog and make sure the selected values are correct."));
1228 return error;
1231 void RbUtilQt::checkUpdate(void)
1233 QString url = SystemInfo::value(SystemInfo::RbutilUrl).toString();
1234 #if defined(Q_OS_WIN32)
1235 url += "win32/";
1236 #elif defined(Q_OS_LINUX)
1237 url += "linux/";
1238 #elif defined(Q_OS_MACX)
1239 url += "macosx/";
1240 #endif
1242 update = new HttpGet(this);
1243 connect(update, SIGNAL(done(bool)), this, SLOT(downloadUpdateDone(bool)));
1244 connect(update, SIGNAL(requestFinished(int, bool)), this, SLOT(downloadDone(int, bool)));
1245 connect(qApp, SIGNAL(lastWindowClosed()), update, SLOT(abort()));
1246 if(RbSettings::value(RbSettings::CacheOffline).toBool())
1247 update->setCache(true);
1249 update->getFile(QUrl(url));
1252 void RbUtilQt::downloadUpdateDone(bool error)
1254 if(error) {
1255 qDebug() << "[RbUtil] network error:" << update->error();
1257 else {
1258 QString toParse(update->readAll());
1260 QRegExp searchString("<a[^>]*>(rbutilqt[^<]*)</a>");
1261 QStringList rbutilList;
1262 int pos = 0;
1263 while ((pos = searchString.indexIn(toParse, pos)) != -1)
1265 rbutilList << searchString.cap(1);
1266 pos += searchString.matchedLength();
1268 qDebug() << "[Checkupdate] " << rbutilList;
1270 QString newVersion ="";
1271 //check if there is a binary with higher version in this list
1272 for(int i=0; i < rbutilList.size(); i++)
1274 #if defined(Q_OS_LINUX)
1275 #if defined(__amd64__)
1276 //skip if it isnt a 64bit build
1277 if( !rbutilList.at(i).contains("64bit"))
1278 continue;
1279 #else
1280 //skip if it is a 64bit build
1281 if(rbutilList.at(i).contains("64bit"))
1282 continue;
1283 #endif
1284 #endif
1285 //check if it is newer, and remember newest
1286 if(newerVersion(VERSION,rbutilList.at(i)))
1288 if(newVersion == "" || newerVersion(newVersion,rbutilList.at(i)))
1290 newVersion = rbutilList.at(i);
1295 // if we found something newer, display info
1296 if(newVersion != "")
1298 QString url = SystemInfo::value(SystemInfo::RbutilUrl).toString();
1299 #if defined(Q_OS_WIN32)
1300 url += "win32/";
1301 #elif defined(Q_OS_LINUX)
1302 url += "linux/";
1303 #elif defined(Q_OS_MACX)
1304 url += "macosx/";
1305 #endif
1306 url += newVersion;
1308 QMessageBox::information(this,tr("RockboxUtility Update available"),
1309 tr("<b>New RockboxUtility Version available.</b> <br><br>"
1310 "Download it from here: <a href='%1'>%2</a>").arg(url).arg(newVersion) );
1315 bool RbUtilQt::newerVersion(QString versionOld,QString versionNew)
1317 QRegExp chars("\\d*(\\D)");
1319 //strip non-number from beginning
1320 versionOld = versionOld.remove(0,versionOld.indexOf(QRegExp("\\d")));
1321 versionNew = versionNew.remove(0,versionNew.indexOf(QRegExp("\\d")));
1323 // split versions by "."
1324 QStringList versionListOld = versionOld.split(".");
1325 QStringList versionListNew = versionNew.split(".");
1327 QStringListIterator iteratorOld(versionListOld);
1328 QStringListIterator iteratorNew(versionListNew);
1330 //check every section
1331 while(iteratorOld.hasNext() && iteratorNew.hasNext())
1333 QString newPart = iteratorNew.next();
1334 QString oldPart = iteratorOld.next();
1335 QString newPartChar = "", oldPartChar = "";
1336 int newPartInt = 0, oldPartInt =0;
1338 //convert to int, if it contains chars, put into seperated variable
1339 if(newPart.contains(chars))
1341 newPartChar = chars.cap(1);
1342 newPart = newPart.remove(newPartChar);
1344 newPartInt = newPart.toInt();
1345 //convert to int, if it contains chars, put into seperated variable
1346 if(oldPart.contains(chars))
1348 oldPartChar = chars.cap(1);
1349 oldPart = oldPart.remove(oldPartChar);
1351 oldPartInt = oldPart.toInt();
1353 if(newPartInt > oldPartInt) // this section int is higher -> true
1354 return true;
1355 else if(newPartInt < oldPartInt) //this section int is lower -> false
1356 return false;
1357 else if(newPartChar > oldPartChar) //ints are the same, chars is higher -> true
1358 return true;
1359 else if(newPartChar < oldPartChar) //ints are the same, chars is lower -> false
1360 return false;
1361 //all the same, next section
1363 // all the same -> false
1364 return false;