bool BootloaderInstallFile::uninstall(void) { qDebug() << "[BootloaderInstallFile] Uninstalling bootloader"; emit logItem(tr("Removing Rockbox bootloader"), LOGINFO); // check if a .ORIG file is present, and allow moving it back. QString origbl = Utils::resolvePathCase(m_blfile + ".ORIG"); if(origbl.isEmpty()) { emit logItem(tr("No original firmware file found."), LOGERROR); emit done(true); return false; } QString fwfile = Utils::resolvePathCase(m_blfile); if(!QFile::remove(fwfile)) { emit logItem(tr("Can't remove Rockbox bootloader file."), LOGERROR); emit done(true); return false; } if(!QFile::rename(origbl, fwfile)) { emit logItem(tr("Can't restore bootloader file."), LOGERROR); emit done(true); return false; } emit logItem(tr("Original bootloader restored successfully."), LOGOK); logInstall(LogRemove); emit done(false); return true; }
void BootloaderInstallBase::checkRemount() { #if defined(Q_OS_MACX) if(m_remountTries--) { int status = 0; // check if device has been remounted QCoreApplication::processEvents(); int num; struct statfs *mntinf; num = getmntinfo(&mntinf, MNT_WAIT); while(num--) { if(QString(mntinf->f_mntfromname).startsWith(m_remountDevice) && QString(mntinf->f_fstypename).contains("msdos", Qt::CaseInsensitive)) status = 1; mntinf++; } if(!status) { // still not remounted, restart timer. QTimer::singleShot(500, this, SLOT(checkRemount())); qDebug() << "[BootloaderInstallBase] Player not remounted yet" << m_remountDevice; } else { emit logItem(tr("Player remounted"), LOGINFO); emit remounted(true); } } else { emit logItem(tr("Timeout on remount"), LOGERROR); emit remounted(false); } #endif }
void BootloaderInstallBase::downloadBlFinish(bool error) { qDebug() << "[BootloaderInstallBase] Downloading bootloader finished, error:" << error; // update progress bar emit logProgress(100, 100); if(m_http.httpResponse() != 200) { emit logItem(tr("Download error: received HTTP error %1.") .arg(m_http.errorString()), LOGERROR); emit done(true); return; } if(error) { emit logItem(tr("Download error: %1") .arg(m_http.error()), LOGERROR); emit done(true); return; } else if(m_http.isCached()) emit logItem(tr("Download finished (cache used)."), LOGOK); else emit logItem(tr("Download finished."), LOGOK); QCoreApplication::processEvents(); m_blversion = m_http.timestamp(); emit downloadDone(); }
bool BootloaderInstallMi4::uninstall(void) { qDebug() << "[BootloaderInstallMi4] Uninstalling bootloader"; // check if it's actually a Rockbox bootloader emit logItem(tr("Checking for Rockbox bootloader"), LOGINFO); if(installed() != BootloaderRockbox) { emit logItem(tr("No Rockbox bootloader found"), LOGERROR); return false; } // check if OF file present emit logItem(tr("Checking for original firmware file"), LOGINFO); QString original = QFileInfo(Utils::resolvePathCase(m_blfile)).absolutePath() + "/OF.mi4"; if(Utils::resolvePathCase(original).isEmpty()) { emit logItem(tr("Error finding original firmware file"), LOGERROR); return false; } // finally remove RB bootloader QString resolved = Utils::resolvePathCase(m_blfile); QFile blfile(resolved); blfile.remove(); QFile::rename(Utils::resolvePathCase(original), m_blfile); emit logItem(tr("Rockbox bootloader successful removed"), LOGINFO); logInstall(LogRemove); emit done(false); return true; }
void BootloaderInstallMi4::installStage2(void) { emit logItem(tr("Installing Rockbox bootloader"), LOGINFO); QCoreApplication::processEvents(); // move old bootloader out of the way QString fwfile(resolvePathCase(m_blfile)); QFile oldbl(fwfile); QString moved = QFileInfo(resolvePathCase(m_blfile)).absolutePath() + "/OF.mi4"; if(!QFileInfo(moved).exists()) { qDebug() << "[BootloaderInstallMi4] renaming" << fwfile << "to" << moved; oldbl.rename(moved); } else { qDebug() << "[BootloaderInstallMi4] OF.mi4 already present, not renaming again."; oldbl.remove(); } // place new bootloader m_tempfile.open(); qDebug() << "[BootloaderInstallMi4] renaming" << m_tempfile.fileName() << "to" << fwfile; m_tempfile.close(); m_tempfile.rename(fwfile); emit logItem(tr("Bootloader successful installed"), LOGOK); logInstall(LogAdd); emit done(false); }
void BootloaderInstallFile::installStage2(void) { emit logItem(tr("Installing Rockbox bootloader"), LOGINFO); QCoreApplication::processEvents(); // if an old bootloader is present (Gigabeat) move it out of the way. QString fwfile(Utils::resolvePathCase(m_blfile)); if(!fwfile.isEmpty()) { QString moved = Utils::resolvePathCase(m_blfile) + ".ORIG"; qDebug() << "[BootloaderInstallFile] renaming" << fwfile << "to" << moved; QFile::rename(fwfile, moved); } // if no old file found resolve path without basename QFileInfo fi(m_blfile); QString absPath = Utils::resolvePathCase(fi.absolutePath()); // if it's not possible to locate the base path try to create it if(absPath.isEmpty()) { QStringList pathElements = m_blfile.split("/"); // remove filename from list and save last path element pathElements.removeLast(); QString lastElement = pathElements.last(); // remove last path element for base pathElements.removeLast(); QString basePath = pathElements.join("/"); // check for base and bail out if not found. Otherwise create folder. absPath = Utils::resolvePathCase(basePath); QDir d(absPath); d.mkpath(lastElement); absPath = Utils::resolvePathCase(fi.absolutePath()); if(absPath.isEmpty()) { emit logItem(tr("Error accessing output folder"), LOGERROR); emit done(true); return; } } fwfile = absPath + "/" + fi.fileName(); // place (new) bootloader m_tempfile.open(); qDebug() << "[BootloaderInstallFile] renaming" << m_tempfile.fileName() << "to" << fwfile; m_tempfile.close(); m_tempfile.copy(fwfile); emit logItem(tr("Bootloader successful installed"), LOGOK); logInstall(LogAdd); emit done(false); }
//! \brief slot, which is connected to the abort of the Logger. Sets a flag, so Creating Talkfiles ends at the next possible position //! void TalkGenerator::abort() { if (ttsFutureWatcher.isRunning()) { ttsFutureWatcher.cancel(); emit logItem(tr("Voicing aborted"), LOGERROR); } if (encFutureWatcher.isRunning()) { encFutureWatcher.cancel(); emit logItem(tr("Encoding aborted"), LOGERROR); } }
void AMActionHistoryModel3::markIndexGroup(const QModelIndex &index, QAbstractItemView *viewer, bool selected){ // Just do the regular markParentSelected if this is a top-level action log item (parent index is invalid) if(!index.parent().isValid()){ recurseMarkParentSelected(index, viewer, selected); return; } // Check if the action log item inherited the loop action (if so, then we need to multi-select/deselect the children) AMActionLogItem3 *item = logItem(index.parent()); if(item->actionInheritedLoop()){ // Figure out your index in the original loop, and select/deselect all of your siblings with the same loop index int actionsPerLoop = rowCount(index.parent())/item->numberOfLoops(); int indexInLoop = (index.row()%actionsPerLoop); QModelIndex markingIndex; for(int x = 0; x < rowCount(index.parent()); x++){ if(x%actionsPerLoop == indexInLoop){ markingIndex = this->index(x, 0, index.parent()); recurseMarkParentSelected(markingIndex, viewer, selected); emit dataChanged(markingIndex, markingIndex); } } } else recurseMarkParentSelected(index, viewer, selected); // Check to see if there are any children left at this level. If not, then deselect the parent as well (no point selecting a list or loop when the user has removed all of the contents) int siblingsSelected = 0; for(int x = 0; x < rowCount(index.parent()); x++){ ParentSelectMap selectMap = data(this->index(x, 0, index.parent()), AMActionHistoryModel3::ParentSelectRole).value<ParentSelectMap>(); if(selectMap.contains(viewer) && selectMap.value(viewer)) siblingsSelected++; } if(siblingsSelected == 0){ // Actually deselect in the selection model if the parent was actually selected if(viewer->selectionModel()->isSelected(index.parent())){ QItemSelectionModel::SelectionFlags deselectFlag = QItemSelectionModel::Deselect; viewer->selectionModel()->select(index.parent(), deselectFlag); ParentSelectMap selectMap = data(index.parent(), AMActionHistoryModel3::ParentSelectRole).value<ParentSelectMap>(); if(selectMap.contains(viewer)){ AMActionLogItem3 *item = logItem(index.parent()); // Make sure it doesn't get parentSelected somehow item->setParentSelected(viewer, false); } emit dataChanged(index.parent(), index.parent()); } // Otherwise just use the group deselect for the parentSelected mapping else markIndexGroupAsDeselected(index.parent(), viewer); } }
/** Finish bootloader installation. */ void BootloaderInstallSansa::installStage2(void) { struct sansa_t sansa; emit logItem(tr("Installing Rockbox bootloader"), LOGINFO); QCoreApplication::processEvents(); if(!sansaInitialize(&sansa)) { emit done(true); return; } if(sansa_reopen_rw(&sansa) < 0) { emit logItem(tr("Could not open Sansa in R/W mode"), LOGERROR); emit done(true); return; } // check model -- if sansapatcher reports a c200 don't install an e200 // bootloader and vice versa. // The model is available in the mi4 file at offset 0x1fc and matches // the targetname set by sansapatcher. emit logItem(tr("Checking downloaded bootloader"), LOGINFO); m_tempfile.open(); QString blfile = m_tempfile.fileName(); char magic[4]; m_tempfile.seek(0x1fc); m_tempfile.read(magic, 4); m_tempfile.close(); if(memcmp(sansa.targetname, magic, 4) != 0) { emit logItem(tr("Bootloader mismatch! Aborting."), LOGERROR); qDebug("[BootloaderInstallSansa] Targetname: %s, mi4 magic: %c%c%c%c", sansa.targetname, magic[0], magic[1], magic[2], magic[3]); emit done(true); sansa_close(&sansa); return; } if(sansa_add_bootloader(&sansa, blfile.toLatin1().data(), FILETYPE_MI4) == 0) { emit logItem(tr("Successfully installed bootloader"), LOGOK); sansa_close(&sansa); #if defined(Q_OS_MACX) m_remountDevice = sansa.diskname; connect(this, SIGNAL(remounted(bool)), this, SLOT(installStage3(bool))); waitRemount(); #else installStage3(true); #endif }
void TalkGenerator::ttsFailEntry(const TalkEntry& entry, TTSStatus status, QString error) { if(status == Warning) { m_ttsWarnings = true; emit logItem(tr("Voicing of %1 failed: %2").arg(entry.toSpeak).arg(error), LOGWARNING); } else if (status == FatalError) { emit logItem(tr("Voicing of %1 failed: %2").arg(entry.toSpeak).arg(error), LOGERROR); abort(); } }
void BootloaderInstallBase::waitRemount() { m_remountTries = 600; emit logItem(tr("Waiting for system to remount player"), LOGINFO); QTimer::singleShot(100, this, SLOT(checkRemount())); }
void ZipInstaller::installStart() { qDebug() << "[ZipInstall] starting installation"; emit logItem(tr("Downloading file %1.%2").arg(QFileInfo(m_url).baseName(), QFileInfo(m_url).completeSuffix()),LOGINFO); // temporary file needs to be opened to get the filename // make sure to get a fresh one on each run. // making this a parent of the temporary file ensures the file gets deleted // after the class object gets destroyed. downloadFile = new QTemporaryFile(this); downloadFile->open(); m_file = downloadFile->fileName(); downloadFile->close(); // get the real file. getter = new HttpGet(this); if(m_usecache) { getter->setCache(true); } getter->setFile(downloadFile); connect(getter, SIGNAL(done(bool)), this, SLOT(downloadDone(bool))); connect(getter, SIGNAL(dataReadProgress(int, int)), this, SIGNAL(logProgress(int, int))); connect(this, SIGNAL(internalAborted()), getter, SLOT(abort())); getter->getFile(QUrl(m_url)); }
PassRefPtr<JSONObject> AutoLogger::logItemWithParams(const String& name) { RefPtr<JSONObject> item = logItem(name); RefPtr<JSONObject> params = JSONObject::create(); item->setObject("params", params); return params.release(); }
//! \brief Cleans up Files potentially left in the temp dir //! bool TalkFileCreator::cleanup() { emit logItem(tr("Cleaning up..."),LOGINFO); for(int i=0; i < m_talkList.size(); i++) { if(QFile::exists(m_talkList[i].wavfilename)) QFile::remove(m_talkList[i].wavfilename); if(QFile::exists(m_talkList[i].talkfilename)) QFile::remove(m_talkList[i].talkfilename); QCoreApplication::processEvents(); } emit logItem(tr("Finished"),LOGINFO); return true; }
bool BootloaderInstallHex::uninstall(void) { emit logItem(tr("Uninstallation not possible, only installation info removed"), LOGINFO); logInstall(LogRemove); emit done(true); return false; }
bool BootloaderInstallAms::uninstall(void) { emit logItem(tr("To uninstall, perform a normal upgrade with an unmodified " "original firmware"), LOGINFO); logInstall(LogRemove); return false; }
//! \brief Encodes a List of strings //! TalkGenerator::Status TalkGenerator::encodeList(QList<TalkEntry>* list) { QStringList dublicates; int progressMax = list->size(); int m_progress = 0; emit logProgress(m_progress,progressMax); for(int i=0; i < list->size(); i++) { if(m_abort) { emit logItem(tr("Encoding aborted"), LOGERROR); return eERROR; } //skip non-voiced entrys if(list->at(i).voiced == false) { qDebug() << "non voiced entry" << list->at(i).toSpeak <<"detected"; emit logProgress(++m_progress,progressMax); continue; } //skip dublicates if(!dublicates.contains(list->at(i).talkfilename)) dublicates.append(list->at(i).talkfilename); else { qDebug() << "dublicate skipped"; (*list)[i].encoded = true; emit logProgress(++m_progress,progressMax); continue; } //encode entry qDebug() << "encoding " << list->at(i).wavfilename << "to" << list->at(i).talkfilename; if(!m_enc->encode(list->at(i).wavfilename,list->at(i).talkfilename)) { emit logItem(tr("Encoding of %1 failed").arg(list->at(i).wavfilename), LOGERROR); return eERROR; } (*list)[i].encoded = true; emit logProgress(++m_progress,progressMax); QCoreApplication::processEvents(); } return eOK; }
void discardable sys_init(void) { logItem("Initializing System Management"); sys_arch_init(); logStatus(logSuccess); }
bool BootloaderInstallMi4::install(void) { emit logItem(tr("Downloading bootloader"), LOGINFO); qDebug() << "[BootloaderInstallMi4] installing bootloader"; downloadBlStart(m_blurl); connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2())); return true; }
bool BootloaderInstallBase::backup(QString to) { qDebug() << "[BootloaderInstallBase] Backing up bootloader file"; QDir targetDir("."); emit logItem(tr("Creating backup of original firmware file."), LOGINFO); if(!targetDir.mkpath(to)) { emit logItem(tr("Creating backup folder failed"), LOGERROR); return false; } QString tofile = to + "/" + QFileInfo(m_blfile).fileName(); qDebug() << "[BootloaderInstallBase] trying to backup" << m_blfile << "to" << tofile; if(!QFile::copy(Utils::resolvePathCase(m_blfile), tofile)) { emit logItem(tr("Creating backup copy failed."), LOGERROR); return false; } emit logItem(tr("Backup created."), LOGOK); return true; }
void BootloaderInstallMi4::installStage2(void) { emit logItem(tr("Installing Rockbox bootloader"), LOGINFO); QCoreApplication::processEvents(); // move old bootloader out of the way QString fwfile(Utils::resolvePathCase(m_blfile)); QFile oldbl(fwfile); QString moved = QFileInfo(Utils::resolvePathCase(m_blfile)).absolutePath() + "/OF.mi4"; if(!QFileInfo(moved).exists()) { LOG_INFO() << "renaming" << fwfile << "to" << moved; oldbl.rename(moved); } else { LOG_INFO() << "OF.mi4 already present, not renaming again."; oldbl.remove(); } // place new bootloader m_tempfile.open(); LOG_INFO() << "renaming" << m_tempfile.fileName() << "to" << fwfile; m_tempfile.close(); if(!Utils::resolvePathCase(fwfile).isEmpty()) { emit logItem(tr("A firmware file is already present on player"), LOGERROR); emit done(true); return; } if(m_tempfile.copy(fwfile)) { emit logItem(tr("Bootloader successful installed"), LOGOK); } else { emit logItem(tr("Copying modified firmware file failed"), LOGERROR); emit done(true); return; } emit logItem(tr("Bootloader successful installed"), LOGOK); logInstall(LogAdd); emit done(false); }
//! @brief log installation to logfile. //! @param mode action to perform. 0: add to log, 1: remove from log. //! @return 0 on success int BootloaderInstallBase::logInstall(LogMode mode) { int result = 0; QString section = m_blurl.path().section('/', -1); QSettings s(m_logfile, QSettings::IniFormat, this); emit logItem(tr("Creating installation log"), LOGINFO); if(mode == LogAdd) { s.setValue("Bootloader/" + section, m_blversion.toString(Qt::ISODate)); qDebug() << "[BootloaderInstallBase] Writing log, version:" << m_blversion.toString(Qt::ISODate); } else { s.remove("Bootloader/" + section); } s.sync(); emit logItem(tr("Installation log created"), LOGOK); return result; }
bool BootloaderInstallBase::setOfFile(QString of, QStringList blfile) { bool found = false; ZipUtil z(this); // check if the file set is in zip format if(z.open(of)) { emit logItem(tr("Zip file format detected"), LOGINFO); QStringList contents = z.files(); qDebug() << "[BootloaderInstallBase] archive contains:" << contents; for(int i = 0; i < blfile.size(); ++i) { // strip any path, we don't know the structure in the zip QString f = QFileInfo(blfile.at(i)).fileName(); qDebug() << "[BootloaderInstallBase] searching archive for" << f; int index = contents.indexOf(f); // FIXME: support files in folders if(index >= 0) { found = true; emit logItem(tr("Extracting firmware %1 from archive") .arg(f), LOGINFO); // store in class temporary file m_tempof.open(); m_offile = m_tempof.fileName(); m_tempof.close(); if(!z.extractArchive(m_offile, contents.at(index))) { emit logItem(tr("Error extracting firmware from archive"), LOGERROR); found = false; break; } } } if(!found) { emit logItem(tr("Could not find firmware in archive"), LOGERROR); } } else { m_offile = of; found = true; } return found; }
bool BootloaderInstallTcc::install(void) { if(m_offile.isEmpty()) return false; // Download firmware from server emit logItem(tr("Downloading bootloader file"), LOGINFO); connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2())); downloadBlStart(m_blurl); return true; }
void ZipInstaller::installContinue() { qDebug() << "[ZipInstall] continuing installation"; runner++; // this gets called when a install finished, so increase first. qDebug() << "[ZipInstall] runner done:" << runner << "/" << m_urllist.size(); if(runner < m_urllist.size()) { emit logItem(tr("done."), LOGOK); m_url = m_urllist.at(runner); m_logsection = m_loglist.at(runner); if(runner < m_verlist.size()) m_logver = m_verlist.at(runner); else m_logver = "0"; installStart(); } else { emit logItem(tr("Installation finished successfully."), LOGOK); emit done(false); return; } }
void ZipInstaller::downloadDone(bool error) { qDebug() << "[ZipInstall] download done, error:" << error; QStringList zipContents; // needed later // update progress bar emit logProgress(1, 1); if(getter->httpResponse() != 200 && !getter->isCached()) { emit logItem(tr("Download error: received HTTP error %1.") .arg(getter->httpResponse()),LOGERROR); emit done(true); return; } if(getter->isCached()) emit logItem(tr("Cached file used."), LOGINFO); if(error) { emit logItem(tr("Download error: %1").arg(getter->errorString()), LOGERROR); emit done(true); return; } else emit logItem(tr("Download finished."),LOGOK); QCoreApplication::processEvents(); if(m_unzip) { // unzip downloaded file qDebug() << "[ZipInstall] about to unzip " << m_file << "to" << m_mountpoint; emit logItem(tr("Extracting file."), LOGINFO); QCoreApplication::processEvents(); ZipUtil zip(this); connect(&zip, SIGNAL(logProgress(int, int)), this, SIGNAL(logProgress(int, int))); connect(&zip, SIGNAL(logItem(QString, int)), this, SIGNAL(logItem(QString, int))); zip.open(m_file, QuaZip::mdUnzip); // check for free space. Make sure after installation will still be // some room for operating (also includes calculation mistakes due to // cluster sizes on the player). if((qint64)Utils::filesystemFree(m_mountpoint) < (zip.totalUncompressedSize(Utils::filesystemClusterSize(m_mountpoint)) + 1000000)) { emit logItem(tr("Not enough disk space! Aborting."), LOGERROR); emit logProgress(1, 1); emit done(true); return; } zipContents = zip.files(); if(!zip.extractArchive(m_mountpoint)) { emit logItem(tr("Extraction failed!"), LOGERROR); emit logProgress(1, 1); emit done(true); return; } zip.close(); } else {
int AMActionHistoryModel3::successfulChildrenCount(const QModelIndex &parent) const{ if( rowCount() == 0 ) return 0; int successfulSubChildCount = 0; int successfulChildCount = 0; for(int x = 0; x < rowCount(parent); x++){ if(hasChildren(index(x, 0, parent))) successfulSubChildCount += successfulChildrenCount(index(x, 0, parent)); AMActionLogItem3 *childLogItem = logItem(index(x, 0, parent)); if(childLogItem->finalState() == 8) successfulChildCount++; } return successfulChildCount + successfulSubChildCount; }
//! \brief Creates Talkfiles. //! //! \param logger A pointer to a Loggerobject bool TalkFileCreator::createTalkFiles() { m_abort = false; QString errStr; emit logItem(tr("Starting Talk file generation for folder %1") .arg(m_dir.dirName()), LOGINFO); emit logProgress(0,0); QCoreApplication::processEvents(); // read in Maps of paths - file/dirnames emit logItem(tr("Reading Filelist..."),LOGINFO); if(createTalkList(m_dir) == false) { emit logItem(tr("Talk file creation aborted"),LOGERROR); doAbort(); return false; } QCoreApplication::processEvents(); // generate entries { TalkGenerator generator(this); // no string corrections yet: do not set language for TalkGenerator. connect(&generator,SIGNAL(done(bool)),this,SIGNAL(done(bool))); connect(&generator,SIGNAL(logItem(QString,int)),this,SIGNAL(logItem(QString,int))); connect(&generator,SIGNAL(logProgress(int,int)),this,SIGNAL(logProgress(int,int))); connect(this,SIGNAL(aborted()),&generator,SLOT(abort())); if(generator.process(&m_talkList) == TalkGenerator::eERROR) { doAbort(); return false; } } // Copying talk files emit logItem(tr("Copying Talkfiles..."),LOGINFO); if(copyTalkFiles(&errStr) == false) { emit logItem(errStr,LOGERROR); doAbort(); return false; } // Deleting left overs if( !cleanup()) return false; emit logItem(tr("Finished creating Talk files"),LOGOK); emit logProgress(1,1); emit done(false); return true; }
void AMActionHistoryModel3::recurseMarkParentSelected(const QModelIndex &index, QAbstractItemView *viewer, bool selected){ // If a child was selected (actually selected) before the parent, unselect the child in the selection model ... later steps will automatically set the parentSelected mapping if(index.parent().isValid() && viewer->selectionModel()->isSelected(index)) viewer->selectionModel()->select(index, QItemSelectionModel::Deselect); // Set this index parentSelected mapping and then recurse through the children if there are any int childrenCount = rowCount(index); AMActionLogItem3 *item = logItem(index); if(item) item->setParentSelected(viewer, selected); // No children is base case if(childrenCount == 0) return; for(int x = 0; x < childrenCount; x++) recurseMarkParentSelected(this->index(x, 0, index), viewer, selected); // Emit dataChanged for the children you just marked emit dataChanged(this->index(0, 0, index), this->index(childrenCount-1, 0, index)); }
/** Start bootloader installation. */ bool BootloaderInstallSansa::install(void) { if(sansa_sectorbuf == NULL) { emit logItem(tr("Error: can't allocate buffer memory!"), LOGERROR); return false; emit done(true); } emit logItem(tr("Searching for Sansa"), LOGINFO); struct sansa_t sansa; int n = sansa_scan(&sansa); if(n == -1) { emit logItem(tr("Permission for disc access denied!\n" "This is required to install the bootloader"), LOGERROR); emit done(true); return false; } if(n == 0) { emit logItem(tr("No Sansa detected!"), LOGERROR); emit done(true); return false; } if(sansa.hasoldbootloader) { emit logItem(tr("OLD ROCKBOX INSTALLATION DETECTED, ABORTING.\n" "You must reinstall the original Sansa firmware before running\n" "sansapatcher for the first time.\n" "See http://www.rockbox.org/wiki/SansaE200Install\n"), LOGERROR); emit done(true); return false; } emit logItem(tr("Downloading bootloader file"), LOGINFO); downloadBlStart(m_blurl); connect(this, SIGNAL(downloadDone()), this, SLOT(installStage2())); return true; }