1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-17 02:52:12 +01:00

OP-99 GCS, Import/Export Plugin: Support for XML-File Format.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1852 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
erhard 2010-10-03 16:13:28 +00:00 committed by erhard
parent 840df39b78
commit dd0d58f64f
6 changed files with 489 additions and 13 deletions

View File

@ -1,19 +1,21 @@
TEMPLATE = lib
TARGET = ImportExportGadget
DEFINES += IMPORTEXPORT_LIBRARY
QT += svg
QT += xml
include(../../openpilotgcsplugin.pri)
include(importexport_dependencies.pri)
HEADERS += importexportplugin.h \
importexportgadgetwidget.h \
importexportdialog.h
importexportdialog.h \
xmlconfig.h
HEADERS += importexportgadget.h
HEADERS += importexportgadgetfactory.h
HEADERS += importexportgadgetconfiguration.h
HEADERS += importexportgadgetoptionspage.h
SOURCES += importexportplugin.cpp \
importexportgadgetwidget.cpp \
importexportdialog.cpp
importexportdialog.cpp \
xmlconfig.cpp
SOURCES += importexportgadget.cpp
SOURCES += importexportgadgetfactory.cpp
SOURCES += importexportgadgetconfiguration.cpp

View File

@ -1,3 +1,28 @@
/**
******************************************************************************
* @file
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @see The GNU Public License (GPL) Version 3
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup importexportplugin
* @{
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef IMPORTEXPORTDIALOG_H
#define IMPORTEXPORTDIALOG_H
@ -24,3 +49,8 @@ private:
};
#endif // IMPORTEXPORTDIALOG_H
/**
* @}
* @}
*/

View File

