From 246318af7b5333e0149d40dfa80e0a28ee75e433 Mon Sep 17 00:00:00 2001 From: zedamota Date: Tue, 20 Sep 2011 22:14:48 +0100 Subject: [PATCH 1/4] Mixer bug fix try --- .../plugins/config/configairframewidget.cpp | 10 +++++++++ .../src/plugins/config/configtaskwidget.cpp | 22 +++++++++++++++++++ .../src/plugins/config/configtaskwidget.h | 3 +++ 3 files changed, 35 insertions(+) diff --git a/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp b/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp index a12d34dca..6a6ad66be 100644 --- a/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp @@ -36,6 +36,9 @@ #include #include #include +#include "systemsettings.h" +#include "mixersettings.h" +#include "actuatorsettings.h" /** Helper delegate for the custom mixer editor table. @@ -443,6 +446,13 @@ void ConfigAirframeWidget::updateCustomThrottle2CurveValue(QList list, d */ void ConfigAirframeWidget::refreshWidgetsValues() { + if(!allObjectsUpdated()) + { + SystemSettings::GetInstance(getObjectManager())->requestUpdate(); + MixerSettings::GetInstance(getObjectManager())->requestUpdate(); + ActuatorSettings::GetInstance(getObjectManager())->requestUpdate(); + return; + } bool dirty=isDirty(); // Get the Airframe type from the system settings: UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("SystemSettings"))); diff --git a/ground/openpilotgcs/src/plugins/config/configtaskwidget.cpp b/ground/openpilotgcs/src/plugins/config/configtaskwidget.cpp index 98b10683c..cad342d6f 100644 --- a/ground/openpilotgcs/src/plugins/config/configtaskwidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/configtaskwidget.cpp @@ -62,6 +62,8 @@ void ConfigTaskWidget::addUAVObjectToWidgetRelation(QString object, QString fiel { obj = objManager->getObject(QString(object)); Q_ASSERT(obj); + objectUpdates.insert(obj,false); + connect(obj, SIGNAL(objectUpdated(UAVObject*)),this, SLOT(objectUpdated(UAVObject*))); connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(refreshWidgetsValues())); } //smartsave->addObject(obj); @@ -153,6 +155,10 @@ void ConfigTaskWidget::onAutopilotDisconnect() { isConnected=false; enableControls(false); + foreach(UAVObject *obj, objectUpdates.keys()) + { + objectUpdates[obj]=false; + } } void ConfigTaskWidget::onAutopilotConnect() @@ -308,6 +314,22 @@ void ConfigTaskWidget::enableObjUpdates() } } +void ConfigTaskWidget::objectUpdated(UAVObject *obj) +{ + objectUpdates[obj]=true; +} + +bool ConfigTaskWidget::allObjectsUpdated() +{ + bool ret=true; + foreach(UAVObject *obj, objectUpdates.keys()) + { + ret=ret & objectUpdates[obj]; + } + qDebug()<<"ALL OBJECTS UPDATE:"< objectUpdates; bool dirty; protected slots: virtual void disableObjUpdates(); From 352620e0ed4fb8bb86069541cb4e69e1656b2525 Mon Sep 17 00:00:00 2001 From: zedamota Date: Fri, 23 Sep 2011 13:48:27 +0100 Subject: [PATCH 2/4] Mixer bug while import fix (try to) --- .../src/plugins/config/Config.pluginspec | 1 + .../src/plugins/config/config.pro | 2 +- .../src/plugins/config/configtaskwidget.cpp | 58 +-- .../src/plugins/config/configtaskwidget.h | 7 +- ground/openpilotgcs/src/plugins/plugins.pro | 1 + .../uavsettingsimportexport.cpp | 321 +--------------- .../uavsettingsimportexport.h | 15 +- .../uavsettingsimportexport.pri | 2 + .../uavsettingsimportexport.pro | 8 +- .../uavsettingsimportexport_global.h | 40 ++ .../uavsettingsimportexportfactory.cpp | 363 ++++++++++++++++++ .../uavsettingsimportexportfactory.h | 54 +++ 12 files changed, 519 insertions(+), 353 deletions(-) create mode 100644 ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.pri create mode 100644 ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport_global.h create mode 100644 ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp create mode 100644 ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.h diff --git a/ground/openpilotgcs/src/plugins/config/Config.pluginspec b/ground/openpilotgcs/src/plugins/config/Config.pluginspec index 0a9da6e94..83013fd28 100644 --- a/ground/openpilotgcs/src/plugins/config/Config.pluginspec +++ b/ground/openpilotgcs/src/plugins/config/Config.pluginspec @@ -9,5 +9,6 @@ + diff --git a/ground/openpilotgcs/src/plugins/config/config.pro b/ground/openpilotgcs/src/plugins/config/config.pro index 29d872ec9..b99fc9edc 100644 --- a/ground/openpilotgcs/src/plugins/config/config.pro +++ b/ground/openpilotgcs/src/plugins/config/config.pro @@ -8,7 +8,7 @@ include(../../plugins/uavtalk/uavtalk.pri) include(../../plugins/coreplugin/coreplugin.pri) include(../../plugins/uavobjects/uavobjects.pri) include(../../plugins/uavobjectutil/uavobjectutil.pri) - +include(../../plugins/uavsettingsimportexport/uavsettingsimportexport.pri) INCLUDEPATH += ../../libs/eigen OTHER_FILES += Config.pluginspec diff --git a/ground/openpilotgcs/src/plugins/config/configtaskwidget.cpp b/ground/openpilotgcs/src/plugins/config/configtaskwidget.cpp index cad342d6f..f40225e71 100644 --- a/ground/openpilotgcs/src/plugins/config/configtaskwidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/configtaskwidget.cpp @@ -26,14 +26,17 @@ */ #include "configtaskwidget.h" #include - +#include "uavsettingsimportexport/uavsettingsimportexportfactory.h" +#include "configgadgetwidget.h" ConfigTaskWidget::ConfigTaskWidget(QWidget *parent) : QWidget(parent),isConnected(false),smartsave(NULL),dirty(false) { pm = ExtensionSystem::PluginManager::instance(); objManager = pm->getObject(); - connect(parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect())); - connect(parent, SIGNAL(autopilotDisconnected()),this, SLOT(onAutopilotDisconnect())); + connect((ConfigGadgetWidget*)parent, SIGNAL(autopilotConnected()),this, SLOT(onAutopilotConnect())); + connect((ConfigGadgetWidget*)parent, SIGNAL(autopilotDisconnected()),this, SLOT(onAutopilotDisconnect())); + UAVSettingsImportExportFactory * importexportplugin = pm->getObject(); + connect(importexportplugin,SIGNAL(importAboutToBegin()),this,SLOT(invalidateObjects())); } void ConfigTaskWidget::addWidget(QWidget * widget) { @@ -62,8 +65,8 @@ void ConfigTaskWidget::addUAVObjectToWidgetRelation(QString object, QString fiel { obj = objManager->getObject(QString(object)); Q_ASSERT(obj); - objectUpdates.insert(obj,false); - connect(obj, SIGNAL(objectUpdated(UAVObject*)),this, SLOT(objectUpdated(UAVObject*))); + objectUpdates.insert(obj,false); + connect(obj, SIGNAL(objectUpdated(UAVObject*)),this, SLOT(objectUpdated(UAVObject*))); connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(refreshWidgetsValues())); } //smartsave->addObject(obj); @@ -155,10 +158,7 @@ void ConfigTaskWidget::onAutopilotDisconnect() { isConnected=false; enableControls(false); - foreach(UAVObject *obj, objectUpdates.keys()) - { - objectUpdates[obj]=false; - } + invalidateObjects(); } void ConfigTaskWidget::onAutopilotConnect() @@ -314,22 +314,30 @@ void ConfigTaskWidget::enableObjUpdates() } } -void ConfigTaskWidget::objectUpdated(UAVObject *obj) -{ - objectUpdates[obj]=true; -} - -bool ConfigTaskWidget::allObjectsUpdated() -{ - bool ret=true; - foreach(UAVObject *obj, objectUpdates.keys()) - { - ret=ret & objectUpdates[obj]; - } - qDebug()<<"ALL OBJECTS UPDATE:"< objectUpdates; + QMap objectUpdates; bool dirty; protected slots: virtual void disableObjUpdates(); diff --git a/ground/openpilotgcs/src/plugins/plugins.pro b/ground/openpilotgcs/src/plugins/plugins.pro index 7a86f53be..12e7d7c43 100644 --- a/ground/openpilotgcs/src/plugins/plugins.pro +++ b/ground/openpilotgcs/src/plugins/plugins.pro @@ -107,6 +107,7 @@ SUBDIRS += plugin_systemhealth plugin_config.subdir = config plugin_config.depends = plugin_coreplugin plugin_config.depends += plugin_uavobjects +plugin_config.depends += plugin_uavsettingsimportexport SUBDIRS += plugin_config #GPS Display gadget diff --git a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.cpp b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.cpp index 342b845e9..5418b455c 100644 --- a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.cpp +++ b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.cpp @@ -31,7 +31,7 @@ #include #include #include - +#include "importsummary.h" // for menu item #include #include @@ -62,321 +62,20 @@ UAVSettingsImportExportPlugin::~UAVSettingsImportExportPlugin() bool UAVSettingsImportExportPlugin::initialize(const QStringList& args, QString *errMsg) { - Q_UNUSED(args); - Q_UNUSED(errMsg); - - // 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), - "UAVSettingsImportExportPlugin.UAVSettingsExport", - QList() << - Core::Constants::C_GLOBAL_ID); - cmd->setDefaultKeySequence(QKeySequence("Ctrl+E")); - cmd->action()->setText(tr("Export UAV Settings...")); - ac->addAction(cmd, Core::Constants::G_FILE_SAVE); - connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(exportUAVSettings())); - - cmd = am->registerAction(new QAction(this), - "UAVSettingsImportExportPlugin.UAVSettingsImport", - QList() << - Core::Constants::C_GLOBAL_ID); - cmd->setDefaultKeySequence(QKeySequence("Ctrl+I")); - cmd->action()->setText(tr("Import UAV Settings...")); - ac->addAction(cmd, Core::Constants::G_FILE_SAVE); - connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(importUAVSettings())); - - cmd = am->registerAction(new QAction(this), - "UAVSettingsImportExportPlugin.UAVDataExport", - QList() << - Core::Constants::C_GLOBAL_ID); - cmd->action()->setText(tr("Export UAV Data...")); - ac->addAction(cmd, Core::Constants::G_FILE_SAVE); - connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(exportUAVData())); - + Q_UNUSED(args); + Q_UNUSED(errMsg); + mf = new UAVSettingsImportExportFactory(this); + addAutoReleasedObject(mf); return true; -} - -void UAVSettingsImportExportPlugin::extensionsInitialized() -{ - // Do nothing -} - - -// Slot called by the menu manager on user action -void UAVSettingsImportExportPlugin::importUAVSettings() -{ - // ask for file name - QString fileName; - QString filters = tr("UAVSettings XML files (*.uav);; XML files (*.xml)"); - fileName = QFileDialog::getOpenFileName(0, tr("Import UAV Settings"), "", filters); - if (fileName.isEmpty()) { - return; - } - - // Now open the file - QFile file(fileName); - QDomDocument doc("UAVSettings"); - file.open(QFile::ReadOnly|QFile::Text); - if (!doc.setContent(file.readAll())) { - QMessageBox msgBox; - msgBox.setText(tr("File Parsing Failed.")); - msgBox.setInformativeText(tr("This file is not a correct XML file")); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.exec(); - return; - } - file.close(); - - QDomElement root = doc.documentElement(); - if (root.tagName() != "settings") { - QMessageBox msgBox; - msgBox.setText(tr("Wrong file contents.")); - msgBox.setInformativeText(tr("This file is not a correct UAVSettings file")); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.exec(); - return; - } - - // We are now ok: setup the import summary dialog & update it as we - // go along. - ImportSummaryDialog swui; - - ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); - UAVObjectManager *objManager = pm->getObject(); - swui.show(); - - QDomNode node = root.firstChild(); - 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); - - } else { - // - Update each field - // - Issue and "updated" command - bool error=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) { - uavfield->setValue(f.attribute("values")); - } else { - // This is an enum: - int i=0; - QStringList list = f.attribute("values").split(","); - foreach (QString element, list) { - uavfield->setValue(element,i++); - } - } - error = false; - } 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 - swui.addLine(uavObjectName, "OK", true); - } - } - node = node.nextSibling(); - } - swui.exec(); - - - -} - -// Create an XML document from UAVObject database -QString UAVSettingsImportExportPlugin::createXMLDocument( - const QString docName, const bool isSettings, 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"); - doc.appendChild(root); - QDomElement versionInfo =doc.createElement("versionInfo"); - root.appendChild(versionInfo); - QDomElement fw=doc.createElement("Embedded"); - UAVObjectUtilManager* utilMngr = pm->getObject(); - - fw.setAttribute("gitcommittag",utilMngr->getBoardDescriptionStruct().gitTag); - fw.setAttribute("fwtag",utilMngr->getBoardDescriptionStruct().description); - fw.setAttribute("cpuSerial",QString(utilMngr->getBoardCPUSerial().toHex())); - - versionInfo.appendChild(fw); - QDomElement gcs=doc.createElement("GCS"); - gcs.setAttribute("revision",QString::fromLatin1(Core::Constants::GCS_REVISION_STR)); - versionInfo.appendChild(gcs); - // iterate over settings objects - QList< QList > objList = objManager->getDataObjects(); - foreach (QList list, objList) { - foreach (UAVDataObject* obj, list) { - if (obj->isSettings() == isSettings) { - - // add each object to the XML - QDomElement o = doc.createElement("object"); - o.setAttribute("name", obj->getName()); - o.setAttribute("id", QString("0x")+ QString().setNum(obj->getObjID(),16).toUpper()); - if (fullExport) { - QDomElement d = doc.createElement("description"); - QDomText t = doc.createTextNode(obj->getDescription().remove("@Ref ", Qt::CaseInsensitive)); - d.appendChild(t); - o.appendChild(d); - } - - // iterate over fields - QList fieldList = obj->getFields(); - - foreach (UAVObjectField* field, fieldList) { - QDomElement f = doc.createElement("field"); - - // iterate over values - QString vals; - quint32 nelem = field->getNumElements(); - for (unsigned int n = 0; n < nelem; ++n) { - vals.append(QString("%1,").arg(field->getValue(n).toString())); - } - vals.chop(1); - - f.setAttribute("name", field->getName()); - f.setAttribute("values", vals); - if (fullExport) { - f.setAttribute("type", field->getTypeAsString()); - f.setAttribute("units", field->getUnits()); - f.setAttribute("elements", nelem); - if (field->getType() == UAVObjectField::ENUM) { - f.setAttribute("options", field->getOptions().join(",")); - } - } - o.appendChild(f); - } - root.appendChild(o); - } - } - } - - return doc.toString(4); -} - -// Slot called by the menu manager on user action -void UAVSettingsImportExportPlugin::exportUAVSettings() -{ - // ask for file name - QString fileName; - QString filters = tr("UAVSettings XML files (*.uav)"); - - fileName = QFileDialog::getSaveFileName(0, tr("Save UAV Settings 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 - if (fileName.endsWith(".xml")) { - fullExport = true; - } else if (!fileName.endsWith(".uav")) { - fileName.append(".uav"); - } - - // generate an XML first (used for all export formats as a formatted data source) - QString xml = createXMLDocument("UAVSettings", true, fullExport); - - // save file - QFile file(fileName); - if (file.open(QIODevice::WriteOnly) && - (file.write(xml.toAscii()) != -1)) { - file.close(); - } else { - QMessageBox::critical(0, - tr("UAV Settings Export"), - tr("Unable to save settings: ") + fileName, - QMessageBox::Ok); - return; - } - - QMessageBox msgBox; - msgBox.setText(tr("Settings saved.")); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.exec(); -} - -// Slot called by the menu manager on user action -void UAVSettingsImportExportPlugin::exportUAVData() -{ - if (QMessageBox::question(0, tr("Are you sure?"), - tr("This option is only useful for passing your current " - "system data to the technical support staff. " - "Do you really want to export?"), - QMessageBox::Ok | QMessageBox::Cancel, - QMessageBox::Ok) != QMessageBox::Ok) { - return; - } - - // ask for file name - QString fileName; - QString filters = tr("UAVData XML files (*.uav)"); - - fileName = QFileDialog::getSaveFileName(0, tr("Save UAV Data 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 - if (fileName.endsWith(".xml")) { - fullExport = true; - } else if (!fileName.endsWith(".uav")) { - fileName.append(".uav"); - } - - // generate an XML first (used for all export formats as a formatted data source) - QString xml = createXMLDocument("UAVData", false, fullExport); - - // save file - QFile file(fileName); - if (file.open(QIODevice::WriteOnly) && - (file.write(xml.toAscii()) != -1)) { - file.close(); - } else { - QMessageBox::critical(0, - tr("UAV Data Export"), - tr("Unable to save data: ") + fileName, - QMessageBox::Ok); - return; - } - - QMessageBox msgBox; - msgBox.setText(tr("Data saved.")); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.exec(); } void UAVSettingsImportExportPlugin::shutdown() { // Do nothing } +void UAVSettingsImportExportPlugin::extensionsInitialized() +{ +} Q_EXPORT_PLUGIN(UAVSettingsImportExportPlugin) + + diff --git a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.h b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.h index ff8972227..a63454153 100644 --- a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.h +++ b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.h @@ -29,9 +29,10 @@ #include #include "uavobjectutil/uavobjectutilmanager.h" -#include "importsummary.h" +#include "uavsettingsimportexport_global.h" #include "../../../../../build/ground/openpilotgcs/gcsversioninfo.h" -class UAVSettingsImportExportPlugin : public ExtensionSystem::IPlugin +#include "uavsettingsimportexportfactory.h" +class UAVSETTINGSIMPORTEXPORT_EXPORT UAVSettingsImportExportPlugin : public ExtensionSystem::IPlugin { Q_OBJECT @@ -42,16 +43,10 @@ public: void extensionsInitialized(); bool initialize(const QStringList & arguments, QString * errorString); void shutdown(); - private: - QString createXMLDocument(const QString docName, - const bool isSettings, - const bool fullExport); + UAVSettingsImportExportFactory *mf; + -private slots: - void importUAVSettings(); - void exportUAVSettings(); - void exportUAVData(); }; diff --git a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.pri b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.pri new file mode 100644 index 000000000..bddd38181 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.pri @@ -0,0 +1,2 @@ +include(uavsettingsimportexport_dependencies.pri) +LIBS *= -l$$qtLibraryName(UAVSettingsImportExport) diff --git a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.pro b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.pro index fcdc11ae6..aa8abccf1 100644 --- a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.pro +++ b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport.pro @@ -3,14 +3,16 @@ TEMPLATE = lib QT += xml TARGET = UAVSettingsImportExport - +DEFINES += UAVSETTINGSIMPORTEXPORT_LIBRARY include(../../openpilotgcsplugin.pri) include(uavsettingsimportexport_dependencies.pri) HEADERS += uavsettingsimportexport.h \ - importsummary.h + importsummary.h \ + uavsettingsimportexportfactory.h SOURCES += uavsettingsimportexport.cpp \ - importsummary.cpp + importsummary.cpp \ + uavsettingsimportexportfactory.cpp OTHER_FILES += uavsettingsimportexport.pluginspec diff --git a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport_global.h b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport_global.h new file mode 100644 index 000000000..703771b4f --- /dev/null +++ b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexport_global.h @@ -0,0 +1,40 @@ +/** + ****************************************************************************** + * + * @file uavsettingsimportexport_global.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @see The GNU Public License (GPL) Version 3 + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup + * @{ + * @brief + *****************************************************************************/ +/* + * 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 UAVSETTINGSIMPORTEXPORT_GLOBAL_H +#define UAVSETTINGSIMPORTEXPORT_GLOBAL_H + +#include + +#if defined(UAVSETTINGSIMPORTEXPORT_LIBRARY) +# define UAVSETTINGSIMPORTEXPORT_EXPORT Q_DECL_EXPORT +#else +# define UAVSETTINGSIMPORTEXPORT_EXPORT Q_DECL_IMPORT +#endif + +#endif // UAVSETTINGSIMPORTEXPORT_GLOBAL_H diff --git a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp new file mode 100644 index 000000000..be81222fe --- /dev/null +++ b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp @@ -0,0 +1,363 @@ +/** + ****************************************************************************** + * + * @file uavsettingsimportexportfactory.cpp + * @author (C) 2011 The OpenPilot Team, http://www.openpilot.org + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup UAVSettingsImportExport UAVSettings Import/Export Plugin + * @{ + * @brief UAVSettings Import/Export Plugin + *****************************************************************************/ +/* + * 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 + */ + +#include "uavsettingsimportexportfactory.h" +#include +#include +#include +#include +#include "importsummary.h" +// for menu item +#include +#include +#include +#include + +// for UAVObjects +#include "uavdataobject.h" +#include "uavobjectmanager.h" +#include "extensionsystem/pluginmanager.h" + +// for XML object +#include + +// for file dialog and error messages +#include +#include + + + +UAVSettingsImportExportFactory::~UAVSettingsImportExportFactory() +{ + // Do nothing +} + +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), + "UAVSettingsImportExportPlugin.UAVSettingsExport", + QList() << + Core::Constants::C_GLOBAL_ID); + cmd->setDefaultKeySequence(QKeySequence("Ctrl+E")); + cmd->action()->setText(tr("Export UAV Settings...")); + ac->addAction(cmd, Core::Constants::G_FILE_SAVE); + connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(exportUAVSettings())); + + cmd = am->registerAction(new QAction(this), + "UAVSettingsImportExportPlugin.UAVSettingsImport", + QList() << + Core::Constants::C_GLOBAL_ID); + cmd->setDefaultKeySequence(QKeySequence("Ctrl+I")); + cmd->action()->setText(tr("Import UAV Settings...")); + ac->addAction(cmd, Core::Constants::G_FILE_SAVE); + connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(importUAVSettings())); + + cmd = am->registerAction(new QAction(this), + "UAVSettingsImportExportPlugin.UAVDataExport", + QList() << + Core::Constants::C_GLOBAL_ID); + cmd->action()->setText(tr("Export UAV Data...")); + ac->addAction(cmd, Core::Constants::G_FILE_SAVE); + connect(cmd->action(), SIGNAL(triggered(bool)), this, SLOT(exportUAVData())); + +} + +// Slot called by the menu manager on user action +void UAVSettingsImportExportFactory::importUAVSettings() +{ + // ask for file name + QString fileName; + QString filters = tr("UAVSettings XML files (*.uav);; XML files (*.xml)"); + fileName = QFileDialog::getOpenFileName(0, tr("Import UAV Settings"), "", filters); + if (fileName.isEmpty()) { + return; + } + + // Now open the file + QFile file(fileName); + QDomDocument doc("UAVSettings"); + file.open(QFile::ReadOnly|QFile::Text); + if (!doc.setContent(file.readAll())) { + QMessageBox msgBox; + msgBox.setText(tr("File Parsing Failed.")); + msgBox.setInformativeText(tr("This file is not a correct XML file")); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.exec(); + return; + } + file.close(); + emit importAboutToBegin(); + QDomElement root = doc.documentElement(); + if (root.tagName() != "settings") { + QMessageBox msgBox; + msgBox.setText(tr("Wrong file contents.")); + msgBox.setInformativeText(tr("This file is not a correct UAVSettings file")); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.exec(); + return; + } + + // We are now ok: setup the import summary dialog & update it as we + // go along. + ImportSummaryDialog swui; + + ExtensionSystem::PluginManager *pm = ExtensionSystem::PluginManager::instance(); + UAVObjectManager *objManager = pm->getObject(); + swui.show(); + + QDomNode node = root.firstChild(); + 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); + + } else { + // - Update each field + // - Issue and "updated" command + bool error=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) { + uavfield->setValue(f.attribute("values")); + } else { + // This is an enum: + int i=0; + QStringList list = f.attribute("values").split(","); + foreach (QString element, list) { + uavfield->setValue(element,i++); + } + } + error = false; + } 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 + swui.addLine(uavObjectName, "OK", true); + } + } + node = node.nextSibling(); + } + swui.exec(); + + + +} + +// Create an XML document from UAVObject database +QString UAVSettingsImportExportFactory::createXMLDocument( + const QString docName, const bool isSettings, 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"); + doc.appendChild(root); + QDomElement versionInfo =doc.createElement("versionInfo"); + root.appendChild(versionInfo); + QDomElement fw=doc.createElement("Embedded"); + UAVObjectUtilManager* utilMngr = pm->getObject(); + + fw.setAttribute("gitcommittag",utilMngr->getBoardDescriptionStruct().gitTag); + fw.setAttribute("fwtag",utilMngr->getBoardDescriptionStruct().description); + fw.setAttribute("cpuSerial",QString(utilMngr->getBoardCPUSerial().toHex())); + + versionInfo.appendChild(fw); + QDomElement gcs=doc.createElement("GCS"); + gcs.setAttribute("revision",QString::fromLatin1(Core::Constants::GCS_REVISION_STR)); + versionInfo.appendChild(gcs); + // iterate over settings objects + QList< QList > objList = objManager->getDataObjects(); + foreach (QList list, objList) { + foreach (UAVDataObject* obj, list) { + if (obj->isSettings() == isSettings) { + + // add each object to the XML + QDomElement o = doc.createElement("object"); + o.setAttribute("name", obj->getName()); + o.setAttribute("id", QString("0x")+ QString().setNum(obj->getObjID(),16).toUpper()); + if (fullExport) { + QDomElement d = doc.createElement("description"); + QDomText t = doc.createTextNode(obj->getDescription().remove("@Ref ", Qt::CaseInsensitive)); + d.appendChild(t); + o.appendChild(d); + } + + // iterate over fields + QList fieldList = obj->getFields(); + + foreach (UAVObjectField* field, fieldList) { + QDomElement f = doc.createElement("field"); + + // iterate over values + QString vals; + quint32 nelem = field->getNumElements(); + for (unsigned int n = 0; n < nelem; ++n) { + vals.append(QString("%1,").arg(field->getValue(n).toString())); + } + vals.chop(1); + + f.setAttribute("name", field->getName()); + f.setAttribute("values", vals); + if (fullExport) { + f.setAttribute("type", field->getTypeAsString()); + f.setAttribute("units", field->getUnits()); + f.setAttribute("elements", nelem); + if (field->getType() == UAVObjectField::ENUM) { + f.setAttribute("options", field->getOptions().join(",")); + } + } + o.appendChild(f); + } + root.appendChild(o); + } + } + } + + return doc.toString(4); +} + +// Slot called by the menu manager on user action +void UAVSettingsImportExportFactory::exportUAVSettings() +{ + // ask for file name + QString fileName; + QString filters = tr("UAVSettings XML files (*.uav)"); + + fileName = QFileDialog::getSaveFileName(0, tr("Save UAV Settings 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 + if (fileName.endsWith(".xml")) { + fullExport = true; + } else if (!fileName.endsWith(".uav")) { + fileName.append(".uav"); + } + + // generate an XML first (used for all export formats as a formatted data source) + QString xml = createXMLDocument("UAVSettings", true, fullExport); + + // save file + QFile file(fileName); + if (file.open(QIODevice::WriteOnly) && + (file.write(xml.toAscii()) != -1)) { + file.close(); + } else { + QMessageBox::critical(0, + tr("UAV Settings Export"), + tr("Unable to save settings: ") + fileName, + QMessageBox::Ok); + return; + } + + QMessageBox msgBox; + msgBox.setText(tr("Settings saved.")); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.exec(); +} + +// Slot called by the menu manager on user action +void UAVSettingsImportExportFactory::exportUAVData() +{ + if (QMessageBox::question(0, tr("Are you sure?"), + tr("This option is only useful for passing your current " + "system data to the technical support staff. " + "Do you really want to export?"), + QMessageBox::Ok | QMessageBox::Cancel, + QMessageBox::Ok) != QMessageBox::Ok) { + return; + } + + // ask for file name + QString fileName; + QString filters = tr("UAVData XML files (*.uav)"); + + fileName = QFileDialog::getSaveFileName(0, tr("Save UAV Data 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 + if (fileName.endsWith(".xml")) { + fullExport = true; + } else if (!fileName.endsWith(".uav")) { + fileName.append(".uav"); + } + + // generate an XML first (used for all export formats as a formatted data source) + QString xml = createXMLDocument("UAVData", false, fullExport); + + // save file + QFile file(fileName); + if (file.open(QIODevice::WriteOnly) && + (file.write(xml.toAscii()) != -1)) { + file.close(); + } else { + QMessageBox::critical(0, + tr("UAV Data Export"), + tr("Unable to save data: ") + fileName, + QMessageBox::Ok); + return; + } + + QMessageBox msgBox; + msgBox.setText(tr("Data saved.")); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.exec(); +} diff --git a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.h b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.h new file mode 100644 index 000000000..2ef5f803e --- /dev/null +++ b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.h @@ -0,0 +1,54 @@ +/** + ****************************************************************************** + * + * @file uavsettingsimportexportfactory.h + * @author (C) 2011 The OpenPilot Team, http://www.openpilot.org + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup UAVSettingsImportExport UAVSettings Import/Export Plugin + * @{ + * @brief UAVSettings Import/Export Plugin + *****************************************************************************/ +/* + * 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 UAVSETTINGSIMPORTEXPORTFACTORY_H +#define UAVSETTINGSIMPORTEXPORTFACTORY_H +#include "uavsettingsimportexport_global.h" +#include "uavobjectutil/uavobjectutilmanager.h" +#include "../../../../../build/ground/openpilotgcs/gcsversioninfo.h" +class UAVSETTINGSIMPORTEXPORT_EXPORT UAVSettingsImportExportFactory : public QObject +{ + Q_OBJECT + +public: + UAVSettingsImportExportFactory(QObject *parent = 0); + ~UAVSettingsImportExportFactory(); + +private: + QString createXMLDocument(const QString docName, + const bool isSettings, + const bool fullExport); + +private slots: + void importUAVSettings(); + void exportUAVSettings(); + void exportUAVData(); +signals: + void importAboutToBegin(); + +}; + +#endif // UAVSETTINGSIMPORTEXPORTFACTORY_H From 797bb38081fc7def804d2398bb213f0277d7c9da Mon Sep 17 00:00:00 2001 From: zedamota Date: Sun, 25 Sep 2011 19:30:32 +0100 Subject: [PATCH 3/4] mixer bug fix. Also added a new debug plugin witch shows the debug messages normally not available on release builds --- .../plugins/config/configairframewidget.cpp | 6 +- .../src/plugins/config/configtaskwidget.cpp | 3 +- .../debuggadget/DebugGadget.pluginspec | 10 ++ .../src/plugins/debuggadget/debug.ui | 31 ++++++ .../src/plugins/debuggadget/debugengine.cpp | 13 +++ .../src/plugins/debuggadget/debugengine.h | 18 ++++ .../src/plugins/debuggadget/debuggadget.cpp | 39 ++++++++ .../src/plugins/debuggadget/debuggadget.h | 59 ++++++++++++ .../src/plugins/debuggadget/debuggadget.pro | 21 ++++ .../debuggadget/debuggadgetfactory.cpp | 47 +++++++++ .../plugins/debuggadget/debuggadgetfactory.h | 50 ++++++++++ .../plugins/debuggadget/debuggadgetwidget.cpp | 96 +++++++++++++++++++ .../plugins/debuggadget/debuggadgetwidget.h | 49 ++++++++++ .../src/plugins/debuggadget/debugplugin.cpp | 65 +++++++++++++ .../src/plugins/debuggadget/debugplugin.h | 47 +++++++++ ground/openpilotgcs/src/plugins/plugins.pro | 6 ++ .../uavsettingsimportexportfactory.cpp | 2 + .../uavsettingsimportexportfactory.h | 1 + 18 files changed, 557 insertions(+), 6 deletions(-) create mode 100644 ground/openpilotgcs/src/plugins/debuggadget/DebugGadget.pluginspec create mode 100644 ground/openpilotgcs/src/plugins/debuggadget/debug.ui create mode 100644 ground/openpilotgcs/src/plugins/debuggadget/debugengine.cpp create mode 100644 ground/openpilotgcs/src/plugins/debuggadget/debugengine.h create mode 100644 ground/openpilotgcs/src/plugins/debuggadget/debuggadget.cpp create mode 100644 ground/openpilotgcs/src/plugins/debuggadget/debuggadget.h create mode 100644 ground/openpilotgcs/src/plugins/debuggadget/debuggadget.pro create mode 100644 ground/openpilotgcs/src/plugins/debuggadget/debuggadgetfactory.cpp create mode 100644 ground/openpilotgcs/src/plugins/debuggadget/debuggadgetfactory.h create mode 100644 ground/openpilotgcs/src/plugins/debuggadget/debuggadgetwidget.cpp create mode 100644 ground/openpilotgcs/src/plugins/debuggadget/debuggadgetwidget.h create mode 100644 ground/openpilotgcs/src/plugins/debuggadget/debugplugin.cpp create mode 100644 ground/openpilotgcs/src/plugins/debuggadget/debugplugin.h diff --git a/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp b/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp index 6a6ad66be..80e920c03 100644 --- a/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp @@ -39,6 +39,7 @@ #include "systemsettings.h" #include "mixersettings.h" #include "actuatorsettings.h" +#include /** Helper delegate for the custom mixer editor table. @@ -447,12 +448,7 @@ void ConfigAirframeWidget::updateCustomThrottle2CurveValue(QList list, d void ConfigAirframeWidget::refreshWidgetsValues() { if(!allObjectsUpdated()) - { - SystemSettings::GetInstance(getObjectManager())->requestUpdate(); - MixerSettings::GetInstance(getObjectManager())->requestUpdate(); - ActuatorSettings::GetInstance(getObjectManager())->requestUpdate(); return; - } bool dirty=isDirty(); // Get the Airframe type from the system settings: UAVDataObject* obj = dynamic_cast(getObjectManager()->getObject(QString("SystemSettings"))); diff --git a/ground/openpilotgcs/src/plugins/config/configtaskwidget.cpp b/ground/openpilotgcs/src/plugins/config/configtaskwidget.cpp index f40225e71..5e579c971 100644 --- a/ground/openpilotgcs/src/plugins/config/configtaskwidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/configtaskwidget.cpp @@ -65,7 +65,7 @@ void ConfigTaskWidget::addUAVObjectToWidgetRelation(QString object, QString fiel { obj = objManager->getObject(QString(object)); Q_ASSERT(obj); - objectUpdates.insert(obj,false); + objectUpdates.insert(obj,true); connect(obj, SIGNAL(objectUpdated(UAVObject*)),this, SLOT(objectUpdated(UAVObject*))); connect(obj, SIGNAL(objectUpdated(UAVObject*)), this, SLOT(refreshWidgetsValues())); } @@ -163,6 +163,7 @@ void ConfigTaskWidget::onAutopilotDisconnect() void ConfigTaskWidget::onAutopilotConnect() { + invalidateObjects(); dirty=false; isConnected=true; enableControls(true); diff --git a/ground/openpilotgcs/src/plugins/debuggadget/DebugGadget.pluginspec b/ground/openpilotgcs/src/plugins/debuggadget/DebugGadget.pluginspec new file mode 100644 index 000000000..05cea6931 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/debuggadget/DebugGadget.pluginspec @@ -0,0 +1,10 @@ + + The OpenPilot Project + (C) 2010 OpenPilot Project + The GNU Public License (GPL) Version 3 + An debug gadget + http://www.openpilot.org + + + + diff --git a/ground/openpilotgcs/src/plugins/debuggadget/debug.ui b/ground/openpilotgcs/src/plugins/debuggadget/debug.ui new file mode 100644 index 000000000..72adcb7ee --- /dev/null +++ b/ground/openpilotgcs/src/plugins/debuggadget/debug.ui @@ -0,0 +1,31 @@ + + + Form + + + + 0 + 0 + 400 + 300 + + + + Form + + + + + + Save to file + + + + + + + + + + + diff --git a/ground/openpilotgcs/src/plugins/debuggadget/debugengine.cpp b/ground/openpilotgcs/src/plugins/debuggadget/debugengine.cpp new file mode 100644 index 000000000..48ec18525 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/debuggadget/debugengine.cpp @@ -0,0 +1,13 @@ +#include "debugengine.h" +debugengine::debugengine() +{ +} + +void debugengine::writeToStdErr(const QString &level, const QList &msgs) +{ + emit dbgMsgError(level,msgs); +} +void debugengine::writeToStdOut(const QString &level, const QList &msgs) +{ + emit dbgMsg(level,msgs); +} diff --git a/ground/openpilotgcs/src/plugins/debuggadget/debugengine.h b/ground/openpilotgcs/src/plugins/debuggadget/debugengine.h new file mode 100644 index 000000000..5452f7590 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/debuggadget/debugengine.h @@ -0,0 +1,18 @@ +#ifndef DEBUGENGINE_H +#define DEBUGENGINE_H +#include "qxtbasicstdloggerengine.h" +#include +class debugengine:public QObject,public QxtBasicSTDLoggerEngine +{ + Q_OBJECT +public: + debugengine(); +protected: + void writeToStdErr ( const QString & level, const QList & msgs ); + void writeToStdOut ( const QString & level, const QList & msgs ); +signals: + void dbgMsgError( const QString & level, const QList & msgs ); + void dbgMsg( const QString & level, const QList & msgs ); +}; + +#endif // DEBUGENGINE_H diff --git a/ground/openpilotgcs/src/plugins/debuggadget/debuggadget.cpp b/ground/openpilotgcs/src/plugins/debuggadget/debuggadget.cpp new file mode 100644 index 000000000..05c147c03 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/debuggadget/debuggadget.cpp @@ -0,0 +1,39 @@ +/** + ****************************************************************************** + * + * @file debuggadget.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup DebugGadgetPlugin Debug Gadget Plugin + * @{ + * @brief A place holder gadget plugin + *****************************************************************************/ +/* + * 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 + */ +#include "debuggadget.h" +#include "debuggadgetwidget.h" + +DebugGadget::DebugGadget(QString classId, DebugGadgetWidget *widget, QWidget *parent) : + IUAVGadget(classId, parent), + m_widget(widget) +{ +} + +DebugGadget::~DebugGadget() +{ + delete m_widget; +} diff --git a/ground/openpilotgcs/src/plugins/debuggadget/debuggadget.h b/ground/openpilotgcs/src/plugins/debuggadget/debuggadget.h new file mode 100644 index 000000000..b39f8b5b5 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/debuggadget/debuggadget.h @@ -0,0 +1,59 @@ +/** + ****************************************************************************** + * + * @file debuggadget.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup DebugGadgetPlugin Debug Gadget Plugin + * @{ + * @brief A place holder gadget plugin + *****************************************************************************/ +/* + * 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 DEBUGGADGET_H_ +#define DEBUGGADGET_H_ + +#include + +namespace Core { +class IUAVGadget; +} +//class QWidget; +//class QString; +class DebugGadgetWidget; + +using namespace Core; + +class DebugGadget : public Core::IUAVGadget +{ + Q_OBJECT +public: + DebugGadget(QString classId, DebugGadgetWidget *widget, QWidget *parent = 0); + ~DebugGadget(); + + QList context() const { return m_context; } + QWidget *widget() { return m_widget; } + QString contextHelpId() const { return QString(); } + +private: + QWidget *m_widget; + QList m_context; +}; + + +#endif // DEBUGGADGET_H_ diff --git a/ground/openpilotgcs/src/plugins/debuggadget/debuggadget.pro b/ground/openpilotgcs/src/plugins/debuggadget/debuggadget.pro new file mode 100644 index 000000000..8434e723d --- /dev/null +++ b/ground/openpilotgcs/src/plugins/debuggadget/debuggadget.pro @@ -0,0 +1,21 @@ +TEMPLATE = lib +TARGET = DebugGadget + +include(../../openpilotgcsplugin.pri) +include(../../plugins/coreplugin/coreplugin.pri) +include(../../libs/libqxt/core/logengines.pri) +HEADERS += debugplugin.h \ + debugengine.h +HEADERS += debuggadget.h +HEADERS += debuggadgetwidget.h +HEADERS += debuggadgetfactory.h +SOURCES += debugplugin.cpp \ + debugengine.cpp +SOURCES += debuggadget.cpp +SOURCES += debuggadgetfactory.cpp +SOURCES += debuggadgetwidget.cpp + +OTHER_FILES += DebugGadget.pluginspec + +FORMS += \ + debug.ui diff --git a/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetfactory.cpp b/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetfactory.cpp new file mode 100644 index 000000000..f7d925b39 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetfactory.cpp @@ -0,0 +1,47 @@ +/** + ****************************************************************************** + * + * @file debuggadgetfactory.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup DebugGadgetPlugin Debug Gadget Plugin + * @{ + * @brief A place holder gadget plugin + *****************************************************************************/ +/* + * 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 + */ +#include "debuggadgetfactory.h" +#include "debuggadgetwidget.h" +#include "debuggadget.h" +#include + +DebugGadgetFactory::DebugGadgetFactory(QObject *parent) : + IUAVGadgetFactory(QString("DebugGadget"), + tr("DebugGadget"), + parent) +{ +} + +DebugGadgetFactory::~DebugGadgetFactory() +{ + +} + +IUAVGadget* DebugGadgetFactory::createGadget(QWidget *parent) { + DebugGadgetWidget* gadgetWidget = new DebugGadgetWidget(parent); + return new DebugGadget(QString("DebugGadget"), gadgetWidget, parent); +} diff --git a/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetfactory.h b/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetfactory.h new file mode 100644 index 000000000..186fca5f6 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetfactory.h @@ -0,0 +1,50 @@ +/** + ****************************************************************************** + * + * @file debuggadgetfactory.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup DebugGadgetPlugin Debug Gadget Plugin + * @{ + * @brief A place holder gadget plugin + *****************************************************************************/ +/* + * 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 DEBUGGADGETFACTORY_H_ +#define DEBUGGADGETFACTORY_H_ + +#include + +namespace Core { +class IUAVGadget; +class IUAVGadgetFactory; +} + +using namespace Core; + +class DebugGadgetFactory : public IUAVGadgetFactory +{ + Q_OBJECT +public: + DebugGadgetFactory(QObject *parent = 0); + ~DebugGadgetFactory(); + + IUAVGadget *createGadget(QWidget *parent); +}; + +#endif // DEBUGGADGETFACTORY_H_ diff --git a/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetwidget.cpp b/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetwidget.cpp new file mode 100644 index 000000000..f7c625a87 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetwidget.cpp @@ -0,0 +1,96 @@ +/** + ****************************************************************************** + * + * @file debuggadgetwidget.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup DebugGadgetPlugin Debug Gadget Plugin + * @{ + * @brief A place holder gadget plugin + *****************************************************************************/ +/* + * 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 + */ +#include "debuggadgetwidget.h" + +#include +#include +#include +#include +#include +#include +#include "qxtlogger.h" +#include "debugengine.h" +#include +#include +#include +#include +DebugGadgetWidget::DebugGadgetWidget(QWidget *parent) : QLabel(parent) +{ + m_config = new Ui_Form(); + m_config->setupUi(this); + debugengine * de=new debugengine(); + QxtLogger::getInstance()->addLoggerEngine("debugplugin", de); + connect(de,SIGNAL(dbgMsg(QString,QList)),this,SLOT(dbgMsg(QString,QList))); + connect(de,SIGNAL(dbgMsgError(QString,QList)),this,SLOT(dbgMsgError(QString,QList))); + connect(m_config->pushButton,SIGNAL(clicked()),this,SLOT(saveLog())); +} + +DebugGadgetWidget::~DebugGadgetWidget() +{ + // Do nothing +} + +void DebugGadgetWidget::dbgMsg(const QString &level, const QList &msgs) +{ + m_config->plainTextEdit->setTextColor(Qt::black); + foreach(QVariant str,msgs) + { + m_config->plainTextEdit->append(QString("[%0]%1").arg(level).arg(str.toString())); + } + QScrollBar *sb = m_config->plainTextEdit->verticalScrollBar(); + sb->setValue(sb->maximum()); +} + +void DebugGadgetWidget::dbgMsgError(const QString &level, const QList &msgs) +{ + m_config->plainTextEdit->setTextColor(Qt::red); + foreach(QVariant str,msgs) + { + m_config->plainTextEdit->append(QString("[%0]%1").arg(level).arg(str.toString())); + } + QScrollBar *sb = m_config->plainTextEdit->verticalScrollBar(); + sb->setValue(sb->maximum()); +} +void DebugGadgetWidget::saveLog() +{ + QString fileName = QFileDialog::getSaveFileName(0, tr("Save log File As"), ""); + if (fileName.isEmpty()) { + return; + } + + QFile file(fileName); + if (file.open(QIODevice::WriteOnly) && + (file.write(m_config->plainTextEdit->toHtml().toAscii()) != -1)) { + file.close(); + } else { + QMessageBox::critical(0, + tr("Log Save"), + tr("Unable to save log: ") + fileName, + QMessageBox::Ok); + return; + } +} diff --git a/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetwidget.h b/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetwidget.h new file mode 100644 index 000000000..ed71f73c2 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetwidget.h @@ -0,0 +1,49 @@ +/** + ****************************************************************************** + * + * @file debuggadgetwidget.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup DebugGadgetPlugin Debug Gadget Plugin + * @{ + * @brief A place holder gadget plugin + *****************************************************************************/ +/* + * 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 DEBUGGADGETWIDGET_H_ +#define DEBUGGADGETWIDGET_H_ + +#include +#include "ui_debug.h" +class DebugGadgetWidget : public QLabel +{ + Q_OBJECT + +public: + DebugGadgetWidget(QWidget *parent = 0); + ~DebugGadgetWidget(); + +private: + Ui_Form *m_config; +private slots: + void saveLog(); + void dbgMsgError( const QString & level, const QList & msgs ); + void dbgMsg( const QString & level, const QList & msgs ); +}; + +#endif /* DEBUGGADGETWIDGET_H_ */ diff --git a/ground/openpilotgcs/src/plugins/debuggadget/debugplugin.cpp b/ground/openpilotgcs/src/plugins/debuggadget/debugplugin.cpp new file mode 100644 index 000000000..f83395ef7 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/debuggadget/debugplugin.cpp @@ -0,0 +1,65 @@ +/** + ****************************************************************************** + * + * @file debugplugin.cpp + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup DebugGadgetPlugin Debug Gadget Plugin + * @{ + * @brief A place holder gadget plugin + *****************************************************************************/ +/* + * 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 + */ +#include "debugplugin.h" +#include "debuggadgetfactory.h" +#include +#include +#include +#include + + +DebugPlugin::DebugPlugin() +{ + // Do nothing +} + +DebugPlugin::~DebugPlugin() +{ + // Do nothing +} + +bool DebugPlugin::initialize(const QStringList& args, QString *errMsg) +{ + Q_UNUSED(args); + Q_UNUSED(errMsg); + mf = new DebugGadgetFactory(this); + addAutoReleasedObject(mf); + + return true; +} + +void DebugPlugin::extensionsInitialized() +{ + // Do nothing +} + +void DebugPlugin::shutdown() +{ + // Do nothing +} +Q_EXPORT_PLUGIN(DebugPlugin) + diff --git a/ground/openpilotgcs/src/plugins/debuggadget/debugplugin.h b/ground/openpilotgcs/src/plugins/debuggadget/debugplugin.h new file mode 100644 index 000000000..9cdbefd02 --- /dev/null +++ b/ground/openpilotgcs/src/plugins/debuggadget/debugplugin.h @@ -0,0 +1,47 @@ +/** + ****************************************************************************** + * + * @file debugplugin.h + * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. + * @addtogroup GCSPlugins GCS Plugins + * @{ + * @addtogroup DebugGadgetPlugin Debug Gadget Plugin + * @{ + * @brief A place holder gadget plugin + *****************************************************************************/ +/* + * 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 DEBUGPLUGIN_H_ +#define DEBUGPLUGIN_H_ + +#include + +class DebugGadgetFactory; + +class DebugPlugin : public ExtensionSystem::IPlugin +{ +public: + DebugPlugin(); + ~DebugPlugin(); + + void extensionsInitialized(); + bool initialize(const QStringList & arguments, QString * errorString); + void shutdown(); +private: + DebugGadgetFactory *mf; +}; +#endif /* DEBUGPLUGIN_H_ */ diff --git a/ground/openpilotgcs/src/plugins/plugins.pro b/ground/openpilotgcs/src/plugins/plugins.pro index 12e7d7c43..8079fa880 100644 --- a/ground/openpilotgcs/src/plugins/plugins.pro +++ b/ground/openpilotgcs/src/plugins/plugins.pro @@ -19,6 +19,12 @@ plugin_emptygadget.subdir = emptygadget plugin_emptygadget.depends = plugin_coreplugin SUBDIRS += plugin_emptygadget +# UAV Settings Import/Export plugin +plugin_debuggadget.subdir = debuggadget +#plugin_debughelper.depends = plugin_coreplugin +#plugin_debughelper.depends += plugin_uavobjects +SUBDIRS += plugin_debuggadget + # Welcome plugin plugin_welcome.subdir = welcome plugin_welcome.depends = plugin_coreplugin diff --git a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp index be81222fe..ff6eb233b 100644 --- a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp +++ b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.cpp @@ -115,6 +115,7 @@ void UAVSettingsImportExportFactory::importUAVSettings() } file.close(); emit importAboutToBegin(); + qDebug()<<"Import about to begin"; QDomElement root = doc.documentElement(); if (root.tagName() != "settings") { QMessageBox msgBox; @@ -188,6 +189,7 @@ void UAVSettingsImportExportFactory::importUAVSettings() } node = node.nextSibling(); } + qDebug()<<"End import"; swui.exec(); diff --git a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.h b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.h index 2ef5f803e..a130d5c4a 100644 --- a/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.h +++ b/ground/openpilotgcs/src/plugins/uavsettingsimportexport/uavsettingsimportexportfactory.h @@ -48,6 +48,7 @@ private slots: void exportUAVData(); signals: void importAboutToBegin(); + void importEnded(); }; From 898d3c980d27d01509e13fc9decee52024df5449 Mon Sep 17 00:00:00 2001 From: zedamota Date: Tue, 27 Sep 2011 22:10:39 +0100 Subject: [PATCH 4/4] Cosmetic changes to the Debug plugin One more fix to the mixer bug --- .../plugins/config/configairframewidget.cpp | 26 ++++++++++++++++--- .../src/plugins/config/configtaskwidget.cpp | 1 + .../src/plugins/config/smartsavebutton.cpp | 5 ++-- .../plugins/debuggadget/debuggadgetwidget.cpp | 20 +++++++------- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp b/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp index 80e920c03..96393b381 100644 --- a/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp +++ b/ground/openpilotgcs/src/plugins/config/configairframewidget.cpp @@ -1522,6 +1522,16 @@ bool ConfigAirframeWidget::setupFrameVtail() */ bool ConfigAirframeWidget::setupMixer(double mixerFactors[8][3]) { + qDebug()<<"Mixer factors"; + qDebug()< mmList; mmList << m_aircraft->multiMotor1 << m_aircraft->multiMotor2 << m_aircraft->multiMotor3 @@ -1539,11 +1549,15 @@ bool ConfigAirframeWidget::setupMixer(double mixerFactors[8][3]) double pFactor = (double)m_aircraft->mrPitchMixLevel->value()/100; double rFactor = (double)m_aircraft->mrRollMixLevel->value()/100; double yFactor = (double)m_aircraft->mrYawMixLevel->value()/100; + qDebug()<currentIndex()-1; - if (channel > -1) - setupQuadMotor(channel, mixerFactors[i][0]*pFactor, - rFactor*mixerFactors[i][1], yFactor*mixerFactors[i][2]); + if(mmList.at(i)->isEnabled()) + { + int channel = mmList.at(i)->currentIndex()-1; + if (channel > -1) + setupQuadMotor(channel, mixerFactors[i][0]*pFactor, + rFactor*mixerFactors[i][1], yFactor*mixerFactors[i][2]); + } } // obj->updated(); return true; @@ -1555,6 +1569,7 @@ bool ConfigAirframeWidget::setupMixer(double mixerFactors[8][3]) */ void ConfigAirframeWidget::setupQuadMotor(int channel, double pitch, double roll, double yaw) { + qDebug()<(getObjectManager()->getObject(QString("MixerSettings"))); Q_ASSERT(obj); UAVObjectField *field = obj->getField(mixerTypes.at(channel)); @@ -1566,10 +1581,13 @@ void ConfigAirframeWidget::setupQuadMotor(int channel, double pitch, double roll field->setValue(127, ti); ti = field->getElementNames().indexOf("Roll"); field->setValue(roll*127,ti); + qDebug()<<"Set roll="<getElementNames().indexOf("Pitch"); field->setValue(pitch*127,ti); + qDebug()<<"Set pitch="<getElementNames().indexOf("Yaw"); field->setValue(yaw*127,ti); + qDebug()<<"Set yaw="<getName(); + qDebug()<<"Object upload error:"<getName(); error=true; continue; } @@ -59,7 +59,7 @@ void smartSaveButton::processClick() { for(int i=0;i<3;++i) { - //qDebug()<<"try to save:"<getName(); + qDebug()<<"try to save:"<getName(); connect(utilMngr,SIGNAL(saveCompleted(int,bool)),this,SLOT(saving_finished(int,bool))); connect(&timer,SIGNAL(timeout()),&loop,SLOT(quit())); utilMngr->saveObjectToSD(obj); @@ -73,6 +73,7 @@ void smartSaveButton::processClick() } if(sv_result==false) { + qDebug()<<"failed to save:"<getName(); error=true; } } diff --git a/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetwidget.cpp b/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetwidget.cpp index f7c625a87..34043c806 100644 --- a/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetwidget.cpp +++ b/ground/openpilotgcs/src/plugins/debuggadget/debuggadgetwidget.cpp @@ -38,6 +38,7 @@ #include #include #include +#include DebugGadgetWidget::DebugGadgetWidget(QWidget *parent) : QLabel(parent) { m_config = new Ui_Form(); @@ -56,22 +57,21 @@ DebugGadgetWidget::~DebugGadgetWidget() void DebugGadgetWidget::dbgMsg(const QString &level, const QList &msgs) { - m_config->plainTextEdit->setTextColor(Qt::black); - foreach(QVariant str,msgs) - { - m_config->plainTextEdit->append(QString("[%0]%1").arg(level).arg(str.toString())); - } + m_config->plainTextEdit->setTextColor(Qt::red); + + m_config->plainTextEdit->append(QString("%2[%0]%1").arg(level).arg(msgs[0].toString()).arg(QTime::currentTime().toString())); + QScrollBar *sb = m_config->plainTextEdit->verticalScrollBar(); sb->setValue(sb->maximum()); } void DebugGadgetWidget::dbgMsgError(const QString &level, const QList &msgs) { - m_config->plainTextEdit->setTextColor(Qt::red); - foreach(QVariant str,msgs) - { - m_config->plainTextEdit->append(QString("[%0]%1").arg(level).arg(str.toString())); - } + m_config->plainTextEdit->setTextColor(Qt::black); + + + m_config->plainTextEdit->append(QString("%2[%0]%1").arg(level).arg(msgs[0].toString()).arg(QTime::currentTime().toString())); + QScrollBar *sb = m_config->plainTextEdit->verticalScrollBar(); sb->setValue(sb->maximum()); }