Put decoder array into IRAM. Improves Coldfire (h300) performance 218MHz ->102.84...
[kugel-rb.git] / rbutil / rbutilqt / rbutilqt.cpp
blobc9becc6eacee496fcf8778b5609d996b00c992ae
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 "rockboxinfo.h"
35 #include "rbzip.h"
36 #include "sysinfo.h"
37 #include "system.h"
38 #include "systrace.h"
39 #include "rbsettings.h"
40 #include "serverinfo.h"
41 #include "systeminfo.h"
43 #include "progressloggerinterface.h"
45 #include "bootloaderinstallbase.h"
48 #if defined(Q_OS_LINUX)
49 #include <stdio.h>
50 #endif
51 #if defined(Q_OS_WIN32)
52 #if defined(UNICODE)
53 #define _UNICODE
54 #endif
55 #include <stdio.h>
56 #include <tchar.h>
57 #include <windows.h>
58 #endif
60 RbUtilQt::RbUtilQt(QWidget *parent) : QMainWindow(parent)
62 // startup log
63 qDebug() << "======================================";
64 qDebug() << "[System] Rockbox Utility " VERSION;
65 qDebug() << "[System] Qt version:" << qVersion();
66 qDebug() << "======================================";
68 absolutePath = qApp->applicationDirPath();
70 HttpGet::setGlobalUserAgent("rbutil/"VERSION);
71 // init startup & autodetection
72 ui.setupUi(this);
73 #if defined(Q_OS_LINUX)
74 QIcon windowIcon(":/icons/rockbox-clef.svg");
75 this->setWindowIcon(windowIcon);
76 #endif
78 #if defined(Q_OS_WIN32)
79 long ret;
80 HKEY hk;
81 ret = RegOpenKeyEx(HKEY_CURRENT_USER, _TEXT("Software\\Wine"),
82 0, KEY_QUERY_VALUE, &hk);
83 if(ret == ERROR_SUCCESS) {
84 QMessageBox::warning(this, tr("Wine detected!"),
85 tr("It seems you are trying to run this program under Wine. "
86 "Please don't do this, running under Wine will fail. "
87 "Use the native Linux binary instead."),
88 QMessageBox::Ok, QMessageBox::Ok);
89 qDebug() << "[RbUtil] WINE DETECTED!";
90 RegCloseKey(hk);
92 #endif
93 downloadInfo();
95 m_gotInfo = false;
96 m_auto = false;
98 // manual tab
99 ui.radioPdf->setChecked(true);
101 // info tab
102 ui.treeInfo->setAlternatingRowColors(true);
103 ui.treeInfo->setHeaderLabels(QStringList() << tr("File") << tr("Version"));
104 ui.treeInfo->expandAll();
105 ui.treeInfo->setColumnCount(2);
106 ui.treeInfo->setLayoutDirection(Qt::LeftToRight);
107 // disable quick install until version info is available
108 ui.buttonSmall->setEnabled(false);
109 ui.buttonComplete->setEnabled(false);
110 ui.actionSmall_Installation->setEnabled(false);
111 ui.actionComplete_Installation->setEnabled(false);
113 connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(updateTabs(int)));
114 connect(ui.actionAbout_Qt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
115 connect(ui.action_About, SIGNAL(triggered()), this, SLOT(about()));
116 connect(ui.action_Help, SIGNAL(triggered()), this, SLOT(help()));
117 connect(ui.action_Configure, SIGNAL(triggered()), this, SLOT(configDialog()));
118 connect(ui.actionE_xit, SIGNAL(triggered()), this, SLOT(shutdown()));
119 connect(ui.buttonChangeDevice, SIGNAL(clicked()), this, SLOT(configDialog()));
120 connect(ui.buttonRockbox, SIGNAL(clicked()), this, SLOT(installBtn()));
121 connect(ui.buttonBootloader, SIGNAL(clicked()), this, SLOT(installBootloaderBtn()));
122 connect(ui.buttonFonts, SIGNAL(clicked()), this, SLOT(installFontsBtn()));
123 connect(ui.buttonGames, SIGNAL(clicked()), this, SLOT(installDoomBtn()));
124 connect(ui.buttonTalk, SIGNAL(clicked()), this, SLOT(createTalkFiles()));
125 connect(ui.buttonCreateVoice, SIGNAL(clicked()), this, SLOT(createVoiceFile()));
126 connect(ui.buttonVoice, SIGNAL(clicked()), this, SLOT(installVoice()));
127 connect(ui.buttonThemes, SIGNAL(clicked()), this, SLOT(installThemes()));
128 connect(ui.buttonRemoveRockbox, SIGNAL(clicked()), this, SLOT(uninstall()));
129 connect(ui.buttonRemoveBootloader, SIGNAL(clicked()), this, SLOT(uninstallBootloader()));
130 connect(ui.buttonDownloadManual, SIGNAL(clicked()), this, SLOT(downloadManual()));
131 connect(ui.buttonSmall, SIGNAL(clicked()), this, SLOT(smallInstall()));
132 connect(ui.buttonComplete, SIGNAL(clicked()), this, SLOT(completeInstall()));
134 // actions accessible from the menu
135 connect(ui.actionComplete_Installation, SIGNAL(triggered()), this, SLOT(completeInstall()));
136 connect(ui.actionSmall_Installation, SIGNAL(triggered()), this, SLOT(smallInstall()));
137 connect(ui.actionInstall_Bootloader, SIGNAL(triggered()), this, SLOT(installBootloaderBtn()));
138 connect(ui.actionInstall_Rockbox, SIGNAL(triggered()), this, SLOT(installBtn()));
139 connect(ui.actionFonts_Package, SIGNAL(triggered()), this, SLOT(installFontsBtn()));
140 connect(ui.actionInstall_Themes, SIGNAL(triggered()), this, SLOT(installThemes()));
141 connect(ui.actionInstall_Game_Files, SIGNAL(triggered()), this, SLOT(installDoomBtn()));
142 connect(ui.actionInstall_Voice_File, SIGNAL(triggered()), this, SLOT(installVoice()));
143 connect(ui.actionCreate_Voice_File, SIGNAL(triggered()), this, SLOT(createVoiceFile()));
144 connect(ui.actionCreate_Talk_Files, SIGNAL(triggered()), this, SLOT(createTalkFiles()));
145 connect(ui.actionRemove_bootloader, SIGNAL(triggered()), this, SLOT(uninstallBootloader()));
146 connect(ui.actionUninstall_Rockbox, SIGNAL(triggered()), this, SLOT(uninstall()));
147 connect(ui.action_System_Info, SIGNAL(triggered()), this, SLOT(sysinfo()));
148 connect(ui.action_Trace, SIGNAL(triggered()), this, SLOT(trace()));
150 #if !defined(STATIC)
151 ui.actionInstall_Rockbox_Utility_on_player->setEnabled(false);
152 #else
153 connect(ui.actionInstall_Rockbox_Utility_on_player, SIGNAL(triggered()), this, SLOT(installPortable()));
154 #endif
159 void RbUtilQt::shutdown(void)
161 // restore default message handler to prevent trace accesses during
162 // object destruction -- the trace object could already be destroyed.
163 // Fixes segfaults on exit.
164 qInstallMsgHandler(0);
165 SysTrace::save();
166 this->close();
170 void RbUtilQt::trace(void)
172 SysTrace wnd(this);
173 wnd.exec();
176 void RbUtilQt::sysinfo(void)
178 Sysinfo info(this);
179 info.exec();
182 void RbUtilQt::updateTabs(int count)
184 switch(count) {
185 case 6:
186 updateInfo();
187 break;
188 default:
189 break;
194 void RbUtilQt::downloadInfo()
196 // try to get the current build information
197 daily = new HttpGet(this);
198 connect(daily, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
199 connect(qApp, SIGNAL(lastWindowClosed()), daily, SLOT(abort()));
200 if(RbSettings::value(RbSettings::CacheOffline).toBool())
201 daily->setCache(true);
202 else
203 daily->setCache(false);
204 ui.statusbar->showMessage(tr("Downloading build information, please wait ..."));
205 qDebug() << "[RbUtil] downloading build info";
206 daily->setFile(&buildInfo);
207 daily->getFile(QUrl(SystemInfo::value(SystemInfo::ServerConfUrl).toString()));
211 void RbUtilQt::downloadDone(bool error)
213 if(error) {
214 qDebug() << "[RbUtil] network error:" << daily->error();
215 ui.statusbar->showMessage(tr("Can't get version information!"));
216 QMessageBox::critical(this, tr("Network error"),
217 tr("Can't get version information.\n"
218 "Network error: %1. Please check your network and proxy settings.")
219 .arg(daily->errorString()));
220 return;
222 qDebug() << "[RbUtil] network status:" << daily->error();
224 // read info into ServerInfo object
225 buildInfo.open();
226 ServerInfo::readBuildInfo(buildInfo.fileName());
227 buildInfo.close();
229 // start bleeding info download
230 bleeding = new HttpGet(this);
231 connect(bleeding, SIGNAL(done(bool)), this, SLOT(downloadBleedingDone(bool)));
232 connect(qApp, SIGNAL(lastWindowClosed()), bleeding, SLOT(abort()));
233 if(RbSettings::value(RbSettings::CacheOffline).toBool())
234 bleeding->setCache(true);
235 bleeding->setFile(&bleedingInfo);
236 bleeding->getFile(QUrl(SystemInfo::value(SystemInfo::BleedingInfo).toString()));
237 ui.statusbar->showMessage(tr("Downloading build information, please wait ..."));
242 void RbUtilQt::downloadBleedingDone(bool error)
244 if(error) {
245 qDebug() << "[RbUtil] network error:" << bleeding->error();
246 ui.statusbar->showMessage(tr("Can't get version information!"));
247 QMessageBox::critical(this, tr("Network error"),
248 tr("Can't get version information.\n"
249 "Network error: %1. Please check your network and proxy settings.")
250 .arg(bleeding->errorString()));
251 return;
253 else {
254 bleedingInfo.open();
255 ServerInfo::readBleedingInfo(bleedingInfo.fileName());
256 bleedingInfo.close();
258 ui.statusbar->showMessage(tr("Download build information finished."), 5000);
259 updateSettings();
260 m_gotInfo = true;
262 //start check for updates
263 checkUpdate();
268 void RbUtilQt::about()
270 QDialog *window = new QDialog(this);
271 Ui::aboutBox about;
272 about.setupUi(window);
273 window->setLayoutDirection(Qt::LeftToRight);
274 window->setModal(true);
276 QFile licence(":/docs/gpl-2.0.html");
277 licence.open(QIODevice::ReadOnly);
278 QTextStream c(&licence);
279 QString cline = c.readAll();
280 about.browserLicense->insertHtml(cline);
281 about.browserLicense->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
282 QFile credits(":/docs/CREDITS");
283 credits.open(QIODevice::ReadOnly);
284 QTextStream r(&credits);
285 r.setCodec(QTextCodec::codecForName("UTF-8"));
286 while(!r.atEnd()) {
287 QString line = r.readLine();
288 // filter out header.
289 line.remove(QRegExp("^[^A-Z]+.*"));
290 line.remove(QRegExp("^People.*"));
291 about.browserCredits->append(line);
293 about.browserCredits->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
294 QString title = QString("<b>The Rockbox Utility</b><br/>Version %1").arg(FULLVERSION);
295 about.labelTitle->setText(title);
297 window->show();
302 void RbUtilQt::help()
304 QUrl helpurl("http://www.rockbox.org/wiki/RockboxUtility");
305 QDesktopServices::openUrl(helpurl);
309 void RbUtilQt::configDialog()
311 Config *cw = new Config(this);
312 connect(cw, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
313 cw->show();
317 void RbUtilQt::updateSettings()
319 qDebug() << "[RbUtil] updating current settings";
320 updateDevice();
321 updateManual();
322 if(RbSettings::value(RbSettings::ProxyType) == "system") {
323 HttpGet::setGlobalProxy(System::systemProxy());
325 else if(RbSettings::value(RbSettings::ProxyType) == "manual") {
326 HttpGet::setGlobalProxy(RbSettings::value(RbSettings::Proxy).toString());
328 else {
329 HttpGet::setGlobalProxy(QUrl(""));
331 HttpGet::setGlobalCache(RbSettings::value(RbSettings::CachePath).toString());
332 HttpGet::setGlobalDumbCache(RbSettings::value(RbSettings::CacheOffline).toBool());
334 if(RbSettings::value(RbSettings::RbutilVersion) != PUREVERSION) {
335 QApplication::processEvents();
336 QMessageBox::information(this, tr("New installation"),
337 tr("This is a new installation of Rockbox Utility, or a new version. "
338 "The configuration dialog will now open to allow you to setup the program, "
339 " or review your settings."));
340 configDialog();
342 else if(chkConfig(false)) {
343 QApplication::processEvents();
344 QMessageBox::critical(this, tr("Configuration error"),
345 tr("Your configuration is invalid. This is most likely due "
346 "to a changed device path. The configuration dialog will "
347 "now open to allow you to correct the problem."));
348 configDialog();
353 void RbUtilQt::updateDevice()
355 /* TODO: We should check the flags of the bootloaderinstall classes, and not
356 * just check if its != none or != "fwpatcher" */
358 /* Enable bootloader installation, if possible */
359 bool bootloaderInstallable =
360 SystemInfo::value(SystemInfo::CurBootloaderMethod) != "none";
361 ui.buttonBootloader->setEnabled(bootloaderInstallable);
362 ui.labelBootloader->setEnabled(bootloaderInstallable);
363 ui.actionInstall_Bootloader->setEnabled(bootloaderInstallable);
365 /* Enable bootloader uninstallation, if possible */
366 bool bootloaderUninstallable = bootloaderInstallable &&
367 SystemInfo::value(SystemInfo::CurBootloaderMethod) != "fwpatcher";
368 ui.labelRemoveBootloader->setEnabled(bootloaderUninstallable);
369 ui.buttonRemoveBootloader->setEnabled(bootloaderUninstallable);
370 ui.actionRemove_bootloader->setEnabled(bootloaderUninstallable);
372 /* Disable the whole tab widget if configuration is invalid */
373 bool configurationValid = !chkConfig(false);
374 ui.tabWidget->setEnabled(configurationValid);
375 ui.menuA_ctions->setEnabled(configurationValid);
377 // displayed device info
378 QString mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
379 QString brand = SystemInfo::value(SystemInfo::CurBrand).toString();
380 QString name = SystemInfo::value(SystemInfo::CurName).toString() +
381 " (" + ServerInfo::value(ServerInfo::CurStatus).toString() + ")";
382 if(name.isEmpty()) name = "&lt;none&gt;";
383 if(mountpoint.isEmpty()) mountpoint = "&lt;invalid&gt;";
384 ui.labelDevice->setText(tr("<b>%1 %2</b> at <b>%3</b>")
385 .arg(brand, name, QDir::toNativeSeparators(mountpoint)));
387 // hide quickstart buttons if no release available
388 bool installable = !ServerInfo::value(ServerInfo::CurReleaseVersion).toString().isEmpty();
389 ui.buttonSmall->setEnabled(installable);
390 ui.buttonComplete->setEnabled(installable);
391 ui.actionSmall_Installation->setEnabled(installable);
392 ui.actionComplete_Installation->setEnabled(installable);
396 void RbUtilQt::updateManual()
398 if(RbSettings::value(RbSettings::Platform) != "")
400 QString manual= SystemInfo::value(SystemInfo::CurManual).toString();
402 if(manual == "")
403 manual = "rockbox-"
404 + SystemInfo::value(SystemInfo::CurBuildserverModel).toString();
405 QString pdfmanual;
406 pdfmanual = SystemInfo::value(SystemInfo::ManualUrl).toString()
407 + "/" + manual + ".pdf";
408 QString htmlmanual;
409 htmlmanual = SystemInfo::value(SystemInfo::ManualUrl).toString()
410 + "/" + manual + "/rockbox-build.html";
411 ui.labelPdfManual->setText(tr("<a href='%1'>PDF Manual</a>")
412 .arg(pdfmanual));
413 ui.labelHtmlManual->setText(tr("<a href='%1'>HTML Manual (opens in browser)</a>")
414 .arg(htmlmanual));
416 else {
417 ui.labelPdfManual->setText(tr("Select a device for a link to the correct manual"));
418 ui.labelHtmlManual->setText(tr("<a href='%1'>Manual Overview</a>")
419 .arg("http://www.rockbox.org/manual.shtml"));
424 void RbUtilQt::completeInstall()
426 if(chkConfig(true)) return;
427 if(QMessageBox::question(this, tr("Confirm Installation"),
428 tr("Do you really want to perform a complete installation?\n\n"
429 "This will install Rockbox %1. To install the most recent "
430 "development build available press \"Cancel\" and "
431 "use the \"Installation\" tab.")
432 .arg(ServerInfo::value(ServerInfo::CurReleaseVersion).toString()),
433 QMessageBox::Ok | QMessageBox::Cancel) != QMessageBox::Ok)
434 return;
435 // create logger
436 logger = new ProgressLoggerGui(this);
437 logger->show();
439 if(smallInstallInner())
440 return;
441 logger->setRunning();
442 // Fonts
443 m_error = false;
444 m_installed = false;
445 if(!installFontsAuto())
446 return;
447 else
449 // wait for installation finished
450 while(!m_installed)
451 QApplication::processEvents();
453 if(m_error) return;
454 logger->setRunning();
456 // Doom
457 if(hasDoom())
459 m_error = false;
460 m_installed = false;
461 if(!installDoomAuto())
462 return;
463 else
465 // wait for installation finished
466 while(!m_installed)
467 QApplication::processEvents();
469 if(m_error) return;
472 // theme
473 // this is a window
474 // it has its own logger window,so close our.
475 logger->close();
476 installThemes();
480 void RbUtilQt::smallInstall()
482 if(chkConfig(true)) return;
483 if(QMessageBox::question(this, tr("Confirm Installation"),
484 tr("Do you really want to perform a minimal installation? "
485 "A minimal installation will contain only the absolutely "
486 "necessary parts to run Rockbox.\n\n"
487 "This will install Rockbox %1. To install the most recent "
488 "development build available press \"Cancel\" and "
489 "use the \"Installation\" tab.")
490 .arg(ServerInfo::value(ServerInfo::CurReleaseVersion).toString()),
491 QMessageBox::Ok | QMessageBox::Cancel) != QMessageBox::Ok)
492 return;
494 // create logger
495 logger = new ProgressLoggerGui(this);
496 logger->show();
498 smallInstallInner();
501 bool RbUtilQt::smallInstallInner()
503 QString mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
504 // show dialog with error if mount point is wrong
505 if(!QFileInfo(mountpoint).isDir()) {
506 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
507 logger->setFinished();
508 return true;
510 // Bootloader
511 if(SystemInfo::value(SystemInfo::CurBootloaderMethod) != "none")
513 m_error = false;
514 m_installed = false;
515 m_auto = true;
516 if(!installBootloaderAuto()) {
517 logger->setFinished();
518 return true;
520 else
522 // wait for boot loader installation finished
523 while(!m_installed)
524 QApplication::processEvents();
526 m_auto = false;
527 if(m_error) return true;
528 logger->setRunning();
531 // Rockbox
532 m_error = false;
533 m_installed = false;
534 if(!installAuto())
535 return true;
536 else
538 // wait for installation finished
539 while(!m_installed)
540 QApplication::processEvents();
543 installBootloaderPost(false);
544 return false;
547 void RbUtilQt::installdone(bool error)
549 qDebug() << "[RbUtil] install done";
550 m_installed = true;
551 m_error = error;
554 void RbUtilQt::installBtn()
556 if(chkConfig(true)) return;
557 install();
560 bool RbUtilQt::installAuto()
562 QString file = SystemInfo::value(SystemInfo::ReleaseUrl).toString();
563 file.replace("%MODEL%", SystemInfo::value(SystemInfo::CurBuildserverModel).toString());
564 file.replace("%RELVERSION%", ServerInfo::value(ServerInfo::CurReleaseVersion).toString());
566 // check installed Version and Target
567 QString warning = Utils::checkEnvironment(false);
568 if(!warning.isEmpty())
570 if(QMessageBox::warning(this, tr("Really continue?"), warning,
571 QMessageBox::Ok | QMessageBox::Abort, QMessageBox::Abort)
572 == QMessageBox::Abort)
574 logger->addItem(tr("Aborted!"), LOGERROR);
575 logger->setFinished();
576 return false;
580 // check version
581 RockboxInfo rbinfo(RbSettings::value(RbSettings::Mountpoint).toString());
582 if(rbinfo.version() != "")
584 if(QMessageBox::question(this, tr("Installed Rockbox detected"),
585 tr("Rockbox installation detected. Do you want to backup first?"),
586 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
588 logger->addItem(tr("Starting backup..."),LOGINFO);
589 QString backupName = RbSettings::value(RbSettings::Mountpoint).toString()
590 + "/.backup/rockbox-backup-" + rbinfo.version() + ".zip";
592 //! create dir, if it doesnt exist
593 QFileInfo backupFile(backupName);
594 if(!QDir(backupFile.path()).exists())
596 QDir a;
597 a.mkpath(backupFile.path());
600 //! create backup
601 RbZip backup;
602 connect(&backup,SIGNAL(zipProgress(int,int)),logger, SLOT(setProgress(int,int)));
603 if(backup.createZip(backupName,
604 RbSettings::value(RbSettings::Mountpoint).toString() + "/.rockbox") == Zip::Ok)
606 logger->addItem(tr("Backup successful"),LOGOK);
608 else
610 logger->addItem(tr("Backup failed!"),LOGERROR);
611 logger->setFinished();
612 return false;
617 //! install current build
618 ZipInstaller* installer = new ZipInstaller(this);
619 installer->setUrl(file);
620 installer->setLogSection("Rockbox (Base)");
621 installer->setLogVersion(ServerInfo::value(ServerInfo::CurReleaseVersion).toString());
622 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
623 installer->setCache(true);
624 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
626 connect(installer, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
627 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
628 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
629 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
630 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
631 installer->install();
632 return true;
636 void RbUtilQt::install()
638 InstallWindow *installWindow = new InstallWindow(this);
639 installWindow->show();
642 bool RbUtilQt::installBootloaderAuto()
644 installBootloader();
645 return !m_error;
648 void RbUtilQt::installBootloaderBtn()
650 if(chkConfig(true)) return;
651 if(QMessageBox::question(this, tr("Confirm Installation"),
652 tr("Do you really want to install the Bootloader?"),
653 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
655 // create logger
656 logger = new ProgressLoggerGui(this);
657 logger->show();
658 installBootloader();
661 void RbUtilQt::installBootloader()
663 QString platform = RbSettings::value(RbSettings::Platform).toString();
664 QString backupDestination = "";
665 m_error = false;
667 // create installer
668 BootloaderInstallBase *bl = BootloaderInstallBase::createBootloaderInstaller(this,
669 SystemInfo::value(SystemInfo::CurBootloaderMethod).toString());
670 if(bl == NULL) {
671 logger->addItem(tr("No install method known."), LOGERROR);
672 logger->setFinished();
673 return;
676 // set bootloader filename. Do this now as installed() needs it.
677 QStringList blfile = SystemInfo::value(SystemInfo::CurBootloaderFile).toStringList();
678 QStringList blfilepath;
679 for(int a = 0; a < blfile.size(); a++) {
680 blfilepath.append(RbSettings::value(RbSettings::Mountpoint).toString()
681 + blfile.at(a));
683 bl->setBlFile(blfilepath);
684 QUrl url(SystemInfo::value(SystemInfo::BootloaderUrl).toString()
685 + SystemInfo::value(SystemInfo::CurBootloaderName).toString());
686 bl->setBlUrl(url);
687 bl->setLogfile(RbSettings::value(RbSettings::Mountpoint).toString()
688 + "/.rockbox/rbutil.log");
690 if(bl->installed() == BootloaderInstallBase::BootloaderRockbox) {
691 if(QMessageBox::question(this, tr("Bootloader detected"),
692 tr("Bootloader already installed. Do you want to reinstall the bootloader?"),
693 QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
694 if(m_auto) {
695 // keep logger open for auto installs.
696 // don't consider abort as error in auto-mode.
697 logger->addItem(tr("Bootloader installation skipped"), LOGINFO);
698 installBootloaderPost(false);
700 else {
701 logger->close();
702 installBootloaderPost(true);
704 delete bl;
705 return;
708 else if(bl->installed() == BootloaderInstallBase::BootloaderOther
709 && bl->capabilities() & BootloaderInstallBase::Backup)
711 QString targetFolder = SystemInfo::value(SystemInfo::CurPlatformName).toString()
712 + " Firmware Backup";
713 // remove invalid character(s)
714 targetFolder.remove(QRegExp("[:/]"));
715 if(QMessageBox::question(this, tr("Create Bootloader backup"),
716 tr("You can create a backup of the original bootloader "
717 "file. Press \"Yes\" to select an output folder on your "
718 "computer to save the file to. The file will get placed "
719 "in a new folder \"%1\" created below the selected folder.\n"
720 "Press \"No\" to skip this step.").arg(targetFolder),
721 QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
722 backupDestination = QFileDialog::getExistingDirectory(this,
723 tr("Browse backup folder"), QDir::homePath());
724 if(!backupDestination.isEmpty())
725 backupDestination += "/" + targetFolder;
727 qDebug() << "[RbUtil] backing up to" << backupDestination;
728 // backup needs to be done after the logger has been set up.
732 if(bl->capabilities() & BootloaderInstallBase::NeedsOf)
734 int ret;
735 ret = QMessageBox::information(this, tr("Prerequisites"),
736 bl->ofHint(),QMessageBox::Ok | QMessageBox::Abort);
737 if(ret != QMessageBox::Ok) {
738 // consider aborting an error to close window / abort automatic
739 // installation.
740 m_error = true;
741 logger->addItem(tr("Bootloader installation aborted"), LOGINFO);
742 logger->setFinished();
743 return;
745 // open dialog to browse to of file
746 QString offile;
747 offile = QFileDialog::getOpenFileName(this,
748 tr("Select firmware file"), QDir::homePath());
749 if(!QFileInfo(offile).isReadable()) {
750 logger->addItem(tr("Error opening firmware file"), LOGERROR);
751 logger->setFinished();
752 m_error = true;
753 return;
755 bl->setOfFile(offile);
758 // the bootloader install class does NOT use any GUI stuff.
759 // All messages are passed via signals.
760 connect(bl, SIGNAL(done(bool)), logger, SLOT(setFinished()));
761 connect(bl, SIGNAL(done(bool)), this, SLOT(installBootloaderPost(bool)));
762 connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
763 connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
765 // start install.
766 if(!backupDestination.isEmpty()) {
767 if(!bl->backup(backupDestination)) {
768 if(QMessageBox::warning(this, tr("Backup error"),
769 tr("Could not create backup file. Continue?"),
770 QMessageBox::No | QMessageBox::Yes)
771 == QMessageBox::No) {
772 logger->setFinished();
773 return;
777 bl->install();
780 void RbUtilQt::installBootloaderPost(bool error)
782 qDebug() << "[RbUtil] Bootloader Post-Installation, error state:" << error;
783 // if an error occured don't perform post install steps.
784 if(error) {
785 m_error = true;
786 return;
788 else
789 m_error = false;
791 m_installed = true;
792 // end here if automated install
793 if(m_auto)
794 return;
796 QString msg = BootloaderInstallBase::postinstallHints(
797 RbSettings::value(RbSettings::Platform).toString());
798 if(!msg.isEmpty()) {
799 QMessageBox::information(this, tr("Manual steps required"), msg);
800 logger->close();
805 void RbUtilQt::installFontsBtn()
807 if(chkConfig(true)) return;
808 if(QMessageBox::question(this, tr("Confirm Installation"),
809 tr("Do you really want to install the fonts package?"),
810 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
811 // create logger
812 logger = new ProgressLoggerGui(this);
813 logger->show();
814 installFonts();
817 bool RbUtilQt::installFontsAuto()
819 installFonts();
821 return !m_error;
824 void RbUtilQt::installFonts()
826 // create zip installer
827 installer = new ZipInstaller(this);
829 installer->setUrl(SystemInfo::value(SystemInfo::FontUrl).toString());
830 installer->setLogSection("Fonts");
831 installer->setLogVersion(ServerInfo::value(ServerInfo::DailyDate).toString());
832 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
833 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
834 installer->setCache(true);
836 connect(installer, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
837 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
838 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
839 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
840 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
841 installer->install();
845 void RbUtilQt::installVoice()
847 if(chkConfig(true)) return;
849 if(m_gotInfo == false)
851 QMessageBox::warning(this, tr("Warning"),
852 tr("The Application is still downloading Information about new Builds."
853 " Please try again shortly."));
854 return;
857 if(QMessageBox::question(this, tr("Confirm Installation"),
858 tr("Do you really want to install the voice file?"),
859 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
860 // create logger
861 logger = new ProgressLoggerGui(this);
862 logger->show();
864 // create zip installer
865 installer = new ZipInstaller(this);
867 QString voiceurl = SystemInfo::value(SystemInfo::VoiceUrl).toString();
868 QDate date = QDate::fromString(ServerInfo::value(ServerInfo::DailyDate).toString(),Qt::ISODate);
869 voiceurl += SystemInfo::value(SystemInfo::CurBuildserverModel).toString() + "-" +
870 date.toString("yyyyMMdd") + "-english.zip";
871 qDebug() << "[RbUtil] voicefile URL:" << voiceurl;
873 installer->setUrl(voiceurl);
874 installer->setLogSection("Voice");
875 installer->setLogVersion(ServerInfo::value(ServerInfo::DailyDate).toString());
876 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
877 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
878 installer->setCache(true);
879 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
880 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
881 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
882 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
883 installer->install();
887 void RbUtilQt::installDoomBtn()
889 if(chkConfig(true)) return;
890 if(!hasDoom()){
891 QMessageBox::critical(this, tr("Error"),
892 tr("Your device doesn't have a doom plugin. Aborting."));
893 return;
896 if(QMessageBox::question(this, tr("Confirm Installation"),
897 tr("Do you really want to install the game addon files?"),
898 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
899 // create logger
900 logger = new ProgressLoggerGui(this);
901 logger->show();
903 installDoom();
905 bool RbUtilQt::installDoomAuto()
907 installDoom();
908 return !m_error;
911 bool RbUtilQt::hasDoom()
913 QFile doomrock(RbSettings::value(RbSettings::Mountpoint).toString()
914 +"/.rockbox/rocks/games/doom.rock");
915 return doomrock.exists();
918 void RbUtilQt::installDoom()
920 // create zip installer
921 installer = new ZipInstaller(this);
923 installer->setUrl(SystemInfo::value(SystemInfo::DoomUrl).toString());
924 installer->setLogSection("Game Addons");
925 installer->setLogVersion(ServerInfo::value(ServerInfo::DailyDate).toString());
926 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
927 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
928 installer->setCache(true);
929 connect(installer, SIGNAL(done(bool)), this, SLOT(installdone(bool)));
930 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
931 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
932 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
933 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
934 installer->install();
938 void RbUtilQt::installThemes()
940 if(chkConfig(true)) return;
941 ThemesInstallWindow* tw = new ThemesInstallWindow(this);
942 tw->setModal(true);
943 tw->show();
946 void RbUtilQt::createTalkFiles(void)
948 if(chkConfig(true)) return;
949 InstallTalkWindow *installWindow = new InstallTalkWindow(this);
950 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
951 installWindow->show();
955 void RbUtilQt::createVoiceFile(void)
957 if(chkConfig(true)) return;
958 CreateVoiceWindow *installWindow = new CreateVoiceWindow(this);
960 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
961 installWindow->show();
964 void RbUtilQt::uninstall(void)
966 if(chkConfig(true)) return;
967 UninstallWindow *uninstallWindow = new UninstallWindow(this);
968 uninstallWindow->show();
972 void RbUtilQt::uninstallBootloader(void)
974 if(chkConfig(true)) return;
975 if(QMessageBox::question(this, tr("Confirm Uninstallation"),
976 tr("Do you really want to uninstall the Bootloader?"),
977 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
978 // create logger
979 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
980 logger->setProgressVisible(false);
981 logger->show();
983 QString platform = RbSettings::value(RbSettings::Platform).toString();
985 // create installer
986 BootloaderInstallBase *bl = BootloaderInstallBase::createBootloaderInstaller(this,
987 SystemInfo::value(SystemInfo::CurBootloaderMethod).toString());
989 if(bl == NULL ) {
990 logger->addItem(tr("No uninstall method for this target known."), LOGERROR);
991 logger->setFinished();
992 return;
994 if( (bl->capabilities() & BootloaderInstallBase::Uninstall) == 0)
996 logger->addItem(tr("Rockbox Utility can not uninstall the bootloader on this target."
997 "Try a normal firmware update to remove the booloader."), LOGERROR);
998 logger->setFinished();
999 delete bl;
1000 return;
1003 QStringList blfile = SystemInfo::value(SystemInfo::CurBootloaderFile).toStringList();
1004 QStringList blfilepath;
1005 for(int a = 0; a < blfile.size(); a++) {
1006 blfilepath.append(RbSettings::value(RbSettings::Mountpoint).toString()
1007 + blfile.at(a));
1009 bl->setBlFile(blfilepath);
1011 connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
1012 connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
1014 int result;
1015 result = bl->uninstall();
1017 logger->setFinished();
1022 void RbUtilQt::downloadManual(void)
1024 if(chkConfig(true)) return;
1025 if(QMessageBox::question(this, tr("Confirm download"),
1026 tr("Do you really want to download the manual? The manual will be saved "
1027 "to the root folder of your player."),
1028 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
1029 return;
1031 QString manual = SystemInfo::value(SystemInfo::CurManual).toString();
1032 if(manual.isEmpty())
1033 manual = "rockbox-"
1034 + SystemInfo::value(SystemInfo::CurBuildserverModel).toString();
1036 QDate date = QDate::fromString(ServerInfo::value(ServerInfo::DailyDate).toString(),Qt::ISODate);
1038 QString manualurl;
1039 QString target;
1040 QString section;
1041 if(ui.radioPdf->isChecked()) {
1042 target = "/" + manual + ".pdf";
1043 section = "Manual (PDF)";
1045 else {
1046 target = "/" + manual + "-" + date.toString("yyyyMMdd") + "-html.zip";
1047 section = "Manual (HTML)";
1049 manualurl = SystemInfo::value(SystemInfo::ManualUrl).toString() + "/" + target;
1050 qDebug() << "[RbUtil] Manual URL:" << manualurl;
1052 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
1053 logger->show();
1054 installer = new ZipInstaller(this);
1055 installer->setMountPoint(RbSettings::value(RbSettings::Mountpoint).toString());
1056 if(!RbSettings::value(RbSettings::CacheDisabled).toBool())
1057 installer->setCache(true);
1058 installer->setLogSection(section);
1059 installer->setLogVersion(ServerInfo::value(ServerInfo::DailyDate).toString());
1060 installer->setUrl(manualurl);
1061 installer->setUnzip(false);
1062 installer->setTarget(target);
1063 connect(installer, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
1064 connect(installer, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
1065 connect(installer, SIGNAL(done(bool)), logger, SLOT(setFinished()));
1066 connect(logger, SIGNAL(aborted()), installer, SLOT(abort()));
1067 installer->install();
1071 void RbUtilQt::installPortable(void)
1073 if(QMessageBox::question(this, tr("Confirm installation"),
1074 tr("Do you really want to install Rockbox Utility to your player? "
1075 "After installation you can run it from the players hard drive."),
1076 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
1077 return;
1079 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
1080 logger->setProgressMax(0);
1081 logger->setProgressValue(0);
1082 logger->show();
1083 logger->addItem(tr("Installing Rockbox Utility"), LOGINFO);
1085 // check mountpoint
1086 if(!QFileInfo(RbSettings::value(RbSettings::Mountpoint).toString()).isDir()) {
1087 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
1088 logger->setFinished();
1089 return;
1092 // remove old files first.
1093 QFile::remove(RbSettings::value(RbSettings::Mountpoint).toString()
1094 + "/RockboxUtility.exe");
1095 QFile::remove(RbSettings::value(RbSettings::Mountpoint).toString()
1096 + "/RockboxUtility.ini");
1097 // copy currently running binary and currently used settings file
1098 if(!QFile::copy(qApp->applicationFilePath(),
1099 RbSettings::value(RbSettings::Mountpoint).toString()
1100 + "/RockboxUtility.exe")) {
1101 logger->addItem(tr("Error installing Rockbox Utility"), LOGERROR);
1102 logger->setFinished();
1103 return;
1105 logger->addItem(tr("Installing user configuration"), LOGINFO);
1106 if(!QFile::copy(RbSettings::userSettingFilename(),
1107 RbSettings::value(RbSettings::Mountpoint).toString()
1108 + "/RockboxUtility.ini")) {
1109 logger->addItem(tr("Error installing user configuration"), LOGERROR);
1110 logger->setFinished();
1111 return;
1113 logger->addItem(tr("Successfully installed Rockbox Utility."), LOGOK);
1114 logger->setFinished();
1115 logger->setProgressMax(1);
1116 logger->setProgressValue(1);
1121 void RbUtilQt::updateInfo()
1123 qDebug() << "[RbUtil] updating server info";
1125 QString mp = RbSettings::value(RbSettings::Mountpoint).toString();
1126 QSettings log(mp + "/.rockbox/rbutil.log", QSettings::IniFormat, this);
1127 QStringList groups = log.childGroups();
1128 QList<QTreeWidgetItem *> items;
1129 QTreeWidgetItem *w, *w2;
1130 QString min, max;
1131 int olditems = 0;
1133 // remove old list entries (if any)
1134 int l = ui.treeInfo->topLevelItemCount();
1135 while(l--) {
1136 QTreeWidgetItem *m;
1137 m = ui.treeInfo->takeTopLevelItem(l);
1138 // delete childs (single level deep, no recursion here)
1139 int n = m->childCount();
1140 while(n--)
1141 delete m->child(n);
1143 // get and populate new items
1144 for(int a = 0; a < groups.size(); a++) {
1145 log.beginGroup(groups.at(a));
1146 QStringList keys = log.allKeys();
1147 w = new QTreeWidgetItem;
1148 w->setFlags(Qt::ItemIsEnabled);
1149 w->setText(0, groups.at(a));
1150 items.append(w);
1151 // get minimum and maximum version information so we can hilight old files
1152 min = max = log.value(keys.at(0)).toString();
1153 for(int b = 0; b < keys.size(); b++) {
1154 if(log.value(keys.at(b)).toString() > max)
1155 max = log.value(keys.at(b)).toString();
1156 if(log.value(keys.at(b)).toString() < min)
1157 min = log.value(keys.at(b)).toString();
1160 for(int b = 0; b < keys.size(); b++) {
1161 QString file;
1162 file = mp + "/" + keys.at(b);
1163 if(QFileInfo(file).isDir())
1164 continue;
1165 w2 = new QTreeWidgetItem(w, QStringList() << "/"
1166 + keys.at(b) << log.value(keys.at(b)).toString());
1167 if(log.value(keys.at(b)).toString() != max) {
1168 w2->setForeground(0, QBrush(QColor(255, 0, 0)));
1169 w2->setForeground(1, QBrush(QColor(255, 0, 0)));
1170 olditems++;
1172 items.append(w2);
1174 log.endGroup();
1175 if(min != max)
1176 w->setData(1, Qt::DisplayRole, QString("%1 / %2").arg(min, max));
1177 else
1178 w->setData(1, Qt::DisplayRole, max);
1180 ui.treeInfo->insertTopLevelItems(0, items);
1181 ui.treeInfo->resizeColumnToContents(0);
1185 QUrl RbUtilQt::proxy()
1187 if(RbSettings::value(RbSettings::ProxyType) == "manual")
1188 return QUrl(RbSettings::value(RbSettings::Proxy).toString());
1189 else if(RbSettings::value(RbSettings::ProxyType) == "system")
1190 return System::systemProxy();
1191 return QUrl("");
1195 bool RbUtilQt::chkConfig(bool warn)
1197 bool error = false;
1198 if(RbSettings::value(RbSettings::Platform).toString().isEmpty()
1199 || RbSettings::value(RbSettings::Mountpoint).toString().isEmpty()
1200 || !QFileInfo(RbSettings::value(RbSettings::Mountpoint).toString()).isWritable()) {
1201 error = true;
1203 if(warn) QMessageBox::critical(this, tr("Configuration error"),
1204 tr("Your configuration is invalid. Please go to the configuration "
1205 "dialog and make sure the selected values are correct."));
1207 return error;
1210 void RbUtilQt::checkUpdate(void)
1212 QString url = SystemInfo::value(SystemInfo::RbutilUrl).toString();
1213 #if defined(Q_OS_WIN32)
1214 url += "win32/";
1215 #elif defined(Q_OS_LINUX)
1216 url += "linux/";
1217 #elif defined(Q_OS_MACX)
1218 url += "macosx/";
1219 #endif
1221 update = new HttpGet(this);
1222 connect(update, SIGNAL(done(bool)), this, SLOT(downloadUpdateDone(bool)));
1223 connect(qApp, SIGNAL(lastWindowClosed()), update, SLOT(abort()));
1224 if(RbSettings::value(RbSettings::CacheOffline).toBool())
1225 update->setCache(true);
1227 update->getFile(QUrl(url));
1230 void RbUtilQt::downloadUpdateDone(bool error)
1232 if(error) {
1233 qDebug() << "[RbUtil] network error:" << update->error();
1235 else {
1236 QString toParse(update->readAll());
1238 QRegExp searchString("<a[^>]*>([a-zA-Z]+[^<]*)</a>");
1239 QStringList rbutilList;
1240 int pos = 0;
1241 while ((pos = searchString.indexIn(toParse, pos)) != -1)
1243 rbutilList << searchString.cap(1);
1244 pos += searchString.matchedLength();
1246 qDebug() << "[Checkupdate] " << rbutilList;
1248 QString newVersion ="";
1249 //check if there is a binary with higher version in this list
1250 for(int i=0; i < rbutilList.size(); i++)
1252 #if defined(Q_OS_LINUX)
1253 #if defined(__amd64__)
1254 //skip if it isnt a 64bit build
1255 if( !rbutilList.at(i).contains("64bit"))
1256 continue;
1257 #else
1258 //skip if it is a 64bit build
1259 if(rbutilList.at(i).contains("64bit"))
1260 continue;
1261 #endif
1262 #endif
1263 //check if it is newer, and remember newest
1264 if(newerVersion(VERSION,rbutilList.at(i)))
1266 if(newVersion == "" || newerVersion(newVersion,rbutilList.at(i)))
1268 newVersion = rbutilList.at(i);
1273 // if we found something newer, display info
1274 if(newVersion != "")
1276 QString url = SystemInfo::value(SystemInfo::RbutilUrl).toString();
1277 #if defined(Q_OS_WIN32)
1278 url += "win32/";
1279 #elif defined(Q_OS_LINUX)
1280 url += "linux/";
1281 #elif defined(Q_OS_MACX)
1282 url += "macosx/";
1283 #endif
1284 url += newVersion;
1286 QMessageBox::information(this,tr("RockboxUtility Update available"),
1287 tr("<b>New RockboxUtility Version available.</b> <br><br>"
1288 "Download it from here: <a href='%1'>%2</a>").arg(url).arg(newVersion) );
1293 bool RbUtilQt::newerVersion(QString versionOld,QString versionNew)
1295 QRegExp chars("\\d*(\\D)");
1297 //strip non-number from beginning
1298 versionOld = versionOld.remove(0,versionOld.indexOf(QRegExp("\\d")));
1299 versionNew = versionNew.remove(0,versionNew.indexOf(QRegExp("\\d")));
1301 // split versions by "."
1302 QStringList versionListOld = versionOld.split(".");
1303 QStringList versionListNew = versionNew.split(".");
1305 QStringListIterator iteratorOld(versionListOld);
1306 QStringListIterator iteratorNew(versionListNew);
1308 //check every section
1309 while(iteratorOld.hasNext() && iteratorNew.hasNext())
1311 QString newPart = iteratorNew.next();
1312 QString oldPart = iteratorOld.next();
1313 QString newPartChar = "", oldPartChar = "";
1314 int newPartInt = 0, oldPartInt =0;
1316 //convert to int, if it contains chars, put into seperated variable
1317 if(newPart.contains(chars))
1319 newPartChar = chars.cap(1);
1320 newPart = newPart.remove(newPartChar);
1322 newPartInt = newPart.toInt();
1323 //convert to int, if it contains chars, put into seperated variable
1324 if(oldPart.contains(chars))
1326 oldPartChar = chars.cap(1);
1327 oldPart = oldPart.remove(oldPartChar);
1329 oldPartInt = oldPart.toInt();
1331 if(newPartInt > oldPartInt) // this section int is higher -> true
1332 return true;
1333 else if(newPartInt < oldPartInt) //this section int is lower -> false
1334 return false;
1335 else if(newPartChar > oldPartChar) //ints are the same, chars is higher -> true
1336 return true;
1337 else if(newPartChar < oldPartChar) //ints are the same, chars is lower -> false
1338 return false;
1339 //all the same, next section
1341 // all the same -> false
1342 return false;