@ -28,6 +28,7 @@
*/
#include "importexportgadgetwidget.h"
#include "ui_importexportgadgetwidget.h"
#include "xmlconfig.h"
#include "coreplugin/uavgadgetinstancemanager.h"
#include "coreplugin/icore.h"
#include <QtDebug>
@ -75,6 +76,20 @@ void ImportExportGadgetWidget::on_exportButton_clicked()
QString file = ui->configFile->text();
qDebug() << "Export pressed! Write to file " << QFileInfo(file).absoluteFilePath();
if ( QFileInfo(file).exists() ){
QMessageBox msgBox;
msgBox.setText(tr("File already exists."));
msgBox.setInformativeText(tr("Do you want to overwrite the existing file?"));
msgBox.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Ok);
if ( msgBox.exec() == QMessageBox::Ok ){
QFileInfo(file).absoluteDir().remove(QFileInfo(file).fileName());
}
else{
qDebug() << "Export canceled!";
return;
}
}
QMessageBox msgBox;
QDir dir = QFileInfo(file).absoluteDir();
if (! dir.exists()) {
@ -96,8 +111,19 @@ void ImportExportGadgetWidget::exportConfiguration(const QString& fileName)
{
bool general = ui->checkBoxGeneral->isChecked();
bool allGadgets = ui->checkBoxAllGadgets->isChecked();
QSettings::Format format;
if ( ui->radioButtonIniFormat->isChecked() ){
format = QSettings::IniFormat;
}
else if ( ui->radioButtonXmlFormat->isChecked() ){
format = XmlConfig::XmlSettingsFormat;
}
else {
qWarning() << "Program Error in ImportExportGadgetWidget::exportConfiguration: unknown format. Assume XML!";
format = XmlConfig::XmlSettingsFormat;
}
QSettings qs(fileName, QSettings::IniFormat);
QSettings qs(fileName, format);
if (general) {
Core::ICore::instance()->saveMainSettings(&qs);
@ -137,8 +163,19 @@ void ImportExportGadgetWidget::importConfiguration(const QString& fileName)
{
bool general = ui->checkBoxGeneral->isChecked();
bool allGadgets = ui->checkBoxAllGadgets->isChecked();
QSettings::Format format;
if ( ui->radioButtonIniFormat->isChecked() ){
format = QSettings::IniFormat;
}
else if ( ui->radioButtonXmlFormat->isChecked() ){
format = XmlConfig::XmlSettingsFormat;
}
else {
qWarning() << "Program Error in ImportExportGadgetWidget::exportConfiguration: unknown format. Assume XML!";
format = XmlConfig::XmlSettingsFormat;
}
QSettings qs(fileName, QSettings::defaultFormat());
QSettings qs(fileName, format);
if (allGadgets) {
Core::ICore::instance()->uavGadgetInstanceManager()->readConfigurations(&qs);

View File

@ -6,15 +6,15 @@
<rect>
<x>0</x>
<y>0</y>
<width>296</width>
<height>222</height>
<width>483</width>
<height>271</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label">
@ -28,12 +28,12 @@
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox">
<item row="1" column="0">
<widget class="QGroupBox" name="groupBoxItems">
<property name="title">
<string>Items</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QCheckBox" name="checkBoxGeneral">
<property name="text">
@ -57,7 +57,7 @@
</layout>
</widget>
</item>
<item>
<item row="2" column="0" colspan="2">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="exportButton">
@ -82,6 +82,32 @@
</item>
</layout>
</item>
<item row="1" column="1">
<widget class="QGroupBox" name="groupBoxFormat">
<property name="title">
<string>Format</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QRadioButton" name="radioButtonXmlFormat">
<property name="text">
<string>XML Format</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QRadioButton" name="radioButtonIniFormat">
<property name="text">
<string>INI Format</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>

View File

@ -0,0 +1,323 @@
/**
******************************************************************************
*
* @file xmlconfig.cpp
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* Parts by Nokia Corporation (qt-info@nokia.com) Copyright (C) 2009.
* @see The GNU Public License (GPL) Version 3
* @brief Widget for Import/Export Plugin
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup importexportplugin
* @{
*
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Nokia Corporation */
#include "xmlconfig.h"
#include <QtDebug>
#include <QStringList>
#include <QRegExp>
#include <QVariant>
#include <QRect>
#include <QSize>
#include <QPoint>
#define NUM_PREFIX "arr_"
QString XmlConfig::rootName = "gcs";
const QSettings::Format XmlConfig::XmlSettingsFormat =
QSettings::registerFormat("xml", XmlConfig::readXmlFile, XmlConfig::writeXmlFile);
bool XmlConfig::readXmlFile(QIODevice &device, QSettings::SettingsMap &map)
{
QDomDocument domDoc;
QDomElement root;
QString errorStr;
int errorLine;
int errorColumn;
if (!domDoc.setContent(&device, true, &errorStr, &errorLine,
&errorColumn)) {
QString err = QString(tr("GCS config")) +
tr("Parse error at line %1, column %2:\n%3")
.arg(errorLine)
.arg(errorColumn)
.arg(errorStr);
qFatal(err.toLatin1().data());
return false;
}
root = domDoc.documentElement();
handleNode(&root, map);
return true;
}
void XmlConfig::handleNode(QDomElement* node, QSettings::SettingsMap &map, QString path)
{
if ( !node ){
return;
}
// qDebug() << "XmlConfig::handleNode start";
QString nodeName = node->nodeName();
// For arrays, QT will use simple numbers as keys, which is not a valid element in XML.
// Therefore we prefixed these.
if ( nodeName.startsWith(NUM_PREFIX) ){
nodeName.replace(NUM_PREFIX, "");
}
if ( nodeName == XmlConfig::rootName )
;
else if ( path == "" )
path = nodeName;
else
path += "/" + nodeName;
// qDebug() << "Node: " << ": " << path << " Children: " << node->childNodes().length();
for ( uint i = 0; i < node->childNodes().length(); ++i ){
QDomNode child = node->childNodes().item(i);
if ( child.isElement() ){
handleNode( static_cast<QDomElement*>(&child), map, path);
}
else if ( child.isText() ){
qDebug() << "Key: " << path << " Value:" << node->text();
map.insert(path, stringToVariant(node->text()));
}
else{
qDebug() << "Child not Element or text!" << child.nodeType();
}
}
// qDebug() << "XmlConfig::handleNode end";
}
bool XmlConfig::writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map)
{
QDomDocument outDocument;
// qDebug() << "writeXmlFile start";
outDocument.appendChild( outDocument.createElement(XmlConfig::rootName));
QMapIterator<QString, QVariant> iter(map);
while (iter.hasNext()) {
iter.next();
// qDebug() << "Entry: " << iter.key() << ": " << iter.value().toString() << endl;
QDomNode node = outDocument.firstChild();
foreach ( QString elem, iter.key().split('/')){
if ( elem == "" ){
continue;
}
// For arrays, QT will use simple numbers as keys, which is not a valid element in XML.
// Therefore we prefixed these.
if ( elem.startsWith(NUM_PREFIX) ){
qWarning() << "ERROR: Settings must not start with " << NUM_PREFIX
<< " in: " + iter.key();
}
if ( QRegExp("[0-9]").exactMatch(elem.left(1)) ){
elem.prepend(NUM_PREFIX);
}
if ( node.firstChildElement(elem).isNull() ){
node.appendChild(outDocument.createElement(elem));
}
node = node.firstChildElement(elem);
}
node.appendChild(outDocument.createTextNode(variantToString(iter.value())));
}
device.write(outDocument.toByteArray(2).constData());
// qDebug() << "Dokument:\n" << outDocument.toByteArray(2).constData();
// qDebug() << "writeXmlFile end";
return true;
}
QSettings::SettingsMap XmlConfig::settingsToMap(QSettings& qs){
qDebug() << "settingsToMap:---------------";
QSettings::SettingsMap map;
QStringList keys = qs.allKeys();
foreach (QString key, keys) {
QVariant val = qs.value(key);
qDebug() << key << val.toString();
map.insert(key, val);
}
qDebug() << "settingsToMap End --------";
return map;
}
QString XmlConfig::variantToString(const QVariant &v)
{
QString result;
switch (v.type()) {
case QVariant::Invalid:
result = QLatin1String("@Invalid()");
break;
case QVariant::ByteArray: {
QByteArray a = v.toByteArray().toBase64();
result = QLatin1String("@ByteArray(");
result += QString::fromLatin1(a.constData(), a.size());
result += QLatin1Char(')');
break;
}
case QVariant::String:
case QVariant::LongLong:
case QVariant::ULongLong:
case QVariant::Int:
case QVariant::UInt:
case QVariant::Bool:
case QVariant::Double:
case QVariant::KeySequence:
case QVariant::Color: {
result = v.toString();
if (result.startsWith(QLatin1Char('@')))
result.prepend(QLatin1Char('@'));
break;
}
#ifndef QT_NO_GEOM_VARIANT
case QVariant::Rect: {
QRect r = qvariant_cast<QRect>(v);
result += QLatin1String("@Rect(");
result += QString::number(r.x());
result += QLatin1Char(' ');
result += QString::number(r.y());
result += QLatin1Char(' ');
result += QString::number(r.width());
result += QLatin1Char(' ');
result += QString::number(r.height());
result += QLatin1Char(')');
break;
}
case QVariant::Size: {
QSize s = qvariant_cast<QSize>(v);
result += QLatin1String("@Size(");
result += QString::number(s.width());
result += QLatin1Char(' ');
result += QString::number(s.height());
result += QLatin1Char(')');
break;
}
case QVariant::Point: {
QPoint p = qvariant_cast<QPoint>(v);
result += QLatin1String("@Point(");
result += QString::number(p.x());
result += QLatin1Char(' ');
result += QString::number(p.y());
result += QLatin1Char(')');
break;
}
#endif // !QT_NO_GEOM_VARIANT
default: {
#ifndef QT_NO_DATASTREAM
QByteArray a;
{
QDataStream s(&a, QIODevice::WriteOnly);
s.setVersion(QDataStream::Qt_4_0);
s << v;
}
result = QLatin1String("@Variant(");
result += QString::fromLatin1(a.toBase64().constData());
result += QLatin1Char(')');
qDebug() << "Variant Type: " << v.type();
qDebug()<< "Variant: " << result;
#else
Q_ASSERT(!"QSettings: Cannot save custom types without QDataStream support");
#endif
break;
}
}
return result;
}
QVariant XmlConfig::stringToVariant(const QString &s)
{
if (s.startsWith(QLatin1Char('@'))) {
if (s.endsWith(QLatin1Char(')'))) {
if (s.startsWith(QLatin1String("@ByteArray("))) {
return QVariant(QByteArray::fromBase64(s.toLatin1().mid(11, s.size() - 12)));
} else if (s.startsWith(QLatin1String("@Variant("))) {
#ifndef QT_NO_DATASTREAM
QByteArray a(QByteArray::fromBase64(s.toLatin1().mid(9)));
QDataStream stream(&a, QIODevice::ReadOnly);
stream.setVersion(QDataStream::Qt_4_0);
QVariant result;
stream >> result;
return result;
#else
Q_ASSERT(!"QSettings: Cannot load custom types without QDataStream support");
#endif
#ifndef QT_NO_GEOM_VARIANT
} else if (s.startsWith(QLatin1String("@Rect("))) {
QStringList args = splitArgs(s, 5);
if (args.size() == 4)
return QVariant(QRect(args[0].toInt(), args[1].toInt(), args[2].toInt(), args[3].toInt()));
} else if (s.startsWith(QLatin1String("@Size("))) {
QStringList args = splitArgs(s, 5);
if (args.size() == 2)
return QVariant(QSize(args[0].toInt(), args[1].toInt()));
} else if (s.startsWith(QLatin1String("@Point("))) {
QStringList args = splitArgs(s, 6);
if (args.size() == 2)
return QVariant(QPoint(args[0].toInt(), args[1].toInt()));
#endif
} else if (s == QLatin1String("@Invalid()")) {
return QVariant();
}
}
if (s.startsWith(QLatin1String("@@")))
return QVariant(s.mid(1));
}
return QVariant(s);
}
QStringList XmlConfig::splitArgs(const QString &s, int idx)
{
int l = s.length();
Q_ASSERT(l > 0);
Q_ASSERT(s.at(idx) == QLatin1Char('('));
Q_ASSERT(s.at(l - 1) == QLatin1Char(')'));
QStringList result;
QString item;
for (++idx; idx < l; ++idx) {
QChar c = s.at(idx);
if (c == QLatin1Char(')')) {
Q_ASSERT(idx == l - 1);
result.append(item);
} else if (c == QLatin1Char(' ')) {
result.append(item);
item.clear();
} else {
item.append(c);
}
}
return result;
}
/**
* @}
* @}
*/

View File

@ -0,0 +1,58 @@
/**
******************************************************************************
* @file
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @see The GNU Public License (GPL) Version 3
* @addtogroup GCSPlugins GCS Plugins
* @{
* @addtogroup importexportplugin
* @{
*****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef XMLCONFIG_H
#define XMLCONFIG_H
#include "importexport_global.h"
#include <QSettings>
#include <QDomElement>
#include <QObject>
class IMPORTEXPORT_EXPORT XmlConfig : QObject
{
public:
static const QSettings::Format XmlSettingsFormat;
static bool readXmlFile(QIODevice &device, QSettings::SettingsMap &map);
static bool writeXmlFile(QIODevice &device, const QSettings::SettingsMap &map);
private:
static QString rootName;
static void handleNode(QDomElement* node, QSettings::SettingsMap &map, QString path = "");
static QSettings::SettingsMap settingsToMap(QSettings& qs);
static QString variantToString(const QVariant &v);
static QVariant stringToVariant(const QString &s);
static QStringList splitArgs(const QString &s, int idx);
};
#endif // XMLCONFIG_H
/**
* @}
* @}
*/