35 #include <QStringList>
38 #include <QMainWindow>
46 #include <QKeySequence>
55 #include <QDomDocument>
59 #include <QFileDialog>
60 #include <QMessageBox>
76 am->
registerAction(
new QAction(
this),
"UAVSettingsImportExportPlugin.UAVSettingsExport",
79 cmd->
action()->setText(tr(
"Export UAV Settings..."));
83 cmd = am->
registerAction(
new QAction(
this),
"UAVSettingsImportExportPlugin.UAVSettingsImport",
86 cmd->action()->setText(tr(
"Import UAV Settings..."));
91 cmd = am->
registerAction(
new QAction(
this),
"UAVSettingsImportExportPlugin.UAVDataExport",
93 cmd->
action()->setText(tr(
"Export UAV Data..."));
95 connect(cmd->action(), SIGNAL(triggered(
bool)),
this, SLOT(
exportUAVData()));
102 auto pm = ExtensionSystem::PluginManager::instance();
106 &UAVSettingsImportExportManager::setCommandsEnabled);
107 setCommandsEnabled(telemetry->isConnected());
113 QDomDocument doc(
"UAVObjects");
115 if (!doc.setContent(settings)) {
117 msgBox.setText(tr(
"File Parsing Failed."));
118 msgBox.setInformativeText(tr(
"This file is not a correct XML file"));
119 msgBox.setStandardButtons(QMessageBox::Ok);
124 qDebug() <<
"Import about to begin";
127 QDomElement root = doc.documentElement();
128 if (root.tagName() ==
"uavobjects") {
129 root = root.firstChildElement(
"settings");
131 if (root.isNull() || (root.tagName() !=
"settings")) {
133 msgBox.setText(tr(
"Wrong file contents"));
134 msgBox.setInformativeText(tr(
"This file does not contain correct UAVSettings"));
135 msgBox.setStandardButtons(QMessageBox::Ok);
150 QDomNode node = root.firstChild();
151 while (!node.isNull()) {
152 QDomElement
e = node.toElement();
153 if (e.tagName() ==
"object") {
156 QString uavObjectName = e.attribute(
"name");
157 uint uavObjectID = e.attribute(
"id").toUInt(NULL, 16);
164 qDebug() <<
"Object unknown:" << uavObjectName << uavObjectID;
165 swui.
addLine(uavObjectName,
"Error (Object unknown)",
false);
167 swui.
addLine(uavObjectName,
"Error (Object not present on hw)",
false);
174 bool setError =
false;
175 QDomNode field = node.firstChild();
176 while (!field.isNull()) {
177 QDomElement f = field.toElement();
178 if (f.tagName() ==
"field") {
181 QStringList list = f.attribute(
"values").split(
",");
182 if (list.length() == 1) {
183 if (
false == uavfield->
checkValue(f.attribute(
"values"))) {
184 qDebug() <<
"checkValue returned false on: " << uavObjectName
185 << f.attribute(
"values");
188 uavfield->
setValue(f.attribute(
"values"));
193 QStringList list = f.attribute(
"values").split(
",");
194 foreach (QString element, list) {
195 if (
false == uavfield->
checkValue(element, i)) {
196 qDebug() <<
"checkValue(list) returned false on: "
197 << uavObjectName << list;
209 field = field.nextSibling();
214 swui.
addLine(uavObjectName,
"Warning (Object field unknown)",
true);
215 }
else if (uavObjectID != newObj->
getObjID()) {
216 qDebug() <<
"Mismatch for Object " << uavObjectName << uavObjectID <<
" - "
218 swui.
addLine(uavObjectName,
"Warning (ObjectID mismatch)",
true);
219 }
else if (setError) {
220 swui.
addLine(uavObjectName,
"Warning (Objects field value(s) invalid)",
false);
222 swui.
addLine(uavObjectName,
"OK",
true);
224 importedObjectManager->registerObject(newObj);
227 node = node.nextSibling();
229 qDebug() <<
"End import";
233 tr(
"Unable to import settings"),
234 tr(
"No settings found in XML dump; the flight controller settings "
235 "may have been blank."),
244 return swui.result() == QDialog::Accepted;
252 QString filters = tr(
"UAVObjects XML files (*.uav);; XML files (*.xml)");
255 tr(
"Import UAV Settings"),
"", filters);
256 if (fileName.isEmpty()) {
261 QFile
file(fileName);
262 QDomDocument doc(
"UAVObjects");
263 file.open(QFile::ReadOnly | QFile::Text);
271 QString UAVSettingsImportExportManager::createXMLDocument(
const enum storedData what,
272 const bool fullExport)
279 QDomDocument doc(
"UAVObjects");
280 QDomElement root = doc.createElement(
"uavobjects");
281 doc.appendChild(root);
284 QDomElement versionInfo = doc.createElement(
"version");
285 root.appendChild(versionInfo);
291 QDomElement hw = doc.createElement(
"hardware");
292 hw.setAttribute(
"type", QString().setNum(board.boardType, 16));
293 hw.setAttribute(
"revision", QString().setNum(board.boardRevision, 16));
295 versionInfo.appendChild(hw);
297 QDomElement fw = doc.createElement(
"firmware");
298 fw.setAttribute(
"date", board.gitDate);
299 fw.setAttribute(
"hash", board.gitHash);
300 fw.setAttribute(
"tag", board.gitTag);
301 versionInfo.appendChild(fw);
304 QString gcsGitDate = gcsRevision.mid(gcsRevision.indexOf(
" ") + 1, 14);
305 QString gcsGitHash = gcsRevision.mid(gcsRevision.indexOf(
":") + 1, 8);
306 QString gcsGitTag = gcsRevision.left(gcsRevision.indexOf(
":"));
308 QDomElement gcs = doc.createElement(
"gcs");
309 gcs.setAttribute(
"date", gcsGitDate);
310 gcs.setAttribute(
"hash", gcsGitHash);
311 gcs.setAttribute(
"tag", gcsGitTag);
312 versionInfo.appendChild(gcs);
315 QDomElement settings = doc.createElement(
"settings");
316 QDomElement
data = doc.createElement(
"data");
320 root.appendChild(settings);
323 root.appendChild(data);
326 root.appendChild(data);
327 root.appendChild(settings);
333 foreach (QVector<UAVDataObject *> list, objList) {
341 QDomElement o = doc.createElement(
"object");
342 o.setAttribute(
"name", obj->
getName());
344 QString(
"0x") + QString().setNum(obj->
getObjID(), 16).toUpper());
346 QDomElement d = doc.createElement(
"description");
347 QDomText
t = doc.createTextNode(
357 QDomElement f = doc.createElement(
"field");
362 for (
unsigned int n = 0;
n < nelem; ++
n) {
363 vals.append(QString(
"%1,").arg(field->
getValue(
n).toString()));
367 f.setAttribute(
"name", field->
getName());
368 f.setAttribute(
"values", vals);
371 f.setAttribute(
"units", field->
getUnits());
372 f.setAttribute(
"elements", nelem);
374 f.setAttribute(
"options", field->
getOptions().join(
","));
382 settings.appendChild(o);
393 QString preliminaryXMLDoc = doc.toString(4);
394 QString alphabetizedAttributesXMLDoc;
395 QString alphabetizedXMLDoc;
403 QString xmlAttributeSorter = R
"(
404 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
405 <xsl:output method="xml" encoding="UTF-8" indent="yes"/>
406 <xsl:template match="*">
408 <xsl:apply-templates select="@*">
409 <xsl:sort select="name() "/>
410 </xsl:apply-templates>
411 <xsl:apply-templates/>
414 <xsl:template match="@*|comment()|processing-instruction() ">
423 QString xmlAlpheticalSorter = R
"(
424 <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
425 <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
426 <xsl:strip-space elements="*"/>
428 <xsl:template match="@* | node() ">
430 <xsl:apply-templates select="@* | node() "/>
434 <xsl:template match="settings">
436 <xsl:apply-templates select="@*" />
437 <xsl:apply-templates select="object">
438 <xsl:sort select="@name" data-type="text"/>
440 </xsl:apply-templates>
448 QXmlQuery
query(QXmlQuery::XSLT20);
451 query.setFocus(preliminaryXMLDoc);
452 query.setQuery(xmlAttributeSorter);
453 query.evaluateTo(&alphabetizedAttributesXMLDoc);
456 query.setFocus(alphabetizedAttributesXMLDoc);
457 query.setQuery(xmlAlpheticalSorter);
458 query.evaluateTo(&alphabetizedXMLDoc);
460 return alphabetizedXMLDoc;
468 QString filters = tr(
"UAVObjects XML files (*.uav)");
472 tr(
"Save UAVSettings File As"),
"", filters);
474 if (fileName.isEmpty()) {
479 bool fullExport =
false;
480 if (fileName.endsWith(
".xml")) {
482 }
else if (!fileName.endsWith(
".uav")) {
483 fileName.append(
".uav");
487 QString xml = createXMLDocument(Settings, fullExport);
490 QFile
file(fileName);
491 if (
file.open(QIODevice::WriteOnly) && (
file.write(xml.toLatin1()) != -1)) {
495 tr(
"UAV Settings Export"), tr(
"Unable to save settings: ") + fileName,
501 msgBox.setText(tr(
"Settings saved."));
502 msgBox.setStandardButtons(QMessageBox::Ok);
511 QString filters = tr(
"UAVObjects XML files (*.uav)");
515 tr(
"Save UAVData File As"),
"", filters);
516 if (fileName.isEmpty()) {
521 bool fullExport =
false;
522 if (fileName.endsWith(
".xml")) {
524 }
else if (!fileName.endsWith(
".uav")) {
525 fileName.append(
".uav");
529 QString xml = createXMLDocument(Both, fullExport);
532 QFile
file(fileName);
533 if (
file.open(QIODevice::WriteOnly) && (
file.write(xml.toLatin1()) != -1)) {
537 tr(
"UAV Data Export"), tr(
"Unable to save data: ") + fileName,
543 msgBox.setText(tr(
"Data saved."));
544 msgBox.setStandardButtons(QMessageBox::Ok);
548 void UAVSettingsImportExportManager::setCommandsEnabled(
bool enabled)
550 static const std::vector<QString> commands{
551 QStringLiteral(
"UAVSettingsImportExportPlugin.UAVSettingsExport"),
552 QStringLiteral(
"UAVSettingsImportExportPlugin.UAVSettingsImport"),
553 QStringLiteral(
"UAVSettingsImportExportPlugin.UAVDataExport")
560 for (
const auto &command : commands)
562 cmd->action()->setEnabled(enabled);
bool checkValue(const QVariant &data, int index=0) const
QString getTypeAsString() const
void connectedChanged(bool)
virtual QAction * action() const =0
virtual Command * registerAction(QAction *action, const QString &id, const QList< int > &context)=0
Makes an action known to the system under the specified string id.
virtual ActionContainer * actionContainer(const QString &id) const =0
Returns the IActionContainter object that is know to the system under the given string id...
void extensionsInitialized()
Core plugin system that manages the plugins, their life cycle and their registered objects...
QVariant getValue(int index=0) const
const char *const G_HELP_HELP
int getNumElements() const
UAVSettingsImportExportManager(QObject *parent=nullptr)
virtual ActionManager * actionManager() const =0
Returns the application's action manager.
void setUAVOSettings(UAVObjectManager *obj)
const char *const G_FILE_SAVE
virtual Command * command(const QString &id) const =0
Returns the Command object that is known to the system under the given string id. ...
QStringList getOptions() const
T * query(Aggregate *obj)
void setValue(const QVariant &data, int index=0)
static ICore * instance()
UAVObjectField * getField(const QString &name)
bool getIsPresentOnHardware() const
QList< UAVObjectField * > getFields()
virtual void addAction(Core::Command *action, const QString &group=QString())=0
const char *const GCS_REVISION_STR
virtual void setDefaultKeySequence(const QKeySequence &key)=0
void addLine(QString objectName, QString text, bool status)
The action manager is responsible for registration of menus and menu items and keyboard shortcuts...
~UAVSettingsImportExportManager()
virtual UAVDataObject * clone(quint32 instID=0)=0
else error('Your technical computing program does not support file choosers.Please input the file name in the argument. ') end elseif nargin >0 logfile
bool getBoardDescriptionStruct(deviceDescriptorStruct &device)
UAVObject * getObject(const QString &name, quint32 instId=0)
QVector< QVector< UAVDataObject * > > getDataObjectsVector()
QByteArray getBoardCPUSerial()
void importAboutToBegin()
The class Command represents an action like a menu item, tool button, or shortcut. You don't create Command objects directly, instead use {ActionManager::registerAction()} to register an action and retrieve a Command. The Command object represents the user visible action and its properties. If multiple actions are registered with the same ID (but different contexts) the returned Command is the shared one between these actions.
FieldType getType() const