From 421cf8954403ce2ba506ea2a238aee48cfe35835 Mon Sep 17 00:00:00 2001 From: Oleg Semyonov Date: Sun, 15 Jan 2012 15:36:52 +0200 Subject: [PATCH 1/2] Fix device info struct fields and variable names, better version info messages - fixed deviceDescriptorStruct field names (gitTag->gitHash, buildDate->gitDate, description->gitTag); - fixed variable names (onBoardDescrition->onBoardDescription, LoadedDescrition->LoadedDescription); - version info in exported UAV files looks now like this: --- .../uavobjectutil/devicedescriptorstruct.h | 4 +- .../uavobjectutil/uavobjectutilmanager.cpp | 69 ++++++++++--------- .../uavsettingsimportexportfactory.cpp | 35 +++++++--- .../src/plugins/uploader/devicewidget.cpp | 36 +++++----- .../src/plugins/uploader/devicewidget.h | 4 +- .../src/plugins/uploader/devicewidget.ui | 6 +- .../plugins/uploader/runningdevicewidget.cpp | 10 +-- .../plugins/uploader/uploadergadgetwidget.cpp | 26 ++++--- 8 files changed, 107 insertions(+), 83 deletions(-) diff --git a/ground/openpilotgcs/src/plugins/uavobjectutil/devicedescriptorstruct.h b/ground/openpilotgcs/src/plugins/uavobjectutil/devicedescriptorstruct.h index c44fb73c0..bf8fafb19 100644 --- a/ground/openpilotgcs/src/plugins/uavobjectutil/devicedescriptorstruct.h +++ b/ground/openpilotgcs/src/plugins/uavobjectutil/devicedescriptorstruct.h @@ -5,9 +5,9 @@ struct deviceDescriptorStruct { public: + QString gitHash; + QString gitDate; QString gitTag; - QString buildDate; - QString description; int boardType; int boardRevision; static QString idToBoardName(int id) diff --git a/ground/openpilotgcs/src/plugins/uavobjectutil/uavobjectutilmanager.cpp b/ground/openpilotgcs/src/plugins/uavobjectutil/uavobjectutilmanager.cpp index 0fc0e5fd9..ac64c61d8 100644 --- a/ground/openpilotgcs/src/plugins/uavobjectutil/uavobjectutilmanager.cpp +++ b/ground/openpilotgcs/src/plugins/uavobjectutil/uavobjectutilmanager.cpp @@ -669,42 +669,45 @@ deviceDescriptorStruct UAVObjectUtilManager::getBoardDescriptionStruct() bool UAVObjectUtilManager::descriptionToStructure(QByteArray desc, deviceDescriptorStruct *struc) { - if (desc.startsWith("OpFw")) { - // This looks like a binary with a description at the end - /* - # 4 bytes: header: "OpFw" - # 4 bytes: GIT commit tag (short version of SHA1) - # 4 bytes: Unix timestamp of compile time - # 2 bytes: target platform. Should follow same rule as BOARD_TYPE and BOARD_REVISION in board define files. - # 26 bytes: commit tag if it is there, otherwise "Unreleased". Zero-padded - # ---- 40 bytes limit --- - # 20 bytes: SHA1 sum of the firmware. - # 40 bytes: free for now. - */ + if (desc.startsWith("OpFw")) { + /* + * This looks like a binary with a description at the end + * 4 bytes: header: "OpFw" + * 4 bytes: git commit hash (short version of SHA1) + * 4 bytes: Unix timestamp of last git commit + * 2 bytes: target platform. Should follow same rule as BOARD_TYPE and BOARD_REVISION in board define files. + * 26 bytes: commit tag if it is there, otherwise "Unreleased". Zero-padded + * ---- 40 bytes limit --- + * 20 bytes: SHA1 sum of the firmware. + * 40 bytes: free for now. + */ - // Note: the ARM binary is big-endian: - quint32 gitCommitTag = desc.at(7)&0xFF; - for (int i=1;i<4;i++) { - gitCommitTag = gitCommitTag<<8; - gitCommitTag += desc.at(7-i) & 0xFF; - } - struc->gitTag=QString::number(gitCommitTag,16); - quint32 buildDate = desc.at(11)&0xFF; - for (int i=1;i<4;i++) { - buildDate = buildDate<<8; - buildDate += desc.at(11-i) & 0xFF; - } - struc->buildDate= QDateTime::fromTime_t(buildDate).toUTC().toString("yyyyMMdd HH:mm"); - QByteArray targetPlatform = desc.mid(12,2); - // TODO: check platform compatibility - QString dscText = QString(desc.mid(14,26)); - struc->boardType=(int)targetPlatform.at(0); - struc->boardRevision=(int)targetPlatform.at(1); - struc->description=dscText; - return true; + // Note: the ARM binary is big-endian: + quint32 gitCommitHash = desc.at(7) & 0xFF; + for (int i = 1; i < 4; i++) { + gitCommitHash = gitCommitHash << 8; + gitCommitHash += desc.at(7-i) & 0xFF; } - return false; + struc->gitHash = QString::number(gitCommitHash, 16); + quint32 gitDate = desc.at(11) & 0xFF; + for (int i = 1; i < 4; i++) { + gitDate = gitDate << 8; + gitDate += desc.at(11-i) & 0xFF; + } + struc->gitDate = QDateTime::fromTime_t(gitDate).toUTC().toString("yyyyMMdd HH:mm"); + + QString gitTag = QString(desc.mid(14,26)); + struc->gitTag = gitTag; + + // TODO: check platform compatibility + QByteArray targetPlatform = desc.mid(12,2); + struc->boardType = (int)targetPlatform.at(0); + struc->boardRevision = (int)targetPlatform.at(1); + + return true; + } + return false; } // ****************************** diff --git a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp index b082e1eb5..7645d0cf7 100644 --- a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp +++ b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp @@ -218,20 +218,37 @@ QString UAVSettingsImportExportFactory::createXMLDocument( QDomDocument doc(docName); QDomElement root = doc.createElement(isSettings ? "settings" : "data"); doc.appendChild(root); - QDomElement versionInfo =doc.createElement("versionInfo"); + + // add hardware, firmware and GCS version info + QDomElement versionInfo = doc.createElement("version"); root.appendChild(versionInfo); - QDomElement fw=doc.createElement("Embedded"); - UAVObjectUtilManager* utilMngr = pm->getObject(); - deviceDescriptorStruct struc=utilMngr->getBoardDescriptionStruct(); - fw.setAttribute("gitcommittag",struc.gitTag); - fw.setAttribute("fwtag",struc.description); - fw.setAttribute("cpuSerial",QString(utilMngr->getBoardCPUSerial().toHex())); + UAVObjectUtilManager *utilMngr = pm->getObject(); + deviceDescriptorStruct board = utilMngr->getBoardDescriptionStruct(); + QDomElement hw = doc.createElement("hardware"); + hw.setAttribute("type", QString().setNum(board.boardType, 16)); + hw.setAttribute("revision", QString().setNum(board.boardRevision, 16)); + hw.setAttribute("serial", QString(utilMngr->getBoardCPUSerial().toHex())); + versionInfo.appendChild(hw); + + QDomElement fw = doc.createElement("firmware"); + fw.setAttribute("date", board.gitDate); + fw.setAttribute("hash", board.gitHash); + fw.setAttribute("tag", board.gitTag); versionInfo.appendChild(fw); - QDomElement gcs=doc.createElement("GCS"); - gcs.setAttribute("revision",QString::fromLatin1(Core::Constants::GCS_REVISION_STR)); + + QString gcsRevision = QString::fromLatin1(Core::Constants::GCS_REVISION_STR); + QString gcsGitDate = gcsRevision.mid(gcsRevision.indexOf(" ") + 1, 14); + QString gcsGitHash = gcsRevision.mid(gcsRevision.indexOf(":") + 1, 8); + QString gcsGitTag = gcsRevision.left(gcsRevision.indexOf(":")); + + QDomElement gcs = doc.createElement("gcs"); + gcs.setAttribute("date", gcsGitDate); + gcs.setAttribute("hash", gcsGitHash); + gcs.setAttribute("tag", gcsGitTag); versionInfo.appendChild(gcs); + // iterate over settings objects QList< QList > objList = objManager->getDataObjects(); foreach (QList list, objList) { diff --git a/ground/openpilotgcs/src/plugins/uploader/devicewidget.cpp b/ground/openpilotgcs/src/plugins/uploader/devicewidget.cpp index 9e57a4225..b5e977a48 100644 --- a/ground/openpilotgcs/src/plugins/uploader/devicewidget.cpp +++ b/ground/openpilotgcs/src/plugins/uploader/devicewidget.cpp @@ -180,13 +180,13 @@ void deviceWidget::freeze() */ bool deviceWidget::populateBoardStructuredDescription(QByteArray desc) { - if(UAVObjectUtilManager::descriptionToStructure(desc,&onBoardDescrition)) + if(UAVObjectUtilManager::descriptionToStructure(desc,&onBoardDescription)) { - myDevice->lblGitTag->setText(onBoardDescrition.gitTag); - myDevice->lblBuildDate->setText(onBoardDescrition.buildDate.insert(4,"-").insert(7,"-")); - if(onBoardDescrition.description.startsWith("release",Qt::CaseInsensitive)) + myDevice->lblGitTag->setText(onBoardDescription.gitHash); + myDevice->lblBuildDate->setText(onBoardDescription.gitDate.insert(4,"-").insert(7,"-")); + if(onBoardDescription.gitTag.startsWith("release",Qt::CaseInsensitive)) { - myDevice->lblDescription->setText(QString("Firmware tag: ")+onBoardDescrition.description); + myDevice->lblDescription->setText(QString("Firmware tag: ")+onBoardDescription.gitTag); QPixmap pix = QPixmap(QString(":uploader/images/application-certificate.svg")); myDevice->lblCertified->setPixmap(pix); myDevice->lblCertified->setToolTip(tr("Tagged officially released firmware build")); @@ -194,13 +194,13 @@ bool deviceWidget::populateBoardStructuredDescription(QByteArray desc) } else { - myDevice->lblDescription->setText(onBoardDescrition.description); + myDevice->lblDescription->setText(onBoardDescription.gitTag); QPixmap pix = QPixmap(QString(":uploader/images/warning.svg")); myDevice->lblCertified->setPixmap(pix); myDevice->lblCertified->setToolTip(tr("Untagged or custom firmware build")); } - myDevice->lblBrdName->setText(idToBoardName(onBoardDescrition.boardType<<8)); + myDevice->lblBrdName->setText(idToBoardName(onBoardDescription.boardType<<8)); return true; } @@ -210,27 +210,27 @@ bool deviceWidget::populateBoardStructuredDescription(QByteArray desc) } bool deviceWidget::populateLoadedStructuredDescription(QByteArray desc) { - if(UAVObjectUtilManager::descriptionToStructure(desc,&LoadedDescrition)) + if(UAVObjectUtilManager::descriptionToStructure(desc,&LoadedDescription)) { - myDevice->lblGitTagL->setText(LoadedDescrition.gitTag); - myDevice->lblBuildDateL->setText( LoadedDescrition.buildDate.insert(4,"-").insert(7,"-")); - if(LoadedDescrition.description.startsWith("release",Qt::CaseInsensitive)) + myDevice->lblGitTagL->setText(LoadedDescription.gitHash); + myDevice->lblBuildDateL->setText( LoadedDescription.gitDate.insert(4,"-").insert(7,"-")); + if(LoadedDescription.gitTag.startsWith("release",Qt::CaseInsensitive)) { - myDevice->lblDescritpionL->setText(LoadedDescrition.description); - myDevice->description->setText(LoadedDescrition.description); + myDevice->lblDescritpionL->setText(LoadedDescription.gitTag); + myDevice->description->setText(LoadedDescription.gitTag); QPixmap pix = QPixmap(QString(":uploader/images/application-certificate.svg")); myDevice->lblCertifiedL->setPixmap(pix); myDevice->lblCertifiedL->setToolTip(tr("Tagged officially released firmware build")); } else { - myDevice->lblDescritpionL->setText(LoadedDescrition.description); - myDevice->description->setText(LoadedDescrition.description); + myDevice->lblDescritpionL->setText(LoadedDescription.gitTag); + myDevice->description->setText(LoadedDescription.gitTag); QPixmap pix = QPixmap(QString(":uploader/images/warning.svg")); myDevice->lblCertifiedL->setPixmap(pix); myDevice->lblCertifiedL->setToolTip(tr("Untagged or custom firmware build")); } - myDevice->lblBrdNameL->setText(deviceDescriptorStruct::idToBoardName(LoadedDescrition.boardType<<8)); + myDevice->lblBrdNameL->setText(deviceDescriptorStruct::idToBoardName(LoadedDescription.boardType<<8)); return true; } @@ -323,12 +323,12 @@ void deviceWidget::loadFirmware() myDevice->statusLabel->setText(tr("WARNING: the loaded firmware is for different hardware. Do not update!")); px.load(QString(":/uploader/images/error.svg")); } - else if(QDateTime::fromString(onBoardDescrition.buildDate)>QDateTime::fromString(LoadedDescrition.buildDate)) + else if(QDateTime::fromString(onBoardDescription.gitDate)>QDateTime::fromString(LoadedDescription.gitDate)) { myDevice->statusLabel->setText(tr("The board has newer firmware than loaded. Are you sure you want to update?")); px.load(QString(":/uploader/images/warning.svg")); } - else if(!LoadedDescrition.description.startsWith("release",Qt::CaseInsensitive)) + else if(!LoadedDescription.gitTag.startsWith("release",Qt::CaseInsensitive)) { myDevice->statusLabel->setText(tr("The loaded firmware is untagged or custom build. Update only if it was received from a trusted source (official website or your own build)")); px.load(QString(":/uploader/images/warning.svg")); diff --git a/ground/openpilotgcs/src/plugins/uploader/devicewidget.h b/ground/openpilotgcs/src/plugins/uploader/devicewidget.h index 772216e3b..3530c3d6a 100644 --- a/ground/openpilotgcs/src/plugins/uploader/devicewidget.h +++ b/ground/openpilotgcs/src/plugins/uploader/devicewidget.h @@ -54,8 +54,8 @@ public: QString setOpenFileName(); QString setSaveFileName(); private: - deviceDescriptorStruct onBoardDescrition; - deviceDescriptorStruct LoadedDescrition; + deviceDescriptorStruct onBoardDescription; + deviceDescriptorStruct LoadedDescription; QByteArray loadedFW; QString idToBoardName(int id); Ui_deviceWidget *myDevice; diff --git a/ground/openpilotgcs/src/plugins/uploader/devicewidget.ui b/ground/openpilotgcs/src/plugins/uploader/devicewidget.ui index c5c7a807e..4fea11eb5 100644 --- a/ground/openpilotgcs/src/plugins/uploader/devicewidget.ui +++ b/ground/openpilotgcs/src/plugins/uploader/devicewidget.ui @@ -208,7 +208,7 @@ - Description: + Firmware tag: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -218,7 +218,7 @@ - Build date: + Firmware date: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter @@ -228,7 +228,7 @@ - Git tag: + Git commit hash: Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter diff --git a/ground/openpilotgcs/src/plugins/uploader/runningdevicewidget.cpp b/ground/openpilotgcs/src/plugins/uploader/runningdevicewidget.cpp index fcde00125..a62fe403c 100644 --- a/ground/openpilotgcs/src/plugins/uploader/runningdevicewidget.cpp +++ b/ground/openpilotgcs/src/plugins/uploader/runningdevicewidget.cpp @@ -112,9 +112,9 @@ void runningDeviceWidget::populate() deviceDescriptorStruct devDesc; if(UAVObjectUtilManager::descriptionToStructure(description,&devDesc)) { - if(devDesc.description.startsWith("release",Qt::CaseInsensitive)) + if(devDesc.gitTag.startsWith("release",Qt::CaseInsensitive)) { - myDevice->lblFWTag->setText(QString("Firmware tag: ")+devDesc.description); + myDevice->lblFWTag->setText(QString("Firmware tag: ")+devDesc.gitTag); QPixmap pix = QPixmap(QString(":uploader/images/application-certificate.svg")); myDevice->lblCertified->setPixmap(pix); myDevice->lblCertified->setToolTip(tr("Tagged officially released firmware build")); @@ -122,13 +122,13 @@ void runningDeviceWidget::populate() } else { - myDevice->lblFWTag->setText(QString("Firmware tag: ")+devDesc.description); + myDevice->lblFWTag->setText(QString("Firmware tag: ")+devDesc.gitTag); QPixmap pix = QPixmap(QString(":uploader/images/warning.svg")); myDevice->lblCertified->setPixmap(pix); myDevice->lblCertified->setToolTip(tr("Untagged or custom firmware build")); } - myDevice->lblGitCommitTag->setText("Git commit tag: "+devDesc.gitTag); - myDevice->lblFWDate->setText(QString("Firmware date: ") + devDesc.buildDate.insert(4,"-").insert(7,"-")); + myDevice->lblGitCommitTag->setText("Git commit hash: "+devDesc.gitHash); + myDevice->lblFWDate->setText(QString("Firmware date: ") + devDesc.gitDate.insert(4,"-").insert(7,"-")); } else { diff --git a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp index 73bc0c535..4a312f6b5 100755 --- a/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp +++ b/ground/openpilotgcs/src/plugins/uploader/uploadergadgetwidget.cpp @@ -619,16 +619,20 @@ void UploaderGadgetWidget::info(QString infoString, int infoNumber) void UploaderGadgetWidget::versionMatchCheck() { ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - UAVObjectUtilManager* utilMngr = pm->getObject(); - deviceDescriptorStruct boardDescription=utilMngr->getBoardDescriptionStruct(); - QString gcsDescription=QString::fromLatin1(Core::Constants::GCS_REVISION_STR); - if(boardDescription.gitTag!=gcsDescription.mid(gcsDescription.indexOf(":")+1,8)) - { - qDebug()<showMessage(QString(tr("GCS and FW versions do not match which can cause configuration problems.")) + " \n" + - QString(tr("GCS Versions: ")) + gcsDescription + " \n" + - QString(tr("FW Versions: ")) + boardDescription.gitTag+":"+boardDescription.buildDate); + UAVObjectUtilManager *utilMngr = pm->getObject(); + deviceDescriptorStruct boardDescription = utilMngr->getBoardDescriptionStruct(); + + QString gcsDescription = QString::fromLatin1(Core::Constants::GCS_REVISION_STR); + QString gcsGitHash = gcsDescription.mid(gcsDescription.indexOf(":")+1, 8); + QString gcsGitDate = gcsDescription.mid(gcsDescription.indexOf(" ")+1, 14); + + QString gcsVersion = gcsGitDate + " (" + gcsGitHash + ")"; + QString fwVersion = boardDescription.gitDate + " (" + boardDescription.gitHash + ")"; + + if (boardDescription.gitHash != gcsGitHash) { + QString warning = QString(tr( + "GCS and firmware versions do not match which can cause configuration problems. " + "GCS version: %1. Firmware version: %2.")).arg(gcsVersion).arg(fwVersion); + msg->showMessage(warning); } } From 873ff617ab60e0e2c08779c09be4644957699569 Mon Sep 17 00:00:00 2001 From: Oleg Semyonov Date: Sun, 15 Jan 2012 18:33:47 +0200 Subject: [PATCH 2/2] Improve UAVObjects export and import file formats Changed file format to be able to save settings and data together. Old settings files still can be imported. Data export will also contain settings, so we always have the system settings with the system state. Sample file: ... ... ... --- .../uavsettingsimportexportfactory.cpp | 203 ++++++++++-------- .../uavsettingsimportexportfactory.h | 5 +- 2 files changed, 119 insertions(+), 89 deletions(-) diff --git a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp index 7645d0cf7..3552ad752 100644 --- a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp +++ b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp @@ -31,6 +31,7 @@ #include #include #include "importsummary.h" + // for menu item #include #include @@ -49,20 +50,18 @@ #include #include - - UAVSettingsImportExportFactory::~UAVSettingsImportExportFactory() { // Do nothing } -UAVSettingsImportExportFactory::UAVSettingsImportExportFactory(QObject * parent):QObject(parent) +UAVSettingsImportExportFactory::UAVSettingsImportExportFactory(QObject *parent):QObject(parent) { // Add Menu entry - Core::ActionManager* am = Core::ICore::instance()->actionManager(); - Core::ActionContainer* ac = am->actionContainer(Core::Constants::M_FILE); - Core::Command* cmd = am->registerAction(new QAction(this), + Core::ActionManager *am = Core::ICore::instance()->actionManager(); + Core::ActionContainer *ac = am->actionContainer(Core::Constants::M_FILE); + Core::Command *cmd = am->registerAction(new QAction(this), "UAVSettingsImportExportPlugin.UAVSettingsExport", QList() << Core::Constants::C_GLOBAL_ID); @@ -95,7 +94,7 @@ void UAVSettingsImportExportFactory::importUAVSettings() { // ask for file name QString fileName; - QString filters = tr("UAVSettings XML files (*.uav);; XML files (*.xml)"); + QString filters = tr("UAVObjects XML files (*.uav);; XML files (*.xml)"); fileName = QFileDialog::getOpenFileName(0, tr("Import UAV Settings"), "", filters); if (fileName.isEmpty()) { return; @@ -103,7 +102,7 @@ void UAVSettingsImportExportFactory::importUAVSettings() // Now open the file QFile file(fileName); - QDomDocument doc("UAVSettings"); + QDomDocument doc("UAVObjects"); file.open(QFile::ReadOnly|QFile::Text); if (!doc.setContent(file.readAll())) { QMessageBox msgBox; @@ -114,13 +113,19 @@ void UAVSettingsImportExportFactory::importUAVSettings() return; } file.close(); + + // find the root of settings subtree emit importAboutToBegin(); qDebug()<<"Import about to begin"; + QDomElement root = doc.documentElement(); - if (root.tagName() != "settings") { + if (root.tagName() == "uavobjects") { + root = root.firstChildElement("settings"); + } + if (root.isNull() || (root.tagName() != "settings")) { QMessageBox msgBox; - msgBox.setText(tr("Wrong file contents.")); - msgBox.setInformativeText(tr("This file is not a correct UAVSettings file")); + msgBox.setText(tr("Wrong file contents")); + msgBox.setInformativeText(tr("This file does not contain correct UAVSettings")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.exec(); return; @@ -138,85 +143,86 @@ void UAVSettingsImportExportFactory::importUAVSettings() while (!node.isNull()) { QDomElement e = node.toElement(); if (e.tagName() == "object") { - // - Read each object - QString uavObjectName = e.attribute("name"); - uint uavObjectID = e.attribute("id").toUInt(NULL,16); - // Sanity Check: - UAVObject* obj = objManager->getObject(uavObjectName); - if (obj == NULL) { - // This object is unknown! - qDebug() << "Object unknown:" << uavObjectName << uavObjectID; - swui.addLine(uavObjectName, "Error (Object unknown)", false); + // - Read each object + QString uavObjectName = e.attribute("name"); + uint uavObjectID = e.attribute("id").toUInt(NULL,16); - } else { - // - Update each field - // - Issue and "updated" command - bool error=false; - bool setError=false; - QDomNode field = node.firstChild(); - while(!field.isNull()) { - QDomElement f = field.toElement(); - if (f.tagName() == "field") { - UAVObjectField *uavfield = obj->getField(f.attribute("name")); - if (uavfield) { - QStringList list = f.attribute("values").split(","); - if (list.length() == 1) { - if (false == uavfield->checkValue(f.attribute("values"))) { - qDebug() << "checkValue returned false on: " << uavObjectName << f.attribute("values"); - setError = true; - } else - uavfield->setValue(f.attribute("values")); - } else { - // This is an enum: - int i=0; - QStringList list = f.attribute("values").split(","); - foreach (QString element, list) { - if (false == uavfield->checkValue(element,i)) { - qDebug() << "checkValue(list) returned false on: " << uavObjectName << list; - setError = true; - } else + // Sanity Check: + UAVObject *obj = objManager->getObject(uavObjectName); + if (obj == NULL) { + // This object is unknown! + qDebug() << "Object unknown:" << uavObjectName << uavObjectID; + swui.addLine(uavObjectName, "Error (Object unknown)", false); + } else { + // - Update each field + // - Issue and "updated" command + bool error = false; + bool setError = false; + QDomNode field = node.firstChild(); + while(!field.isNull()) { + QDomElement f = field.toElement(); + if (f.tagName() == "field") { + UAVObjectField *uavfield = obj->getField(f.attribute("name")); + if (uavfield) { + QStringList list = f.attribute("values").split(","); + if (list.length() == 1) { + if (false == uavfield->checkValue(f.attribute("values"))) { + qDebug() << "checkValue returned false on: " << uavObjectName << f.attribute("values"); + setError = true; + } else { + uavfield->setValue(f.attribute("values")); + } + } else { + // This is an enum: + int i = 0; + QStringList list = f.attribute("values").split(","); + foreach (QString element, list) { + if (false == uavfield->checkValue(element, i)) { + qDebug() << "checkValue(list) returned false on: " << uavObjectName << list; + setError = true; + } else { uavfield->setValue(element,i); - i++; - } - } - } else { - error = true; - } - } - field = field.nextSibling(); - } - obj->updated(); - if (error) { - swui.addLine(uavObjectName, "Warning (Object field unknown)", true); - } else if (uavObjectID != obj->getObjID()) { - qDebug() << "Mismatch for Object " << uavObjectName << uavObjectID << " - " << obj->getObjID(); - swui.addLine(uavObjectName, "Warning (ObjectID mismatch)", true); - } else if (setError) { - swui.addLine(uavObjectName, "Warning (Objects field value(s) invalid)", false); - } else - swui.addLine(uavObjectName, "OK", true); - } + } + i++; + } + } + } else { + error = true; + } + } + field = field.nextSibling(); + } + obj->updated(); + + if (error) { + swui.addLine(uavObjectName, "Warning (Object field unknown)", true); + } else if (uavObjectID != obj->getObjID()) { + qDebug() << "Mismatch for Object " << uavObjectName << uavObjectID << " - " << obj->getObjID(); + swui.addLine(uavObjectName, "Warning (ObjectID mismatch)", true); + } else if (setError) { + swui.addLine(uavObjectName, "Warning (Objects field value(s) invalid)", false); + } else { + swui.addLine(uavObjectName, "OK", true); + } + } } node = node.nextSibling(); } - qDebug()<<"End import"; + qDebug() << "End import"; swui.exec(); - - - } // Create an XML document from UAVObject database -QString UAVSettingsImportExportFactory::createXMLDocument( - const QString docName, const bool isSettings, const bool fullExport) +QString UAVSettingsImportExportFactory::createXMLDocument(const enum storedData what, const bool fullExport) { // generate an XML first (used for all export formats as a formatted data source) ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); UAVObjectManager *objManager = pm->getObject(); - QDomDocument doc(docName); - QDomElement root = doc.createElement(isSettings ? "settings" : "data"); + // create an XML root + QDomDocument doc("UAVObjects"); + QDomElement root = doc.createElement("uavobjects"); doc.appendChild(root); // add hardware, firmware and GCS version info @@ -249,11 +255,31 @@ QString UAVSettingsImportExportFactory::createXMLDocument( gcs.setAttribute("tag", gcsGitTag); versionInfo.appendChild(gcs); + // create settings and/or data elements + QDomElement settings = doc.createElement("settings"); + QDomElement data = doc.createElement("data"); + + switch (what) + { + case Settings: + root.appendChild(settings); + break; + case Data: + root.appendChild(data); + break; + case Both: + root.appendChild(data); + root.appendChild(settings); + break; + } + // iterate over settings objects QList< QList > objList = objManager->getDataObjects(); foreach (QList list, objList) { - foreach (UAVDataObject* obj, list) { - if (obj->isSettings() == isSettings) { + foreach (UAVDataObject *obj, list) { + if (((what == Settings) && obj->isSettings()) || + ((what == Data) && !obj->isSettings()) || + (what == Both)) { // add each object to the XML QDomElement o = doc.createElement("object"); @@ -292,7 +318,12 @@ QString UAVSettingsImportExportFactory::createXMLDocument( } o.appendChild(f); } - root.appendChild(o); + + // append to the settings or data element + if (obj->isSettings()) + settings.appendChild(o); + else + data.appendChild(o); } } } @@ -305,15 +336,15 @@ void UAVSettingsImportExportFactory::exportUAVSettings() { // ask for file name QString fileName; - QString filters = tr("UAVSettings XML files (*.uav)"); + QString filters = tr("UAVObjects XML files (*.uav)"); - fileName = QFileDialog::getSaveFileName(0, tr("Save UAV Settings File As"), "", filters); + fileName = QFileDialog::getSaveFileName(0, tr("Save UAVSettings File As"), "", filters); if (fileName.isEmpty()) { return; } - bool fullExport = false; // If the filename ends with .xml, we will do a full export, otherwise, a simple export + bool fullExport = false; if (fileName.endsWith(".xml")) { fullExport = true; } else if (!fileName.endsWith(".uav")) { @@ -321,7 +352,7 @@ void UAVSettingsImportExportFactory::exportUAVSettings() } // generate an XML first (used for all export formats as a formatted data source) - QString xml = createXMLDocument("UAVSettings", true, fullExport); + QString xml = createXMLDocument(Settings, fullExport); // save file QFile file(fileName); @@ -356,15 +387,15 @@ void UAVSettingsImportExportFactory::exportUAVData() // ask for file name QString fileName; - QString filters = tr("UAVData XML files (*.uav)"); + QString filters = tr("UAVObjects XML files (*.uav)"); - fileName = QFileDialog::getSaveFileName(0, tr("Save UAV Data File As"), "", filters); + fileName = QFileDialog::getSaveFileName(0, tr("Save UAVData File As"), "", filters); if (fileName.isEmpty()) { return; } - bool fullExport = false; // If the filename ends with .xml, we will do a full export, otherwise, a simple export + bool fullExport = false; if (fileName.endsWith(".xml")) { fullExport = true; } else if (!fileName.endsWith(".uav")) { @@ -372,7 +403,7 @@ void UAVSettingsImportExportFactory::exportUAVData() } // generate an XML first (used for all export formats as a formatted data source) - QString xml = createXMLDocument("UAVData", false, fullExport); + QString xml = createXMLDocument(Both, fullExport); // save file QFile file(fileName); diff --git a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.h b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.h index a130d5c4a..d2fb03952 100644 --- a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.h +++ b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.h @@ -38,9 +38,8 @@ public: ~UAVSettingsImportExportFactory(); private: - QString createXMLDocument(const QString docName, - const bool isSettings, - const bool fullExport); + enum storedData { Settings, Data, Both }; + QString createXMLDocument(const enum storedData, const bool fullExport); private slots: void importUAVSettings();