Commit 01cecc3c authored by Thomas BOUTROUE's avatar Thomas BOUTROUE

Add a details dialog for physical values in table

Enhance look and behavior of detail dialogs

Remove useless isXXXXX properties in objects

Use enums+switch/case directly

Fix HTML export for I/O's, Sensors, and Actuator

Add special cases for hybrid objects

Cleanup Help objects tree

Code style fixes
parent 03742180
......@@ -10,8 +10,6 @@
AbstractActuator::AbstractActuator (const ObjectType::Type type, QObject * parent)
: BasicObject (ObjectFamily::ACTUATOR, parent)
, m_type (type)
, m_isAnalog (type == ObjectType::ANALOG)
, m_isDigital (type == ObjectType::DIGITAL)
{ }
AbstractActuator::~AbstractActuator (void) { }
......
......@@ -17,8 +17,6 @@ class LinkHybridActuatorToPhysicalValue;
class AbstractActuator : public BasicObject {
Q_OBJECT
QML_CONSTANT_VAR_PROPERTY (ObjectType::Type, type)
QML_CONSTANT_VAR_PROPERTY (bool, isAnalog)
QML_CONSTANT_VAR_PROPERTY (bool, isDigital)
QML_WRITABLE_CSTREF_PROPERTY (QString, description)
public:
......
......@@ -127,7 +127,7 @@ Project {
fileTags: "qt.core.resource_data";
files: [
"components/AbstractDelegateRoutine.qml",
"components/AbstractDialogDetailsIO.qml",
"components/AbstractDialogDetails.qml",
"components/BorderedBackground.qml",
"components/Circle.qml",
"components/ClickableTextLabel.qml",
......@@ -188,6 +188,7 @@ Project {
"components/DialogDetailsAout.qml",
"components/DialogDetailsDin.qml",
"components/DialogDetailsDout.qml",
"components/DialogDetailsPhy.qml",
"components/DialogExportSnapshot.qml",
"components/DialogImportSnapshot.qml",
"components/DialogOpenNetworkDefinition.qml",
......
......@@ -34,14 +34,6 @@ static ObjectHelp abstractSensor {
"type", "enum (ObjectType)", "constant", false,
"The type of sensor (analog or digital)."
},
new PropertyHelp {
"isAnalog", "bool", "constant", false,
"Whether sensor is analog (convenience flag derived from type property)."
},
new PropertyHelp {
"isDigital", "bool", "constant", false,
"Whether sensor is digital (convenience flag derived from type property)."
},
new PropertyHelp {
"description", "string", "writable", false,
"A text description for UI help mode and HTML export."
......@@ -210,14 +202,6 @@ static ObjectHelp abstractActuator {
"type", "enum (ObjectType)", "constant", false,
"The type of actuator (analog or digital)."
},
new PropertyHelp {
"isAnalog", "bool", "constant", false,
"Whether actuator is analog (convenience flag derived from type property)."
},
new PropertyHelp {
"isDigital", "bool", "constant", false,
"Whether actuator is digital (convenience flag derived from type property)."
},
new PropertyHelp {
"description", "string", "writable", false,
"A text description for UI help mode and HTML export."
......@@ -264,6 +248,14 @@ static ObjectHelp analogActuator {
"valSpeed", "int32", "readonly", false,
"The current speed generated by the actuator."
},
new PropertyHelp {
"percent", "int32", "readonly", false,
"The current value of the actuator as a percentage (takes in account the split point if any)."
},
new PropertyHelp {
"useSplitPoint", "bool", "writable", false,
"The range mode for actuator's percentage computation : if true, actuator is -100 to +100 %, else it is 0 to 100 % (default). Usefull for bidirectional motors."
},
new PropertyHelp {
"decimals", "int32", "writable", false,
"The amount of decimals that should be used when setting physical (floating) speed and convert it from integer."
......@@ -350,26 +342,6 @@ static ObjectHelp abstractIO {
"direction", "enum (ObjectDirection)", "constant", false,
"The direction of I/O (input or output)."
},
new PropertyHelp {
"isAnalog", "bool", "constant", false,
"Whether I/O is analog (convenience flag derived from type property)."
},
new PropertyHelp {
"isDigital", "bool", "constant", false,
"Whether I/O is digital (convenience flag derived from type property)."
},
new PropertyHelp {
"isInput", "bool", "constant", false,
"Whether I/O is an input (convenience flag derived from direction property)."
},
new PropertyHelp {
"isOutput", "bool", "constant", false,
"Whether I/O is an output (convenience flag derived from direction property)."
},
new PropertyHelp {
"link", "AbstractLink", "readonly", false,
"Reference of the link that is connected to this I/O, if any (null by default)."
},
},
{ },
{ },
......
......@@ -10,11 +10,6 @@ AbstractIO::AbstractIO (const ObjectType::Type type, const ObjectDirection::Type
: BasicObject (ObjectFamily::IO, parent)
, m_type (type)
, m_direction (direction)
, m_isInput (direction == ObjectDirection::INPUT)
, m_isOutput (direction == ObjectDirection::OUTPUT)
, m_isAnalog (type == ObjectType::ANALOG)
, m_isDigital (type == ObjectType::DIGITAL)
, m_link (Q_NULLPTR)
{ }
AbstractIO::~AbstractIO (void) { }
......
......@@ -15,11 +15,6 @@ class AbstractIO : public BasicObject {
Q_OBJECT
QML_CONSTANT_VAR_PROPERTY (ObjectType::Type, type)
QML_CONSTANT_VAR_PROPERTY (ObjectDirection::Type, direction)
QML_CONSTANT_VAR_PROPERTY (bool, isInput)
QML_CONSTANT_VAR_PROPERTY (bool, isOutput)
QML_CONSTANT_VAR_PROPERTY (bool, isAnalog)
QML_CONSTANT_VAR_PROPERTY (bool, isDigital)
QML_READONLY_PTR_PROPERTY (AbstractLink, link)
public:
explicit AbstractIO (const ObjectType::Type type = ObjectType::UNKNOWN_TYPE, const ObjectDirection::Type direction = ObjectDirection::UNKNOWN_DIRECTION, QObject * parent = Q_NULLPTR);
......
......@@ -52,9 +52,6 @@ void AbstractLink::sync (void) {
void AbstractLink::onSourceChanged (void) {
if (m_source) {
connect (m_source, &BasicObject::destroyed, this, &AbstractLink::onSourceDestroyed, Qt::UniqueConnection);
if (AbstractIO * io = m_source->as<AbstractIO> ()) {
io->update_link (this);
}
}
initHandler ();
ensureValid ();
......@@ -63,9 +60,6 @@ void AbstractLink::onSourceChanged (void) {
void AbstractLink::onTargetChanged (void) {
if (m_target) {
connect (m_target, &BasicObject::destroyed, this, &AbstractLink::onTargetDestroyed, Qt::UniqueConnection);
if (AbstractIO * io = m_target->as<AbstractIO> ()) {
io->update_link (this);
}
}
initHandler ();
ensureValid ();
......
This diff is collapsed.
......@@ -176,6 +176,9 @@ public:
Q_INVOKABLE void setDelegateForPath (const QString & path, QQuickItem * item);
Q_INVOKABLE QVariantList getLinksAsSource (BasicObject * object) const;
Q_INVOKABLE QVariantList getLinksAsTarget (BasicObject * object) const;
public slots:
void load (const QString & networkDefinition);
void init (void);
......
......@@ -10,9 +10,6 @@
AbstractSensor::AbstractSensor (const ObjectType::Type type, QObject * parent)
: BasicObject (ObjectFamily::SENSOR, parent)
, m_type (type)
, m_isAnalog (type == ObjectType::ANALOG)
, m_isDigital (type == ObjectType::DIGITAL)
, m_isHybrid (type == ObjectType::HYBRID)
{ }
AbstractSensor::~AbstractSensor (void) { }
......
......@@ -17,9 +17,6 @@ class LinkHybridSensorToDigitalInput;
class AbstractSensor : public BasicObject {
Q_OBJECT
QML_CONSTANT_VAR_PROPERTY (ObjectType::Type, type)
QML_CONSTANT_VAR_PROPERTY (bool, isAnalog)
QML_CONSTANT_VAR_PROPERTY (bool, isDigital)
QML_CONSTANT_VAR_PROPERTY (bool, isHybrid)
QML_WRITABLE_CSTREF_PROPERTY (QString, description)
public:
......
......@@ -232,6 +232,34 @@ QString SharedObject::format (const int value, const int decimals, const QString
return (!unit.isEmpty () ? tmp % ' ' % unit : tmp);
}
void SharedObject::highlightLinkedObject (BasicObject * object) {
if (object) {
switch (object->get_family ()) {
case ObjectFamily::IO: {
set_highlightIO (Q_NULLPTR);
set_highlightIO (object->as<AbstractIO> ());
break;
}
case ObjectFamily::VALUE: {
set_highlightPhyVal (Q_NULLPTR);
set_highlightPhyVal (object->as<PhysicalValue> ());
break;
}
case ObjectFamily::SENSOR: {
set_highlightSensor (Q_NULLPTR);
set_highlightSensor (object->as<AbstractSensor> ());
break;
}
case ObjectFamily::ACTUATOR: {
set_highlightActuator (Q_NULLPTR);
set_highlightActuator (object->as<AbstractActuator> ());
break;
}
default: break;
}
}
}
void SharedObject::addMru (const QString & filePath) {
QStringList tmp = m_settings.value ("mru").toStringList ();
tmp.removeAll (filePath);
......
......@@ -20,6 +20,7 @@ class AbstractIO;
class AbstractSensor;
class AbstractActuator;
class PhysicalValue;
class BasicObject;
class SharedObject : public QObject {
Q_OBJECT
......@@ -47,6 +48,8 @@ public:
Q_INVOKABLE int floatToInt (const qreal value, const int decimals) const;
Q_INVOKABLE QString format (const int value, const int decimals, const QString unit = "") const;
Q_INVOKABLE void highlightLinkedObject (BasicObject * object);
public slots:
void addMru (const QString & filePath);
void removeMru (const QString & filePath);
......
......@@ -7,10 +7,10 @@ ModalDialog {
buttons: buttonOk;
minWidth: layoutDetails.implicitWidth;
maxWidth: layoutDetails.implicitWidth;
message: (io ? [ "UID : %1".arg (io.path) ] : []);
message: (object ? [ "UID : %1".arg (object.path) ] : []);
onButtonClicked: { hide (); }
property AbstractIO io : null;
property BasicObject object : null;
default property alias fields : layoutDetails.data;
......
......@@ -49,6 +49,7 @@ QtObject {
readonly property Component dlgAoutDetails : Component { DialogDetailsAout { } }
readonly property Component dlgDinDetails : Component { DialogDetailsDin { } }
readonly property Component dlgDoutDetails : Component { DialogDetailsDout { } }
readonly property Component dlgPhyValDetails : Component { DialogDetailsPhy { } }
readonly property Component dlgConfCanBus : Component { DialogConfigCanBus { } }
readonly property Component dlgConfSerialBus : Component { DialogConfigSerialBus { } }
readonly property Component dlgOpen : Component { DialogOpenNetworkDefinition { } }
......
......@@ -8,6 +8,8 @@ StretchRowContainer {
property AbstractLink link : null;
property alias showLabel : lbl.visible;
TextButton {
flat: true;
icon: SymbolLoader {
......@@ -25,7 +27,9 @@ StretchRowContainer {
onClicked: { link.detached = !link.detached; }
}
SvgIconLoader {
icon: (link && link.reversed ? "qrc:///icons/reverse.svg" : "qrc:///icons/normal.svg");
icon: (link && link.reversed
? "qrc:///icons/reverse.svg"
: "qrc:///icons/normal.svg");
size: Style.fontSizeSmall;
color: Style.colorForeground;
visible: (link && link.source);
......@@ -33,6 +37,7 @@ StretchRowContainer {
anchors.verticalCenter: parent.verticalCenter;
}
TextLabel {
id: lbl;
text: (link ? link.title + " :" : "");
enabled: (link && link.enabled);
emphasis: true;
......@@ -43,18 +48,13 @@ StretchRowContainer {
text: (link && link.source ? link && link.source.path : "(N/A)");
broken: (link && link.detached);
enabled: (link && link.enabled && link.source);
clickable: (link && link.source && (link.source.family === ObjectFamily.IO || link.source.family === ObjectFamily.VALUE));
clickable: (link && link.source &&
(link.source.family === ObjectFamily.IO ||
link.source.family === ObjectFamily.VALUE ||
link.source.family === ObjectFamily.SENSOR ||
link.source.family === ObjectFamily.ACTUATOR));
font.pixelSize: Style.fontSizeSmall;
anchors.verticalCenter: parent.verticalCenter;
onClicked: {
if (link.source.family === ObjectFamily.IO) {
Shared.highlightIO = null;
Shared.highlightIO = link.source;
}
else if (link.source.family === ObjectFamily.VALUE) {
Shared.highlightPhyVal = null;
Shared.highlightPhyVal = link.source;
}
}
onClicked: { Shared.highlightLinkedObject (link.source); }
}
}
......@@ -8,6 +8,8 @@ StretchRowContainer {
property AbstractLink link : null;
property alias showLabel : lbl.visible;
TextButton {
flat: true;
icon: SymbolLoader {
......@@ -25,7 +27,9 @@ StretchRowContainer {
onClicked: { link.detached = !link.detached; }
}
SvgIconLoader {
icon: (link && link.reversed ? "qrc:///icons/reverse.svg" : "qrc:///icons/normal.svg");
icon: (link && link.reversed
? "qrc:///icons/reverse.svg"
: "qrc:///icons/normal.svg");
size: Style.fontSizeSmall;
color: Style.colorForeground;
visible: (link && link.target);
......@@ -33,6 +37,7 @@ StretchRowContainer {
anchors.verticalCenter: parent.verticalCenter;
}
TextLabel {
id: lbl;
text: (link ? link.title + " :" : "");
enabled: (link && link.enabled);
emphasis: true;
......@@ -43,18 +48,13 @@ StretchRowContainer {
text: (link && link.target ? link.target.path : "(N/A)");
broken: (link && link.detached);
enabled: (link && link.enabled && link.target);
clickable: (link && link.target && (link.target.family === ObjectFamily.IO || link.target.family === ObjectFamily.VALUE));
clickable: (link && link.target &&
(link.target.family === ObjectFamily.IO ||
link.target.family === ObjectFamily.VALUE ||
link.target.family === ObjectFamily.SENSOR ||
link.target.family === ObjectFamily.ACTUATOR));
font.pixelSize: Style.fontSizeSmall;
anchors.verticalCenter: parent.verticalCenter;
onClicked: {
if (link.target.family === ObjectFamily.IO) {
Shared.highlightIO = null;
Shared.highlightIO = link.target;
}
else if (link.target.family === ObjectFamily.VALUE) {
Shared.highlightPhyVal = null;
Shared.highlightPhyVal = link.target;
}
}
onClicked: { Shared.highlightLinkedObject (link.target); }
}
}
......@@ -24,6 +24,7 @@ ExpandableGroup {
property PhysicalBlock block : null;
signal needVisible (Item item);
signal needDetails (PhysicalValue phyVal);
DimensionsList {
id: dims;
......@@ -40,6 +41,9 @@ ExpandableGroup {
base.expanded = true;
base.needVisible (item);
}
onNeedDetails: {
base.needDetails (phyVal);
}
onValueEdited: {
if (dimension === block.absoluteAngle) {
var oldAbs = phyVal.val;
......
......@@ -24,6 +24,7 @@ ExpandableGroup {
property PhysicalGroup group : null;
signal needVisible (Item item);
signal needDetails (PhysicalValue phyVal);
Repeater {
model: (group ? group.subObjects : 0);
......@@ -56,6 +57,9 @@ ExpandableGroup {
base.expanded = true;
base.needVisible (item);
}
onNeedDetails: {
base.needDetails (phyVal);
}
}
}
}
......
......@@ -24,6 +24,7 @@ ExpandableGroup {
property PhysicalMarker marker : null;
signal needVisible (Item item);
signal needDetails (PhysicalValue phyVal);
DimensionsList {
id: dims;
......@@ -38,6 +39,9 @@ ExpandableGroup {
base.expanded = true;
base.needVisible (item);
}
onNeedDetails: {
base.needDetails (phyVal);
}
onValueEdited: { }
}
}
......@@ -30,6 +30,7 @@ BorderedBackground {
readonly property bool editable : (phyVal ? phyVal.min !== phyVal.max : false);
signal needVisible (Item item);
signal needDetails (PhysicalValue phyVal);
signal valueEdited (real value);
MouseArea {
......@@ -57,6 +58,10 @@ BorderedBackground {
margins: -Style.spacingSmall;
}
}
MouseArea {
anchors.fill: parent;
onClicked: { base.needDetails (phyVal); }
}
}
Stretcher { }
TextLabel {
......
......@@ -52,6 +52,7 @@ BorderedBackground {
}
Stretcher { }
CheckableBox {
size: Style.fontSizeBig;
anchors.verticalCenter: parent.verticalCenter;
onEdited: { io.value = value; }
......
......@@ -53,6 +53,7 @@ BorderedBackground {
Stretcher { }
Stretcher { implicitWidth: (Style.spacingBig * 3); }
CheckableBox {
size: Style.fontSizeBig;
anchors.verticalCenter: parent.verticalCenter;
onEdited: { io.value = value; }
......
......@@ -2,138 +2,112 @@ import QtQuick 2.1;
import QtQmlTricks.UiElements 2.0;
import QtCAN.CanTestBench 2.0;
AbstractDialogDetailsIO {
AbstractDialogDetails {
id: base;
title: qsTr ("Details of analog input :");
readonly property AnalogInput ain : io;
readonly property AnalogInput ain : object;
StretchRowContainer {
spacing: Style.spacingSmall;
FormContainer {
colSpacing: Style.spacingNormal;
rowSpacing: Style.spacingNormal;
TextLabel {
id: lblVal;
text: qsTr ("Value :");
emphasis: true;
anchors.verticalCenter: parent.verticalCenter;
}
Stretcher { }
TextLabel {
text: (ain ? ain.valRaw : "");
font.family: Style.fontFixedName;
anchors.baseline: lblVal.baseline;
}
TextLabel {
text: "mV";
font.pixelSize: Style.fontSizeSmall;
anchors.baseline: lblVal.baseline;
}
}
StretchRowContainer {
spacing: Style.spacingSmall;
StretchRowContainer {
spacing: Style.spacingSmall;
Stretcher { }
TextLabel {
id: lblVal;
text: (ain ? ain.valRaw : "");
font.family: Style.fontFixedName;
anchors.verticalCenter: parent.verticalCenter;
}
TextLabel {
text: "mV";
font.pixelSize: Style.fontSizeSmall;
anchors.baseline: lblVal.baseline;
}
}
TextLabel {
id: lblMin;
text: qsTr ("Minimum :");
emphasis: true;
anchors.verticalCenter: parent.verticalCenter;
}
Stretcher { }
TextLabel {
text: (ain ? ain.minRaw : "");
font.family: Style.fontFixedName;
anchors.baseline: lblMin.baseline;
}
TextLabel {
text: "mV";
font.pixelSize: Style.fontSizeSmall;
anchors.baseline: lblMin.baseline;
}
}
StretchRowContainer {
spacing: Style.spacingSmall;
StretchRowContainer {
spacing: Style.spacingSmall;
Stretcher { }
TextLabel {
id: lblMin;
text: (ain ? ain.minRaw : "");
font.family: Style.fontFixedName;
anchors.verticalCenter: parent.verticalCenter;
}
TextLabel {
text: "mV";
font.pixelSize: Style.fontSizeSmall;
anchors.baseline: lblMin.baseline;
}
}
TextLabel {
id: lblMax;
text: qsTr ("Maximum :");
emphasis: true;
anchors.verticalCenter: parent.verticalCenter;
}
Stretcher { }
TextLabel {
text: (ain ? ain.maxRaw : "");
font.family: Style.fontFixedName;
anchors.baseline: lblMax.baseline;
}
TextLabel {
text: "mV";
font.pixelSize: Style.fontSizeSmall;
anchors.baseline: lblMax.baseline;
}
}
StretchRowContainer {
spacing: Style.spacingSmall;
StretchRowContainer {
spacing: Style.spacingSmall;
Stretcher { }
TextLabel {
id: lblMax;
text: (ain ? ain.maxRaw : "");
font.family: Style.fontFixedName;
anchors.verticalCenter: parent.verticalCenter;
}
TextLabel {
text: "mV";
font.pixelSize: Style.fontSizeSmall;
anchors.baseline: lblMax.baseline;
}
}
TextLabel {
id: lblResolution;
text: qsTr ("Resolution :");
emphasis: true;
anchors.verticalCenter: parent.verticalCenter;
}
Stretcher { }
TextLabel {
text: (ain ? ain.resolutionInPoints : "");
font.family: Style.fontFixedName;
anchors.baseline: lblResolution.baseline;
}
TextLabel {
text: "points";
font.pixelSize: Style.fontSizeSmall;
anchors.baseline: lblResolution.baseline;
}
}
StretchRowContainer {
spacing: Style.spacingSmall;
StretchRowContainer {
spacing: Style.spacingSmall;
Stretcher { }
TextLabel {
id: lblResolution;
text: (ain ? ain.resolutionInPoints : "");
font.family: Style.fontFixedName;
anchors.verticalCenter: parent.verticalCenter;
}
TextLabel {
text: "points";
font.pixelSize: Style.fontSizeSmall;
anchors.baseline: lblResolution.baseline;
}
}
TextLabel {
id: lblLinkedSensor;
text: qsTr ("Linked to :");
text: qsTr ("Linked as target to :");
visible: repeaterLinksAsTarget.count;
emphasis: true;
anchors.verticalCenter: parent.verticalCenter;
}
Stretcher { }
Stretcher { implicitWidth: Style.spacingNormal; }
TextButton {
flat: true;
icon: SymbolLoader {
symbol: Components.symbolPlug;
size: Style.iconSize (0.5);
}
textColor: (ain && ain.link && ain.link.source
? (ain && ain.link && ain.link.detached
? Style.colorError
: Style.colorLink)
: Style.colorForeground);
padding: (Style.lineSize * 2);
visible: (ain && ain.link && ain.link.source);
anchors.verticalCenter: parent.verticalCenter;
onClicked: { ain.link.detached = !ain.link.detached; }
}
ClickableTextLabel {
text: (ain && ain.link && ain.link.source ? ain.link.source.path : "(N/A)");
broken: (ain && ain.link && ain.link.detached);
clickable: (ain && ain.link && ain.link.source);
anchors.baseline: lblLinkedSensor.baseline;
onClicked: {
if (ain.link.source.family === ObjectFamily.SENSOR) {
Shared.highlightSensor = null;
Shared.highlightSensor = ain.link.source;
}
else if (ain.link.source.family === ObjectFamily.IO) {
Shared.highlightIO = null;
Shared.highlightIO = ain.link.source;
Column {
spacing: Style.lineSize;
visible: repeaterLinksAsTarget.count;
Repeater {
id: repeaterLinksAsTarget;
model: Shared.manager.getLinksAsTarget (ain);
delegate: DelegateLinkSource {
link: modelData;
showLabel: false;
}
else { }
}
}
}
......
......@@ -2,138 +2,112 @@ import QtQuick 2.1;
import QtQmlTricks.UiElements 2.0;
import QtCAN.CanTestBench 2.0;
AbstractDialogDetailsIO {
AbstractDialogDetails {
id: base;
title: qsTr ("Details of analog output :");
readonly property AnalogOutput aout : io;
readonly property AnalogOutput aout : object;
StretchRowContainer {
spacing: Style.spacingSmall;
FormContainer {
colSpacing: Style.spacingNormal;
rowSpacing: Style.spacingNormal;
TextLabel {
id: lblVal;
text: qsTr ("Value :");
emphasis: true;
anchors.verticalCenter: parent.verticalCenter;
}
Stretcher { }
TextLabel {
text: (aout ? aout.valRaw : "");
font.family: Style.fontFixedName;
anchors.baseline: lblVal.baseline;
}
TextLabel {
text: "mV";
font.pixelSize: Style.fontSizeSmall;
anchors.baseline: lblVal.baseline;
}
}
StretchRowContainer {
spacing: Style.spacingSmall;
StretchRowContainer {
spacing: Style.spacingSmall;