summaryrefslogtreecommitdiff
path: root/utils/rbutilqt/rbutilqt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/rbutilqt/rbutilqt.cpp')
-rw-r--r--utils/rbutilqt/rbutilqt.cpp721
1 files changed, 721 insertions, 0 deletions
diff --git a/utils/rbutilqt/rbutilqt.cpp b/utils/rbutilqt/rbutilqt.cpp
new file mode 100644
index 0000000000..16735dc83a
--- /dev/null
+++ b/utils/rbutilqt/rbutilqt.cpp
@@ -0,0 +1,721 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 *
9 * Copyright (C) 2007 by Dominik Riebeling
10 *
11 * All files in this archive are subject to the GNU General Public License.
12 * See the file COPYING in the source tree root for full license agreement.
13 *
14 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
15 * KIND, either express or implied.
16 *
17 ****************************************************************************/
18
19#include <QMainWindow>
20#include <QMessageBox>
21
22#include "version.h"
23#include "rbutilqt.h"
24#include "ui_rbutilqtfrm.h"
25#include "ui_aboutbox.h"
26#include "configure.h"
27#include "installtalkwindow.h"
28#include "createvoicewindow.h"
29#include "httpget.h"
30#include "themesinstallwindow.h"
31#include "uninstallwindow.h"
32#include "utils.h"
33#include "rockboxinfo.h"
34#include "sysinfo.h"
35#include "system.h"
36#include "systrace.h"
37#include "rbsettings.h"
38#include "playerbuildinfo.h"
39#include "ziputil.h"
40#include "infowidget.h"
41#include "selectiveinstallwidget.h"
42#include "backupdialog.h"
43#include "changelog.h"
44
45#include "progressloggerinterface.h"
46
47#include "bootloaderinstallbase.h"
48#include "bootloaderinstallhelper.h"
49
50#include "Logger.h"
51
52#if defined(Q_OS_LINUX)
53#include <stdio.h>
54#endif
55#if defined(Q_OS_WIN32)
56#if !defined(_UNICODE)
57#define _UNICODE
58#endif
59#include <stdio.h>
60#include <tchar.h>
61#include <windows.h>
62#endif
63
64QList<QTranslator*> RbUtilQt::translators;
65
66RbUtilQt::RbUtilQt(QWidget *parent) : QMainWindow(parent)
67{
68 // startup log
69 LOG_INFO() << "======================================";
70 LOG_INFO() << "Rockbox Utility" << VERSION;
71 LOG_INFO() << "Qt version:" << qVersion();
72#if defined(__clang__)
73 LOG_INFO("compiled using clang %i.%i.%i",
74 __clang_major__, __clang_minor__, __clang_patchlevel__);
75#elif defined(__GNUC__)
76 LOG_INFO("compiled using gcc %i.%i.%i",
77 __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
78#elif defined(_MSC_VER)
79 LOG_INFO() << "compiled using MSVC" << _MSC_FULL_VER;
80#endif
81 LOG_INFO() << "======================================";
82
83 absolutePath = qApp->applicationDirPath();
84
85 QString c = RbSettings::value(RbSettings::CachePath).toString();
86 HttpGet::setGlobalCache(c.isEmpty() ? QDir::tempPath() : c);
87 HttpGet::setGlobalUserAgent("rbutil/" VERSION);
88 HttpGet::setGlobalProxy(proxy());
89 // init startup & autodetection
90 ui.setupUi(this);
91 QIcon windowIcon(":/icons/rockbox-clef.svg");
92 this->setWindowIcon(windowIcon);
93#if defined(Q_OS_MACX)
94 // don't translate menu entries that are handled specially on OS X
95 // (Configure, Quit). Qt handles them for us if they use english string.
96 ui.action_Configure->setText("Configure");
97 ui.actionE_xit->setText("Quit");
98#endif
99#if defined(Q_OS_WIN32)
100 long ret;
101 HKEY hk;
102 ret = RegOpenKeyEx(HKEY_CURRENT_USER, _TEXT("Software\\Wine"),
103 0, KEY_QUERY_VALUE, &hk);
104 if(ret == ERROR_SUCCESS) {
105 QMessageBox::warning(this, tr("Wine detected!"),
106 tr("It seems you are trying to run this program under Wine. "
107 "Please don't do this, running under Wine will fail. "
108 "Use the native Linux binary instead."),
109 QMessageBox::Ok, QMessageBox::Ok);
110 LOG_WARNING() << "WINE DETECTED!";
111 RegCloseKey(hk);
112 }
113#endif
114
115#if !defined(Q_OS_WIN32) && !defined(Q_OS_MACX)
116 /* eject funtionality is not available on Linux right now. */
117 ui.buttonEject->setEnabled(false);
118#endif
119 updateDevice();
120 downloadInfo();
121
122 m_gotInfo = false;
123 m_auto = false;
124
125 // selective "install" tab.
126 QGridLayout *selectivetablayout = new QGridLayout(this);
127 ui.selective->setLayout(selectivetablayout);
128 selectiveinstallwidget = new SelectiveInstallWidget(this);
129 selectivetablayout->addWidget(selectiveinstallwidget);
130 connect(ui.buttonChangeDevice, SIGNAL(clicked()), selectiveinstallwidget, SLOT(saveSettings()));
131
132 // info tab
133 QGridLayout *infotablayout = new QGridLayout(this);
134 ui.info->setLayout(infotablayout);
135 info = new InfoWidget(this);
136 infotablayout->addWidget(info);
137
138 connect(ui.tabWidget, SIGNAL(currentChanged(int)), this, SLOT(updateTabs(int)));
139 connect(ui.actionAbout_Qt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
140 connect(ui.action_About, SIGNAL(triggered()), this, SLOT(about()));
141 connect(ui.action_Help, SIGNAL(triggered()), this, SLOT(help()));
142 connect(ui.action_Configure, SIGNAL(triggered()), this, SLOT(configDialog()));
143 connect(ui.actionE_xit, SIGNAL(triggered()), this, SLOT(shutdown()));
144 connect(ui.buttonChangeDevice, SIGNAL(clicked()), this, SLOT(configDialog()));
145 connect(ui.buttonEject, SIGNAL(clicked()), this, SLOT(eject()));
146 connect(ui.buttonTalk, SIGNAL(clicked()), this, SLOT(createTalkFiles()));
147 connect(ui.buttonCreateVoice, SIGNAL(clicked()), this, SLOT(createVoiceFile()));
148 connect(ui.buttonRemoveRockbox, SIGNAL(clicked()), this, SLOT(uninstall()));
149 connect(ui.buttonRemoveBootloader, SIGNAL(clicked()), this, SLOT(uninstallBootloader()));
150 connect(ui.buttonBackup, SIGNAL(clicked()), this, SLOT(backup()));
151
152 // actions accessible from the menu
153 connect(ui.actionCreate_Voice_File, SIGNAL(triggered()), this, SLOT(createVoiceFile()));
154 connect(ui.actionCreate_Talk_Files, SIGNAL(triggered()), this, SLOT(createTalkFiles()));
155 connect(ui.actionRemove_bootloader, SIGNAL(triggered()), this, SLOT(uninstallBootloader()));
156 connect(ui.actionUninstall_Rockbox, SIGNAL(triggered()), this, SLOT(uninstall()));
157 connect(ui.action_System_Info, SIGNAL(triggered()), this, SLOT(sysinfo()));
158 connect(ui.action_Trace, SIGNAL(triggered()), this, SLOT(trace()));
159 connect(ui.actionShow_Changelog, SIGNAL(triggered()), this, SLOT(changelog()));
160
161#if !defined(STATIC)
162 ui.actionInstall_Rockbox_Utility_on_player->setEnabled(false);
163#else
164 connect(ui.actionInstall_Rockbox_Utility_on_player, SIGNAL(triggered()), this, SLOT(installPortable()));
165#endif
166 Utils::findRunningProcess(QStringList("iTunes"));
167
168}
169
170
171void RbUtilQt::shutdown(void)
172{
173 this->close();
174}
175
176
177void RbUtilQt::trace(void)
178{
179 SysTrace wnd(this);
180 wnd.exec();
181}
182
183void RbUtilQt::sysinfo(void)
184{
185 Sysinfo sysinfo(this);
186 sysinfo.exec();
187}
188
189void RbUtilQt::changelog(void)
190{
191
192 Changelog cl(this);
193 cl.exec();
194}
195
196
197void RbUtilQt::updateTabs(int count)
198{
199 if(count == ui.tabWidget->indexOf(info->parentWidget()))
200 info->updateInfo();
201}
202
203
204void RbUtilQt::downloadInfo()
205{
206 // try to get the current build information
207 daily = new HttpGet(this);
208 connect(daily, SIGNAL(done(bool)), this, SLOT(downloadDone(bool)));
209 connect(qApp, SIGNAL(lastWindowClosed()), daily, SLOT(abort()));
210 daily->setCache(false);
211 ui.statusbar->showMessage(tr("Downloading build information, please wait ..."));
212 LOG_INFO() << "downloading build info";
213 daily->setFile(&buildInfo);
214 daily->getFile(QUrl(PlayerBuildInfo::instance()->value(PlayerBuildInfo::BuildInfoUrl).toString()));
215}
216
217
218void RbUtilQt::downloadDone(bool error)
219{
220 if(error) {
221 LOG_INFO() << "network error:" << daily->errorString();
222 ui.statusbar->showMessage(tr("Can't get version information!"));
223 QMessageBox::critical(this, tr("Network error"),
224 tr("Can't get version information.\n"
225 "Network error: %1. Please check your network and proxy settings.")
226 .arg(daily->errorString()));
227 return;
228 }
229 LOG_INFO() << "network status:" << daily->errorString();
230
231 // read info into PlayerBuildInfo object
232 buildInfo.open();
233 PlayerBuildInfo::instance()->setBuildInfo(buildInfo.fileName());
234 buildInfo.close();
235
236 ui.statusbar->showMessage(tr("Download build information finished."), 5000);
237 if(RbSettings::value(RbSettings::RbutilVersion) != PUREVERSION
238 || RbSettings::value(RbSettings::ShowChangelog).toBool()) {
239 changelog();
240 }
241 updateSettings();
242 m_gotInfo = true;
243
244 //start check for updates
245 checkUpdate();
246
247}
248
249
250void RbUtilQt::about()
251{
252 QDialog *window = new QDialog(this);
253 Ui::aboutBox about;
254 about.setupUi(window);
255 window->setLayoutDirection(Qt::LeftToRight);
256 window->setModal(true);
257
258 QFile licence(":/docs/gpl-2.0.html");
259 licence.open(QIODevice::ReadOnly);
260 QTextStream c(&licence);
261 about.browserLicense->insertHtml(c.readAll());
262 about.browserLicense->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
263 licence.close();
264
265 QString html = "<p>" + tr("Libraries used") + "</p>";
266 html += "<ul>";
267 html += "<li>Speex: <a href='#speex'>Speex License</a></li>";
268 html += "<li>bspatch: <a href='#bspatch'>bspatch License</a></li>";
269 html += "<li>bzip2: <a href='#bzip2'>bzip2 License</a></li>";
270 html += "<li>mspack: <a href='#lgpl2'>LGPL v2.1 License</a></li>";
271 html += "<li>quazip: <a href='#lgpl2'>LGPL v2.1 License</a></li>";
272 html += "<li>tomcrypt: <a href='#tomcrypt'>Tomcrypt License</a></li>";
273 html += "<li>CuteLogger: <a href='#lgpl2'>LGPL v2.1 License</a></li>";
274 html += "</ul>";
275 about.browserLicenses->insertHtml(html);
276
277 QMap<QString, QString> licenses;
278 licenses[":/docs/COPYING.SPEEX"] = "<a id='speex'>Speex License</a>";
279 licenses[":/docs/lgpl-2.1.txt"] = "<a id='lgpl2'>LGPL v2.1</a>";
280 licenses[":/docs/LICENSE.TOMCRYPT"] = "<a id='tomcrypt'>Tomcrypt License</a>";
281 licenses[":/docs/LICENSE.BZIP2"] = "<a id='bzip2'>bzip2 License</a>";
282 licenses[":/docs/LICENSE.BSPATCH"] = "<a id='bspatch'>bspatch License</a>";
283
284 for (int i = 0; i < licenses.size(); i++) {
285 QString key = licenses.keys().at(i);
286 QFile license(key);
287 license.open(QIODevice::ReadOnly);
288 QTextStream s(&license);
289 about.browserLicenses->insertHtml("<hr/><h2>" + licenses[key] + "</h2><br/>\n");
290 about.browserLicenses->insertHtml("<pre>" + s.readAll() + "</pre>");
291 license.close();
292 }
293 about.browserLicenses->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
294
295 QFile credits(":/docs/CREDITS");
296 credits.open(QIODevice::ReadOnly);
297 QTextStream r(&credits);
298#if QT_VERSION < 0x060000
299 r.setCodec(QTextCodec::codecForName("UTF-8"));
300#else
301 r.setEncoding(QStringConverter::Utf8);
302#endif
303 while(!r.atEnd()) {
304 QString line = r.readLine();
305 // filter out header.
306 line.remove(QRegExp("^ +.*"));
307 line.remove(QRegExp("^People.*"));
308 about.browserCredits->append(line);
309 }
310 credits.close();
311 about.browserCredits->moveCursor(QTextCursor::Start, QTextCursor::MoveAnchor);
312 QString title = QString("<b>The Rockbox Utility</b><br/>Version %1").arg(FULLVERSION);
313 about.labelTitle->setText(title);
314
315 window->show();
316
317}
318
319
320void RbUtilQt::help()
321{
322 QUrl helpurl("http://www.rockbox.org/wiki/RockboxUtility");
323 QDesktopServices::openUrl(helpurl);
324}
325
326
327void RbUtilQt::configDialog()
328{
329 Config *cw = new Config(this);
330 connect(cw, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
331 cw->show();
332}
333
334
335void RbUtilQt::updateSettings()
336{
337 LOG_INFO() << "updating current settings";
338 updateDevice();
339 QString c = RbSettings::value(RbSettings::CachePath).toString();
340 HttpGet::setGlobalCache(c.isEmpty() ? QDir::tempPath() : c);
341 HttpGet::setGlobalProxy(proxy());
342
343 if(RbSettings::value(RbSettings::RbutilVersion) != PUREVERSION) {
344 QApplication::processEvents();
345 QMessageBox::information(this, tr("New installation"),
346 tr("This is a new installation of Rockbox Utility, or a new version. "
347 "The configuration dialog will now open to allow you to setup the program, "
348 " or review your settings."));
349 configDialog();
350 }
351 else if(chkConfig(nullptr)) {
352 QApplication::processEvents();
353 QMessageBox::critical(this, tr("Configuration error"),
354 tr("Your configuration is invalid. This is most likely due "
355 "to a changed device path. The configuration dialog will "
356 "now open to allow you to correct the problem."));
357 configDialog();
358 }
359 selectiveinstallwidget->updateVersion();
360}
361
362
363void RbUtilQt::updateDevice()
364{
365 /* TODO: We should check the flags of the bootloaderinstall classes, and not
366 * just check if its != none or != "fwpatcher" */
367
368 /* Enable bootloader installation, if possible */
369 bool bootloaderInstallable =
370 PlayerBuildInfo::instance()->value(PlayerBuildInfo::BootloaderMethod).toString() != "none";
371
372 /* Enable bootloader uninstallation, if possible */
373 bool bootloaderUninstallable = bootloaderInstallable &&
374 PlayerBuildInfo::instance()->value(PlayerBuildInfo::BootloaderMethod) != "fwpatcher";
375 ui.labelRemoveBootloader->setEnabled(bootloaderUninstallable);
376 ui.buttonRemoveBootloader->setEnabled(bootloaderUninstallable);
377 ui.actionRemove_bootloader->setEnabled(bootloaderUninstallable);
378
379 /* Disable the whole tab widget if configuration is invalid */
380 bool configurationValid = !chkConfig(nullptr);
381 ui.tabWidget->setEnabled(configurationValid);
382 ui.menuA_ctions->setEnabled(configurationValid);
383
384 // displayed device info
385 QString brand = PlayerBuildInfo::instance()->value(PlayerBuildInfo::Brand).toString();
386 QString name
387 = QString("%1 (%2)").arg(
388 PlayerBuildInfo::instance()->value(PlayerBuildInfo::DisplayName).toString(),
389 PlayerBuildInfo::instance()->statusAsString());
390 ui.labelDevice->setText(QString("<b>%1 %2</b>").arg(brand, name));
391
392 QString mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
393 QString mountdisplay = QDir::toNativeSeparators(mountpoint);
394 if(!mountdisplay.isEmpty()) {
395 QString label = Utils::filesystemName(mountpoint);
396 if(!label.isEmpty()) mountdisplay += QString(" (%1)").arg(label);
397 ui.labelMountpoint->setText(QString("<b>%1</b>").arg(mountdisplay));
398 }
399 else {
400 mountdisplay = "(unknown)";
401 }
402
403 QPixmap pm;
404 QString m = PlayerBuildInfo::instance()->value(PlayerBuildInfo::PlayerPicture).toString();
405 pm.load(":/icons/players/" + m + "-small.png");
406 pm = pm.scaledToHeight(QFontMetrics(QApplication::font()).height() * 3);
407 ui.labelPlayerPic->setPixmap(pm);
408
409}
410
411
412void RbUtilQt::backup(void)
413{
414 backupdialog = new BackupDialog(this);
415 backupdialog->show();
416
417}
418
419
420void RbUtilQt::installdone(bool error)
421{
422 LOG_INFO() << "install done";
423 m_installed = true;
424 m_error = error;
425}
426
427
428void RbUtilQt::createTalkFiles(void)
429{
430 if(chkConfig(this)) return;
431 InstallTalkWindow *installWindow = new InstallTalkWindow(this);
432 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
433 installWindow->show();
434
435}
436
437void RbUtilQt::createVoiceFile(void)
438{
439 if(chkConfig(this)) return;
440 CreateVoiceWindow *installWindow = new CreateVoiceWindow(this);
441
442 connect(installWindow, SIGNAL(settingsUpdated()), this, SLOT(updateSettings()));
443 installWindow->show();
444}
445
446void RbUtilQt::uninstall(void)
447{
448 if(chkConfig(this)) return;
449 UninstallWindow *uninstallWindow = new UninstallWindow(this);
450 uninstallWindow->show();
451
452}
453
454void RbUtilQt::uninstallBootloader(void)
455{
456 if(chkConfig(this)) return;
457 if(QMessageBox::question(this, tr("Confirm Uninstallation"),
458 tr("Do you really want to uninstall the Bootloader?"),
459 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) return;
460 // create logger
461 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
462 logger->show();
463
464 QString platform = RbSettings::value(RbSettings::Platform).toString();
465
466 // create installer
467 BootloaderInstallBase *bl
468 = BootloaderInstallHelper::createBootloaderInstaller(this,
469 PlayerBuildInfo::instance()->value(PlayerBuildInfo::BootloaderMethod).toString());
470
471 if(bl == nullptr) {
472 logger->addItem(tr("No uninstall method for this target known."), LOGERROR);
473 logger->setFinished();
474 return;
475 }
476 QStringList blfile = PlayerBuildInfo::instance()->value(PlayerBuildInfo::BootloaderFile).toStringList();
477 QStringList blfilepath;
478 for(int a = 0; a < blfile.size(); a++) {
479 blfilepath.append(RbSettings::value(RbSettings::Mountpoint).toString()
480 + blfile.at(a));
481 }
482 bl->setBlFile(blfilepath);
483 bl->setLogfile(RbSettings::value(RbSettings::Mountpoint).toString()
484 + "/.rockbox/rbutil.log");
485
486 BootloaderInstallBase::BootloaderType currentbl = bl->installed();
487 if((bl->capabilities() & BootloaderInstallBase::Uninstall) == 0) {
488 logger->addItem(tr("Rockbox Utility can not uninstall the bootloader on your player. "
489 "Please perform a firmware update using your player vendors "
490 "firmware update process."), LOGERROR);
491 logger->addItem(tr("Important: make sure to boot your player into the original "
492 "firmware before using the vendors firmware update process."), LOGERROR);
493 logger->setFinished();
494 delete bl;
495 return;
496 }
497 if(currentbl == BootloaderInstallBase::BootloaderUnknown
498 || currentbl == BootloaderInstallBase::BootloaderOther) {
499 logger->addItem(tr("No Rockbox bootloader found."), LOGERROR);
500 logger->setFinished();
501 delete bl;
502 return;
503 }
504
505 connect(bl, SIGNAL(logItem(QString, int)), logger, SLOT(addItem(QString, int)));
506 connect(bl, SIGNAL(logProgress(int, int)), logger, SLOT(setProgress(int, int)));
507 connect(bl, SIGNAL(done(bool)), logger, SLOT(setFinished()));
508 // pass Abort button click signal to current installer
509 connect(logger, SIGNAL(aborted()), bl, SLOT(progressAborted()));
510
511 bl->uninstall();
512
513}
514
515
516void RbUtilQt::installPortable(void)
517{
518 if(QMessageBox::question(this, tr("Confirm installation"),
519 tr("Do you really want to install Rockbox Utility to your player? "
520 "After installation you can run it from the players hard drive."),
521 QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes)
522 return;
523
524 ProgressLoggerGui* logger = new ProgressLoggerGui(this);
525 logger->setProgressMax(0);
526 logger->setProgressValue(0);
527 logger->show();
528 logger->addItem(tr("Installing Rockbox Utility"), LOGINFO);
529
530 // check mountpoint
531 if(!QFileInfo(RbSettings::value(RbSettings::Mountpoint).toString()).isDir()) {
532 logger->addItem(tr("Mount point is wrong!"),LOGERROR);
533 logger->setFinished();
534 return;
535 }
536
537 // remove old files first.
538 QFile::remove(RbSettings::value(RbSettings::Mountpoint).toString()
539 + "/RockboxUtility.exe");
540 QFile::remove(RbSettings::value(RbSettings::Mountpoint).toString()
541 + "/RockboxUtility.ini");
542 // copy currently running binary and currently used settings file
543 if(!QFile::copy(qApp->applicationFilePath(),
544 RbSettings::value(RbSettings::Mountpoint).toString()
545 + "/RockboxUtility.exe")) {
546 logger->addItem(tr("Error installing Rockbox Utility"), LOGERROR);
547 logger->setFinished();
548 return;
549 }
550 logger->addItem(tr("Installing user configuration"), LOGINFO);
551 if(!QFile::copy(RbSettings::userSettingFilename(),
552 RbSettings::value(RbSettings::Mountpoint).toString()
553 + "/RockboxUtility.ini")) {
554 logger->addItem(tr("Error installing user configuration"), LOGERROR);
555 logger->setFinished();
556 return;
557 }
558 logger->addItem(tr("Successfully installed Rockbox Utility."), LOGOK);
559 logger->setFinished();
560 logger->setProgressMax(1);
561 logger->setProgressValue(1);
562
563}
564
565
566QUrl RbUtilQt::proxy()
567{
568 QUrl proxy;
569 QString proxytype = RbSettings::value(RbSettings::ProxyType).toString();
570 if(proxytype == "manual") {
571 proxy.setUrl(RbSettings::value(RbSettings::Proxy).toString(),
572 QUrl::TolerantMode);
573 QByteArray pw = QByteArray::fromBase64(proxy.password().toUtf8());
574 proxy.setPassword(pw);
575 }
576 else if(proxytype == "system")
577 proxy = System::systemProxy();
578
579 LOG_INFO() << "Proxy is" << proxy;
580 return proxy;
581}
582
583
584bool RbUtilQt::chkConfig(QWidget *parent)
585{
586 bool error = false;
587 if(RbSettings::value(RbSettings::Platform).toString().isEmpty()
588 || RbSettings::value(RbSettings::Mountpoint).toString().isEmpty()
589 || !QFileInfo(RbSettings::value(RbSettings::Mountpoint).toString()).isWritable()) {
590 error = true;
591
592 if(parent) QMessageBox::critical(parent, tr("Configuration error"),
593 tr("Your configuration is invalid. Please go to the configuration "
594 "dialog and make sure the selected values are correct."));
595 }
596 return error;
597}
598
599void RbUtilQt::checkUpdate(void)
600{
601 QString url = PlayerBuildInfo::instance()->value(PlayerBuildInfo::RbutilUrl).toString();
602#if defined(Q_OS_WIN32)
603 url += "win32/";
604#elif defined(Q_OS_LINUX)
605 url += "linux/";
606#elif defined(Q_OS_MACX)
607 url += "macosx/";
608#endif
609
610 update = new HttpGet(this);
611 connect(update, SIGNAL(done(bool)), this, SLOT(downloadUpdateDone(bool)));
612 connect(qApp, SIGNAL(lastWindowClosed()), update, SLOT(abort()));
613
614 ui.statusbar->showMessage(tr("Checking for update ..."));
615 update->getFile(QUrl(url));
616}
617
618void RbUtilQt::downloadUpdateDone(bool error)
619{
620 if(error) {
621 LOG_INFO() << "network error:" << update->errorString();
622 }
623 else {
624 QString toParse(update->readAll());
625
626 QRegExp searchString("<a[^>]*>([a-zA-Z]+[^<]*)</a>");
627 QStringList rbutilList;
628 int pos = 0;
629 while ((pos = searchString.indexIn(toParse, pos)) != -1)
630 {
631 rbutilList << searchString.cap(1);
632 pos += searchString.matchedLength();
633 }
634 LOG_INFO() << "Checking for update";
635
636 QString newVersion = "";
637 QString foundVersion = "";
638 // check if there is a binary with higher version in this list
639 for(int i=0; i < rbutilList.size(); i++)
640 {
641 QString item = rbutilList.at(i);
642#if defined(Q_OS_LINUX)
643#if defined(__amd64__)
644 // skip if it isn't a 64 bit build
645 if( !item.contains("64bit"))
646 continue;
647 // strip the "64bit" suffix for comparison
648 item = item.remove("64bit");
649#else
650 //skip if it is a 64bit build
651 if(item.contains("64bit"))
652 continue;
653#endif
654#endif
655 // check if it is newer, and remember newest
656 if(Utils::compareVersionStrings(VERSION, item) == 1)
657 {
658 if(Utils::compareVersionStrings(newVersion, item) == 1)
659 {
660 newVersion = item;
661 foundVersion = rbutilList.at(i);
662 }
663 }
664 }
665
666 // if we found something newer, display info
667 if(foundVersion != "")
668 {
669 QString url = PlayerBuildInfo::instance()->value(PlayerBuildInfo::RbutilUrl).toString();
670#if defined(Q_OS_WIN32)
671 url += "win32/";
672#elif defined(Q_OS_LINUX)
673 url += "linux/";
674#elif defined(Q_OS_MACX)
675 url += "macosx/";
676#endif
677 url += foundVersion;
678
679 QMessageBox::information(this,tr("Rockbox Utility Update available"),
680 tr("<b>New Rockbox Utility version available.</b><br><br>"
681 "You are currently using version %1. "
682 "Get version %2 at <a href='%3'>%3</a>")
683 .arg(VERSION).arg(Utils::trimVersionString(foundVersion)).arg(url));
684 ui.statusbar->showMessage(tr("New version of Rockbox Utility available."));
685 }
686 else {
687 ui.statusbar->showMessage(tr("Rockbox Utility is up to date."), 5000);
688 }
689 }
690}
691
692
693void RbUtilQt::changeEvent(QEvent *e)
694{
695 if(e->type() == QEvent::LanguageChange) {
696 ui.retranslateUi(this);
697 buildInfo.open();
698 PlayerBuildInfo::instance()->setBuildInfo(buildInfo.fileName());
699 buildInfo.close();
700 updateDevice();
701 } else {
702 QMainWindow::changeEvent(e);
703 }
704}
705
706void RbUtilQt::eject(void)
707{
708 QString mountpoint = RbSettings::value(RbSettings::Mountpoint).toString();
709 if(Utils::ejectDevice(mountpoint)) {
710 QMessageBox::information(this, tr("Device ejected"),
711 tr("Device successfully ejected. "
712 "You may now disconnect the player from the PC."));
713 }
714 else {
715 QMessageBox::critical(this, tr("Ejecting failed"),
716 tr("Ejecting the device failed. Please make sure no programs "
717 "are accessing files on the device. If ejecting still "
718 "fails please use your computers eject funtionality."));
719 }
720}
721