/**************************************************************************** ** ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). ** All rights reserved. ** Contact: Nokia Corporation (qt-info@nokia.com) ** ** This file is part of the examples of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial Usage ** Licensees holding valid Qt Commercial licenses may use this file in ** accordance with the Qt Commercial License Agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and Nokia. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 2.1 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 2.1 requirements ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt LGPL Exception ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the ** packaging of this file. Please review the following information to ** ensure the GNU General Public License version 3.0 requirements will be ** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you have questions regarding the use of this file, please contact ** Nokia at qt-info@nokia.com. ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include #include #include "mainwindow.h" #include "mdichild.h" #include "burnconfigdialog.h" #include "avroutputdialog.h" #include "comparedialog.h" #include "logsdialog.h" #include "preferencesdialog.h" #include "flashinterface.h" #include "fusesdialog.h" #include "downloaddialog.h" #include "printdialog.h" #include "version.h" #include "contributorsdialog.h" #include "customizesplashdialog.h" #include "burndialog.h" #include "hexinterface.h" #include "warnings.h" #include "firmwares/opentx/open9xinterface.h" // TODO get rid of this include #define DONATE_STR "https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=QUZ48K4SEXDP2" #ifdef __APPLE__ #define C9X_STAMP "http://companion9x.googlecode.com/svn/trunk/companion9x-macosx.stamp" #define C9X_INSTALLER "/Companion9xMacUpdate.%1.pkg.zip" #define C9X_URL "http://companion9x.googlecode.com/files/Companion9xMacUpdate.%1.pkg.zip" #else #define C9X_STAMP "http://companion9x.googlecode.com/svn/trunk/companion9x.stamp" #define C9X_INSTALLER "/companion9xInstall_v%1.exe" #define C9X_URL "http://companion9x.googlecode.com/files/companion9xInstall_v%1.exe" #endif #if defined WIN32 || !defined __GNUC__ #include #define sleep(x) Sleep(x*1000) #else #include #include "mountlist.h" #endif MainWindow::MainWindow(): downloadDialog_forWait(NULL) { mdiArea = new QMdiArea; mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setCentralWidget(mdiArea); connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(updateMenus())); windowMapper = new QSignalMapper(this); connect(windowMapper, SIGNAL(mapped(QWidget*)), this, SLOT(setActiveSubWindow(QWidget*))); MaxRecentFiles=MAX_RECENT; createActions(); createMenus(); createToolBars(); createStatusBar(); updateMenus(); readSettings(); FirmwareInfo *firmware = GetCurrentFirmware(); if (ActiveProfile) { setWindowTitle(tr("companion9x - EEPROM Editor - firmware %1 - profile %2").arg(firmware->name).arg(ActiveProfileName)); } else { setWindowTitle(tr("companion9x - EEPROM Editor - firmware %1").arg(firmware->name)); } setUnifiedTitleAndToolBarOnMac(true); this->setWindowIcon(QIcon(":/icon.png")); QNetworkProxyFactory::setUseSystemConfiguration(true); setAcceptDrops(true); // give time to the main windows to open before starting updates, delay 1s QTimer::singleShot(1000, this, SLOT(doAutoUpdates())); QTimer::singleShot(1000, this, SLOT(displayWarnings())); QStringList strl = QApplication::arguments(); QString str; QString printfilename; int printing=false; int model=-1; if (strl.contains("--print")) printing=true; int count=0; foreach(QString arg, strl) { count++; if (arg.contains("--model")) { model=strl[count].toInt()-1; } if (arg.contains("--filename")) { printfilename=strl[count]; } } if(strl.count()>1) str = strl[1]; if(!str.isEmpty()) { int fileType = getFileType(str); if(fileType==FILE_TYPE_HEX) { burnToFlash(str); } if(fileType==FILE_TYPE_EEPE || fileType==FILE_TYPE_EEPM || fileType==FILE_TYPE_BIN) { MdiChild *child = createMdiChild(); if (child->loadFile(str)) { if (!(printing && (model >=0 && modelgetMaxModels()) && !printfilename.isEmpty() )) { statusBar()->showMessage(tr("File loaded"), 2000); child->show(); } else { child->show(); child->print(model,printfilename); child->close(); } } } } if (printing) { QTimer::singleShot(0, this, SLOT(autoClose())); } } void MainWindow::displayWarnings() { QSettings settings("companion9x", "companion9x"); int warnId=settings.value("warningId", 0 ).toInt(); if (warnId0) { QMessageBox::warning(this, "companion9x", WARNING); res = QMessageBox::question(this, "companion9x",tr("Display previous warning again at startup ?"),QMessageBox::Yes | QMessageBox::No); } else { QMessageBox::about(this, "companion9x", WARNING); res = QMessageBox::question(this, "companion9x",tr("Display previous message again at startup ?"),QMessageBox::Yes | QMessageBox::No); } if (res == QMessageBox::No) { settings.setValue("warningId", WARNING_ID); } } else if (warnId==0) { settings.setValue("warningId", WARNING_ID); } } void MainWindow::doAutoUpdates() { checkForUpdates(false, current_firmware_variant.id); } void MainWindow::doUpdates() { checkForUpdates(true, current_firmware_variant.id); } void MainWindow::checkForUpdates(bool ignoreSettings, QString & fwId) { showcheckForUpdatesResult = ignoreSettings; check1done = true; check2done = true; QSettings settings("companion9x", "companion9x"); fwToUpdate = fwId; QString stamp = GetFirmware(fwToUpdate)->stamp; if (!stamp.isEmpty()) { if (checkFW || ignoreSettings) { check1done=false; manager1 = new QNetworkAccessManager(this); connect(manager1, SIGNAL(finished(QNetworkReply*)), this, SLOT(reply1Finished(QNetworkReply*))); QUrl url(stamp); QNetworkRequest request(url); request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); manager1->get(request); } } if (checkCompanion9x || ignoreSettings) { check2done = false; manager2 = new QNetworkAccessManager(this); connect(manager2, SIGNAL(finished(QNetworkReply*)),this, SLOT(checkForUpdateFinished(QNetworkReply*))); QNetworkRequest request(QUrl(C9X_STAMP)); request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); manager2->get(request); } if(ignoreSettings) { downloadDialog_forWait = new downloadDialog(this, tr("Checking for updates")); downloadDialog_forWait->show(); } else { downloadDialog_forWait = NULL; // TODO needed? } } void MainWindow::checkForUpdateFinished(QNetworkReply * reply) { check2done = true; if(check1done && check2done && downloadDialog_forWait) { downloadDialog_forWait->close(); // TODO delete downloadDialog_forWait? } QByteArray qba = reply->readAll(); int i = qba.indexOf("C9X_VERSION"); if (i>0) { QString version = qba.mid(i+14, 4); if (version.isNull()) { QMessageBox::warning(this, "companion9x", tr("Unable to check for updates.")); return; } double vnum=version.toDouble(); QString c9xversion=QString(C9X_VERSION); int i; for (i=0; i" "Would you like to download it?").arg(version) , QMessageBox::Yes | QMessageBox::No); QSettings settings("companion9x", "companion9x"); if (ret == QMessageBox::Yes) { #if defined __APPLE__ QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), settings.value("lastUpdatesDir").toString() + QString(C9X_INSTALLER).arg(version)); #else QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), settings.value("lastUpdatesDir").toString() + QString(C9X_INSTALLER).arg(version), tr("Executable (*.exe)")); #endif if (!fileName.isEmpty()) { settings.setValue("lastUpdatesDir", QFileInfo(fileName).dir().absolutePath()); downloadDialog * dd = new downloadDialog(this, QString(C9X_URL).arg(version), fileName); installer_fileName = fileName; connect(dd, SIGNAL(accepted()), this, SLOT(updateDownloaded())); dd->show(); } } #else QMessageBox::warning(this, tr("New release available"), tr("A new release of companion is available please check the repository")); #endif } else { if (showcheckForUpdatesResult && check1done && check2done) QMessageBox::information(this, "companion9x", tr("No updates available at this time.")); } } else { if(check1done && check2done) QMessageBox::warning(this, "companion9x", tr("Unable to check for updates.")); } } void MainWindow::updateDownloaded() { int ret = QMessageBox::question(this, "companion9x", tr("Would you like to launch the installer?") , QMessageBox::Yes | QMessageBox::No); if (ret == QMessageBox::Yes) { if(QDesktopServices::openUrl(QUrl::fromLocalFile(installer_fileName))) QApplication::exit(); } } void MainWindow::downloadLatestFW(FirmwareInfo * firmware, const QString & firmwareId) { QString url, ext, cpuid; QSettings settings("companion9x", "companion9x"); url = firmware->getUrl(firmwareId); cpuid=settings.value("cpuid","").toString(); ext = url.mid(url.lastIndexOf(".")); QString fileName = QFileDialog::getSaveFileName(this, tr("Save As"), settings.value("lastFlashDir").toString() + "/" + firmwareId + ext); if (!fileName.isEmpty()) { downloadedFW = firmwareId; needRename=true; downloadedFWFilename = fileName; if (!cpuid.isEmpty()) { url.append("&cpuid="); url.append(cpuid); } settings.setValue("lastFlashDir", QFileInfo(fileName).dir().absolutePath()); downloadDialog * dd = new downloadDialog(this, url, fileName); connect(dd, SIGNAL(accepted()), this, SLOT(reply1Accepted())); dd->exec(); } } void MainWindow::reply1Accepted() { QString errormsg; QSettings settings("companion9x", "companion9x"); bool autoflash=settings.value("burnFirmware", true).toBool(); bool addversion=settings.value("rename_firmware_files", false).toBool(); settings.beginGroup("FwRevisions"); if (downloadedFWFilename.isEmpty()) { if (!(downloadedFW.isEmpty())) { QFile file(downloadedFW); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file QMessageBox::critical(this, tr("Error"), tr("Error opening file %1:\n%2.") .arg(downloadedFW) .arg(file.errorString())); return; } file.reset(); QTextStream inputStream(&file); QString hline = inputStream.readLine(); if (hline.startsWith("ERROR:")) { int errnum=hline.mid(6).toInt(); switch(errnum) { case 1: errormsg=tr("Firmware does not longer fit in flash, due to selected firmware options"); break; case 2: errormsg=tr("Compilation server temporary failure, try later"); break; case 3: errormsg=tr("Compilation server too busy, try later"); break; case 4: errormsg=tr("Compilation server requires registration, please check opentx web site"); break; default: errormsg=tr("Unknown server failure, try later"); break; } file.close(); QMessageBox::critical(this, tr("Error"), errormsg); settings.endGroup(); return; } file.close(); currentFWrev = currentFWrev_temp; settings.setValue(downloadedFW, currentFWrev); } } else { QFile file(downloadedFWFilename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file QMessageBox::critical(this, tr("Error"), tr("Error opening file %1:\n%2.") .arg(downloadedFWFilename) .arg(file.errorString())); return; } file.reset(); QTextStream inputStream(&file); QString hline = inputStream.readLine(); if (hline.startsWith("ERROR:")) { int errnum=hline.mid(6).toInt(); switch(errnum) { case 1: errormsg=tr("Firmware does not fit in flash, due to selected firmware options"); break; case 2: errormsg=tr("Compilation server termporary failure, try later"); break; case 3: errormsg=tr("Compilation server too busy, try later"); break; case 4: errormsg=tr("Compilation server requires registration, please check opentx web site"); break; default: errormsg=tr("Unknown server failure, try later"); break; } file.close(); QMessageBox::critical(this, tr("Error"), errormsg); settings.endGroup(); return; } file.close(); FlashInterface flash(downloadedFWFilename); QString rev=flash.getSvn(); int pos=rev.lastIndexOf("-r"); if (pos>0) { currentFWrev=rev.mid(pos+2).toInt(); if (addversion && needRename) { QFileInfo fi(downloadedFWFilename); QString path=fi.path()+QDir::separator (); path.append(fi.completeBaseName()); path.append(rev.mid(pos)); path.append("."); path.append(fi.suffix()); QDir qd; qd.remove(path); qd.rename(downloadedFWFilename,path); downloadedFWFilename=path; } settings.setValue(downloadedFW, currentFWrev); if (autoflash) { int ret = QMessageBox::question(this, "companion9x", tr("Do you want to flash the firmware now ?"), QMessageBox::Yes | QMessageBox::No); if (ret == QMessageBox::Yes) { burnToFlash(downloadedFWFilename); } } } } settings.endGroup(); } void MainWindow::reply1Finished(QNetworkReply * reply) { int OldFwRev; check1done = true; bool download = false; bool ignore = false; QString cpuid; if(check1done && check2done && downloadDialog_forWait) { downloadDialog_forWait->close(); // TODO delete downloadDialog_forWait? } QSettings settings("companion9x", "companion9x"); cpuid=settings.value("cpuid","").toString(); QByteArray qba = reply->readAll(); int i = qba.indexOf("SVN_VERS"); int warning = qba.indexOf("WARNING"); if(i>0) { bool cres; int k = qba.indexOf("-r", i); int l = qba.indexOf('"', k); int rev = QString::fromAscii(qba.mid(k+2, l-k-2)).toInt(&cres); QString newrev=qba.mid(k).replace('"', "").trimmed(); if(!cres) { QMessageBox::warning(this, "companion9x", tr("Unable to check for updates.")); int server = settings.value("fwserver",0).toInt(); server++; settings.setValue("fwserver",server); return; } if(rev>0) { NewFwRev=rev; settings.beginGroup("FwRevisions"); OldFwRev = settings.value(fwToUpdate, 0).toInt(); settings.endGroup(); QMessageBox msgBox; QSpacerItem* horizontalSpacer = new QSpacerItem(500, 0, QSizePolicy::Minimum, QSizePolicy::Expanding); QGridLayout* layout = (QGridLayout*)msgBox.layout(); layout->addItem(horizontalSpacer, layout->rowCount(), 0, 1, layout->columnCount()); if (OldFwRev == 0) { showcheckForUpdatesResult = false; // update is available - do not show dialog QString rn = GetFirmware(fwToUpdate)->rnurl; QAbstractButton *rnButton; msgBox.setInformativeText(tr("Firmware %1 does not seem to have ever been downloaded.\nVersion %2 is available.\nDo you want to download it now ?").arg(fwToUpdate).arg(NewFwRev)); QAbstractButton *YesButton = msgBox.addButton(trUtf8("Yes"), QMessageBox::YesRole); msgBox.addButton(trUtf8("No"), QMessageBox::NoRole); if (!rn.isEmpty()) { rnButton = msgBox.addButton(trUtf8("Release Notes"), QMessageBox::ActionRole); } msgBox.setIcon(QMessageBox::Question); msgBox.resize(0,0); msgBox.exec(); if( msgBox.clickedButton() == rnButton ) { contributorsDialog *cd = new contributorsDialog(this,2,rn); cd->exec(); int ret2 = QMessageBox::question(this, "companion9x", tr("Do you want to download release %1 now ?").arg(NewFwRev), QMessageBox::Yes | QMessageBox::No); if (ret2 == QMessageBox::Yes) { download = true; } else { ignore = true; } } else if (msgBox.clickedButton() == YesButton ) { download = true; } else { ignore = true; } } else if (NewFwRev > OldFwRev) { showcheckForUpdatesResult = false; // update is available - do not show dialog QString rn = GetFirmware(fwToUpdate)->rnurl; QAbstractButton *rnButton; msgBox.setText("companion9x"); msgBox.setInformativeText(tr("A new version of %1 firmware is available (current %2 - newer %3).\nDo you want to download it now ?").arg(fwToUpdate).arg(OldFwRev).arg(NewFwRev)); QAbstractButton *YesButton = msgBox.addButton(trUtf8("Yes"), QMessageBox::YesRole); msgBox.addButton(trUtf8("No"), QMessageBox::NoRole); if (!rn.isEmpty()) { rnButton = msgBox.addButton(trUtf8("Release Notes"), QMessageBox::ActionRole); } msgBox.setIcon(QMessageBox::Question); msgBox.resize(0,0); msgBox.exec(); if( msgBox.clickedButton() == rnButton ) { warning=0; contributorsDialog *cd = new contributorsDialog(this,2,rn); cd->exec(); int ret2 = QMessageBox::question(this, "companion9x", tr("Do you want to download release %1 now ?").arg(NewFwRev), QMessageBox::Yes | QMessageBox::No); if (ret2 == QMessageBox::Yes) { download = true; } else { ignore = true; } } else if (msgBox.clickedButton() == YesButton ) { download = true; } else { ignore = true; } } else { if(showcheckForUpdatesResult && check1done && check2done) QMessageBox::information(this, "companion9x", tr("No updates available at this time.")); } if (ignore) { int res = QMessageBox::question(this, "companion9x",tr("Ignore this version (r%1)?").arg(rev), QMessageBox::Yes | QMessageBox::No); if (res==QMessageBox::Yes) { settings.beginGroup("FwRevisions"); settings.setValue(fwToUpdate, NewFwRev); settings.endGroup(); } } else if (download == true) { if (warning>0) { QString rn = GetFirmware(fwToUpdate)->rnurl; if (!rn.isEmpty()) { int ret2 = QMessageBox::warning(this, "companion9x", tr("Release notes contain very important informations. Do you want to see them now ?"), QMessageBox::Yes | QMessageBox::No); if (ret2 == QMessageBox::Yes) { contributorsDialog *cd = new contributorsDialog(this,2,rn); cd->exec(); } } } downloadedFW = fwToUpdate; QString url = GetFirmware(fwToUpdate)->getUrl(fwToUpdate); QString ext = url.mid(url.lastIndexOf(".")); needRename=false; bool addversion=settings.value("rename_firmware_files", false).toBool(); QString fileName; if (addversion) { fileName = QFileDialog::getSaveFileName(this, tr("Save As"), settings.value("lastFlashDir").toString() + "/" + fwToUpdate + newrev + ext); } else { fileName = QFileDialog::getSaveFileName(this, tr("Save As"), settings.value("lastFlashDir").toString() + "/" + fwToUpdate + ext); } if (!fileName.isEmpty()) { if (!cpuid.isEmpty()) { url.append("&cpuid="); url.append(cpuid); } downloadedFWFilename = fileName; settings.setValue("lastFlashDir", QFileInfo(fileName).dir().absolutePath()); downloadDialog * dd = new downloadDialog(this, url, fileName); currentFWrev_temp = NewFwRev; connect(dd, SIGNAL(accepted()), this, SLOT(reply1Accepted())); dd->exec(); downloadedFW = fwToUpdate; } } } else { QMessageBox::warning(this, "companion9x", tr("Unable to check for updates.")); } } else { if(check1done && check2done) { QMessageBox::warning(this, "companion9x", tr("Unable to check for updates.")); int server = settings.value("fwserver",0).toInt(); server++; settings.setValue("fwserver",server); return; } } } void MainWindow::closeEvent(QCloseEvent *event) { mdiArea->closeAllSubWindows(); if (mdiArea->currentSubWindow()) { event->ignore(); } else { writeSettings(); event->accept(); } } void MainWindow::newFile() { MdiChild *child = createMdiChild(); child->newFile(); child->show(); } void MainWindow::openFile() { QSettings settings("companion9x", "companion9x"); QString fileName = QFileDialog::getOpenFileName(this, tr("Open"), settings.value("lastDir").toString(),tr(EEPROM_FILES_FILTER)); if (!fileName.isEmpty()) { settings.setValue("lastDir", QFileInfo(fileName).dir().absolutePath()); QMdiSubWindow *existing = findMdiChild(fileName); if (existing) { mdiArea->setActiveSubWindow(existing); return; } MdiChild *child = createMdiChild(); if (child->loadFile(fileName)) { statusBar()->showMessage(tr("File loaded"), 2000); child->show(); } } } void MainWindow::save() { if (activeMdiChild() && activeMdiChild()->save()) statusBar()->showMessage(tr("File saved"), 2000); } void MainWindow::saveAs() { if (activeMdiChild() && activeMdiChild()->saveAs()) statusBar()->showMessage(tr("File saved"), 2000); } void MainWindow::openRecentFile() { QSettings settings("companion9x", "companion9x"); QAction *action = qobject_cast(sender()); if (action) { QString fileName=action->data().toString(); // settings.setValue("lastDir", QFileInfo(fileName).dir().absolutePath()); QMdiSubWindow *existing = findMdiChild(fileName); if (existing) { mdiArea->setActiveSubWindow(existing); return; } MdiChild *child = createMdiChild(); if (child->loadFile(fileName)) { statusBar()->showMessage(tr("File loaded"), 2000); child->show(); } } } void MainWindow::loadProfile() { QSettings settings("companion9x", "companion9x"); QAction *action = qobject_cast(sender()); int chord,defmod, burnfw; bool renfw; if (action) { int profnum=action->data().toInt(); QSettings settings("companion9x", "companion9x"); settings.setValue("ActiveProfile",profnum); settings.beginGroup("Profiles"); QString profile=QString("profile%1").arg(profnum); settings.beginGroup(profile); ActiveProfile=profnum; ActiveProfileName=settings.value("Name", "").toString(); chord=settings.value("default_channel_order", 0).toInt(); defmod=settings.value("default_mode", 0).toInt(); burnfw=settings.value("burnFirmware", 0).toInt(); QString sdPath=settings.value("sdPath", ".").toString(); renfw=settings.value("rename_firmware_files", false).toBool(); QString SplashFileName=settings.value("SplashFileName","").toString(); QString SplashImage=settings.value("SplashImage", "").toString(); QString firmware_id=settings.value("firmware", default_firmware_variant.id).toString(); firmware_id.replace("open9x","opentx"); firmware_id.replace("x9da","taranis"); settings.setValue("firmware", firmware_id); settings.endGroup(); settings.endGroup(); settings.setValue("default_channel_order", chord); settings.setValue("default_mode", defmod); settings.setValue("burnFirmware", burnfw); settings.setValue("rename_firmware_files", renfw); settings.setValue("sdPath", sdPath); settings.setValue("SplashFileName", SplashFileName); settings.setValue("SplashImage", SplashImage); settings.setValue("firmware", firmware_id); settings.setValue("profileId", profnum); current_firmware_variant = GetFirmwareVariant(firmware_id); FirmwareInfo *firmware = GetCurrentFirmware(); setWindowTitle(tr("companion9x - EEPROM Editor - firmware %1").arg(firmware->name)); // settings.setValue("lastDir", QFileInfo(fileName).dir().absolutePath()); foreach (QMdiSubWindow *window, mdiArea->subWindowList()) { MdiChild *mdiChild = qobject_cast(window->widget()); mdiChild->eepromInterfaceChanged(); } setWindowTitle(tr("companion9x - EEPROM Editor - firmware %1 - profile %2").arg(firmware->name).arg(ActiveProfileName)); } } void MainWindow::unloadProfile() { ActiveProfile=0; ActiveProfileName=""; QSettings settings("companion9x", "companion9x"); settings.setValue("ActiveProfile",0); FirmwareInfo *firmware = GetCurrentFirmware(); setWindowTitle(tr("companion9x - EEPROM Editor - firmware %1").arg(firmware->name)); } void MainWindow::preferences() { preferencesDialog *pd = new preferencesDialog(this); pd->exec(); FirmwareInfo *firmware = GetCurrentFirmware(); if (ActiveProfile) { setWindowTitle(tr("companion9x - EEPROM Editor - firmware %1 - profile %2").arg(firmware->name).arg(ActiveProfileName)); } else { setWindowTitle(tr("companion9x - EEPROM Editor - firmware %1").arg(firmware->name)); } foreach (QMdiSubWindow *window, mdiArea->subWindowList()) { MdiChild *mdiChild = qobject_cast(window->widget()); mdiChild->eepromInterfaceChanged(); } updateMenus(); } void MainWindow::contributors() { contributorsDialog *cd = new contributorsDialog(this,0); cd->exec(); } void MainWindow::changelog() { contributorsDialog *cd = new contributorsDialog(this,1); cd->exec(); } void MainWindow::fwchangelog() { FirmwareInfo *currfirm = GetCurrentFirmware(); QString rn=currfirm->rnurl; if (rn.isEmpty()) { QMessageBox::information(this, tr("Firmware updates"), tr("Current firmware does not provide release notes informations.")); } else { contributorsDialog *cd = new contributorsDialog(this,2, rn); cd->exec(); } } void MainWindow::customizeSplash() { customizeSplashDialog *cd = new customizeSplashDialog(this); cd->exec(); } void MainWindow::cut() { if (activeMdiChild()) { activeMdiChild()->cut(); updateMenus(); } } void MainWindow::copy() { if (activeMdiChild()) { activeMdiChild()->copy(); updateMenus(); } } void MainWindow::paste() { if (activeMdiChild()) activeMdiChild()->paste(); } void MainWindow::burnTo() { if (activeMdiChild()) activeMdiChild()->burnTo(); } void MainWindow::simulate() { if (activeMdiChild()) activeMdiChild()->simulate(); } void MainWindow::print() { if (activeMdiChild()) activeMdiChild()->print(); } void MainWindow::loadBackup() { if (activeMdiChild()) activeMdiChild()->loadBackup(); } QString MainWindow::GetAvrdudeLocation() { burnConfigDialog bcd; EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { return bcd.getDFU(); } else if (IS_SKY9X(GetEepromInterface()->getBoard())) { return bcd.getSAMBA(); } else { return bcd.getAVRDUDE(); } } QStringList MainWindow::GetAvrdudeArguments(const QString &cmd, const QString &filename) { QStringList arguments; burnConfigDialog bcd; QString programmer = bcd.getProgrammer(); QStringList args = bcd.getAVRArgs(); QString mcu = bcd.getMCU(); if(!bcd.getPort().isEmpty()) args << "-P" << bcd.getPort(); arguments << "-c" << programmer << "-p"; if (GetEepromInterface()->getBoard() == BOARD_GRUVIN9X) arguments << "m2560"; else if (GetEepromInterface()->getBoard() == BOARD_M128) arguments << "m128"; else arguments << mcu; arguments << args; QString fullcmd = cmd + filename; if(QFileInfo(filename).suffix().toUpper()=="HEX") fullcmd += ":i"; else if(QFileInfo(filename).suffix().toUpper()=="BIN") fullcmd += ":r"; else fullcmd += ":a"; arguments << "-U" << fullcmd; return arguments; } QStringList MainWindow::GetDFUUtilArguments(const QString &cmd, const QString &filename) { QStringList arguments; burnConfigDialog bcd; QStringList args = bcd.getDFUArgs(); QString memory="0x08000000"; if (cmd=="-U") { memory.append(QString(":%1").arg(MAX_FSIZE)); } arguments << args << "--dfuse-address" << memory << "-d" << "0483:df11"; QString fullcmd = cmd + filename; arguments << "" << fullcmd; return arguments; } QStringList MainWindow::GetSambaArguments(const QString &tcl) { QStringList result; QString tclFilename = QDir::tempPath() + "/temp.tcl"; if (QFile::exists(tclFilename)) { unlink(tclFilename.toAscii()); } QFile tclFile(tclFilename); if (!tclFile.open(QIODevice::WriteOnly | QIODevice::Text)) { QMessageBox::warning(this, tr("Error"), tr("Cannot write file %1:\n%2.") .arg(tclFilename) .arg(tclFile.errorString())); return result; } QTextStream outputStream(&tclFile); outputStream << tcl; burnConfigDialog bcd; result << bcd.getSambaPort() << bcd.getArmMCU() << tclFilename ; return result; } QStringList MainWindow::GetReceiveEEpromCommand(const QString &filename) { QStringList ret; EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { // return NULL; // to be implemented } else if (IS_SKY9X(eepromInterface->getBoard())) { ret=GetSambaArguments(QString("SERIALFLASH::Init 0\n") + "receive_file {SerialFlash AT25} \"" + filename + "\" 0x0 0x80000 0\n"); } else { ret=GetAvrdudeArguments("eeprom:r:", filename); } return ret; } QStringList MainWindow::GetSendEEpromCommand(const QString &filename) { QStringList ret; EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { // return NULL; // to be implemented } else if (IS_SKY9X(eepromInterface->getBoard())) { ret=GetSambaArguments(QString("SERIALFLASH::Init 0\n") + "send_file {SerialFlash AT25} \"" + filename + "\" 0x0 0\n"); } else { ret=GetAvrdudeArguments("eeprom:w:", filename); } return ret; } QStringList MainWindow::GetSendFlashCommand(const QString &filename) { QStringList ret; EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { ret=GetDFUUtilArguments("-D", filename); } else if (eepromInterface->getBoard() == BOARD_SKY9X) { ret=GetSambaArguments(QString("send_file {Flash} \"") + filename + "\" 0x400000 0\n" + "FLASH::ScriptGPNMV 2\n"); } else if (eepromInterface->getBoard() == BOARD_9XRPRO) { ret=GetSambaArguments(QString("send_file {Flash} \"") + filename + "\" 0x400000 0\n" + "FLASH::ScriptGPNMV 2\n"); } else { ret=GetAvrdudeArguments("flash:w:", filename); } return ret; } QStringList MainWindow::GetReceiveFlashCommand(const QString &filename) { EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { return GetDFUUtilArguments("-U", filename); } else if (eepromInterface->getBoard() == BOARD_SKY9X) { return GetSambaArguments(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x40000 0\n"); } else if (eepromInterface->getBoard() == BOARD_9XRPRO) { return GetSambaArguments(QString("receive_file {Flash} \"") + filename + "\" 0x400000 0x40000 0\n"); } else { return GetAvrdudeArguments("flash:r:", filename); } } QString MainWindow::FindTaranisPath() { int pathcount=0; QString path; QStringList drives; QString eepromfile; QString fsname; #if defined WIN32 || !defined __GNUC__ foreach( QFileInfo drive, QDir::drives() ) { WCHAR szVolumeName[256] ; WCHAR szFileSystemName[256]; DWORD dwSerialNumber = 0; DWORD dwMaxFileNameLength=256; DWORD dwFileSystemFlags=0; bool ret = GetVolumeInformationW( (WCHAR *) drive.absolutePath().utf16(),szVolumeName,256,&dwSerialNumber,&dwMaxFileNameLength,&dwFileSystemFlags,szFileSystemName,256); if(ret) { QString vName=QString::fromUtf16 ( (const ushort *) szVolumeName) ; if (vName.contains("TARANIS")) { eepromfile=drive.absolutePath(); eepromfile.append("/TARANIS.BIN"); if (QFile::exists(eepromfile)) { pathcount++; path=eepromfile; } } } } #else struct mount_entry *entry; entry = read_file_system_list(true); while (entry != NULL) { if (!drives.contains(entry->me_devname)) { drives.append(entry->me_devname); eepromfile=entry->me_mountdir; eepromfile.append("/TARANIS.BIN"); #if !defined __APPLE__ && !defined WIN32 QString fstype=entry->me_type; qDebug() << fstype; if (QFile::exists(eepromfile) && fstype.contains("fat") ) { #else if (QFile::exists(eepromfile)) { #endif pathcount++; path=eepromfile; } } entry = entry->me_next; ; } #endif if (pathcount==1) { return path; } else { return ""; } } void MainWindow::burnFrom() { QString tempDir = QDir::tempPath(); QString tempFile; int res=0; EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_ARM(eepromInterface->getBoard())) tempFile = tempDir + "/temp.bin"; else tempFile = tempDir + "/temp.hex"; if (QFile::exists(tempFile)) { unlink(tempFile.toAscii()); } if (IS_TARANIS(eepromInterface->getBoard())) { QString path=FindTaranisPath(); if (path.isEmpty()) { QMessageBox::warning(this, tr("Taranis radio not found"), tr("Impossible to identify the radio on your system, please verify the eeprom disk is connected.")); res=false; } else { QStringList str; str << path << tempFile; avrOutputDialog *ad = new avrOutputDialog(this,"", str, tr("Read EEPROM From Tx")); //, AVR_DIALOG_KEEP_OPEN); ad->setWindowIcon(QIcon(":/images/read_eeprom.png")); res = ad->exec(); sleep(1); } } else { QStringList str = GetReceiveEEpromCommand(tempFile); avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, tr("Read EEPROM From Tx")); //, AVR_DIALOG_KEEP_OPEN); ad->setWindowIcon(QIcon(":/images/read_eeprom.png")); res = ad->exec(); } if(QFileInfo(tempFile).exists() && res) { MdiChild *child = createMdiChild(); child->newFile(); child->loadFile(tempFile, false); child->show(); } } void MainWindow::burnExtenalToEEPROM() { QSettings settings("companion9x", "companion9x"); QString fileName; bool backup = false; burnDialog *cd = new burnDialog(this, 1, &fileName, &backup); cd->exec(); if (!fileName.isEmpty()) { settings.setValue("lastDir", QFileInfo(fileName).dir().absolutePath()); int ret = QMessageBox::question(this, "companion9x", tr("Write %1 to EEPROM memory?").arg(QFileInfo(fileName).fileName()), QMessageBox::Yes | QMessageBox::No); if (ret != QMessageBox::Yes) return; if (!isValidEEPROM(fileName)) ret = QMessageBox::question(this, "companion9x", tr("The file %1\nhas not been recognized as a valid EEPROM\nBurn anyway ?").arg(QFileInfo(fileName).fileName()), QMessageBox::Yes | QMessageBox::No); if (ret != QMessageBox::Yes) return; bool backupEnable = settings.value("backupEnable", true).toBool(); QString backupPath = settings.value("backupPath", "").toString(); if (!backupPath.isEmpty()) { if (!QDir(backupPath).exists()) { if (backupEnable) { QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist")); } backupEnable = false; } } else { backupEnable = false; } EEPROMInterface *eepromInterface = GetEepromInterface(); if (backup) { if (backupEnable) { QString backupFile = backupPath + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-HHmmss") + ".bin"; if (IS_TARANIS(eepromInterface->getBoard())) { QString path=FindTaranisPath(); if (path.isEmpty()) { QMessageBox::warning(this, tr("Taranis radio not found"), tr("Impossible to identify the radio on your system, please verify the eeprom disk is connected.")); return; } else { QStringList str; str << path << backupFile; avrOutputDialog *ad = new avrOutputDialog(this,"", str, tr("Backup EEPROM From Tx")); //, AVR_DIALOG_KEEP_OPEN); ad->setWindowIcon(QIcon(":/images/read_eeprom.png")); ad->exec(); sleep(1); } } else { QStringList str = GetReceiveEEpromCommand(backupFile); avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, tr("Backup EEPROM From Tx")); ad->setWindowIcon(QIcon(":/images/read_eeprom.png")); ad->exec(); sleep(1); } } int oldrev = getEpromVersion(fileName); QString tempDir = QDir::tempPath(); QString tempFlash = tempDir + "/flash.bin"; QStringList str = GetReceiveFlashCommand(tempFlash); avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, "Read Flash From Tx"); ad->setWindowIcon(QIcon(":/images/read_flash.png")); ad->exec(); sleep(1); QString restoreFile = tempDir + "/compat.bin"; if (!convertEEPROM(fileName, restoreFile, tempFlash)) { int ret = QMessageBox::question(this, "Error", tr("Cannot check eeprom compatibility! Continue anyway?") , QMessageBox::Yes | QMessageBox::No); if (ret==QMessageBox::No) return; } else { int rev = getEpromVersion(restoreFile); if ((rev / 100) != (oldrev / 100)) { QMessageBox::warning(this, tr("Warning"), tr("Firmware in radio is of a different family of eeprom written, check file and preferences!")); } else if (rev < oldrev) { QMessageBox::warning(this, tr("Warning"), tr("Firmware in flash is outdated, please upgrade!")); } fileName = restoreFile; } QByteArray ba = tempFlash.toLatin1(); char *name = ba.data(); unlink(name); } else { if (backupEnable) { QString backupFile = backupPath + "/backup-" + QDateTime().currentDateTime().toString("yyyy-MM-dd-hhmmss") + ".bin"; if (IS_TARANIS(eepromInterface->getBoard())) { QString path=FindTaranisPath(); if (path.isEmpty()) { QMessageBox::warning(this, tr("Taranis radio not found"), tr("Impossible to identify the radio on your system, please verify the eeprom disk is connected.")); return; } else { QStringList str; str << path << backupFile; avrOutputDialog *ad = new avrOutputDialog(this,"", str, tr("Backup EEPROM From Tx")); //, AVR_DIALOG_KEEP_OPEN); ad->setWindowIcon(QIcon(":/images/read_eeprom.png")); ad->exec(); sleep(1); } } else { QStringList str = ((MainWindow *)this->parent())->GetReceiveEEpromCommand(backupFile); avrOutputDialog *ad = new avrOutputDialog(this, ((MainWindow *)this->parent())->GetAvrdudeLocation(), str, tr("Backup EEPROM From Tx")); ad->setWindowIcon(QIcon(":/images/read_eeprom.png")); ad->exec(); sleep(1); } } } if (IS_TARANIS(eepromInterface->getBoard())) { QString path=FindTaranisPath(); if (path.isEmpty()) { QMessageBox::warning(this, tr("Taranis radio not found"), tr("Impossible to identify the radio on your system, please verify the eeprom disk is connected.")); return; } else { QStringList str; str << fileName << path; avrOutputDialog *ad = new avrOutputDialog(this,"", str, tr("Write EEPROM To Tx")); //, AVR_DIALOG_KEEP_OPEN); ad->setWindowIcon(QIcon(":/images/read_eeprom.png")); ad->exec(); sleep(1); } } else { QStringList str = GetSendEEpromCommand(fileName); avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, "Write EEPROM To Tx", AVR_DIALOG_SHOW_DONE); ad->setWindowIcon(QIcon(":/images/write_eeprom.png")); ad->exec(); } } } int MainWindow::getFileType(const QString &fullFileName) { if(QFileInfo(fullFileName).suffix().toUpper()=="HEX") return FILE_TYPE_HEX; if(QFileInfo(fullFileName).suffix().toUpper()=="BIN") return FILE_TYPE_BIN; if(QFileInfo(fullFileName).suffix().toUpper()=="EEPM") return FILE_TYPE_EEPM; if(QFileInfo(fullFileName).suffix().toUpper()=="EEPE") return FILE_TYPE_EEPE; if(QFileInfo(fullFileName).suffix().toUpper()=="XML") return FILE_TYPE_XML; return 0; } bool MainWindow::isValidEEPROM(QString eepromfile) { int eeprom_size; QFile file(eepromfile); int fileType = getFileType(eepromfile); if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) return false; eeprom_size = file.size(); uint8_t *eeprom = (uint8_t *)malloc(eeprom_size); QTextStream inputStream(&file); eeprom_size = HexInterface(inputStream).load(eeprom, eeprom_size); if (!eeprom_size) { free(eeprom); return false; } file.close(); RadioData * radioData = new RadioData(); bool result = LoadEeprom(*radioData, eeprom, eeprom_size); free(eeprom); delete radioData; return result; } else if (fileType==FILE_TYPE_BIN) { //read binary if (!file.open(QFile::ReadOnly)) return false; eeprom_size = file.size(); uint8_t *eeprom = (uint8_t *)malloc(eeprom_size); memset(eeprom, 0, eeprom_size); long read = file.read((char*)eeprom, eeprom_size); file.close(); if (read != eeprom_size) { free(eeprom); return false; } RadioData * radioData = new RadioData(); bool result = LoadEeprom(*radioData, eeprom, eeprom_size); free(eeprom); delete radioData; return result; } return false; } bool MainWindow::convertEEPROM(QString backupFile, QString restoreFile, QString flashFile) { FirmwareInfo *firmware = GetCurrentFirmware(); FlashInterface flash(flashFile); if (!flash.isValid()) return false; QString fwSvn = flash.getSvn(); if (fwSvn.isEmpty() || !fwSvn.contains("-r")) return false; QStringList svnTags = fwSvn.split("-r", QString::SkipEmptyParts); fwSvn = svnTags.back(); if (fwSvn.endsWith('M')) fwSvn = fwSvn.mid(0, fwSvn.size()-1); int revision = fwSvn.toInt(); if (!revision) return false; unsigned int version = 0; unsigned int variant = 0; if ((svnTags.at(0) == "open9x")||(svnTags.at(0) == "opentx")) { if (revision > 1464) { QString fwBuild = flash.getBuild(); if (fwBuild.contains("-")) { QStringList buildTags = fwBuild.split("-", QString::SkipEmptyParts); if (buildTags.size() >= 1) version = buildTags.at(0).toInt(); if (buildTags.size() >= 2) variant = buildTags.at(1).toInt(); } else { version = fwBuild.toInt(); // TODO changer le nom de la variable } } else { version = ((Open9xFirmware *)firmware)->getEepromVersion(revision); } } QFile file(backupFile); int eeprom_size = file.size(); if (!eeprom_size) return false; if (!file.open(QIODevice::ReadOnly)) return false; uint8_t *eeprom = (uint8_t *)malloc(eeprom_size); long result = file.read((char*)eeprom, eeprom_size); file.close(); RadioData radioData; if (!LoadEeprom(radioData, eeprom, eeprom_size)) return false; if (!firmware->saveEEPROM(eeprom, radioData, variant, version)) return false; QFile file2(restoreFile); if (!file2.open(QIODevice::WriteOnly)) return false; result = file2.write((char*)eeprom, eeprom_size); file2.close(); if (result != eeprom_size) return false; free(eeprom); return true; } void MainWindow::burnToFlash(QString fileToFlash) { QSettings settings("companion9x", "companion9x"); QString fileName; bool backup = settings.value("backupOnFlash", false).toBool(); if(!fileToFlash.isEmpty()) fileName = fileToFlash; burnDialog *cd = new burnDialog(this, 2, &fileName, &backup); cd->exec(); if (IS_TARANIS(GetEepromInterface()->getBoard())) backup=false; if (!fileName.isEmpty()) { settings.setValue("backupOnFlash", backup); if (backup) { QString tempDir = QDir::tempPath(); QString backupFile = tempDir + "/backup.bin"; bool backupEnable=settings.value("backupEnable", true).toBool(); QString backupPath=settings.value("backupPath", "").toString(); if (!backupPath.isEmpty() && !IS_TARANIS(GetEepromInterface()->getBoard())) { if (!QDir(backupPath).exists()) { if (backupEnable) { QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist")); } backupEnable=false; } } else { backupEnable=false; } if (backupEnable) { QDateTime datetime; backupFile.clear(); backupFile=backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-hhmmss")+".bin"; } QStringList str = GetReceiveEEpromCommand(backupFile); avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, tr("Backup EEPROM From Tx"), AVR_DIALOG_CLOSE_IF_SUCCESSFUL); ad->setWindowIcon(QIcon(":/images/read_eeprom.png")); int res = ad->exec(); if (QFileInfo(backupFile).exists() && res) { sleep(1); QStringList str = GetSendFlashCommand(fileName); avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, tr("Write Flash To Tx"), AVR_DIALOG_CLOSE_IF_SUCCESSFUL); ad->setWindowIcon(QIcon(":/images/write_flash.png")); int res = ad->exec(); if (res) { QString restoreFile = tempDir + "/restore.bin"; if (!convertEEPROM(backupFile, restoreFile, fileName)) { QMessageBox::warning(this, tr("Conversion failed"), tr("Cannot convert EEProm for this firmware, original EEProm file will be used")); restoreFile = backupFile; } sleep(1); QStringList str = GetSendEEpromCommand(restoreFile); avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, tr("Restore EEPROM To Tx"), AVR_DIALOG_CLOSE_IF_SUCCESSFUL); ad->setWindowIcon(QIcon(":/images/write_eeprom.png")); res=ad->exec(); if (!res) { QMessageBox::warning(this, tr("Restore failed"), tr("Cannot restore EEProm to TX, original EEProm file can be found at: %1").arg(backupFile)); } } else { QMessageBox::warning(this, tr("Flash failed"), tr("Cannot flash the TX, original EEProm file can be found at: %1").arg(backupFile)); } } else { QMessageBox::warning(this, tr("Backup failed"), tr("Cannot backup existing EEProm from TX, Flash process aborted")); } } else { bool backupEnable=settings.value("backupEnable", true).toBool(); QString backupPath=settings.value("backupPath", "").toString(); if (!QDir(backupPath).exists()) { if (backupEnable) { QMessageBox::warning(this, tr("Backup is impossible"), tr("The backup dir set in preferences does not exist")); } backupEnable=false; } if (backupEnable && !IS_TARANIS(GetEepromInterface()->getBoard())) { QDateTime datetime; QString backupFile=backupPath+"/backup-"+QDateTime().currentDateTime().toString("yyyy-MM-dd-hhmmss")+".bin"; QStringList str = GetReceiveEEpromCommand(backupFile); avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, tr("Backup EEPROM From Tx")); ad->setWindowIcon(QIcon(":/images/read_eeprom.png")); ad->exec(); sleep(1); } QStringList str = GetSendFlashCommand(fileName); avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, tr("Write Flash To Tx"), AVR_DIALOG_SHOW_DONE); ad->setWindowIcon(QIcon(":/images/write_flash.png")); ad->exec(); } } } void MainWindow::burnExtenalFromEEPROM() { QSettings settings("companion9x", "companion9x"); QString fileName = QFileDialog::getSaveFileName(this, tr("Read EEPROM memory to File"), settings.value("lastDir").toString(), tr(EXTERNAL_EEPROM_FILES_FILTER)); if (!fileName.isEmpty()) { EEPROMInterface *eepromInterface = GetEepromInterface(); if (IS_TARANIS(eepromInterface->getBoard())) { QString path=FindTaranisPath(); if (path.isEmpty()) { QMessageBox::warning(this, tr("Taranis radio not found"), tr("Impossible to identify the radio on your system, please verify the eeprom disk is connected.")); return; } else { QStringList str; str << path << fileName; avrOutputDialog *ad = new avrOutputDialog(this,"", str, tr("Read EEPROM From Tx")); //, AVR_DIALOG_KEEP_OPEN); ad->setWindowIcon(QIcon(":/images/read_eeprom.png")); ad->exec(); } } else { settings.setValue("lastDir", QFileInfo(fileName).dir().absolutePath()); QStringList str = GetReceiveEEpromCommand(fileName); avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, tr("Read EEPROM From Tx")); ad->setWindowIcon(QIcon(":/images/read_eeprom.png")); ad->exec(); } } } void MainWindow::burnFromFlash() { QSettings settings("companion9x", "companion9x"); QString fileName = QFileDialog::getSaveFileName(this,tr("Read Flash to File"), settings.value("lastFlashDir").toString(),tr(FLASH_FILES_FILTER)); if (!fileName.isEmpty()) { QFile file(fileName); if (file.exists()) { file.remove(); } settings.setValue("lastFlashDir",QFileInfo(fileName).dir().absolutePath()); QStringList str = GetReceiveFlashCommand(fileName); avrOutputDialog *ad = new avrOutputDialog(this, GetAvrdudeLocation(), str, "Read Flash From Tx"); ad->setWindowIcon(QIcon(":/images/read_flash.png")); ad->exec(); } } void MainWindow::burnConfig() { burnConfigDialog *bcd = new burnConfigDialog(this); bcd->exec(); } void MainWindow::burnList() { burnConfigDialog *bcd = new burnConfigDialog(this); bcd->listProgrammers(); } void MainWindow::burnFuses() { fusesDialog *fd = new fusesDialog(this); fd->exec(); } void MainWindow::compare() { compareDialog *fd = new compareDialog(this); fd->show(); } void MainWindow::logFile() { logsDialog *fd = new logsDialog(this); fd->show(); } void MainWindow::about() { QString aboutStr = "

"; aboutStr.append(tr("Copyright") +" Bertrand Songis & Romolo Manfredini © 2011- 2013
"); aboutStr.append(QString("http://code.google.com/p/companion9x/
")+tr("Version %1 (revision %2), %3").arg(C9X_VERSION).arg(C9X_REVISION).arg(__DATE__)+QString("

")); aboutStr.append(tr("The companion9x project was originally forked from eePe")+QString(" http://code.google.com/p/eepe

")); aboutStr.append(tr("If you've found this program useful, please support by")); aboutStr.append(" "); aboutStr.append(tr("donating") + "
"); QMessageBox::about(this, tr("About companion9x"),aboutStr); } void MainWindow::updateMenus() { bool hasMdiChild = (activeMdiChild() != 0); saveAct->setEnabled(hasMdiChild); saveAsAct->setEnabled(hasMdiChild); pasteAct->setEnabled(hasMdiChild ? activeMdiChild()->hasPasteData() : false); closeAct->setEnabled(hasMdiChild); closeAllAct->setEnabled(hasMdiChild); tileAct->setEnabled(hasMdiChild); cascadeAct->setEnabled(hasMdiChild); nextAct->setEnabled(hasMdiChild); previousAct->setEnabled(hasMdiChild); burnToAct->setEnabled(hasMdiChild); separatorAct->setVisible(hasMdiChild); bool hasSelection = (activeMdiChild() && activeMdiChild()->hasSelection()); cutAct->setEnabled(hasSelection); copyAct->setEnabled(hasSelection); simulateAct->setEnabled(hasSelection); printAct->setEnabled(hasSelection); loadbackupAct->setEnabled(hasMdiChild); compareAct->setEnabled(activeMdiChild()); updateRecentFileActions(); updateProfilesActions(); bool notfound=true; QSettings settings("companion9x", "companion9x"); settings.beginGroup("Profiles"); for (int i=0; isetDisabled(notfound); } void MainWindow::updateWindowMenu() { windowMenu->clear(); windowMenu->addAction(closeAct); windowMenu->addAction(closeAllAct); windowMenu->addSeparator(); windowMenu->addAction(tileAct); windowMenu->addAction(cascadeAct); windowMenu->addSeparator(); windowMenu->addAction(nextAct); windowMenu->addAction(previousAct); windowMenu->addAction(separatorAct); QList windows = mdiArea->subWindowList(); separatorAct->setVisible(!windows.isEmpty()); for (int i = 0; i < windows.size(); ++i) { MdiChild *child = qobject_cast(windows.at(i)->widget()); QString text; if (i < 9) { text = tr("&%1 %2").arg(i + 1).arg(child->userFriendlyCurrentFile()); } else { text = tr("%1 %2").arg(i + 1).arg(child->userFriendlyCurrentFile()); } QAction *action = windowMenu->addAction(text); action->setCheckable(true); action ->setChecked(child == activeMdiChild()); connect(action, SIGNAL(triggered()), windowMapper, SLOT(map())); windowMapper->setMapping(action, windows.at(i)); } } MdiChild *MainWindow::createMdiChild() { MdiChild *child = new MdiChild; mdiArea->addSubWindow(child); if(!child->parentWidget()->isMaximized() && !child->parentWidget()->isMinimized()) child->parentWidget()->resize(400, 400); connect(child, SIGNAL(copyAvailable(bool)),cutAct, SLOT(setEnabled(bool))); connect(child, SIGNAL(copyAvailable(bool)),copyAct, SLOT(setEnabled(bool))); connect(child, SIGNAL(copyAvailable(bool)),simulateAct, SLOT(setEnabled(bool))); connect(child, SIGNAL(copyAvailable(bool)),printAct, SLOT(setEnabled(bool))); return child; } void MainWindow::createActions() { newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); newAct->setShortcuts(QKeySequence::New); newAct->setStatusTip(tr("Create a new file")); connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); openAct->setShortcuts(QKeySequence::Open); openAct->setStatusTip(tr("Open an existing file")); connect(openAct, SIGNAL(triggered()), this, SLOT(openFile())); loadbackupAct = new QAction(QIcon(":/images/open.png"), tr("&loadBackup..."), this); loadbackupAct->setStatusTip(tr("Load backup from file")); connect(loadbackupAct, SIGNAL(triggered()), this, SLOT(loadBackup())); saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); saveAct->setShortcuts(QKeySequence::Save); saveAct->setStatusTip(tr("Save the document to disk")); connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); saveAsAct = new QAction(QIcon(":/images/saveas.png"), tr("Save &As..."), this); saveAsAct->setShortcuts(QKeySequence::SaveAs); saveAsAct->setStatusTip(tr("Save the document under a new name")); connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); logsAct = new QAction(QIcon(":/images/logs.png"), tr("Lo&gs"), this); logsAct->setShortcut(tr("Ctrl+G")); logsAct->setStatusTip(tr("Open log file")); connect(logsAct, SIGNAL(triggered()), this, SLOT(logFile())); preferencesAct = new QAction(QIcon(":/images/preferences.png"), tr("&Preferences..."), this); preferencesAct->setStatusTip(tr("Edit general preferences")); connect(preferencesAct, SIGNAL(triggered()), this, SLOT(preferences())); checkForUpdatesAct = new QAction(QIcon(":/images/update.png"), tr("&Check for updates..."), this); checkForUpdatesAct->setStatusTip(tr("Check for new version of companion9x/er9x")); connect(checkForUpdatesAct, SIGNAL(triggered()), this, SLOT(doUpdates())); contributorsAct = new QAction(QIcon(":/images/contributors.png"), tr("Contributors &List..."), this); contributorsAct->setStatusTip(tr("Show companion9x contributors list")); connect(contributorsAct, SIGNAL(triggered()), this, SLOT(contributors())); changelogAct = new QAction(QIcon(":/images/changelog.png"), tr("ChangeLog..."), this); changelogAct->setStatusTip(tr("Show companion9x changelog")); connect(changelogAct, SIGNAL(triggered()), this, SLOT(changelog())); fwchangelogAct = new QAction(QIcon(":/images/changelog.png"), tr("Firmware ChangeLog..."), this); fwchangelogAct->setStatusTip(tr("Show firmware changelog")); connect(fwchangelogAct, SIGNAL(triggered()), this, SLOT(fwchangelog())); compareAct = new QAction(QIcon(":/images/compare.png"), tr("Compare..."), this); compareAct->setStatusTip(tr("Compare models")); compareAct->setEnabled(false); connect(compareAct, SIGNAL(triggered()), this, SLOT(compare())); customizeSplashAct = new QAction(QIcon(":/images/customize.png"), tr("Customize your &TX..."), this); customizeSplashAct->setStatusTip(tr("Customize the splash screen of your TX")); connect(customizeSplashAct, SIGNAL(triggered()), this, SLOT(customizeSplash())); //! [0] exitAct = new QAction(QIcon(":/images/exit.png"), tr("E&xit"), this); exitAct->setShortcuts(QKeySequence::Quit); exitAct->setStatusTip(tr("Exit the application")); connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); //! [0] cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this); cutAct->setShortcuts(QKeySequence::Cut); cutAct->setStatusTip(tr("Cut the current selection's contents to the " "clipboard")); connect(cutAct, SIGNAL(triggered()), this, SLOT(cut())); copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this); copyAct->setShortcuts(QKeySequence::Copy); copyAct->setStatusTip(tr("Copy the current selection's contents to the " "clipboard")); connect(copyAct, SIGNAL(triggered()), this, SLOT(copy())); pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this); pasteAct->setShortcuts(QKeySequence::Paste); pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " "selection")); connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste())); burnToAct = new QAction(QIcon(":/images/write_eeprom.png"), tr("&Write EEPROM To Tx"), this); burnToAct->setShortcut(tr("Ctrl+Alt+W")); burnToAct->setStatusTip(tr("Write EEPROM to transmitter")); connect(burnToAct,SIGNAL(triggered()),this,SLOT(burnTo())); burnFromAct = new QAction(QIcon(":/images/read_eeprom.png"), tr("&Read EEPROM From Tx"), this); burnFromAct->setShortcut(tr("Ctrl+Alt+R")); burnFromAct->setStatusTip(tr("Read EEPROM from transmitter")); connect(burnFromAct,SIGNAL(triggered()),this,SLOT(burnFrom())); burnToFlashAct = new QAction(QIcon(":/images/write_flash.png"), tr("Write Flash memory"), this); burnToFlashAct->setStatusTip(tr("Write flash memory to transmitter")); connect(burnToFlashAct,SIGNAL(triggered()),this,SLOT(burnToFlash())); burnExtenalToEEPROMAct = new QAction(QIcon(":/images/write_eeprom_file.png"), tr("Write EEPROM memory from file"), this); burnExtenalToEEPROMAct->setStatusTip(tr("Write EEPROM memory from file to transmitter")); connect(burnExtenalToEEPROMAct,SIGNAL(triggered()),this,SLOT(burnExtenalToEEPROM())); burnExtenalFromEEPROMAct = new QAction(QIcon(":/images/read_eeprom_file.png"), tr("Read EEPROM memory to file"), this); burnExtenalFromEEPROMAct->setStatusTip(tr("Read EEPROM memory from transmitter to file")); connect(burnExtenalFromEEPROMAct,SIGNAL(triggered()),this,SLOT(burnExtenalFromEEPROM())); burnFromFlashAct = new QAction(QIcon(":/images/read_flash.png"), tr("Read Flash memory"), this); burnFromFlashAct->setStatusTip(tr("Read flash memory to transmitter")); connect(burnFromFlashAct,SIGNAL(triggered()),this,SLOT(burnFromFlash())); burnConfigAct = new QAction(QIcon(":/images/configure.png"), tr("&Configure..."), this); burnConfigAct->setStatusTip(tr("Configure burning software")); connect(burnConfigAct,SIGNAL(triggered()),this,SLOT(burnConfig())); EEPROMInterface *eepromInterface = GetEepromInterface(); if (!IS_ARM(eepromInterface->getBoard())) { burnListAct = new QAction(QIcon(":/images/list.png"), tr("&List programmers"), this); burnListAct->setStatusTip(tr("List available programmers")); connect(burnListAct,SIGNAL(triggered()),this,SLOT(burnList())); burnFusesAct = new QAction(QIcon(":/images/fuses.png"), tr("&Fuses..."), this); burnFusesAct->setStatusTip(tr("Show fuses dialog")); connect(burnFusesAct,SIGNAL(triggered()),this,SLOT(burnFuses())); } simulateAct = new QAction(QIcon(":/images/simulate.png"), tr("&Simulate"), this); simulateAct->setShortcut(tr("Alt+S")); simulateAct->setStatusTip(tr("Simulate selected model.")); simulateAct->setEnabled(false); connect(simulateAct,SIGNAL(triggered()),this,SLOT(simulate())); printAct = new QAction(QIcon(":/images/print.png"), tr("&Print"), this); printAct->setShortcut(tr("Ctrl+P")); printAct->setStatusTip(tr("Print current model.")); printAct->setEnabled(false); connect(printAct,SIGNAL(triggered()),this,SLOT(print())); closeAct = new QAction(tr("Cl&ose"), this); closeAct->setStatusTip(tr("Close the active window")); connect(closeAct, SIGNAL(triggered()), mdiArea, SLOT(closeActiveSubWindow())); closeAllAct = new QAction(tr("Close &All"), this); closeAllAct->setStatusTip(tr("Close all the windows")); connect(closeAllAct, SIGNAL(triggered()), mdiArea, SLOT(closeAllSubWindows())); tileAct = new QAction(tr("&Tile"), this); tileAct->setStatusTip(tr("Tile the windows")); connect(tileAct, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows())); cascadeAct = new QAction(tr("&Cascade"), this); cascadeAct->setStatusTip(tr("Cascade the windows")); connect(cascadeAct, SIGNAL(triggered()), mdiArea, SLOT(cascadeSubWindows())); nextAct = new QAction(tr("Ne&xt"), this); nextAct->setShortcuts(QKeySequence::NextChild); nextAct->setStatusTip(tr("Move the focus to the next window")); connect(nextAct, SIGNAL(triggered()), mdiArea, SLOT(activateNextSubWindow())); previousAct = new QAction(tr("Pre&vious"), this); previousAct->setShortcuts(QKeySequence::PreviousChild); previousAct->setStatusTip(tr("Move the focus to the previous " "window")); connect(previousAct, SIGNAL(triggered()), mdiArea, SLOT(activatePreviousSubWindow())); separatorAct = new QAction(this); separatorAct->setSeparator(true); aboutAct = new QAction(QIcon(":/icon.png"), tr("&About"), this); aboutAct->setStatusTip(tr("Show the application's About box")); connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); switchLayoutDirectionAct = new QAction(QIcon(":/images/switch_dir.png"), tr("Switch layout direction"), this); switchLayoutDirectionAct->setStatusTip(tr("Switch layout Left/Right")); connect(switchLayoutDirectionAct, SIGNAL(triggered()), this, SLOT(switchLayoutDirection())); for (int i = 0; i < MaxRecentFiles; ++i) { recentFileActs[i] = new QAction(this); recentFileActs[i]->setVisible(false); connect(recentFileActs[i], SIGNAL(triggered()), this, SLOT(openRecentFile())); } updateRecentFileActions(); for (int i=0; isetVisible(false); connect(profileActs[i], SIGNAL(triggered()), this, SLOT(loadProfile())); } updateProfilesActions(); } void MainWindow::createMenus() { QMenu *recentFileMenu=new QMenu(tr("Recent Files")); QMenu *profilesMenu=new QMenu(tr("Firmware Profiles")); fileMenu = menuBar()->addMenu(tr("&File")); fileMenu->addAction(newAct); fileMenu->addAction(openAct); fileMenu->addAction(saveAct); fileMenu->addAction(saveAsAct); fileMenu->addMenu(recentFileMenu); recentFileMenu->setIcon(QIcon(":/images/recentdocument.png")); for ( int i = 0; i < MaxRecentFiles; ++i) recentFileMenu->addAction(recentFileActs[i]); fileMenu->addSeparator(); fileMenu->addAction(logsAct); fileMenu->addSeparator(); fileMenu->addAction(simulateAct); fileMenu->addAction(printAct); fileMenu->addAction(compareAct); fileMenu->addSeparator(); fileMenu->addAction(preferencesAct); fileMenu->addMenu(profilesMenu); profilesMenu->setIcon(QIcon(":/images/profiles.png")); for ( int i = 0; i < MAX_PROFILES; ++i) profilesMenu->addAction(profileActs[i]); fileMenu->addAction(switchLayoutDirectionAct); fileMenu->addAction(exitAct); editMenu = menuBar()->addMenu(tr("&Edit")); editMenu->addAction(cutAct); editMenu->addAction(copyAct); editMenu->addAction(pasteAct); burnMenu = menuBar()->addMenu(tr("&Burn")); burnMenu->addAction(burnToAct); burnMenu->addAction(burnFromAct); burnMenu->addSeparator(); burnMenu->addAction(burnExtenalToEEPROMAct); burnMenu->addAction(burnExtenalFromEEPROMAct); burnMenu->addSeparator(); burnMenu->addAction(burnToFlashAct); burnMenu->addAction(burnFromFlashAct); burnMenu->addSeparator(); burnMenu->addAction(customizeSplashAct); burnMenu->addSeparator(); burnMenu->addAction(burnConfigAct); EEPROMInterface *eepromInterface = GetEepromInterface(); if (!IS_ARM(eepromInterface->getBoard())) { burnMenu->addAction(burnFusesAct); burnMenu->addAction(burnListAct); } windowMenu = menuBar()->addMenu(tr("&Window")); updateWindowMenu(); connect(windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu())); menuBar()->addSeparator(); helpMenu = menuBar()->addMenu(tr("&Help")); helpMenu->addSeparator(); helpMenu->addAction(aboutAct); helpMenu->addSeparator(); helpMenu->addAction(checkForUpdatesAct); helpMenu->addSeparator(); helpMenu->addAction(changelogAct); helpMenu->addAction(fwchangelogAct); helpMenu->addSeparator(); helpMenu->addAction(contributorsAct); } QMenu *MainWindow::createRecentFileMenu() { QMenu *recentFileMenu = new QMenu(this); for ( int i = 0; i < MaxRecentFiles; ++i) recentFileMenu->addAction(recentFileActs[i]); return recentFileMenu; } QMenu *MainWindow::createProfilesMenu() { QMenu *profilesMenu = new QMenu(this); for ( int i = 0; i < MAX_PROFILES; ++i) profilesMenu->addAction(profileActs[i]); return profilesMenu; } void MainWindow::createToolBars() { fileToolBar = addToolBar(tr("File")); fileToolBar->addAction(newAct); fileToolBar->addAction(openAct); QToolButton * recentToolButton = new QToolButton; recentToolButton->setPopupMode(QToolButton::InstantPopup); recentToolButton->setMenu(createRecentFileMenu()); recentToolButton->setIcon(QIcon(":/images/recentdocument.png")); recentToolButton->setToolTip(tr("Recent Files")); fileToolBar->addWidget(recentToolButton); fileToolBar->addAction(saveAct); fileToolBar->addAction(logsAct); fileToolBar->addSeparator(); fileToolBar->addAction(preferencesAct); profileButton = new QToolButton; profileButton->setPopupMode(QToolButton::InstantPopup); profileButton->setMenu(createProfilesMenu()); profileButton->setIcon(QIcon(":/images/profiles.png")); profileButton->setToolTip(tr("Firmware Profiles")); fileToolBar->addWidget(profileButton); bool notfound=true; QSettings settings("companion9x", "companion9x"); settings.beginGroup("Profiles"); for (int i=0; isetDisabled(notfound); fileToolBar->addSeparator(); fileToolBar->addAction(simulateAct); fileToolBar->addAction(printAct); fileToolBar->addAction(compareAct); editToolBar = addToolBar(tr("Edit")); editToolBar->addAction(cutAct); editToolBar->addAction(copyAct); editToolBar->addAction(pasteAct); burnToolBar = addToolBar(tr("Burn")); burnToolBar->addAction(burnToAct); burnToolBar->addAction(burnFromAct); burnToolBar->addSeparator(); burnToolBar->addAction(burnExtenalToEEPROMAct); burnToolBar->addAction(burnExtenalFromEEPROMAct); burnToolBar->addSeparator(); burnToolBar->addAction(burnToFlashAct); burnToolBar->addAction(burnFromFlashAct); burnToolBar->addSeparator(); burnToolBar->addAction(burnConfigAct); helpToolBar = addToolBar(tr("Help")); helpToolBar->addAction(aboutAct); helpToolBar->addAction(checkForUpdatesAct); } void MainWindow::createStatusBar() { statusBar()->showMessage(tr("Ready")); } void MainWindow::readSettings() { QSettings settings("companion9x", "companion9x"); bool maximized = settings.value("maximized", false).toBool(); QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); QSize size = settings.value("size", QSize(400, 400)).toSize(); checkCompanion9x = settings.value("startup_check_companion9x", true).toBool(); checkFW = settings.value("startup_check_fw", true).toBool(); MaxRecentFiles =settings.value("history_size",10).toInt(); ActiveProfile=settings.value("activeprofile",0).toInt(); if (ActiveProfile) { settings.beginGroup("Profiles"); QString profile=QString("profile%1").arg(ActiveProfile); settings.beginGroup(profile); ActiveProfileName=settings.value("Name","").toString(); settings.endGroup(); settings.endGroup(); } if (maximized) { setWindowState(Qt::WindowMaximized); } else { move(pos); resize(size); } } void MainWindow::writeSettings() { QSettings settings("companion9x", "companion9x"); settings.setValue("maximized", isMaximized()); if(!isMaximized()) { settings.setValue("pos", pos()); settings.setValue("size", size()); } } MdiChild *MainWindow::activeMdiChild() { if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow()) return qobject_cast(activeSubWindow->widget()); return 0; } QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName) { QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath(); foreach (QMdiSubWindow *window, mdiArea->subWindowList()) { MdiChild *mdiChild = qobject_cast(window->widget()); if (mdiChild->currentFile() == canonicalFilePath) return window; } return 0; } void MainWindow::switchLayoutDirection() { if (layoutDirection() == Qt::LeftToRight) qApp->setLayoutDirection(Qt::RightToLeft); else qApp->setLayoutDirection(Qt::LeftToRight); } void MainWindow::setActiveSubWindow(QWidget *window) { if (!window) return; mdiArea->setActiveSubWindow(qobject_cast(window)); } void MainWindow::updateRecentFileActions() { int i,j, numRecentFiles; QSettings settings("companion9x", "companion9x"); QStringList files = settings.value("recentFileList").toStringList(); numRecentFiles = qMin(files.size(), (int)MaxRecentFiles); for ( i = 0; i < numRecentFiles; ++i) { QString text = tr("&%1 %2").arg(i + 1).arg(strippedName(files[i])); recentFileActs[i]->setText(text); recentFileActs[i]->setData(files[i]); recentFileActs[i]->setVisible(true); } for ( j = numRecentFiles; j < MaxRecentFiles; ++j) recentFileActs[j]->setVisible(false); // separatorAct->setVisible(numRecentFiles > 0); } void MainWindow::updateProfilesActions() { int i; QSettings settings("companion9x", "companion9x"); settings.beginGroup("Profiles"); for (i=0; isetText(text); profileActs[i]->setData(i+1); profileActs[i]->setVisible(true); } else { profileActs[i]->setVisible(false); } settings.endGroup(); } // separatorAct->setVisible(numRecentFiles > 0); } QString MainWindow::strippedName(const QString &fullFileName) { return QFileInfo(fullFileName).fileName(); } int MainWindow::getEpromVersion(QString fileName) { RadioData testData; if (fileName.isEmpty()) { return -1; } QFile file(fileName); if (!file.exists()) { QMessageBox::critical(this, tr("Error"), tr("Unable to find file %1!").arg(fileName)); return -1; } int fileType = getFileType(fileName); if (fileType==FILE_TYPE_XML) { if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file QMessageBox::critical(this, tr("Error"),tr("Error opening file %1:\n%2.").arg(fileName).arg(file.errorString())); return -1; } QTextStream inputStream(&file); XmlInterface(inputStream).load(testData); } else if (fileType==FILE_TYPE_HEX || fileType==FILE_TYPE_EEPE) { //read HEX file if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { //reading HEX TEXT file QMessageBox::critical(this, tr("Error"),tr("Error opening file %1:\n%2.").arg(fileName).arg(file.errorString())); return -1; } QDomDocument doc(ER9X_EEPROM_FILE_TYPE); bool xmlOK = doc.setContent(&file); if(xmlOK) { if (!LoadEepromXml(testData, doc)){ return -1; } } file.reset(); QTextStream inputStream(&file); if (fileType==FILE_TYPE_EEPE) { // read EEPE file header QString hline = inputStream.readLine(); if (hline!=EEPE_EEPROM_FILE_HEADER) { file.close(); return -1; } } uint8_t eeprom[EESIZE_RLC_MAX]; int eeprom_size = HexInterface(inputStream).load(eeprom, EESIZE_RLC_MAX); if (!eeprom_size) { QMessageBox::critical(this, tr("Error"), tr("Invalid EEPROM File %1").arg(fileName)); file.close(); return -1; } file.close(); if (!LoadEeprom(testData, eeprom, eeprom_size)) { QMessageBox::critical(this, tr("Error"),tr("Invalid EEPROM File %1").arg(fileName)); return -1; } } else if (fileType==FILE_TYPE_BIN) { //read binary int eeprom_size = file.size(); if (!file.open(QFile::ReadOnly)) { //reading binary file - TODO HEX support QMessageBox::critical(this, tr("Error"),tr("Error opening file %1:\n%2.").arg(fileName).arg(file.errorString())); return -1; } uint8_t *eeprom = (uint8_t *)malloc(eeprom_size); memset(eeprom, 0, eeprom_size); long result = file.read((char*)eeprom, eeprom_size); file.close(); if (result != eeprom_size) { QMessageBox::critical(this, tr("Error"),tr("Error reading file %1:\n%2.").arg(fileName).arg(file.errorString())); return -1; } if (!LoadEeprom(testData, eeprom, eeprom_size)) { QMessageBox::critical(this, tr("Error"),tr("Invalid binary EEPROM File %1").arg(fileName)); return -1; } } return testData.generalSettings.version; } void MainWindow::dragEnterEvent(QDragEnterEvent *event) { if (event->mimeData()->hasFormat("text/uri-list")) event->acceptProposedAction(); } void MainWindow::dropEvent(QDropEvent *event) { QList urls = event->mimeData()->urls(); if (urls.isEmpty()) return; QString fileName = urls.first().toLocalFile(); if (fileName.isEmpty()) return; QSettings settings("companion9x", "companion9x"); settings.setValue("lastDir", QFileInfo(fileName).dir().absolutePath()); QMdiSubWindow *existing = findMdiChild(fileName); if (existing) { mdiArea->setActiveSubWindow(existing); return; } MdiChild *child = createMdiChild(); if (child->loadFile(fileName)) { statusBar()->showMessage(tr("File loaded"), 2000); child->show(); } } void MainWindow::autoClose() { this->close(); }