diff options
author | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2021-12-15 21:04:28 +0100 |
---|---|---|
committer | Dominik Riebeling <Dominik.Riebeling@gmail.com> | 2021-12-24 18:05:53 +0100 |
commit | c876d3bbefe0dc00c27ca0c12d29da5874946962 (patch) | |
tree | 69f468a185a369b01998314bc3ecc19b70f4fcaa /utils/rbutilqt/rbutilqt.cpp | |
parent | 6c6f0757d7a902feb293be165d1490c42bc8e7ad (diff) | |
download | rockbox-c876d3bbefe0dc00c27ca0c12d29da5874946962.tar.gz rockbox-c876d3bbefe0dc00c27ca0c12d29da5874946962.zip |
rbutil: Merge rbutil with utils folder.
rbutil uses several components from the utils folder, and can be
considered part of utils too. Having it in a separate folder is an
arbitrary split that doesn't help anymore these days, so merge them.
This also allows other utils to easily use libtools.make without the
need to navigate to a different folder.
Change-Id: I3fc2f4de19e3e776553efb5dea5f779dfec0dc21
Diffstat (limited to 'utils/rbutilqt/rbutilqt.cpp')
-rw-r--r-- | utils/rbutilqt/rbutilqt.cpp | 721 |
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 | |||
64 | QList<QTranslator*> RbUtilQt::translators; | ||
65 | |||
66 | RbUtilQt::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 | |||
171 | void RbUtilQt::shutdown(void) | ||
172 | { | ||
173 | this->close(); | ||
174 | } | ||
175 | |||
176 | |||
177 | void RbUtilQt::trace(void) | ||
178 | { | ||
179 | SysTrace wnd(this); | ||
180 | wnd.exec(); | ||
181 | } | ||
182 | |||
183 | void RbUtilQt::sysinfo(void) | ||
184 | { | ||
185 | Sysinfo sysinfo(this); | ||
186 | sysinfo.exec(); | ||
187 | } | ||
188 | |||
189 | void RbUtilQt::changelog(void) | ||
190 | { | ||
191 | |||
192 | Changelog cl(this); | ||
193 | cl.exec(); | ||
194 | } | ||
195 | |||
196 | |||
197 | void RbUtilQt::updateTabs(int count) | ||
198 | { | ||
199 | if(count == ui.tabWidget->indexOf(info->parentWidget())) | ||
200 | info->updateInfo(); | ||
201 | } | ||
202 | |||
203 | |||
204 | void 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 | |||
218 | void 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 | |||
250 | void 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 | |||
320 | void RbUtilQt::help() | ||
321 | { | ||
322 | QUrl helpurl("http://www.rockbox.org/wiki/RockboxUtility"); | ||
323 | QDesktopServices::openUrl(helpurl); | ||
324 | } | ||
325 | |||
326 | |||
327 | void RbUtilQt::configDialog() | ||
328 | { | ||
329 | Config *cw = new Config(this); | ||
330 | connect(cw, SIGNAL(settingsUpdated()), this, SLOT(updateSettings())); | ||
331 | cw->show(); | ||
332 | } | ||
333 | |||
334 | |||
335 | void 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 | |||
363 | void 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 | |||
412 | void RbUtilQt::backup(void) | ||
413 | { | ||
414 | backupdialog = new BackupDialog(this); | ||
415 | backupdialog->show(); | ||
416 | |||
417 | } | ||
418 | |||
419 | |||
420 | void RbUtilQt::installdone(bool error) | ||
421 | { | ||
422 | LOG_INFO() << "install done"; | ||
423 | m_installed = true; | ||
424 | m_error = error; | ||
425 | } | ||
426 | |||
427 | |||
428 | void 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 | |||
437 | void 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 | |||
446 | void RbUtilQt::uninstall(void) | ||
447 | { | ||
448 | if(chkConfig(this)) return; | ||
449 | UninstallWindow *uninstallWindow = new UninstallWindow(this); | ||
450 | uninstallWindow->show(); | ||
451 | |||
452 | } | ||
453 | |||
454 | void 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 | |||
516 | void 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 | |||
566 | QUrl 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 | |||
584 | bool 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 | |||
599 | void 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 | |||
618 | void 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 | |||
693 | void 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 | |||
706 | void 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 | |||