Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QmlControls: Fix Parenting of Several Classes #12035

Merged
merged 1 commit into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading