Commit ad06d2dd authored by Lorenz Meier's avatar Lorenz Meier

Merged master

parents 61364a59 e7d85710
......@@ -175,6 +175,7 @@ WindowsBuild {
$$DLL_DIR\\Qt5PrintSupport$${DLL_QT_DEBUGCHAR}.dll \
$$DLL_DIR\\Qt5Qml$${DLL_QT_DEBUGCHAR}.dll \
$$DLL_DIR\\Qt5Quick$${DLL_QT_DEBUGCHAR}.dll \
$$DLL_DIR\\Qt5QuickWidgets$${DLL_QT_DEBUGCHAR}.dll \
$$DLL_DIR\\Qt5Sensors$${DLL_QT_DEBUGCHAR}.dll \
$$DLL_DIR\\Qt5SerialPort$${DLL_QT_DEBUGCHAR}.dll \
$$DLL_DIR\\Qt5OpenGL$${DLL_QT_DEBUGCHAR}.dll \
......
......@@ -46,11 +46,6 @@ QGroundControl builds are supported for OSX, Linux and Windows. See the individu
### Build on Mac OSX
Supported builds are 64 bit, built using the clang compiler.
#### Install SDL prerequisite
1. Download SDL 1.2 from: <http://www.libsdl.org/release/SDL-1.2.14.dmg>
2. From the SDL disk image, copy the `sdl.framework` bundle to `/Library/Frameworks` directory (if you are not an admin copy to `~/Library/Frameworks`)
#### Install QT
- - -
1. Download Qt 5.3 from: <http://download.qt-project.org/official_releases/qt/5.3/5.3.1/qt-opensource-mac-x64-clang-5.3.1.dmg>
......
......@@ -11,21 +11,24 @@ UninstPage instfiles
LicenseData license.txt
Section ""
Section
SetOutPath $INSTDIR
File /r release\*.*
WriteUninstaller $INSTDIR\QGroundControl_uninstall.exe
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\QGroundControl" "DisplayName" "QGroundControl"
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\QGroundControl" "UninstallString" "$\"$INSTDIR\QGroundControl_uninstall.exe$\""
SectionEnd
Section "Uninstall"
SetShellVarContext all
Delete $INSTDIR\QGroundControl_uninstall.exe
RMDir /r /REBOOTOK $INSTDIR
RMDir /r /REBOOTOK "$SMPROGRAMS\QGroundControl\"
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\QGroundControl"
SectionEnd
Section "create Start Menu Shortcuts"
SetShellVarContext all
CreateDirectory "$SMPROGRAMS\QGroundControl"
CreateShortCut "$SMPROGRAMS\QGroundControl\uninstall.lnk" "$INSTDIR\QGroundControl_uninstall.exe" "" "$INSTDIR\QGroundControl_uninstall.exe" 0
CreateShortCut "$SMPROGRAMS\QGroundControl\QGroundControl.lnk" "$INSTDIR\qgroundcontrol.exe" "" "$INSTDIR\qgroundcontrol.exe" 0
SectionEnd
\ No newline at end of file
import QtQuick 2.0
import QtQuick.Controls 1.2
import QGroundControl.FactSystem 1.0
TextInput {
property Fact fact
text: fact.value
font.family: "Helvetica"
font.pointSize: 24
color: "red"
focus: true
onAccepted: { fact.value = text; }
}
Module QGroundControl.FactControls
FactTextInput 1.0 FactTextInput.qml
\ No newline at end of file
......@@ -111,7 +111,8 @@ QT += network \
serialport \
sql \
printsupport \
quick
quick \
quickwidgets
contains(DEFINES, QGC_NOTIFY_TUNES_ENABLED) {
QT += multimedia
......@@ -418,7 +419,6 @@ HEADERS += \
src/ui/map/QGCMapToolBar.h \
src/QGCGeo.h \
src/ui/QGCToolBar.h \
src/ui/QGCStatusBar.h \
src/ui/QGCMAVLinkInspector.h \
src/ui/MAVLinkDecoder.h \
src/ui/WaypointViewOnlyView.h \
......@@ -485,7 +485,8 @@ HEADERS += \
src/QGCMessageBox.h \
src/QGCComboBox.h \
src/QGCTemporaryFile.h \
src/audio/QGCAudioWorker.h
src/audio/QGCAudioWorker.h \
src/QGCQuickWidget.h
SOURCES += \
src/main.cc \
......@@ -562,7 +563,6 @@ SOURCES += \
src/ui/map/QGCMapTool.cc \
src/ui/map/QGCMapToolBar.cc \
src/ui/QGCToolBar.cc \
src/ui/QGCStatusBar.cc \
src/ui/QGCMAVLinkInspector.cc \
src/ui/MAVLinkDecoder.cc \
src/ui/WaypointViewOnlyView.cc \
......@@ -625,8 +625,8 @@ SOURCES += \
src/QGCFileDialog.cc \
src/QGCComboBox.cc \
src/QGCTemporaryFile.cc \
src/audio/QGCAudioWorker.cpp
src/audio/QGCAudioWorker.cpp \
src/QGCQuickWidget.cc
#
# Unit Test specific configuration goes here
......@@ -716,7 +716,8 @@ HEADERS+= \
src/AutoPilotPlugins/PX4/FlightModesComponent.h \
src/AutoPilotPlugins/PX4/FlightModeConfig.h \
src/AutoPilotPlugins/PX4/AirframeComponent.h \
src/AutoPilotPlugins/PX4/SensorsComponent.h
src/AutoPilotPlugins/PX4/SensorsComponent.h \
src/AutoPilotPlugins/PX4/PX4ParameterFacts.h \
SOURCES += \
src/VehicleSetup/SetupView.cc \
......@@ -731,4 +732,22 @@ SOURCES += \
src/AutoPilotPlugins/PX4/FlightModesComponent.cc \
src/AutoPilotPlugins/PX4/FlightModeConfig.cc \
src/AutoPilotPlugins/PX4/AirframeComponent.cc \
src/AutoPilotPlugins/PX4/SensorsComponent.cc
src/AutoPilotPlugins/PX4/SensorsComponent.cc \
src/AutoPilotPlugins/PX4/PX4ParameterFacts.cc \
# Fact System code
INCLUDEPATH += \
src/FactSystem
HEADERS += \
src/FactSystem/FactSystem.h \
src/FactSystem/Fact.h \
src/FactSystem/FactMetaData.h \
src/FactSystem/FactValidator.h \
SOURCES += \
src/FactSystem/FactSystem.cc \
src/FactSystem/Fact.cc \
src/FactSystem/FactMetaData.cc \
src/FactSystem/FactValidator.cc \
......@@ -231,4 +231,14 @@
<qresource prefix="/unittest">
<file alias="MockLink.param">src/qgcunittest/MockLink.param</file>
</qresource>
<qresource prefix="/QLoggingCategory">
<file alias="qtlogging.ini">files/QLoggingCategory/qtlogging.ini</file>
</qresource>
<qresource prefix="/qml">
<file alias="QGroundControlFactControls/qmldir">files/qml/qmldir</file>
<file alias="QGroundControlFactControls/FactTextInput.qml">files/qml/FactTextInput.qml</file>
</qresource>
<qresource prefix="/AutoPilotPlugins/PX4">
<file alias="ParameterFactMetaData.xml">src/AutoPilotPlugins/PX4/ParameterFactMetaData.xml</file>
</qresource>
</RCC>
......@@ -27,9 +27,11 @@
#include <QObject>
#include <QList>
#include <QString>
#include <QQmlContext>
#include "UASInterface.h"
#include "VehicleComponent.h"
#include "FactSystem.h"
/// @file
/// @brief The AutoPilotPlugin class is an abstract base class which represent the methods and objects
......@@ -57,6 +59,9 @@ public:
/// @brief Returns a human readable short description for the specified mode.
virtual QString getShortModeText(uint8_t baseMode, uint32_t customMode) const = 0;
/// @brief Adds the FactSystem properties associated with this AutoPilot to the Qml context.
virtual void addFactsToQmlContext(QQmlContext* context, UASInterface* uas) const = 0;
protected:
// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin
AutoPilotPlugin(QObject* parent = NULL) : QObject(parent) { }
......
......@@ -85,3 +85,11 @@ QString GenericAutoPilotPlugin::getShortModeText(uint8_t baseMode, uint32_t cust
return mode;
}
void GenericAutoPilotPlugin::addFactsToQmlContext(QQmlContext* context, UASInterface* uas) const
{
Q_UNUSED(context);
Q_UNUSED(uas);
// Qml not yet supported for Generic
Q_ASSERT(false);
}
......@@ -38,9 +38,11 @@ class GenericAutoPilotPlugin : public AutoPilotPlugin
public:
GenericAutoPilotPlugin(QObject* parent = NULL);
// Overrides from AutoPilotPlugin
virtual QList<VehicleComponent*> getVehicleComponents(UASInterface* uas) const ;
virtual QList<FullMode_t> getModes(void) const;
virtual QString getShortModeText(uint8_t baseMode, uint32_t customMode) const;
virtual void addFactsToQmlContext(QQmlContext* context, UASInterface* uas) const;
};
#endif
......@@ -27,6 +27,9 @@
#include "SensorsComponent.h"
#include "FlightModesComponent.h"
#include "AutoPilotPluginManager.h"
#include "UASManager.h"
#include "QGCUASParamManagerInterface.h"
#include "PX4ParameterFacts.h"
/// @file
/// @brief This is the AutoPilotPlugin implementatin for the MAV_AUTOPILOT_PX4 type.
......@@ -65,7 +68,24 @@ union px4_custom_mode {
PX4AutoPilotPlugin::PX4AutoPilotPlugin(QObject* parent) :
AutoPilotPlugin(parent)
{
UASManagerInterface* uasMgr = UASManager::instance();
Q_ASSERT(uasMgr);
// We need to track uas coming and going so that we can create PX4ParameterFacts instances for each uas
connect(uasMgr, &UASManagerInterface::UASCreated, this, &PX4AutoPilotPlugin::_uasCreated);
connect(uasMgr, &UASManagerInterface::UASDeleted, this, &PX4AutoPilotPlugin::_uasDeleted);
PX4ParameterFacts::loadParameterFactMetaData();
}
PX4AutoPilotPlugin::~PX4AutoPilotPlugin()
{
PX4ParameterFacts::deleteParameterFactMetaData();
foreach(UASInterface* uas, _mapUas2ParameterFacts.keys()) {
delete _mapUas2ParameterFacts[uas];
}
_mapUas2ParameterFacts.clear();
}
QList<VehicleComponent*> PX4AutoPilotPlugin::getVehicleComponents(UASInterface* uas) const
......@@ -172,3 +192,46 @@ QString PX4AutoPilotPlugin::getShortModeText(uint8_t baseMode, uint32_t customMo
return mode;
}
void PX4AutoPilotPlugin::addFactsToQmlContext(QQmlContext* context, UASInterface* uas) const
{
Q_ASSERT(context);
Q_ASSERT(uas);
QGCUASParamManagerInterface* paramMgr = uas->getParamManager();
Q_UNUSED(paramMgr);
Q_ASSERT(paramMgr);
Q_ASSERT(paramMgr->parametersReady());
PX4ParameterFacts* facts = _parameterFactsForUas(uas);
Q_ASSERT(facts);
context->setContextProperty("parameterFacts", facts);
}
/// @brief When a new uas is create we add a new set of parameter facts for it
void PX4AutoPilotPlugin::_uasCreated(UASInterface* uas)
{
Q_ASSERT(uas);
Q_ASSERT(!_mapUas2ParameterFacts.contains(uas));
// Each uas has it's own set of parameter facts
PX4ParameterFacts* facts = new PX4ParameterFacts(uas, this);
Q_CHECK_PTR(facts);
_mapUas2ParameterFacts[uas] = facts;
}
/// @brief When the uas is deleted we remove the parameter facts for it from the system
void PX4AutoPilotPlugin::_uasDeleted(UASInterface* uas)
{
delete _parameterFactsForUas(uas);
_mapUas2ParameterFacts.remove(uas);
}
PX4ParameterFacts* PX4AutoPilotPlugin::_parameterFactsForUas(UASInterface* uas) const
{
Q_ASSERT(uas);
Q_ASSERT(_mapUas2ParameterFacts.contains(uas));
return _mapUas2ParameterFacts[uas];
}
......@@ -25,6 +25,8 @@
#define PX4AUTOPILOT_H
#include "AutoPilotPlugin.h"
#include "UASInterface.h"
#include "PX4ParameterFacts.h"
/// @file
/// @brief This is the PX4 specific implementation of the AutoPilot class.
......@@ -36,10 +38,22 @@ class PX4AutoPilotPlugin : public AutoPilotPlugin
public:
PX4AutoPilotPlugin(QObject* parent);
~PX4AutoPilotPlugin();
// Overrides from AutoPilotPlugin
virtual QList<VehicleComponent*> getVehicleComponents(UASInterface* uas) const ;
virtual QList<FullMode_t> getModes(void) const;
virtual QString getShortModeText(uint8_t baseMode, uint32_t customMode) const;
virtual void addFactsToQmlContext(QQmlContext* context, UASInterface* uas) const;
private slots:
void _uasCreated(UASInterface* uas);
void _uasDeleted(UASInterface* uas);
private:
PX4ParameterFacts* _parameterFactsForUas(UASInterface* uas) const;
QMap<UASInterface*, PX4ParameterFacts*> _mapUas2ParameterFacts;
};
#endif
This diff is collapsed.
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#include "Fact.h"
#include <QtQml>
Fact::Fact(QObject* parent) :
QObject(parent)
{
}
void Fact::setValue(QVariant& value)
{
_value = value;
emit valueUpdated(value);
}
void Fact::updateValue(QVariant& value)
{
_value = value;
emit valueChanged(value);
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef Fact_H
#define Fact_H
#include "FactMetaData.h"
#include <QObject>
#include <QString>
#include <QVariant>
/// @brief A Fact is used to hold a single value within the system.
///
/// Along with the value property is a set of meta data which further describes the Fact. This information is
/// exposed through QObject Properties such that you can bind to it from QML as well as use it within C++ code.
/// Since the meta data is common to all instances of the same Fact, it is acually stored once in a seperate object.
class Fact : public QObject
{
Q_OBJECT
Q_PROPERTY(QVariant value READ value WRITE setValue NOTIFY valueChanged USER true)
Q_PROPERTY(QVariant defaultValue READ defaultValue CONSTANT)
Q_PROPERTY(FactMetaData::ValueType_t type READ type CONSTANT)
Q_PROPERTY(QString shortDescription READ shortDescription CONSTANT)
Q_PROPERTY(QString longDescription READ longDescription CONSTANT)
Q_PROPERTY(QString units READ units CONSTANT)
Q_PROPERTY(QVariant min READ min CONSTANT)
Q_PROPERTY(QVariant max READ max CONSTANT)
Q_ENUMS(FactMetaData::ValueType_t)
public:
Fact(QObject* parent = NULL);
// Property system methods
/// Read accessor for value property
QVariant value(void) const { return _value; }
/// Write accessor for value property
void setValue(QVariant& value);
/// Read accesor for defaultValue property
QVariant defaultValue(void) { return _metaData->defaultValue; }
/// Read accesor for type property
FactMetaData::ValueType_t type(void) { return _metaData->type; }
/// Read accesor for shortDescription property
QString shortDescription(void) { return _metaData->shortDescription; }
/// Read accesor for longDescription property
QString longDescription(void) { return _metaData->longDescription; }
/// Read accesor for units property
QString units(void) { return _metaData->units; }
/// Read accesor for min property
QVariant min(void) { return _metaData->min; }
/// Read accesor for max property
QVariant max(void) { return _metaData->max; }
/// Used to update the value property from C++ code.
///
/// The setValue method is only for use by the QObject Property system. It should not be called directly by C++ app code.
void updateValue(QVariant& value);
/// Sets the meta data associated with the Fact.
void setMetaData(FactMetaData* metaData) { _metaData = metaData; }
signals:
/// QObject Property System signal for value property changes
///
/// This signal is only meant for use by the QT property system. It should not be connected to by client code.
void valueChanged(QVariant& value);
/// Signalled when property has been changed by a call to the property write accessor
///
/// This signal is meant for use by client code.
void valueUpdated(QVariant& value);
private:
QVariant _value; ///< Fact value
FactMetaData* _metaData; ///< FactMetaData object for Fact
};
#endif
\ No newline at end of file
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @brief Object which exposes a FactMetaData
///
/// @author Don Gagne <don@thegagnes.com>
#include "FactMetaData.h"
FactMetaData::FactMetaData(QObject* parent) :
QObject(parent)
{
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef FactMetaData_H
#define FactMetaData_H
#include <QObject>
#include <QString>
#include <QVariant>
/// Holds the meta data associated with a Fact.
///
/// Holds the meta data associated with a Fact. This is kept in a seperate object from the Fact itself
/// since you may have multiple instances of the same Fact. But there is only ever one FactMetaData
/// instance or each Fact.
class FactMetaData : public QObject
{
Q_OBJECT
public:
FactMetaData(QObject* parent = NULL);
typedef enum {
valueTypeUint8,
valueTypeInt8,
valueTypeUint16,
valueTypeInt16,
valueTypeUint32,
valueTypeInt32,
valueTypeFloat,
valueTypeDouble
} ValueType_t;
QVariant defaultValue;
ValueType_t type;
QString shortDescription;
QString longDescription;
QString units;
QVariant min;
QVariant max;
};
#endif
\ No newline at end of file
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#include "FactSystem.h"
#include "UASManager.h"
#include <QtQml>
FactSystem* FactSystem::_instance = NULL;
QMutex FactSystem::_singletonLock;
const char* FactSystem::_factSystemQmlUri = "QGroundControl.FactSystem";
FactSystem* FactSystem::instance(void)
{
if(_instance == 0) {
_singletonLock.lock();
if (_instance == 0) {
_instance = new FactSystem(qgcApp());
Q_CHECK_PTR(_instance);
}
_singletonLock.unlock();
}
Q_ASSERT(_instance);
return _instance;
}
void FactSystem::deleteInstance(void)
{
_instance = NULL;
delete this;
}
FactSystem::FactSystem(QObject* parent, bool registerSingleton) :
QGCSingleton(parent, registerSingleton)
{
qmlRegisterType<Fact>(_factSystemQmlUri, 1, 0, "Fact");
qmlRegisterType<FactValidator>(_factSystemQmlUri, 1, 0, "FactValidator");
}
FactSystem::~FactSystem()
{
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef FactSystem_h
#define FactSystem_h
#include "Fact.h"
#include "FactMetaData.h"
#include "UASInterface.h"
#include "QGCSingleton.h"
#include "FactValidator.h"
#include <QMutex>
/// FactSystem is a singleton which provides access to the Facts in the system
///
/// The components of the FactSystem are a Fact which holds an individual value. FactMetaData holds
/// additional meta data associated with a Fact such as description, min/max ranges and so forth.
/// The FactValidator object is a QML validator which validates input according to the FactMetaData
/// settings. Client code can then use this system to expose sets of Facts to QML code. An example
/// of this is the PX4ParameterFacts onbject which is part of the PX4 AutoPilot plugin. It exposes
/// the firmware parameters to QML such that you can bind QML ui elements directly to parameters.
class FactSystem : public QGCSingleton
{
Q_OBJECT
public:
/// Returns the FactSystem singleton
static FactSystem* instance(void);
/// Override from QGCSingleton
virtual void deleteInstance(void);
~FactSystem();
private:
/// All access to FactSystem is through FactSystem::instance, so constructor is private
FactSystem(QObject* parent = NULL, bool registerSingleton = true);
static QMutex _singletonLock; ///< Mutex to make calls to instance thread-safe
static FactSystem* _instance; ///< FactSystem singleton
static const char* _factSystemQmlUri; ///< URI for FactSystem QML imports
};
#endif
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#include "FactValidator.h"
FactValidator::FactValidator(QObject* parent) :
QValidator(parent)
{
}
void FactValidator::fixup(QString& input) const
{
Q_UNUSED(input);
}
FactValidator::State FactValidator::validate(QString& input, int& pos) const
{
Q_UNUSED(input);
Q_UNUSED(pos);
return Acceptable;
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
/// @file
/// @author Don Gagne <don@thegagnes.com>
#ifndef FactValidator_H
#define FactValidator_H
#include <QValidator>
class Fact;
/// QML Validator for Facts (Work In Progress)
///
/// The validator uses the FactMetaData to impose restrictions on the input. It is used as follows:
/// @code{.unparsed}
/// TextInput {
/// validator: FactValidator { fact: parameterFacts.RC_MAP_THROTTLE; }
/// }
/// @endcode
class FactValidator : public QValidator
{
Q_OBJECT
Q_PROPERTY(Fact* fact READ fact WRITE setFact)
public:
FactValidator(QObject* parent = NULL);
// Property system methods
/// Read accessor for fact property
Fact* fact(void) { return _fact; }
/// Write accessor for fact property
void setFact(Fact* fact) { _fact = fact; }
/// Override from QValidator
virtual void fixup(QString& input) const;
/// Override from QValidator
virtual State validate(QString& input, int& pos) const;
private:
Fact* _fact; ///< Fact that the validator is working on
};
#endif
\ No newline at end of file
......@@ -92,6 +92,39 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting) :
Q_ASSERT(_app == NULL);
_app = this;
#ifdef QT_DEBUG
// First thing we want to do is set up the qtlogging.ini file. If it doesn't already exist we copy
// it to the correct location. This way default debug builds will have logging turned off.
static const char* qtProjectDir = "QtProject";
static const char* qtLoggingFile = "qtlogging.ini";
bool loggingDirectoryOk = false;
QDir iniFileLocation(QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation));
if (!iniFileLocation.cd(qtProjectDir)) {
if (!iniFileLocation.mkdir(qtProjectDir)) {
qDebug() << "Unable to create qtlogging.ini directory" << iniFileLocation.filePath(qtProjectDir);
} else {
if (!iniFileLocation.cd(qtProjectDir)) {
qDebug() << "Unable to access qtlogging.ini directory" << iniFileLocation.filePath(qtProjectDir);;
}
loggingDirectoryOk = true;
}
} else {
loggingDirectoryOk = true;
}
if (loggingDirectoryOk) {
qDebug () << iniFileLocation;
if (!iniFileLocation.exists(qtLoggingFile)) {
if (!QFile::copy(":QLoggingCategory/qtlogging.ini", iniFileLocation.filePath(qtLoggingFile))) {
qDebug() << "Unable to copy" << QString(qtLoggingFile) << "to" << iniFileLocation;
}
}
}
#endif
// Set application information
if (_runningUnitTests) {
// We don't want unit tests to use the same QSettings space as the normal app. So we tweak the app
......@@ -403,6 +436,11 @@ void QGCApplication::_createSingletons(void)
AutoPilotPluginManager* pluginManager = AutoPilotPluginManager::instance();
Q_UNUSED(pluginManager);
Q_ASSERT(pluginManager);
// Must be after UASManager since FactSystem connects to UASManager
FactSystem* factSystem = FactSystem::instance();
Q_UNUSED(factSystem);
Q_ASSERT(factSystem);
}
void QGCApplication::destroySingletonsForUnitTest(void)
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include "QGCQuickWidget.h"
#include "UASManager.h"
#include "AutoPilotPluginManager.h"
#include <QQmlContext>
#include <QQmlEngine>
/// @file
/// @brief Subclass of QQuickWidget which injects Facts and the Pallete object into
/// the QML context.
///
/// @author Don Gagne <don@thegagnes.com>
QGCQuickWidget::QGCQuickWidget(QWidget* parent) :
QQuickWidget(parent)
{
UASManagerInterface* uasMgr = UASManager::instance();
Q_ASSERT(uasMgr);
UASInterface* uas = uasMgr->getActiveUAS();
Q_ASSERT(uas);
AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(uas->getAutopilotType())->addFactsToQmlContext(rootContext(), uas);
rootContext()->engine()->addImportPath("qrc:/qml");
setSource(QUrl::fromLocalFile("/Users/Don/repos/qgroundcontrol/test.qml"));
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2014 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef QGCQuickWidget_H
#define QGCQuickWidget_H
#include <QQuickWidget>
#include "UASInterface.h"
/// @file
/// @brief Subclass of QQuickWidget which injects Facts and the Pallete object into
/// the QML context.
///
/// @author Don Gagne <don@thegagnes.com>
class QGCQuickWidget : public QQuickWidget {
Q_OBJECT
public:
QGCQuickWidget(QWidget* parent = NULL);
};
#endif
......@@ -694,7 +694,11 @@ void MAVLinkProtocol::_startLogging(void)
void MAVLinkProtocol::_stopLogging(void)
{
if (_closeLogFile()) {
emit saveTempFlightDataLog(_tempLogFile.fileName());
if (qgcApp()->promptFlightDataSave()) {
emit saveTempFlightDataLog(_tempLogFile.fileName());
} else {
QFile::remove(_tempLogFile.fileName());
}
}
}
......@@ -753,3 +757,15 @@ void MAVLinkProtocol::suspendLogForReplay(bool suspend)
_logSuspendReplay = suspend;
}
void MAVLinkProtocol::deleteTempLogFiles(void)
{
QDir tempDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
QString filter(QString("*.%1").arg(_logFileExtension));
QFileInfoList fileInfoList = tempDir.entryInfoList(QStringList(filter), QDir::Files);
foreach(const QFileInfo fileInfo, fileInfoList) {
QFile::remove(fileInfo.filePath());
}
}
......@@ -199,6 +199,9 @@ public slots:
/// and not called directly in order to synchronize with the bytesReady signal
/// which may be ahead of it in the signal queue.
void suspendLogForReplay(bool suspend);
/// @brief Deletes any log files which are in the temp directory
static void deleteTempLogFiles(void);
protected:
// Override from QObject
......
......@@ -43,6 +43,7 @@ This file is part of the QGROUNDCONTROL project
#include "QGC.h"
#include "MainWindow.h"
#include "QGCFileDialog.h"
#include "QGCMessageBox.h"
// FlightGear _fgProcess start and connection is quite fragile. Uncomment the define below to get higher level of debug output
// for tracking down problems.
......@@ -860,11 +861,47 @@ bool QGCFlightGearLink::connectSimulation()
return false;
}
// Make sure we can find the communication protocol file in QGC install
QString fgProtocolXmlFile = fgProtocol + ".xml";
QString qgcProtocolFileFullyQualified = qgcProtocolDir.absoluteFilePath(fgProtocolXmlFile);
if (!QFileInfo(qgcProtocolFileFullyQualified).exists()) {
MainWindow::instance()->showCriticalMessage(tr("Incorrect QGroundControl installation"), tr("FlightGear protocol file missing: %1").arg(qgcProtocolFileFullyQualified));
return false;
}
// Communication protocol must be in FlightGear protocol directory. There does not appear to be any way
// around this by specifying something on the FlightGear command line. FG code does direct append
// of protocol xml file to $FG_ROOT and $FG_ROOT only allows a single directory to be specified.
QString fgProtocolXmlFile = fgProtocol + ".xml";
_fgProtocolFileFullyQualified = fgProtocolDir.absoluteFilePath(fgProtocolXmlFile);
if (QFileInfo(_fgProtocolFileFullyQualified).exists()) {
// Verify that the file is current by comparing it against the one in QGC
QFile fgFile(_fgProtocolFileFullyQualified);
QFile qgcFile(qgcProtocolFileFullyQualified);
if (!fgFile.open(QIODevice::ReadOnly) ||
!qgcFile.open(QIODevice::ReadOnly)) {
QGCMessageBox::warning(tr("FlightGear HIL"), tr("Unable to verify that protocol file %1 is current. "
"If file is out of date, you may experience problems. "
"Safest approach is to delete the file manually and allow QGroundControl install the latest file.").arg(_fgProtocolFileFullyQualified));
}
QByteArray fgBytes = fgFile.readAll();
QByteArray qgcBytes = qgcFile.readAll();
fgFile.close();
qgcFile.close();
if (fgBytes != qgcBytes) {
QGCMessageBox::warning(tr("FlightGear HIL"), tr("FlightGear protocol file %1 is out of date. It will be deleted, which will cause QGroundControl to install the latest version of the file.").arg(_fgProtocolFileFullyQualified));
if (!QFile::remove(_fgProtocolFileFullyQualified)) {
QGCMessageBox::warning(tr("FlightGear HIL"), tr("Delete of protocol file failed. You will have to manually delete the file."));
return false;
}
}
}
if (!QFileInfo(_fgProtocolFileFullyQualified).exists()) {
QMessageBox msgBox(QMessageBox::Critical,
tr("FlightGear Failed to Start"),
......@@ -877,13 +914,6 @@ bool QGCFlightGearLink::connectSimulation()
return false;
}
// Make sure we can find the communication protocol file in QGC install before we attempt to copy to FlightGear
QString qgcProtocolFileFullyQualified = qgcProtocolDir.absoluteFilePath(fgProtocolXmlFile);
if (!QFileInfo(qgcProtocolFileFullyQualified).exists()) {
MainWindow::instance()->showCriticalMessage(tr("Incorrect QGroundControl installation"), tr("FlightGear protocol file missing: %1").arg(qgcProtocolFileFullyQualified));
return false;
}
// Now that we made it this far, we should be able to try to copy the protocol file to FlightGear.
bool succeeded = QFile::copy(qgcProtocolFileFullyQualified, _fgProtocolFileFullyQualified);
if (!succeeded) {
......
......@@ -28,6 +28,8 @@
#include "MainWindowTest.h"
#include "QGCToolBar.h"
#include "MockLink.h"
#include "QGCMessageBox.h"
UT_REGISTER_TEST(MainWindowTest)
......@@ -66,3 +68,28 @@ void MainWindowTest::_clickThrough_test(void)
}
}
void MainWindowTest::_connectWindowClose_test(void)
{
LinkManager* linkMgr = LinkManager::instance();
Q_CHECK_PTR(linkMgr);
MockLink* link = new MockLink();
Q_CHECK_PTR(link);
// FIXME: LinkManager/MainWindow needs to be re-architected so that you don't have to addLink to MainWindow to get things to work
_mainWindow->addLink(link);
linkMgr->connectLink(link);
QTest::qWait(5000); // Give enough time for UI to settle and heartbeats to go through
// On MainWindow close we should get a message box telling the user to disconnect first
setExpectedMessageBox(QGCMessageBox::Ok);
_mainWindow->close();
QTest::qWait(1000); // Need to allow signals to move between threads
checkExpectedMessageBox();
// We are going to disconnect the link which is going to pop a save file dialog
setExpectedFileDialog(getSaveFileName, QStringList());
linkMgr->disconnectLink(link);
QTest::qWait(1000); // Need to allow signals to move between threads
checkExpectedFileDialog();
}
......@@ -44,6 +44,7 @@ private slots:
void cleanup(void);
void _clickThrough_test(void);
void _connectWindowClose_test(void);
private:
MainWindow* _mainWindow;
......
......@@ -125,7 +125,7 @@ void MavlinkLogTest::_bootLogDetectionSave_test(void)
void MavlinkLogTest::_bootLogDetectionZeroLength_test(void)
{
// Create a fake eempty mavlink log
// Create a fake empty mavlink log
_createTempLogFile(true);
// Zero length log files should not generate any additional UI pop-ups. It should just be deleted silently.
......@@ -170,32 +170,13 @@ void MavlinkLogTest::_connectLog_test(void)
QTest::qWait(1000); // Need to allow signals to move between threads to shutdown MainWindow
}
void MavlinkLogTest::_connectLogWindowClose_test(void)
void MavlinkLogTest::_deleteTempLogFiles_test(void)
{
MainWindow* mainWindow = MainWindow::_create(NULL, MainWindow::CUSTOM_MODE_PX4);
Q_CHECK_PTR(mainWindow);
LinkManager* linkMgr = LinkManager::instance();
Q_CHECK_PTR(linkMgr);
// Verify that the MAVLinkProtocol::deleteTempLogFiles api works correctly
MockLink* link = new MockLink();
Q_CHECK_PTR(link);
// FIXME: LinkManager/MainWindow needs to be re-architected so that you don't have to addLink to MainWindow to get things to work
mainWindow->addLink(link);
linkMgr->connectLink(link);
QTest::qWait(5000); // Give enough time for UI to settle and heartbeats to go through
// On Disconnect: We should get a getSaveFileName dialog.
QDir logSaveDir(QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation));
QString logSaveFile(logSaveDir.filePath(_saveLogFilename));
setExpectedFileDialog(getSaveFileName, QStringList(logSaveFile));
// MainWindow deletes itself on close
mainWindow->close();
QTest::qWait(1000); // Need to allow signals to move between threads
checkExpectedFileDialog();
// Make sure the file is there and delete it
QCOMPARE(logSaveDir.remove(_saveLogFilename), true);
_createTempLogFile(false);
MAVLinkProtocol::deleteTempLogFiles();
QDir tmpDir(QStandardPaths::writableLocation(QStandardPaths::TempLocation));
QStringList logFiles(tmpDir.entryList(QStringList(QString("*.%1").arg(_logFileExtension)), QDir::Files));
QCOMPARE(logFiles.count(), 0);
}
......@@ -46,7 +46,7 @@ private slots:
void _bootLogDetectionSave_test(void);
void _bootLogDetectionZeroLength_test(void);
void _connectLog_test(void);
void _connectLogWindowClose_test(void);
void _deleteTempLogFiles_test(void);
private:
void _createTempLogFile(bool zeroLength);
......
......@@ -103,7 +103,7 @@ public:
virtual QList<LinkInterface*>* getLinks() { Q_ASSERT(false); return NULL; };
virtual bool systemCanReverse() const { Q_ASSERT(false); return false; };
virtual QString getSystemTypeName() { Q_ASSERT(false); return _bogusString; };
virtual int getAutopilotType() { Q_ASSERT(false); return 0; };
virtual int getAutopilotType() { return MAV_AUTOPILOT_PX4; };
virtual QGCUASFileManager* getFileManager() {Q_ASSERT(false); return NULL; }
/** @brief Send a message over this link (to this or to all UAS on this link) */
......@@ -133,7 +133,6 @@ public slots:
virtual void setTargetPosition(float x, float y, float z, float yaw) { Q_UNUSED(x); Q_UNUSED(y); Q_UNUSED(z); Q_UNUSED(yaw); Q_ASSERT(false); };
virtual void setLocalOriginAtCurrentGPSPosition() { Q_ASSERT(false); };
virtual void setHomePosition(double lat, double lon, double alt) { Q_UNUSED(lat); Q_UNUSED(lon); Q_UNUSED(alt); Q_ASSERT(false); };
virtual void requestParameters() { Q_ASSERT(false); };
virtual void requestParameter(int component, const QString& parameter) { Q_UNUSED(component); Q_UNUSED(parameter); Q_ASSERT(false); };
virtual void writeParametersToStorage() { Q_ASSERT(false); };
virtual void readParametersFromStorage() { Q_ASSERT(false); };
......
......@@ -28,6 +28,7 @@
#include "UnitTest.h"
#include "QGCApplication.h"
#include "MAVLinkProtocol.h"
bool UnitTest::_messageBoxRespondedTo = false;
bool UnitTest::_badResponseButton = false;
......@@ -115,6 +116,8 @@ void UnitTest::init(void)
// Each test gets a clean global state
qgcApp()->destroySingletonsForUnitTest();
qgcApp()->createSingletonsForUnitTest();
MAVLinkProtocol::deleteTempLogFiles();
}
/// @brief Called after each test.
......
......@@ -79,7 +79,7 @@ UASInterface* QGCMAVLinkUASFactory::createUAS(MAVLinkProtocol* mavlink, LinkInte
uas->addLink(link);
// First thing we do with a new UAS is get the parameters
uas->requestParameters();
uas->getParamManager()->requestParameterList();
// Now add UAS to "official" list, which makes the whole application aware of it
UASManager::instance()->addUAS(uas);
......
......@@ -217,6 +217,8 @@ void QGCUASParamManager::requestRcCalibrationParamsUpdate() {
void QGCUASParamManager::_parameterListUpToDate(void)
{
qDebug() << "Emitting parameters ready, count:" << paramDataModel.countOnboardParams();
_parametersReady = true;
emit parameterListUpToDate();
}
......@@ -1968,16 +1968,6 @@ int UAS::getCommunicationStatus() const
return commStatus;
}
void UAS::requestParameters()
{
mavlink_message_t msg;
mavlink_msg_param_request_list_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, this->getUASID(), MAV_COMP_ID_ALL);
sendMessage(msg);
QDateTime time = QDateTime::currentDateTime();
qDebug() << __FILE__ << ":" << __LINE__ << time.toString() << "LOADING PARAM LIST";
}
void UAS::writeParametersToStorage()
{
mavlink_message_t msg;
......
......@@ -830,9 +830,6 @@ public slots:
/** @brief Set current mode of operation, e.g. auto or manual, does not check the arming status, for anything else than arming/disarming operations use setMode instead */
void setModeArm(uint8_t newBaseMode, uint32_t newCustomMode);
/** @brief Request all parameters */
void requestParameters();
/** @brief Request a single parameter by name */
void requestParameter(int component, const QString& parameter);
/** @brief Request a single parameter by index */
......
......@@ -315,8 +315,6 @@ public slots:
virtual void setLocalOriginAtCurrentGPSPosition() = 0;
/** @brief Set world frame origin / home position at this GPS position */
virtual void setHomePosition(double lat, double lon, double alt) = 0;
/** @brief Request all onboard parameters of all components */
virtual void requestParameters() = 0;
/** @brief Request one specific onboard parameter */
virtual void requestParameter(int component, const QString& parameter) = 0;
/** @brief Write parameter to permanent storage */
......
......@@ -5,11 +5,13 @@
#include "QGCUASParamManagerInterface.h"
#include "UASInterface.h"
#include "MAVLinkProtocol.h"
#include "MainWindow.h"
#define RC_CAL_CHAN_MAX 8
Q_LOGGING_CATEGORY(UASParameterCommsMgrLog, "UASParameterCommsMgrLog")
UASParameterCommsMgr::UASParameterCommsMgr(QObject *parent) :
QObject(parent),
lastReceiveTime(0),
......@@ -67,7 +69,15 @@ void UASParameterCommsMgr::loadParamCommsSettings()
settings.endGroup();
}
void UASParameterCommsMgr::_sendParamRequestListMsg(void)
{
MAVLinkProtocol* mavlink = MainWindow::instance()->getMAVLink();
Q_ASSERT(mavlink);
mavlink_message_t msg;
mavlink_msg_param_request_list_pack(mavlink->getSystemId(), mavlink->getComponentId(), &msg, mav->getUASID(), MAV_COMP_ID_ALL);
mav->sendMessage(msg);
}
/**
* Send a request to deliver the list of onboard parameters
......@@ -78,16 +88,20 @@ void UASParameterCommsMgr::requestParameterList()
if (!mav) {
return;
}
if (!transmissionListMode) {
qCDebug(UASParameterCommsMgrLog) << "Requesting full parameter list";
transmissionListMode = true;//TODO eliminate?
//we use (compId 0, paramId 0) as indicating all params for the system
markReadParamWaiting(0,0);
mav->requestParameters();
_sendParamRequestListMsg();
updateSilenceTimer();
}
else {
qDebug() << __FILE__ << __LINE__ << "Ignoring requestParameterList because we're receiving params list";
qCDebug(UASParameterCommsMgrLog) << "Ignoring requestParameterList because we're receiving params list";
}
}
......@@ -119,7 +133,7 @@ void UASParameterCommsMgr::markWriteParamWaiting(int compId, QString paramName,
*/
void UASParameterCommsMgr::clearRetransmissionLists(int& missingReadCount, int& missingWriteCount )
{
qDebug() << __FILE__ << __LINE__ << "clearRetransmissionLists";
qCDebug(UASParameterCommsMgrLog) << "Clearing re-transmission lists";
missingReadCount = 0;
QList<int> compIds = readsWaiting.keys();
......@@ -192,7 +206,7 @@ void UASParameterCommsMgr::resendReadWriteRequests()
qDebug() << "compId " << compId << "readsWaiting:" << missingReadParams->count();
foreach (int paramId, *missingReadParams) {
if (0 == paramId && 0 == compId) {
mav->requestParameters();
_sendParamRequestListMsg();
//don't request any other params individually for this component
break;
}
......@@ -203,7 +217,7 @@ void UASParameterCommsMgr::resendReadWriteRequests()
requestedReadCount++;
}
else {
qDebug() << "Throttling read retransmit requests at" << requestedReadCount;
qCDebug(UASParameterCommsMgrLog) << "Throttling read retransmit requests at" << requestedReadCount;
break;
}
}
......@@ -223,7 +237,7 @@ void UASParameterCommsMgr::resendReadWriteRequests()
requestedWriteCount++;
}
else {
qDebug() << "Throttling write retransmit requests at" << requestedWriteCount;
qCDebug(UASParameterCommsMgrLog) << "Throttling write retransmit requests at" << requestedWriteCount;
break;
}
}
......@@ -243,7 +257,7 @@ void UASParameterCommsMgr::silenceTimerExpired()
{
quint64 curTime = QGC::groundTimeMilliseconds();
int elapsed = (int)(curTime - lastSilenceTimerReset);
qDebug() << "silenceTimerExpired elapsed:" << elapsed;
qCDebug(UASParameterCommsMgrLog) << "silenceTimerExpired elapsed:" << elapsed;
if (elapsed < silenceTimeout) {
//reset the guard timer: it fired prematurely
......@@ -253,7 +267,7 @@ void UASParameterCommsMgr::silenceTimerExpired()
int totalElapsed = (int)(curTime - lastReceiveTime);
if (totalElapsed > maxSilenceTimeout) {
qDebug() << "maxSilenceTimeout exceeded: " << totalElapsed;
qCDebug(UASParameterCommsMgrLog) << "maxSilenceTimeout exceeded: " << totalElapsed;
int missingReads, missingWrites;
clearRetransmissionLists(missingReads,missingWrites);
emit _stopSilenceTimer(); // Stop timer on our thread;
......@@ -299,7 +313,7 @@ void UASParameterCommsMgr::requestRcCalibrationParamsUpdate()
}
}
else {
qDebug() << __FILE__ << __LINE__ << "Ignoring requestRcCalibrationParamsUpdate because we're receiving params list";
qCDebug(UASParameterCommsMgrLog) << "Ignoring requestRcCalibrationParamsUpdate because we're receiving params list";
}
}
......@@ -377,6 +391,7 @@ void UASParameterCommsMgr::updateSilenceTimer()
}
else {
//all parameters have been received, broadcast to UI
qCDebug(UASParameterCommsMgrLog) << "emitting parameterListUpToDate";
emit parameterListUpToDate();
resetAfterListReceive();
emit _stopSilenceTimer(); // Stop timer on our thread;
......@@ -396,6 +411,8 @@ void UASParameterCommsMgr::setParameterStatusMsg(const QString& msg, ParamCommsS
void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int paramCount, int paramId, QString paramName, QVariant value)
{
qCDebug(UASParameterCommsMgrLog) << QString("Received parameter update for: name(%1) count(%2) index(%3)").arg(paramName).arg(paramCount).arg(paramId);
Q_UNUSED(uas); //this object is assigned to one UAS only
lastReceiveTime = QGC::groundTimeMilliseconds();
// qDebug() << "compId" << compId << "receivedParameterUpdate:" << paramName;
......@@ -423,7 +440,7 @@ void UASParameterCommsMgr::receivedParameterUpdate(int uas, int compId, int para
//remove our placeholder read request for all params
readsWaiting.value(0)->remove(0);
qDebug() << "Mark all parameters as missing: " << paramCount;
qCDebug(UASParameterCommsMgrLog) << "receivedParameterUpdate: Mark all parameters as missing: " << paramCount;
for (int i = 1; i < paramCount; ++i) { //param Id 0 is "all parameters" and not valid
compMissingReads->insert(i);
}
......@@ -533,7 +550,7 @@ void UASParameterCommsMgr::sendPendingParameters(bool copyToPersistent, bool for
}
else {
setParameterStatusMsg(tr("Transmitting %1 parameters.").arg(parametersSent));
qDebug() << "Pending parameters now:" << paramDataModel->countPendingParams();
qCDebug(UASParameterCommsMgrLog) << "Pending parameters now:" << paramDataModel->countPendingParams();
}
......@@ -546,7 +563,7 @@ UASParameterCommsMgr::~UASParameterCommsMgr()
QString ptrStr;
ptrStr.sprintf("%8p", this);
qDebug() << "UASParameterCommsMgr destructor: " << ptrStr ;
qCDebug(UASParameterCommsMgrLog) << "UASParameterCommsMgr destructor: " << ptrStr ;
}
......
......@@ -6,11 +6,12 @@
#include <QTimer>
#include <QVariant>
#include <QVector>
#include <QLoggingCategory>
class UASInterface;
class UASParameterDataModel;
Q_DECLARE_LOGGING_CATEGORY(UASParameterCommsMgrLog)
class UASParameterCommsMgr : public QObject
{
......@@ -122,6 +123,9 @@ private slots:
/// @brief We signal this to ourselves in order to get timer started/stopped on our own thread.
void _startSilenceTimerOnThisThread(void);
void _stopSilenceTimerOnThisThread(void);
private:
void _sendParamRequestListMsg(void);
};
......
......@@ -57,7 +57,6 @@ This file is part of the QGROUNDCONTROL project
#include "MAVLinkDecoder.h"
#include "QGCMAVLinkMessageSender.h"
#include "QGCRGBDView.h"
#include "QGCStatusBar.h"
#include "UASQuickView.h"
#include "QGCDataPlot2D.h"
#include "Linecharts.h"
......@@ -225,8 +224,7 @@ MainWindow::MainWindow(QSplashScreen* splashScreen, enum MainWindow::CUSTOM_MODE
advancedActions << ui.actionSimulationView;
toolBar->setPerspectiveChangeAdvancedActions(advancedActions);
customStatusBar = new QGCStatusBar(this);
setStatusBar(customStatusBar);
setStatusBar(new QStatusBar(this));
statusBar()->setSizeGripEnabled(true);
emit initStatusChanged(tr("Building common widgets."), Qt::AlignLeft | Qt::AlignBottom, QColor(62, 93, 141));
......@@ -503,8 +501,8 @@ void MainWindow::buildCommonWidgets()
this, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)));
// Log player
logPlayer = new QGCMAVLinkLogPlayer(mavlink, customStatusBar);
customStatusBar->setLogPlayer(logPlayer);
logPlayer = new QGCMAVLinkLogPlayer(mavlink, statusBar());
statusBar()->addPermanentWidget(logPlayer);
// Initialize all of the views, if they haven't been already, and add their central widgets
if (!plannerView)
......@@ -778,12 +776,32 @@ void MainWindow::showHILConfigurationWidget(UASInterface* uas)
void MainWindow::closeEvent(QCloseEvent *event)
{
// Disallow window close if there are active connections
bool foundConnections = false;
foreach(LinkInterface* link, LinkManager::instance()->getLinks()) {
if (link->isConnected()) {
foundConnections = true;
break;
}
}
if (foundConnections) {
QGCMessageBox::warning(tr("QGroundControl close"), tr("There are still active connections to vehicles. Please disconnect all connections before closing QGroundControl."));
event->ignore();
return;
}
// Should not be any active connections
foreach(LinkInterface* link, LinkManager::instance()->getLinks()) {
Q_UNUSED(link);
Q_ASSERT(!link->isConnected());
}
storeViewState();
storeSettings();
mavlink->storeSettings();
UASManager::instance()->storeSettings();
// FIXME: If connected links, should prompt before close
LinkManager::instance()->disconnectAll();
event->accept();
}
......@@ -1734,14 +1752,12 @@ bool MainWindow::dockWidgetTitleBarsEnabled() const
void MainWindow::_saveTempFlightDataLog(QString tempLogfile)
{
if (qgcApp()->promptFlightDataSave()) {
QString saveFilename = QGCFileDialog::getSaveFileName(this,
tr("Select file to save Flight Data Log"),
qgcApp()->mavlinkLogFilesLocation(),
tr("Flight Data Log (*.mavlink)"));
if (!saveFilename.isEmpty()) {
QFile::copy(tempLogfile, saveFilename);
}
QString saveFilename = QGCFileDialog::getSaveFileName(this,
tr("Select file to save Flight Data Log"),
qgcApp()->mavlinkLogFilesLocation(),
tr("Flight Data Log (*.mavlink)"));
if (!saveFilename.isEmpty()) {
QFile::copy(tempLogfile, saveFilename);
}
QFile::remove(tempLogfile);
}
......
......@@ -416,7 +416,6 @@ protected:
QPointer<QDockWidget> hudDockWidget;
QPointer<QGCToolBar> toolBar;
QPointer<QGCStatusBar> customStatusBar;
QPointer<QDockWidget> mavlinkInspectorWidget;
QPointer<MAVLinkDecoder> mavlinkDecoder;
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2013 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#include <QToolButton>
#include <QLabel>
#include <QSpacerItem>
#include <QFileDialog>
#include "QGCStatusBar.h"
#include "UASManager.h"
#include "MainWindow.h"
#include "QGCApplication.h"
QGCStatusBar::QGCStatusBar(QWidget *parent) :
QStatusBar(parent),
player(NULL),
changed(true),
lastLogDirectory(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation))
{
setObjectName("QGC_STATUSBAR");
loadSettings();
}
void QGCStatusBar::paintEvent(QPaintEvent * event)
{
Q_UNUSED(event);
QPainter p(this);
QStyleOption opt;
opt.initFrom(this);
style()->drawPrimitive(QStyle::PE_PanelStatusBar, &opt, &p, this);
}
void QGCStatusBar::setLogPlayer(QGCMAVLinkLogPlayer* player)
{
this->player = player;
addPermanentWidget(player);
}
void QGCStatusBar::loadSettings()
{
QSettings settings;
settings.beginGroup("QGC_MAVLINKLOGPLAYER");
lastLogDirectory = settings.value("LAST_LOG_DIRECTORY", lastLogDirectory).toString();
settings.endGroup();
}
void QGCStatusBar::storeSettings()
{
QSettings settings;
settings.beginGroup("QGC_MAVLINKLOGPLAYER");
settings.setValue("LAST_LOG_DIRECTORY", lastLogDirectory);
settings.endGroup();
}
QGCStatusBar::~QGCStatusBar()
{
storeSettings();
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009 - 2013 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
This file is part of the QGROUNDCONTROL project
QGROUNDCONTROL 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.
QGROUNDCONTROL 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 QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.
======================================================================*/
#ifndef QGCSTATUSBAR_H
#define QGCSTATUSBAR_H
#include <QStatusBar>
#include <QAction>
#include <QToolButton>
#include <QPushButton>
#include <QLabel>
#include <QProgressBar>
#include "UASInterface.h"
#include "QGCMAVLinkLogPlayer.h"
class QGCStatusBar : public QStatusBar
{
Q_OBJECT
public:
explicit QGCStatusBar(QWidget* parent = 0);
void addPerspectiveChangeAction(QAction* action);
~QGCStatusBar();
public slots:
/** @brief Set log playing component */
void setLogPlayer(QGCMAVLinkLogPlayer* player);
virtual void paintEvent(QPaintEvent * event);
protected:
void storeSettings();
void loadSettings();
QGCMAVLinkLogPlayer* player;
bool changed;
QString lastLogDirectory;
};
#endif // QGCSTATUSBAR_H
......@@ -33,7 +33,6 @@ This file is part of the QGROUNDCONTROL project
#include <QComboBox>
#include <QTimer>
#include "UASInterface.h"
#include "QGCMAVLinkLogPlayer.h"
#include "SerialLink.h"
class QGCToolBar : public QToolBar
......@@ -124,7 +123,6 @@ protected:
QProgressBar* toolBarBatteryBar;
QLabel* toolBarBatteryVoltageLabel;
QGCMAVLinkLogPlayer* player;
QComboBox *portComboBox;
QComboBox *baudcomboBox;
QTimer portBoxTimer;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment