FS#10728 - Cowon D2: Add support for D2 in rbutil
[kugel-rb.git] / rbutil / rbutilqt / rbutilqt.cpp
blobfd5983306d0ece343eb7ebb1f7420abe457cd21c
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 // disable quick install until version info is available
93 ui.buttonSmall->setEnabled(false);
94 ui.buttonComplete->setEnabled(false);
96 connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(updateTabs(int)));
97 connect(ui.actionAbout_Qt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
98 connect(ui.action_About, SIGNAL(triggered()), this, SLOT(about()));
99 connect(ui.action_Help, SIGNAL(triggered()), this, SLOT(help()));
100 connect(ui.action_Configure, SIGNAL(triggered()), this, SLOT(configDialog()));
101 connect(ui.buttonChangeDevice, SIGNAL(clicked()), this, SLOT(configDialog()));
102 connect(ui.buttonRockbox, SIGNAL(clicked()), this, SLOT(installBtn()));
103 connect(ui.buttonBootloader, SIGNAL(clicked()), this, SLOT(installBootloaderBtn()));
104 connect(ui.buttonFonts, SIGNAL(clicked()), this, SLOT(installFontsBtn()));
105 connect(ui.buttonGames, SIGNAL(clicked()), this, SLOT(installDoomBtn()));
106 connect(ui.buttonTalk, SIGNAL(clicked()), this, SLOT(createTalkFiles()));
107 connect(ui.buttonCreateVoice, SIGNAL(clicked()), this, SLOT(createVoiceFile()));
108 connect(ui.buttonVoice, SIGNAL(clicked()), this, SLOT(installVoice()));
109 connect(ui.buttonThemes, SIGNAL(clicked()), this, SLOT(installThemes()));
110 connect(ui.buttonRemoveRockbox, SIGNAL(clicked()), this, SLOT(uninstall()));
111 connect(ui.buttonRemoveBootloader, SIGNAL(clicked()), this, SLOT(uninstallBootloader()));
112 connect(ui.buttonDownloadManual, SIGNAL(clicked()), this, SLOT(downloadManual()));
113 connect(ui.buttonSmall, SIGNAL(clicked()), this, SLOT(smallInstall()));
114 connect(ui.buttonComplete, SIGNAL(clicked()), this, SLOT(completeInstall()));
116 // actions accessible from the menu
117 connect(ui.actionComplete_Installation, SIGNAL(triggered()), this, SLOT(completeInstall()));
118 connect(ui.actionSmall_Installation, SIGNAL(triggered()), this, SLOT(smallInstall()));
119 connect(ui.actionInstall_Bootloader, SIGNAL(triggered()), this, SLOT(installBootloaderBtn()));
120 connect(ui.actionInstall_Rockbox, SIGNAL(triggered()), this, SLOT(installBtn()));
121 connect(ui.actionFonts_Package, SIGNAL(triggered()), this, SLOT(installFontsBtn()));
122 connect(ui.actionInstall_Themes, SIGNAL(triggered()), this, SLOT(installThemes()));
123 connect(ui.actionInstall_Game_Files, SIGNAL(triggered()), this, SLOT(installDoomBtn()));
124 connect(ui.actionInstall_Voice_File, SIGNAL(triggered()), this, SLOT(installVoice()));
125 connect(ui.actionCreate_Voice_File, SIGNAL(triggered()), this, SLOT(createVoiceFile()));
126 connect(ui.actionCreate_Talk_Files, SIGNAL(triggered()), this, SLOT(createTalkFiles()));
127 connect(ui.actionRemove_bootloader, SIGNAL(triggered()), this, SLOT(uninstallBootloader()));
128 connect(ui.actionUninstall_Rockbox, SIGNAL(triggered()), this, SLOT(uninstall()));
129 connect(ui.action_System_Info, SIGNAL(triggered()), this, SLOT(sysinfo()));
130 connect(ui.action_Trace, SIGNAL(triggered()), this, SLOT(trace()));
132 #if !defined(STATIC)
133 ui.actionInstall_Rockbox_Utility_on_player->setEnabled(false);
134 #else
135 connect(ui.actionInstall_Rockbox_Utility_on_player, SIGNAL(triggered()), this, SLOT(installPortable()));
136 #endif
141 void RbUtilQt::trace(void)
143 SysTrace wnd(this);
144 wnd.exec();
147 void RbUtilQt::sysinfo(void)
149 Sysinfo info(this);
150 info.exec();
153 void RbUtilQt::updateTabs(int count)
155 switch(count) {
156 case 6:
157 updateInfo();
158 break;
159 default:
160 break;
165 void RbUtilQt::downloadInfo()
167 // make sure the version map is repopulated correctly later.
168 versmap.clear();
169 // try to get the current build information
170 daily = new HttpGet(this);
171 connect(daily, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
172 connect(daily, SIGNAL(requestFinished(int, bool)), this, SLOT(downloadDone(int, bool)));
173 connect(qApp, SIGNAL(lastWindowClosed()), daily, SLOT(abort()));
174 if(RbSettings::value(RbSettings::CacheOffline).toBool())
175 daily->setCache(true);
176 else
177 daily->setCache(false);
178 ui.statusbar->showMessage(tr("Downloading build information, please wait ..."));
179 qDebug() << "[RbUtil] downloading build info";
180 daily->setFile(&buildInfo);
181 daily->getFile(QUrl(RbSettings::value(RbSettings::ServerConfUrl).toString()));
185 void RbUtilQt::downloadDone(bool error)
187 if(error) {
188 qDebug() << "[RbUtil] network error:" << daily->error();
189 ui.statusbar->showMessage(tr("Can't get version information!"));
190 QMessageBox::critical(this, tr("Network error"),
191 tr("Can't get version information."));
192 return;
194 qDebug() << "[RbUtil] network status:" << daily->error();
196 buildInfo.open();
197 QSettings info(buildInfo.fileName(), QSettings::IniFormat, this);
198 buildInfo.close();
199 versmap.insert("arch_rev", info.value("dailies/rev").toString());
200 versmap.insert("arch_date", info.value("dailies/date").toString());
202 info.beginGroup("release");
203 versmap.insert("rel_rev", info.value(RbSettings::value(RbSettings::CurBuildserverModel).toString()).toString());
204 info.endGroup();
206 if(versmap.value("rel_rev").isEmpty()) {
207 ui.buttonSmall->setEnabled(false);
208 ui.buttonComplete->setEnabled(false);
210 else {
211 ui.buttonSmall->setEnabled(true);
212 ui.buttonComplete->setEnabled(true);
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(RbSettings::value(RbSettings::BleedingInfo).toString()));
223 ui.statusbar->showMessage(tr("Downloading build information, please wait ..."));
225 if(RbSettings::value(RbSettings::RbutilVersion) != PUREVERSION) {
226 QApplication::processEvents();
227 QMessageBox::information(this, tr("New installation"),
228 tr("This is a new installation of Rockbox Utility, or a new version. "
229 "The configuration dialog will now open to allow you to setup the program, "
230 " or review your settings."));
231 configDialog();
233 else if(chkConfig(false)) {
234 QApplication::processEvents();
235 QMessageBox::critical(this, tr("Configuration error"),
236 tr("Your configuration is invalid. This is most likely due "
237 "to a changed device path. The configuration dialog will "
238 "now open to allow you to correct the problem."));
239 configDialog();
244 void RbUtilQt::downloadBleedingDone(bool error)
246 if(error) {
247 qDebug() << "[RbUtil] network error:" << bleeding->error();
249 else {
250 bleedingInfo.open();
251 QSettings info(bleedingInfo.fileName(), QSettings::IniFormat, this);
252 bleedingInfo.close();
253 versmap.insert("bleed_rev", info.value("bleeding/rev").toString());
254 versmap.insert("bleed_date", info.value("bleeding/timestamp").toString());
255 qDebug() << "[RbUtil] version map:" << versmap;
256 ui.statusbar->showMessage(tr("Download build information finished."), 5000);
258 m_gotInfo = true;
260 //start check for updates
261 checkUpdate();
266 void RbUtilQt::downloadDone(int id, bool error)
268 QString errorString;
269 errorString = tr("Network error: %1. Please check your network and proxy settings.")
270 .arg(daily->errorString());
271 if(error) {
272 QMessageBox::about(this, "Network Error", errorString);
273 m_networkerror = daily->errorString();
275 qDebug() << "[RbUtil] downloadDone:" << id << "error:" << error;
279 void RbUtilQt::about()
281 QDialog *window = new QDialog(this);
282 Ui::aboutBox about;
283 about.setupUi(window);
284 window->setModal(true);
286 QFile licence(":/docs/gpl-2.0.html");
287 licence.open(QIODevice::ReadOnly);
288 QTextStream c(&licence);
289 QString cline = c.readAll();
290 about.browserLicense->insertHtml(cline);
291 about.browserLicense->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
292 QFile credits(":/docs/CREDITS");
293 credits.open(QIODevice::ReadOnly);
294 QTextStream r(&credits);
295 r.setCodec(QTextCodec::codecForName("UTF-8"));
296 QString rline = r.readAll();
297 about.browserCredits->insertPlainText(rline);
298 about.browserCredits->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
299 QString title = QString("<b>The Rockbox Utility</b><br/>Version %1").arg(FULLVERSION);
300 about.labelTitle->setText(title);
302 window->show();
307 void RbUtilQt::help()
309 QUrl helpurl("http://www.rockbox.org/wiki/RockboxUtility");
310 QDesktopServices::openUrl(helpurl);
314 void RbUtilQt::configDialog()
316 Config *cw = new Config(this);
317 connect(cw, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
318 connect(cw, SIGNAL(settingsUpdated()), this, SLOT(downloadInfo()));
319 cw->show();
323 void RbUtilQt::updateSettings()
325 qDebug() << "[RbUtil] updating current settings";
326 updateDevice();
327 updateManual();
328 if(RbSettings::value(RbSettings::ProxyType) == "system") {
329 HttpGet::setGlobalProxy(System::systemProxy());
331 else if(RbSettings::value(RbSettings::ProxyType) == "manual") {
332 HttpGet::setGlobalProxy(RbSettings::value(RbSettings::Proxy).toString());
334 else {
335 HttpGet::setGlobalProxy(QUrl(""));
337 HttpGet::setGlobalCache(RbSettings::value(RbSettings::CachePath).toString());
338 HttpGet::setGlobalDumbCache(RbSettings::value(RbSettings::CacheOffline).toBool());
342 void RbUtilQt::updateDevice()
344 if(RbSettings::value(RbSettings::CurBootloaderMethod) == "none" ) {
345 ui.buttonBootloader->setEnabled(false);
346 ui.buttonRemoveBootloader->setEnabled(false);
347 ui.labelBootloader->setEnabled(false);
348 ui.labelRemoveBootloader->setEnabled(false);
350 else {
351 ui.buttonBootloader->setEnabled(true);
352 ui.labelBootloader->setEnabled(true);
353 if(RbSettings::value(RbSettings::CurBootloaderMethod) == "fwpatcher") {
354 ui.labelRemoveBootloader->setEnabled(false);
355 ui.buttonRemoveBootloader->setEnabled(false);
357 else {
358 ui.labelRemoveBootloader->setEnabled(true);
359 ui.buttonRemoveBootloader->setEnabled(true);
363 // displayed device info
364 QString mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
365 QString brand = RbSettings::value(RbSettings::CurBrand).toString();
366 QString name = RbSettings::value(RbSettings::CurName).toString();
367 if(name.isEmpty()) name = "&lt;none&gt;";
368 if(mountpoint.isEmpty()) mountpoint = "&lt;invalid&gt;";
369 ui.labelDevice->setText(tr("<b>%1 %2</b> at <b>%3</b>")
370 .arg(brand, name, QDir::toNativeSeparators(mountpoint)));
374 void RbUtilQt::updateManual()
376 if(RbSettings::value(RbSettings::Platform) != "")
378 QString manual= RbSettings::value(RbSettings::CurManual).toString();
380 if(manual == "")
381 manual = "rockbox-" + RbSettings::value(RbSettings::Platform).toString();
382 QString pdfmanual;
383 pdfmanual = RbSettings::value(RbSettings::ManualUrl).toString()
384 + "/" + manual + ".pdf";
385 QString htmlmanual;
386 htmlmanual = RbSettings::value(RbSettings::ManualUrl).toString()
387 + "/" + manual + "/rockbox-build.html";
388 ui.labelPdfManual->setText(tr("<a href='%1'>PDF Manual</a>")
389 .arg(pdfmanual));
390 ui.labelHtmlManual->setText(tr("<a href='%1'>HTML Manual (opens in browser)</a>")
391 .arg(htmlmanual));
393 else {
394 ui.labelPdfManual->setText(tr("Select a device for a link to the correct manual"));
395 ui.labelHtmlManual->setText(tr("<a href='%1'>Manual Overview</a>")
396 .arg("http://www.rockbox.org/manual.shtml"));
401 void RbUtilQt::completeInstall()
403 if(chkConfig(true)) return;
404 if(QMessageBox::question(this, tr("Confirm Installation"),
405 tr("Do you really want to perform a complete installation?\n\n"
406 "This will install Rockbox %1. To install the most recent "
407 "development build available press \"Cancel\" and "
408 "use the \"Installation\" tab.")
409 .arg(versmap.value("rel_rev")),
410 QMessageBox::Ok | QMessageBox::Cancel) != QMessageBox::Ok)
411 return;
412 // create logger
413 logger = new ProgressLoggerGui(this);
414 logger->show();
416 if(smallInstallInner())
417 return;
418 logger->setRunning();
419 // Fonts
420 m_error = false;
421 m_installed = false;
422 if(!installFontsAuto())
423 return;
424 else
426 // wait for installation finished
427 while(!m_installed)
428 QApplication::processEvents();
430 if(m_error) return;
431 logger->setRunning();
433 // Doom
434 if(hasDoom())
436 m_error = false;
437 m_installed = false;
438 if(!installDoomAuto())
439 return;
440 else
442 // wait for installation finished
443 while(!m_installed)
444 QApplication::processEvents();
446 if(m_error) return;
449 // theme
450 // this is a window
451 // it has its own logger window,so close our.
452 logger->close();
453 installThemes();
457 void RbUtilQt::smallInstall()
459 if(chkConfig(true)) return;
460 if(QMessageBox::question(this, tr("Confirm Installation"),
461 tr("Do you really want to perform a minimal installation? "
462 "A minimal installation will contain only the absolutely "
463 "necessary parts to run Rockbox.\n\n"
464 "This will install Rockbox %1. To install the most recent "
465 "development build available press \"Cancel\" and "
466 "use the \"Installation\" tab.")
467 .arg(versmap.value("rel_rev")),
468 QMessageBox::Ok | QMessageBox::Cancel) != QMessageBox::Ok)
469 return;
471 // create logger
472 logger = new ProgressLoggerGui(this);
473 logger->show();
475 smallInstallInner();
478 bool RbUtilQt::smallInstallInner()
480 QString mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
481 // show dialog with error if mount point is wrong
482 if(!QFileInfo(mountpoint).isDir()) {
483 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
484 logger->setFinished();
485 return true;
487 // Bootloader
488 if(RbSettings::value(RbSettings::CurBootloaderMethod) != "none")
490 m_error = false;
491 m_installed = false;
492 m_auto = true;
493 if(!installBootloaderAuto()) {
494 logger->setFinished();
495 return true;
497 else
499 // wait for boot loader installation finished
500 while(!m_installed)
501 QApplication::processEvents();
503 m_auto = false;
504 if(m_error) return true;
505 logger->setRunning();
508 // Rockbox
509 m_error = false;
510 m_installed = false;
511 if(!installAuto())
512 return true;
513 else
515 // wait for installation finished
516 while(!m_installed)
517 QApplication::processEvents();
520 installBootloaderPost(false);
521 return false;
524 void RbUtilQt::installdone(bool error)
526 qDebug() << "[RbUtil] install done";
527 m_installed = true;
528 m_error = error;
531 void RbUtilQt::installBtn()
533 if(chkConfig(true)) return;
534 install();
537 bool RbUtilQt::installAuto()
539 QString file = RbSettings::value(RbSettings::ReleaseUrl).toString();
540 file.replace("%MODEL%", RbSettings::value(RbSettings::CurBuildserverModel).toString());
541 file.replace("%RELVERSION%", versmap.value("rel_rev"));
542 buildInfo.open();
543 QSettings info(buildInfo.fileName(), QSettings::IniFormat, this);
544 buildInfo.close();
546 // check installed Version and Target
547 QString warning = check(false);
548 if(!warning.isEmpty())
550 if(QMessageBox::warning(this, tr("Really continue?"), warning,
551 QMessageBox::Ok | QMessageBox::Abort, QMessageBox::Abort)
552 == QMessageBox::Abort)
554 logger->addItem(tr("Aborted!"), LOGERROR);
555 logger->setFinished();
556 return false;
560 // check version
561 RockboxInfo rbinfo(RbSettings::value(RbSettings::Mountpoint).toString());
562 if(rbinfo.version() != "")
564 if(QMessageBox::question(this, tr("Installed Rockbox detected"),
565 tr("Rockbox installation detected. Do you want to backup first?"),
566 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
568 logger->addItem(tr("Starting backup..."),LOGINFO);
569 QString backupName = RbSettings::value(RbSettings::Mountpoint).toString()
570 + "/.backup/rockbox-backup-" + rbinfo.version() + ".zip";
572 //! create dir, if it doesnt exist
573 QFileInfo backupFile(backupName);
574 if(!QDir(backupFile.path()).exists())
576 QDir a;
577 a.mkpath(backupFile.path());
580 //! create backup
581 RbZip backup;
582 connect(&backup,SIGNAL(zipProgress(int,int)),logger, SLOT(setProgress(int,int)));
583 if(backup.createZip(backupName,
584 RbSettings::value(RbSettings::Mountpoint).toString() + "/.rockbox") == Zip::Ok)
586 logger->addItem(tr("Backup successful"),LOGOK);
588 else
590 logger->addItem(tr("Backup failed!"),LOGERROR);
591 logger->setFinished();
592 return false;
597 //! install current build
598 ZipInstaller* installer = new ZipInstaller(this);
599 installer->setUrl(file);
600 installer->setLogSection("Rockbox (Base)");
601 installer->setLogVersion(versmap.value("rel_rev"));
602 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
603 installer->setCache(true);
604 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
606 connect(installer, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
607 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
608 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
609 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
610 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
611 installer->install();
612 return true;
616 void RbUtilQt::install()
618 Install *installWindow = new Install(this);
620 buildInfo.open();
621 QSettings info(buildInfo.fileName(), QSettings::IniFormat, this);
622 buildInfo.close();
623 installWindow->setVersionStrings(versmap);
625 installWindow->show();
628 bool RbUtilQt::installBootloaderAuto()
630 installBootloader();
631 return !m_error;
634 void RbUtilQt::installBootloaderBtn()
636 if(chkConfig(true)) return;
637 if(QMessageBox::question(this, tr("Confirm Installation"),
638 tr("Do you really want to install the Bootloader?"),
639 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
641 // create logger
642 logger = new ProgressLoggerGui(this);
643 logger->show();
644 installBootloader();
647 void RbUtilQt::installBootloader()
649 QString platform = RbSettings::value(RbSettings::Platform).toString();
650 QString backupDestination = "";
651 m_error = false;
653 // create installer
654 BootloaderInstallBase *bl;
655 QString type = RbSettings::value(RbSettings::CurBootloaderMethod).toString();
656 if(type == "mi4") {
657 bl = new BootloaderInstallMi4(this);
659 else if(type == "hex") {
660 bl = new BootloaderInstallHex(this);
662 else if(type == "sansa") {
663 bl = new BootloaderInstallSansa(this);
665 else if(type == "ipod") {
666 bl = new BootloaderInstallIpod(this);
668 else if(type == "file") {
669 bl = new BootloaderInstallFile(this);
671 else if(type == "chinachip") {
672 bl = new BootloaderInstallChinaChip(this);
674 else if(type == "ams") {
675 bl = new BootloaderInstallAms(this);
677 else if(type == "tcc") {
678 bl = new BootloaderInstallTcc(this);
680 else {
681 logger->addItem(tr("No install method known."), LOGERROR);
682 logger->setFinished();
683 return;
686 // set bootloader filename. Do this now as installed() needs it.
687 QStringList blfile = RbSettings::value(RbSettings::CurBootloaderFile).toStringList();
688 QStringList blfilepath;
689 for(int a = 0; a < blfile.size(); a++) {
690 blfilepath.append(RbSettings::value(RbSettings::Mountpoint).toString()
691 + blfile.at(a));
693 bl->setBlFile(blfilepath);
694 QUrl url(RbSettings::value(RbSettings::BootloaderUrl).toString()
695 + RbSettings::value(RbSettings::CurBootloaderName).toString());
696 bl->setBlUrl(url);
697 bl->setLogfile(RbSettings::value(RbSettings::Mountpoint).toString()
698 + "/.rockbox/rbutil.log");
700 if(bl->installed() == BootloaderInstallBase::BootloaderRockbox) {
701 if(QMessageBox::question(this, tr("Bootloader detected"),
702 tr("Bootloader already installed. Do you want to reinstall the bootloader?"),
703 QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
704 if(m_auto) {
705 // keep logger open for auto installs.
706 // don't consider abort as error in auto-mode.
707 logger->addItem(tr("Bootloader installation skipped"), LOGINFO);
708 installBootloaderPost(false);
710 else {
711 logger->close();
712 installBootloaderPost(true);
714 delete bl;
715 return;
718 else if(bl->installed() == BootloaderInstallBase::BootloaderOther
719 && bl->capabilities() & BootloaderInstallBase::Backup)
721 QString targetFolder = RbSettings::value(RbSettings::CurPlatformName).toString()
722 + " Firmware Backup";
723 // remove invalid character(s)
724 targetFolder.remove(QRegExp("[:/]"));
725 if(QMessageBox::question(this, tr("Create Bootloader backup"),
726 tr("You can create a backup of the original bootloader "
727 "file. Press \"Yes\" to select an output folder on your "
728 "computer to save the file to. The file will get placed "
729 "in a new folder \"%1\" created below the selected folder.\n"
730 "Press \"No\" to skip this step.").arg(targetFolder),
731 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
732 BrowseDirtree tree(this, tr("Browse backup folder"));
733 tree.setDir(QDir::home());
734 tree.exec();
736 backupDestination = tree.getSelected() + "/" + targetFolder;
737 qDebug() << "[RbUtil] backing up to" << backupDestination;
738 // backup needs to be done after the logger has been set up.
742 if(bl->capabilities() & BootloaderInstallBase::NeedsOf)
744 int ret;
745 ret = QMessageBox::information(this, tr("Prerequisites"),
746 bl->ofHint(),QMessageBox::Ok | QMessageBox::Abort);
747 if(ret != QMessageBox::Ok) {
748 // consider aborting an error to close window / abort automatic
749 // installation.
750 m_error = true;
751 logger->addItem(tr("Bootloader installation aborted"), LOGINFO);
752 logger->setFinished();
753 return;
755 // open dialog to browse to of file
756 QString offile;
757 offile = QFileDialog::getOpenFileName(this,
758 tr("Select firmware file"), QDir::homePath());
759 if(!QFileInfo(offile).isReadable()) {
760 logger->addItem(tr("Error opening firmware file"), LOGERROR);
761 logger->setFinished();
762 m_error = true;
763 return;
765 bl->setOfFile(offile);
768 // the bootloader install class does NOT use any GUI stuff.
769 // All messages are passed via signals.
770 connect(bl, SIGNAL(done(bool)), logger, SLOT(setFinished()));
771 connect(bl, SIGNAL(done(bool)), this, SLOT(installBootloaderPost(bool)));
772 connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
773 connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
775 // start install.
776 if(!backupDestination.isEmpty()) {
777 if(!bl->backup(backupDestination)) {
778 if(QMessageBox::warning(this, tr("Backup error"),
779 tr("Could not create backup file. Continue?"),
780 QMessageBox::No | QMessageBox::Yes)
781 == QMessageBox::No) {
782 logger->setFinished();
783 return;
787 bl->install();
790 void RbUtilQt::installBootloaderPost(bool error)
792 qDebug() << "[RbUtil] Bootloader Post-Installation, error state:" << error;
793 // if an error occured don't perform post install steps.
794 if(error) {
795 m_error = true;
796 return;
798 else
799 m_error = false;
801 m_installed = true;
802 // end here if automated install
803 if(m_auto)
804 return;
806 QString msg = BootloaderInstallBase::postinstallHints(
807 RbSettings::value(RbSettings::Platform).toString());
808 if(!msg.isEmpty()) {
809 QMessageBox::information(this, tr("Manual steps required"), msg);
810 logger->close();
815 void RbUtilQt::installFontsBtn()
817 if(chkConfig(true)) return;
818 if(QMessageBox::question(this, tr("Confirm Installation"),
819 tr("Do you really want to install the fonts package?"),
820 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
821 // create logger
822 logger = new ProgressLoggerGui(this);
823 logger->show();
824 installFonts();
827 bool RbUtilQt::installFontsAuto()
829 installFonts();
831 return !m_error;
834 void RbUtilQt::installFonts()
836 // create zip installer
837 installer = new ZipInstaller(this);
839 installer->setUrl(RbSettings::value(RbSettings::FontUrl).toString());
840 installer->setLogSection("Fonts");
841 installer->setLogVersion(versmap.value("arch_date"));
842 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
843 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
844 installer->setCache(true);
846 connect(installer, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
847 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
848 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
849 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
850 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
851 installer->install();
855 void RbUtilQt::installVoice()
857 if(chkConfig(true)) return;
859 if(m_gotInfo == false)
861 QMessageBox::warning(this, tr("Warning"),
862 tr("The Application is still downloading Information about new Builds."
863 " Please try again shortly."));
864 return;
867 if(QMessageBox::question(this, tr("Confirm Installation"),
868 tr("Do you really want to install the voice file?"),
869 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
870 // create logger
871 logger = new ProgressLoggerGui(this);
872 logger->show();
874 // create zip installer
875 installer = new ZipInstaller(this);
877 QString voiceurl = RbSettings::value(RbSettings::VoiceUrl).toString();
879 voiceurl += RbSettings::value(RbSettings::CurBuildserverModel).toString() + "-" +
880 versmap.value("arch_date") + "-english.zip";
881 qDebug() << "[RbUtil] voicefile URL:" << voiceurl;
883 installer->setUrl(voiceurl);
884 installer->setLogSection("Voice");
885 installer->setLogVersion(versmap.value("arch_date"));
886 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
887 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
888 installer->setCache(true);
889 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
890 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
891 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
892 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
893 installer->install();
897 void RbUtilQt::installDoomBtn()
899 if(chkConfig(true)) return;
900 if(!hasDoom()){
901 QMessageBox::critical(this, tr("Error"),
902 tr("Your device doesn't have a doom plugin. Aborting."));
903 return;
906 if(QMessageBox::question(this, tr("Confirm Installation"),
907 tr("Do you really want to install the game addon files?"),
908 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
909 // create logger
910 logger = new ProgressLoggerGui(this);
911 logger->show();
913 installDoom();
915 bool RbUtilQt::installDoomAuto()
917 installDoom();
918 return !m_error;
921 bool RbUtilQt::hasDoom()
923 QFile doomrock(RbSettings::value(RbSettings::Mountpoint).toString()
924 +"/.rockbox/rocks/games/doom.rock");
925 return doomrock.exists();
928 void RbUtilQt::installDoom()
930 // create zip installer
931 installer = new ZipInstaller(this);
933 installer->setUrl(RbSettings::value(RbSettings::DoomUrl).toString());
934 installer->setLogSection("Game Addons");
935 installer->setLogVersion(versmap.value("arch_date"));
936 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
937 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
938 installer->setCache(true);
939 connect(installer, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
940 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
941 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
942 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
943 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
944 installer->install();
948 void RbUtilQt::installThemes()
950 if(chkConfig(true)) return;
951 ThemesInstallWindow* tw = new ThemesInstallWindow(this);
952 tw->setModal(true);
953 tw->show();
956 void RbUtilQt::createTalkFiles(void)
958 if(chkConfig(true)) return;
959 InstallTalkWindow *installWindow = new InstallTalkWindow(this);
961 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(downloadInfo()));
962 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
963 installWindow->show();
967 void RbUtilQt::createVoiceFile(void)
969 if(chkConfig(true)) return;
970 CreateVoiceWindow *installWindow = new CreateVoiceWindow(this);
972 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(downloadInfo()));
973 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
974 installWindow->show();
977 void RbUtilQt::uninstall(void)
979 if(chkConfig(true)) return;
980 UninstallWindow *uninstallWindow = new UninstallWindow(this);
981 uninstallWindow->show();
985 void RbUtilQt::uninstallBootloader(void)
987 if(chkConfig(true)) return;
988 if(QMessageBox::question(this, tr("Confirm Uninstallation"),
989 tr("Do you really want to uninstall the Bootloader?"),
990 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
991 // create logger
992 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
993 logger->setProgressVisible(false);
994 logger->show();
996 QString platform = RbSettings::value(RbSettings::Platform).toString();
998 // create installer
999 BootloaderInstallBase *bl;
1000 QString type = RbSettings::value(RbSettings::CurBootloaderMethod).toString();
1001 if(type == "mi4") {
1002 bl = new BootloaderInstallMi4(this);
1004 else if(type == "hex") {
1005 bl = new BootloaderInstallHex(this);
1007 else if(type == "sansa") {
1008 bl = new BootloaderInstallSansa(this);
1010 else if(type == "ipod") {
1011 bl = new BootloaderInstallIpod(this);
1013 else if(type == "file") {
1014 bl = new BootloaderInstallFile(this);
1016 else {
1017 logger->addItem(tr("No uninstall method known."), LOGERROR);
1018 logger->setFinished();
1019 return;
1022 QStringList blfile = RbSettings::value(RbSettings::CurBootloaderFile).toStringList();
1023 QStringList blfilepath;
1024 for(int a = 0; a < blfile.size(); a++) {
1025 blfilepath.append(RbSettings::value(RbSettings::Mountpoint).toString()
1026 + blfile.at(a));
1028 bl->setBlFile(blfilepath);
1030 connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
1031 connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
1033 int result;
1034 result = bl->uninstall();
1036 logger->setFinished();
1041 void RbUtilQt::downloadManual(void)
1043 if(chkConfig(true)) return;
1044 if(QMessageBox::question(this, tr("Confirm download"),
1045 tr("Do you really want to download the manual? The manual will be saved "
1046 "to the root folder of your player."),
1047 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
1048 return;
1050 buildInfo.open();
1051 QSettings info(buildInfo.fileName(), QSettings::IniFormat, this);
1052 buildInfo.close();
1054 QString manual = RbSettings::value(RbSettings::CurManual).toString();
1055 if(manual.isEmpty())
1056 manual = "rockbox-" + RbSettings::value(RbSettings::Platform).toString();
1058 QString date = (info.value("dailies/date").toString());
1060 QString manualurl;
1061 QString target;
1062 QString section;
1063 if(ui.radioPdf->isChecked()) {
1064 target = "/" + manual + ".pdf";
1065 section = "Manual (PDF)";
1067 else {
1068 target = "/" + manual + "-" + date + "-html.zip";
1069 section = "Manual (HTML)";
1071 manualurl = RbSettings::value(RbSettings::ManualUrl).toString() + "/" + target;
1072 qDebug() << "[RbUtil] Manual URL:" << manualurl;
1074 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
1075 logger->show();
1076 installer = new ZipInstaller(this);
1077 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
1078 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
1079 installer->setCache(true);
1080 installer->setLogSection(section);
1081 installer->setLogVersion(date);
1082 installer->setUrl(manualurl);
1083 installer->setUnzip(false);
1084 installer->setTarget(target);
1085 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
1086 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
1087 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
1088 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
1089 installer->install();
1093 void RbUtilQt::installPortable(void)
1095 if(QMessageBox::question(this, tr("Confirm installation"),
1096 tr("Do you really want to install Rockbox Utility to your player? "
1097 "After installation you can run it from the players hard drive."),
1098 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
1099 return;
1101 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
1102 logger->setProgressMax(0);
1103 logger->setProgressValue(0);
1104 logger->show();
1105 logger->addItem(tr("Installing Rockbox Utility"), LOGINFO);
1107 // check mountpoint
1108 if(!QFileInfo(RbSettings::value(RbSettings::Mountpoint).toString()).isDir()) {
1109 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
1110 logger->setFinished();
1111 return;
1114 // remove old files first.
1115 QFile::remove(RbSettings::value(RbSettings::Mountpoint).toString()
1116 + "/RockboxUtility.exe");
1117 QFile::remove(RbSettings::value(RbSettings::Mountpoint).toString()
1118 + "/RockboxUtility.ini");
1119 // copy currently running binary and currently used settings file
1120 if(!QFile::copy(qApp->applicationFilePath(),
1121 RbSettings::value(RbSettings::Mountpoint).toString()
1122 + "/RockboxUtility.exe")) {
1123 logger->addItem(tr("Error installing Rockbox Utility"), LOGERROR);
1124 logger->setFinished();
1125 return;
1127 logger->addItem(tr("Installing user configuration"), LOGINFO);
1128 if(!QFile::copy(RbSettings::userSettingFilename(),
1129 RbSettings::value(RbSettings::Mountpoint).toString()
1130 + "/RockboxUtility.ini")) {
1131 logger->addItem(tr("Error installing user configuration"), LOGERROR);
1132 logger->setFinished();
1133 return;
1135 logger->addItem(tr("Successfully installed Rockbox Utility."), LOGOK);
1136 logger->setFinished();
1137 logger->setProgressMax(1);
1138 logger->setProgressValue(1);
1143 void RbUtilQt::updateInfo()
1145 qDebug() << "[RbUtil] updating server info";
1147 QSettings log(RbSettings::value(RbSettings::Mountpoint).toString()
1148 + "/.rockbox/rbutil.log", QSettings::IniFormat, this);
1149 QStringList groups = log.childGroups();
1150 QList<QTreeWidgetItem *> items;
1151 QTreeWidgetItem *w, *w2;
1152 QString min, max;
1153 int olditems = 0;
1155 // remove old list entries (if any)
1156 int l = ui.treeInfo->topLevelItemCount();
1157 while(l--) {
1158 QTreeWidgetItem *m;
1159 m = ui.treeInfo->takeTopLevelItem(l);
1160 // delete childs (single level deep, no recursion here)
1161 int n = m->childCount();
1162 while(n--)
1163 delete m->child(n);
1165 // get and populate new items
1166 for(int a = 0; a < groups.size(); a++) {
1167 log.beginGroup(groups.at(a));
1168 QStringList keys = log.allKeys();
1169 w = new QTreeWidgetItem;
1170 w->setFlags(Qt::ItemIsEnabled);
1171 w->setText(0, groups.at(a));
1172 items.append(w);
1173 // get minimum and maximum version information so we can hilight old files
1174 min = max = log.value(keys.at(0)).toString();
1175 for(int b = 0; b < keys.size(); b++) {
1176 if(log.value(keys.at(b)).toString() > max)
1177 max = log.value(keys.at(b)).toString();
1178 if(log.value(keys.at(b)).toString() < min)
1179 min = log.value(keys.at(b)).toString();
1182 for(int b = 0; b < keys.size(); b++) {
1183 QString file;
1184 file = RbSettings::value(RbSettings::Mountpoint).toString() + "/" + keys.at(b);
1185 if(QFileInfo(file).isDir())
1186 continue;
1187 w2 = new QTreeWidgetItem(w, QStringList() << "/"
1188 + keys.at(b) << log.value(keys.at(b)).toString());
1189 if(log.value(keys.at(b)).toString() != max) {
1190 w2->setForeground(0, QBrush(QColor(255, 0, 0)));
1191 w2->setForeground(1, QBrush(QColor(255, 0, 0)));
1192 olditems++;
1194 items.append(w2);
1196 log.endGroup();
1197 if(min != max)
1198 w->setData(1, Qt::DisplayRole, QString("%1 / %2").arg(min, max));
1199 else
1200 w->setData(1, Qt::DisplayRole, max);
1202 ui.treeInfo->insertTopLevelItems(0, items);
1203 ui.treeInfo->resizeColumnToContents(0);
1207 QUrl RbUtilQt::proxy()
1209 if(RbSettings::value(RbSettings::ProxyType) == "manual")
1210 return QUrl(RbSettings::value(RbSettings::Proxy).toString());
1211 else if(RbSettings::value(RbSettings::ProxyType) == "system")
1212 return System::systemProxy();
1213 return QUrl("");
1217 bool RbUtilQt::chkConfig(bool warn)
1219 bool error = false;
1220 if(RbSettings::value(RbSettings::Platform).toString().isEmpty()
1221 || RbSettings::value(RbSettings::Mountpoint).toString().isEmpty()
1222 || !QFileInfo(RbSettings::value(RbSettings::Mountpoint).toString()).isWritable()) {
1223 error = true;
1225 if(warn) QMessageBox::critical(this, tr("Configuration error"),
1226 tr("Your configuration is invalid. Please go to the configuration "
1227 "dialog and make sure the selected values are correct."));
1229 return error;
1232 void RbUtilQt::checkUpdate(void)
1234 QString url = RbSettings::value(RbSettings::RbutilUrl).toString();
1235 #if defined(Q_OS_WIN32)
1236 url += "win32/";
1237 #elif defined(Q_OS_LINUX)
1238 url += "linux/";
1239 #elif defined(Q_OS_MACX)
1240 url += "macosx/";
1241 #endif
1243 update = new HttpGet(this);
1244 connect(update, SIGNAL(done(bool)), this, SLOT(downloadUpdateDone(bool)));
1245 connect(update, SIGNAL(requestFinished(int, bool)), this, SLOT(downloadDone(int, bool)));
1246 connect(qApp, SIGNAL(lastWindowClosed()), update, SLOT(abort()));
1247 if(RbSettings::value(RbSettings::CacheOffline).toBool())
1248 update->setCache(true);
1250 update->getFile(QUrl(url));
1253 void RbUtilQt::downloadUpdateDone(bool error)
1255 if(error) {
1256 qDebug() << "[RbUtil] network error:" << update->error();
1258 else {
1259 QString toParse(update->readAll());
1261 QRegExp searchString("<a[^>]*>(rbutilqt[^<]*)</a>");
1262 QStringList rbutilList;
1263 int pos = 0;
1264 while ((pos = searchString.indexIn(toParse, pos)) != -1)
1266 rbutilList << searchString.cap(1);
1267 pos += searchString.matchedLength();
1269 qDebug() << "[Checkupdate] " << rbutilList;
1271 QString newVersion ="";
1272 //check if there is a binary with higher version in this list
1273 for(int i=0; i < rbutilList.size(); i++)
1275 #if defined(Q_OS_LINUX)
1276 #if defined(__amd64__)
1277 //skip if it isnt a 64bit build
1278 if( !rbutilList.at(i).contains("64bit"))
1279 continue;
1280 #else
1281 //skip if it is a 64bit build
1282 if(rbutilList.at(i).contains("64bit"))
1283 continue;
1284 #endif
1285 #endif
1286 //check if it is newer, and remember newest
1287 if(newerVersion(VERSION,rbutilList.at(i)))
1289 if(newVersion == "" || newerVersion(newVersion,rbutilList.at(i)))
1291 newVersion = rbutilList.at(i);
1296 // if we found something newer, display info
1297 if(newVersion != "")
1299 QString url = RbSettings::value(RbSettings::RbutilUrl).toString();
1300 #if defined(Q_OS_WIN32)
1301 url += "win32/";
1302 #elif defined(Q_OS_LINUX)
1303 url += "linux/";
1304 #elif defined(Q_OS_MACX)
1305 url += "macosx/";
1306 #endif
1307 url += newVersion;
1309 QMessageBox::information(this,tr("RockboxUtility Update available"),
1310 tr("<b>New RockboxUtility Version available.</b> <br><br>"
1311 "Download it from here: <a href='%1'>%2</a>").arg(url).arg(newVersion) );
1316 bool RbUtilQt::newerVersion(QString versionOld,QString versionNew)
1318 QRegExp chars("\\d*(\\D)");
1320 //strip non-number from beginning
1321 versionOld = versionOld.remove(0,versionOld.indexOf(QRegExp("\\d")));
1322 versionNew = versionNew.remove(0,versionNew.indexOf(QRegExp("\\d")));
1324 // split versions by "."
1325 QStringList versionListOld = versionOld.split(".");
1326 QStringList versionListNew = versionNew.split(".");
1328 QStringListIterator iteratorOld(versionListOld);
1329 QStringListIterator iteratorNew(versionListNew);
1331 //check every section
1332 while(iteratorOld.hasNext() && iteratorNew.hasNext())
1334 QString newPart = iteratorNew.next();
1335 QString oldPart = iteratorOld.next();
1336 QString newPartChar = "", oldPartChar = "";
1337 int newPartInt = 0, oldPartInt =0;
1339 //convert to int, if it contains chars, put into seperated variable
1340 if(newPart.contains(chars))
1342 newPartChar = chars.cap(1);
1343 newPart = newPart.remove(newPartChar);
1345 newPartInt = newPart.toInt();
1346 //convert to int, if it contains chars, put into seperated variable
1347 if(oldPart.contains(chars))
1349 oldPartChar = chars.cap(1);
1350 oldPart = oldPart.remove(oldPartChar);
1352 oldPartInt = oldPart.toInt();
1354 if(newPartInt > oldPartInt) // this section int is higher -> true
1355 return true;
1356 else if(newPartInt < oldPartInt) //this section int is lower -> false
1357 return false;
1358 else if(newPartChar > oldPartChar) //ints are the same, chars is higher -> true
1359 return true;
1360 else if(newPartChar < oldPartChar) //ints are the same, chars is lower -> false
1361 return false;
1362 //all the same, next section
1364 // all the same -> false
1365 return false;