Skip to content

Commit

Permalink
QmlControls: Fix Parenting of Several Classes
Browse files Browse the repository at this point in the history
  • Loading branch information
HTRamsey committed Oct 26, 2024
1 parent 2095344 commit 8202e60
Show file tree
Hide file tree
Showing 17 changed files with 503 additions and 348 deletions.
1 change: 1 addition & 0 deletions src/Joystick/Joystick.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include "QGCMAVLink.h"
#include "CustomActionManager.h"
#include "QmlObjectListModel.h"

#include <QtCore/QObject>
#include <QtCore/QThread>
Expand Down
40 changes: 39 additions & 1 deletion src/QmlControls/CustomAction.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,46 @@

#include "CustomAction.h"
#include "Vehicle.h"
#include "QGCLoggingCategory.h"

void CustomAction::sendTo(Vehicle* vehicle) {
QGC_LOGGING_CATEGORY(CustomActionLog, "qgc.qmlcontrols.customaction")

CustomAction::CustomAction(QObject *parent)
: QObject(parent)
{
// qCDebug(CustomActionLog) << Q_FUNC_INFO << this;
}

CustomAction::CustomAction(
const QString &label,
const QString &description,
MAV_CMD mavCmd,
MAV_COMPONENT compId,
float param1,
float param2,
float param3,
float param4,
float param5,
float param6,
float param7,
QObject *parent
) : QObject(parent)
, _label(label)
, _description(description)
, _mavCmd(mavCmd)
, _compId(compId)
, _params{ param1, param2, param3, param4, param5, param6, param7 }
{
// qCDebug(CustomActionLog) << Q_FUNC_INFO << this;
};

CustomAction::~CustomAction()
{
// qCDebug(CustomActionLog) << Q_FUNC_INFO << this;
}

void CustomAction::sendTo(Vehicle *vehicle)
{
if (vehicle) {
const bool showError = true;
vehicle->sendMavCommand(_compId, _mavCmd, showError, _params[0], _params[1], _params[2], _params[3], _params[4], _params[5], _params[6]);
Expand Down
66 changes: 33 additions & 33 deletions src/QmlControls/CustomAction.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,49 +11,49 @@

#include "MAVLinkLib.h"

#include <QtCore/QLoggingCategory>
#include <QtCore/QObject>
#include <QtQmlIntegration/QtQmlIntegration>

Q_DECLARE_LOGGING_CATEGORY(CustomActionLog)

class Vehicle;

class CustomAction: public QObject
{
Q_OBJECT

Q_PROPERTY(QString label READ label CONSTANT)
Q_PROPERTY(QString description READ description CONSTANT)
QML_ELEMENT
Q_MOC_INCLUDE("Vehicle.h")
Q_PROPERTY(QString label READ label CONSTANT)
Q_PROPERTY(QString description READ description CONSTANT)

public:
CustomAction() { CustomAction(QString(), QString(), MAV_CMD(0), MAV_COMPONENT(0), 0, 0, 0, 0, 0, 0, 0); } // this is required for QML reflection
explicit CustomAction(QObject *parent = nullptr);
CustomAction(
QString label,
QString description,
MAV_CMD mavCmd,
MAV_COMPONENT compId,
float param1,
float param2,
float param3,
float param4,
float param5,
float param6,
float param7,
QObject* parent = nullptr)
: QObject (parent)
, _label (label)
, _description (description)
, _mavCmd (mavCmd)
, _compId (compId)
, _params { param1, param2, param3, param4, param5, param6, param7 }
{};

Q_INVOKABLE void sendTo(Vehicle* vehicle);

QString label () const { return _label; }
QString description() const { return _description; }
const QString &label,
const QString &description,
MAV_CMD mavCmd,
MAV_COMPONENT compId,
float param1,
float param2,
float param3,
float param4,
float param5,
float param6,
float param7,
QObject *parent = nullptr
);
~CustomAction();

Q_INVOKABLE void sendTo(Vehicle *vehicle);

const QString &label() const { return _label; }
const QString &description() const { return _description; }

private:
QString _label;
QString _description;
MAV_CMD _mavCmd;
MAV_COMPONENT _compId;
float _params[7];
const QString _label;
const QString _description;
const MAV_CMD _mavCmd = MAV_CMD_ENUM_END;
const MAV_COMPONENT _compId = MAV_COMPONENT_ENUM_END;
const float _params[7]{};
};
98 changes: 55 additions & 43 deletions src/QmlControls/CustomActionManager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,88 +7,98 @@
*
****************************************************************************/

#include <QtQml/QQmlEngine>
#include <QtCore/QJsonArray>
#include <QtCore/QDir>

#include "CustomActionManager.h"
#include "CustomAction.h"
#include "Fact.h"
#include "JsonHelper.h"
#include "QGCApplication.h"
#include "SettingsManager.h"
#include "QGCLoggingCategory.h"
#include "QmlObjectListModel.h"

#include <QtCore/QDir>
#include <QtCore/QJsonArray>
#include <QtQml/QQmlEngine>

CustomActionManager::CustomActionManager(QObject* parent)
QGC_LOGGING_CATEGORY(CustomActionManagerLog, "qgc.qmlcontrols.customactionmanager")

CustomActionManager::CustomActionManager(QObject *parent)
: QObject(parent)
, _actions(new QmlObjectListModel(this))
{

// qCDebug(CustomActionManagerLog) << Q_FUNC_INFO << this;
}

CustomActionManager::CustomActionManager(Fact* actionFileNameFact, QObject* parent)
CustomActionManager::CustomActionManager(Fact *actionFileNameFact, QObject *parent)
: QObject(parent)
, _actions(new QmlObjectListModel(this))
{
setActionFileNameFact(actionFileNameFact);
}

void CustomActionManager::setActionFileNameFact(Fact* actionFileNameFact)
CustomActionManager::~CustomActionManager()
{
// qCDebug(CustomActionManagerLog) << Q_FUNC_INFO << this;
}

void CustomActionManager::setActionFileNameFact(Fact *actionFileNameFact)
{
_actionFileNameFact = actionFileNameFact;
emit actionFileNameFactChanged();
connect(_actionFileNameFact, &Fact::rawValueChanged, this, &CustomActionManager::_loadActionsFile);
(void) connect(_actionFileNameFact, &Fact::rawValueChanged, this, &CustomActionManager::_loadActionsFile);

_loadActionsFile();
}

void CustomActionManager::_loadActionsFile()
void CustomActionManager::_loadActionsFile()
{
_actions.clearAndDeleteContents();
QString actionFileName = _actionFileNameFact->rawValue().toString();
_actions->clearAndDeleteContents();
const QString actionFileName = _actionFileNameFact->rawValue().toString();
if (actionFileName.isEmpty()) {
return;
}

// Custom actions are always loaded from the custom actions save path
QString savePath = qgcApp()->toolbox()->settingsManager()->appSettings()->customActionsSavePath();
QDir saveDir(savePath);
QString fullPath = saveDir.absoluteFilePath(actionFileName);
const QString savePath = qgcApp()->toolbox()->settingsManager()->appSettings()->customActionsSavePath();
const QDir saveDir = QDir(savePath);
const QString fullPath = saveDir.absoluteFilePath(actionFileName);

// It's ok for the file to not exist
QFileInfo fileInfo(fullPath);
const QFileInfo fileInfo = QFileInfo(fullPath);
if (!fileInfo.exists()) {
return;
}

const char* kQgcFileType = "CustomActions";
const char* kActionListKey = "actions";
constexpr const char *kQgcFileType = "CustomActions";
constexpr const char *kActionListKey = "actions";

_actions.clearAndDeleteContents();
_actions->clearAndDeleteContents();

QString errorString;
int version;
QJsonObject jsonObject = JsonHelper::openInternalQGCJsonFile(fullPath, kQgcFileType, 1, 1, version, errorString);
const QJsonObject jsonObject = JsonHelper::openInternalQGCJsonFile(fullPath, kQgcFileType, 1, 1, version, errorString);
if (!errorString.isEmpty()) {
qgcApp()->showAppMessage(tr("Failed to load custom actions file: `%1` error: `%2`").arg(fullPath).arg(errorString));
qgcApp()->showAppMessage(tr("Failed to load custom actions file: `%1` error: `%2`").arg(fullPath, errorString));
return;
}

QList<JsonHelper::KeyValidateInfo> keyInfoList = {
const QList<JsonHelper::KeyValidateInfo> keyInfoList = {
{ kActionListKey, QJsonValue::Array, /* required= */ true },
};
if (!JsonHelper::validateKeys(jsonObject, keyInfoList, errorString)) {
qgcApp()->showAppMessage(tr("Custom actions file - incorrect format: %1").arg(errorString));
return;
}

QJsonArray actionList = jsonObject[kActionListKey].toArray();
for (auto actionJson: actionList) {
const QJsonArray actionList = jsonObject[kActionListKey].toArray();
for (const auto &actionJson: actionList) {
if (!actionJson.isObject()) {
qgcApp()->showAppMessage(tr("Custom actions file - incorrect format: JsonValue not an object"));
_actions.clearAndDeleteContents();
_actions->clearAndDeleteContents();
return;
}

auto actionObj = actionJson.toObject();

QList<JsonHelper::KeyValidateInfo> actionKeyInfoList = {
const QList<JsonHelper::KeyValidateInfo> actionKeyInfoList = {
{ "label", QJsonValue::String, /* required= */ true },
{ "description", QJsonValue::String, /* required= */ true },
{ "mavCmd", QJsonValue::Double, /* required= */ true },
Expand All @@ -102,26 +112,28 @@ void CustomActionManager::_loadActionsFile()
{ "param6", QJsonValue::Double, /* required= */ false },
{ "param7", QJsonValue::Double, /* required= */ false },
};

const auto actionObj = actionJson.toObject();
if (!JsonHelper::validateKeys(actionObj, actionKeyInfoList, errorString)) {
qgcApp()->showAppMessage(tr("Custom actions file - incorrect format: %1").arg(errorString));
_actions.clearAndDeleteContents();
_actions->clearAndDeleteContents();
return;
}

auto label = actionObj["label"].toString();
auto description = actionObj["description"].toString();
auto mavCmd = (MAV_CMD)actionObj["mavCmd"].toInt();
auto compId = (MAV_COMPONENT)actionObj["compId"].toInt(MAV_COMP_ID_AUTOPILOT1);
auto param1 = actionObj["param1"].toDouble(0.0);
auto param2 = actionObj["param2"].toDouble(0.0);
auto param3 = actionObj["param3"].toDouble(0.0);
auto param4 = actionObj["param4"].toDouble(0.0);
auto param5 = actionObj["param5"].toDouble(0.0);
auto param6 = actionObj["param6"].toDouble(0.0);
auto param7 = actionObj["param7"].toDouble(0.0);

CustomAction* action = new CustomAction(label, description, mavCmd, compId, param1, param2, param3, param4, param5, param6, param7, this);
const auto label = actionObj["label"].toString();
const auto description = actionObj["description"].toString();
const auto mavCmd = (MAV_CMD)actionObj["mavCmd"].toInt();
const auto compId = (MAV_COMPONENT)actionObj["compId"].toInt(MAV_COMP_ID_AUTOPILOT1);
const auto param1 = actionObj["param1"].toDouble(0.0);
const auto param2 = actionObj["param2"].toDouble(0.0);
const auto param3 = actionObj["param3"].toDouble(0.0);
const auto param4 = actionObj["param4"].toDouble(0.0);
const auto param5 = actionObj["param5"].toDouble(0.0);
const auto param6 = actionObj["param6"].toDouble(0.0);
const auto param7 = actionObj["param7"].toDouble(0.0);

CustomAction *const action = new CustomAction(label, description, mavCmd, compId, param1, param2, param3, param4, param5, param6, param7, this);
QQmlEngine::setObjectOwnership(action, QQmlEngine::CppOwnership);
_actions.append(action);
(void) _actions->append(action);
}
}
35 changes: 21 additions & 14 deletions src/QmlControls/CustomActionManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,36 +9,43 @@

#pragma once

#include "Fact.h"
#include "QmlObjectListModel.h"

#include <QtCore/QLoggingCategory>
#include <QtCore/QObject>
#include <QtQmlIntegration/QtQmlIntegration>

Q_DECLARE_LOGGING_CATEGORY(CustomActionManagerLog)

class Fact;
class QmlObjectListModel;

/// Loads the specified action file and provides access to the actions it contains.
/// Action files are loaded from the default CustomActions directory.
/// The actions file name is filename only, no path.
class CustomActionManager : public QObject
{
Q_OBJECT

Q_PROPERTY(Fact* actionFileNameFact READ actionFileNameFact WRITE setActionFileNameFact NOTIFY actionFileNameFactChanged)
Q_PROPERTY(QmlObjectListModel* actions READ actions CONSTANT)
QML_ELEMENT
Q_MOC_INCLUDE("Fact.h")
Q_MOC_INCLUDE("QmlObjectListModel.h")
Q_PROPERTY(Fact* actionFileNameFact READ actionFileNameFact WRITE setActionFileNameFact NOTIFY actionFileNameFactChanged)
Q_PROPERTY(QmlObjectListModel* actions READ actions CONSTANT)

public:
CustomActionManager(QObject* parent = nullptr);
CustomActionManager(Fact* actionFileNameFact, QObject* parent = nullptr);
explicit CustomActionManager(QObject *parent = nullptr);
explicit CustomActionManager(Fact *actionFileNameFact, QObject *parent = nullptr);
~CustomActionManager();

Fact* actionFileNameFact (void) { return _actionFileNameFact; }
void setActionFileNameFact (Fact* actionFileNameFact);
QmlObjectListModel* actions (void) { return &_actions; }
Fact *actionFileNameFact() { return _actionFileNameFact; }
void setActionFileNameFact(Fact *actionFileNameFact);
QmlObjectListModel *actions() { return _actions; }

signals:
void actionFileNameFactChanged();

private slots:
void _loadActionsFile(void);
void _loadActionsFile();

private:
Fact* _actionFileNameFact;
QmlObjectListModel _actions;
Fact *_actionFileNameFact = nullptr;
QmlObjectListModel *_actions = nullptr;
};
Loading

0 comments on commit 8202e60

Please sign in to comment.