Commit 97c92ae7 authored by Don Gagne's avatar Don Gagne

Add dirty bit support

parent dca59af3
resources/Sync.png

3.48 KB | W: | H:

resources/Sync.png

3.94 KB | W: | H:

resources/Sync.png
resources/Sync.png
resources/Sync.png
resources/Sync.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -73,6 +73,7 @@ void MissionEditor::_newMissionItemsAvailable(void) ...@@ -73,6 +73,7 @@ void MissionEditor::_newMissionItemsAvailable(void)
_canEdit = missionManager->canEdit(); _canEdit = missionManager->canEdit();
_missionItems = missionManager->copyMissionItems(); _missionItems = missionManager->copyMissionItems();
_reSequence(); _reSequence();
_missionItems->setDirty(false);
emit missionItemsChanged(); emit missionItemsChanged();
emit canEditChanged(_canEdit); emit canEditChanged(_canEdit);
...@@ -95,6 +96,7 @@ void MissionEditor::setMissionItems(void) ...@@ -95,6 +96,7 @@ void MissionEditor::setMissionItems(void)
if (activeVehicle) { if (activeVehicle) {
activeVehicle->missionManager()->writeMissionItems(*_missionItems); activeVehicle->missionManager()->writeMissionItems(*_missionItems);
_missionItems->setDirty(false);
} }
} }
...@@ -225,6 +227,7 @@ void MissionEditor::loadMissionFromFile(void) ...@@ -225,6 +227,7 @@ void MissionEditor::loadMissionFromFile(void)
_missionItems->clear(); _missionItems->clear();
} }
_missionItems->setDirty(false);
emit canEditChanged(_canEdit); emit canEditChanged(_canEdit);
} }
...@@ -250,4 +253,6 @@ void MissionEditor::saveMissionToFile(void) ...@@ -250,4 +253,6 @@ void MissionEditor::saveMissionToFile(void)
qobject_cast<MissionItem*>(_missionItems->get(i))->save(out); qobject_cast<MissionItem*>(_missionItems->get(i))->save(out);
} }
} }
_missionItems->setDirty(false);
} }
...@@ -88,11 +88,6 @@ QGCView { ...@@ -88,11 +88,6 @@ QGCView {
longitude = _homePositionCoordinate.longitude longitude = _homePositionCoordinate.longitude
} }
QGCLabel {
anchors.bottom: parent.bottom
text: "WIP: Danger, do not fly with this!"; font.pixelSize: ScreenTools.largeFontPixelSize }
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
...@@ -110,6 +105,31 @@ QGCView { ...@@ -110,6 +105,31 @@ QGCView {
} }
} }
Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
width: parent.width / 3
height: syncNeededText.height + (ScreenTools.defaultFontPixelWidth * 2)
border.width: 1
border.color: "white"
color: "black"
opacity: 0.75
visible: controller.missionItems.dirty
QGCLabel {
id: syncNeededText
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
font.pixelSize: ScreenTools.mediumFontPixelSize
text: "You have unsaved changes. Be sure to use the Sync tool to save when ready."
}
}
Rectangle { Rectangle {
id: addMissionItemsButton id: addMissionItemsButton
anchors.rightMargin: ScreenTools.defaultFontPixelHeight anchors.rightMargin: ScreenTools.defaultFontPixelHeight
......
...@@ -83,6 +83,7 @@ MissionItem::MissionItem(QObject* parent, ...@@ -83,6 +83,7 @@ MissionItem::MissionItem(QObject* parent,
, _isCurrentItem(isCurrentItem) , _isCurrentItem(isCurrentItem)
, _reachedTime(0) , _reachedTime(0)
, _yawRadiansFact(NULL) , _yawRadiansFact(NULL)
,_dirty(false)
{ {
_latitudeFact = new Fact(0, "Latitude:", FactMetaData::valueTypeDouble, this); _latitudeFact = new Fact(0, "Latitude:", FactMetaData::valueTypeDouble, this);
_longitudeFact = new Fact(0, "Longitude:", FactMetaData::valueTypeDouble, this); _longitudeFact = new Fact(0, "Longitude:", FactMetaData::valueTypeDouble, this);
...@@ -147,6 +148,16 @@ MissionItem::MissionItem(QObject* parent, ...@@ -147,6 +148,16 @@ MissionItem::MissionItem(QObject* parent,
_altitudeFact->setMetaData(altitudeMetaData); _altitudeFact->setMetaData(altitudeMetaData);
_yawRadiansFact->setMetaData(yawMetaData); _yawRadiansFact->setMetaData(yawMetaData);
_loiterOrbitRadiusFact->setMetaData(loiterOrbitRadiusMetaData); _loiterOrbitRadiusFact->setMetaData(loiterOrbitRadiusMetaData);
// Connect to valueChanged to track dirty state
connect(_latitudeFact, &Fact::valueChanged, this, &MissionItem::_factValueChanged);
connect(_longitudeFact, &Fact::valueChanged, this, &MissionItem::_factValueChanged);
connect(_altitudeFact, &Fact::valueChanged, this, &MissionItem::_factValueChanged);
connect(_yawRadiansFact, &Fact::valueChanged, this, &MissionItem::_factValueChanged);
connect(_loiterOrbitRadiusFact, &Fact::valueChanged, this, &MissionItem::_factValueChanged);
connect(_param1Fact, &Fact::valueChanged, this, &MissionItem::_factValueChanged);
connect(_param2Fact, &Fact::valueChanged, this, &MissionItem::_factValueChanged);
connect(_altitudeRelativeToHomeFact, &Fact::valueChanged, this, &MissionItem::_factValueChanged);
} }
MissionItem::MissionItem(const MissionItem& other, QObject* parent) MissionItem::MissionItem(const MissionItem& other, QObject* parent)
...@@ -187,6 +198,7 @@ const MissionItem& MissionItem::operator=(const MissionItem& other) ...@@ -187,6 +198,7 @@ const MissionItem& MissionItem::operator=(const MissionItem& other)
_autocontinue = other._autocontinue; _autocontinue = other._autocontinue;
_reachedTime = other._reachedTime; _reachedTime = other._reachedTime;
_altitudeRelativeToHomeFact = other._altitudeRelativeToHomeFact; _altitudeRelativeToHomeFact = other._altitudeRelativeToHomeFact;
_dirty = other._dirty;
*_latitudeFact = *other._latitudeFact; *_latitudeFact = *other._latitudeFact;
*_longitudeFact = *other._longitudeFact; *_longitudeFact = *other._longitudeFact;
...@@ -797,3 +809,15 @@ bool MissionItem::canEdit(void) ...@@ -797,3 +809,15 @@ bool MissionItem::canEdit(void)
return false; return false;
} }
} }
void MissionItem::setDirty(bool dirty)
{
_dirty = dirty;
emit dirtyChanged(_dirty);
}
void MissionItem::_factValueChanged(QVariant value)
{
Q_UNUSED(value);
setDirty(true);
}
...@@ -61,6 +61,9 @@ public: ...@@ -61,6 +61,9 @@ public:
const MissionItem& operator=(const MissionItem& other); const MissionItem& operator=(const MissionItem& other);
/// Returns true if the item has been modified since the last time dirty was false
Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged)
Q_PROPERTY(int sequenceNumber READ sequenceNumber WRITE setSequenceNumber NOTIFY sequenceNumberChanged) Q_PROPERTY(int sequenceNumber READ sequenceNumber WRITE setSequenceNumber NOTIFY sequenceNumberChanged)
Q_PROPERTY(bool isCurrentItem READ isCurrentItem WRITE setIsCurrentItem NOTIFY isCurrentItemChanged) Q_PROPERTY(bool isCurrentItem READ isCurrentItem WRITE setIsCurrentItem NOTIFY isCurrentItemChanged)
Q_PROPERTY(bool specifiesCoordinate READ specifiesCoordinate NOTIFY commandChanged) Q_PROPERTY(bool specifiesCoordinate READ specifiesCoordinate NOTIFY commandChanged)
...@@ -106,6 +109,9 @@ public: ...@@ -106,6 +109,9 @@ public:
double yawDegrees(void) const; double yawDegrees(void) const;
void setYawDegrees(double yaw); void setYawDegrees(double yaw);
bool dirty(void) { return _dirty; }
void setDirty(bool dirty);
// C++ only methods // C++ only methods
/// Returns true if this item can be edited in the ui /// Returns true if this item can be edited in the ui
...@@ -184,6 +190,7 @@ signals: ...@@ -184,6 +190,7 @@ signals:
void isCurrentItemChanged(bool isCurrentItem); void isCurrentItemChanged(bool isCurrentItem);
void coordinateChanged(const QGeoCoordinate& coordinate); void coordinateChanged(const QGeoCoordinate& coordinate);
void yawChanged(double yaw); void yawChanged(double yaw);
void dirtyChanged(bool dirty);
/** @brief Announces a change to the waypoint data */ /** @brief Announces a change to the waypoint data */
void changed(MissionItem* wp); void changed(MissionItem* wp);
...@@ -219,6 +226,9 @@ public: ...@@ -219,6 +226,9 @@ public:
void setChanged() { void setChanged() {
emit changed(this); emit changed(this);
} }
private slots:
void _factValueChanged(QVariant value);
private: private:
QString _oneDecimalString(double value); QString _oneDecimalString(double value);
...@@ -254,6 +264,8 @@ private: ...@@ -254,6 +264,8 @@ private:
FactMetaData* _jumpSequenceMetaData; FactMetaData* _jumpSequenceMetaData;
FactMetaData* _jumpRepeatMetaData; FactMetaData* _jumpRepeatMetaData;
bool _dirty;
static const int _cMavCmd2Name = 9; static const int _cMavCmd2Name = 9;
static const MavCmd2Name_t _rgMavCmd2Name[_cMavCmd2Name]; static const MavCmd2Name_t _rgMavCmd2Name[_cMavCmd2Name];
}; };
......
...@@ -34,6 +34,7 @@ const int QmlObjectListModel::TextRole = Qt::UserRole + 1; ...@@ -34,6 +34,7 @@ const int QmlObjectListModel::TextRole = Qt::UserRole + 1;
QmlObjectListModel::QmlObjectListModel(QObject* parent) QmlObjectListModel::QmlObjectListModel(QObject* parent)
: QAbstractListModel(parent) : QAbstractListModel(parent)
, _dirty(false)
{ {
} }
...@@ -142,22 +143,36 @@ const QObject* QmlObjectListModel::operator[](int index) const ...@@ -142,22 +143,36 @@ const QObject* QmlObjectListModel::operator[](int index) const
void QmlObjectListModel::clear(void) void QmlObjectListModel::clear(void)
{ {
while (rowCount()) { while (rowCount()) {
removeRows(0, 1); removeAt(0);
} }
} }
void QmlObjectListModel::removeAt(int i) void QmlObjectListModel::removeAt(int i)
{ {
setDirty(true);
// Look for a dirtyChanged signal on the object
if (_objectList[i]->metaObject()->indexOfSignal(QMetaObject::normalizedSignature("dirtyChanged(bool)")) != -1) {
QObject::disconnect(_objectList[i], SIGNAL(dirtyChanged(bool)), this, SLOT(_childDirtyChanged(bool)));
}
removeRows(i, 1); removeRows(i, 1);
} }
void QmlObjectListModel::insert(int i, QObject* object) void QmlObjectListModel::insert(int i, QObject* object)
{ {
setDirty(true);
if (i < 0 || i > _objectList.count()) { if (i < 0 || i > _objectList.count()) {
qWarning() << "Invalid index index:count" << i << _objectList.count(); qWarning() << "Invalid index index:count" << i << _objectList.count();
} }
QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership); QQmlEngine::setObjectOwnership(object, QQmlEngine::CppOwnership);
// Look for a dirtyChanged signal on the object
if (object->metaObject()->indexOfSignal(QMetaObject::normalizedSignature("dirtyChanged(bool)")) != -1) {
QObject::connect(object, SIGNAL(dirtyChanged(bool)), this, SLOT(_childDirtyChanged(bool)));
}
_objectList.insert(i, object); _objectList.insert(i, object);
insertRows(i, 1); insertRows(i, 1);
...@@ -177,3 +192,25 @@ QObject* QmlObjectListModel::get(int index) ...@@ -177,3 +192,25 @@ QObject* QmlObjectListModel::get(int index)
{ {
return _objectList[index]; return _objectList[index];
} }
void QmlObjectListModel::setDirty(bool dirty)
{
_dirty = dirty;
if (!dirty) {
// Need to clear dirty from all children
foreach(QObject* object, _objectList) {
if (object->property("dirty").isValid()) {
object->setProperty("dirty", false);
}
}
}
emit dirtyChanged(_dirty);
}
void QmlObjectListModel::_childDirtyChanged(bool dirty)
{
_dirty |= dirty;
emit dirtyChanged(_dirty);
}
...@@ -37,8 +37,18 @@ public: ...@@ -37,8 +37,18 @@ public:
Q_INVOKABLE QObject* get(int index); Q_INVOKABLE QObject* get(int index);
Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(int count READ count NOTIFY countChanged)
/// Returns true if any of the items in the list are dirty. Requires each object to have
/// a dirty property and dirtyChanged signal.
Q_PROPERTY(bool dirty READ dirty WRITE setDirty NOTIFY dirtyChanged)
// Property accessors
int count(void) const; int count(void) const;
bool dirty(void) { return _dirty; }
void setDirty(bool dirty);
void append(QObject* object); void append(QObject* object);
void clear(void); void clear(void);
void removeAt(int i); void removeAt(int i);
...@@ -51,6 +61,10 @@ public: ...@@ -51,6 +61,10 @@ public:
signals: signals:
void countChanged(int count); void countChanged(int count);
void dirtyChanged(bool dirtyChanged);
private slots:
void _childDirtyChanged(bool dirty);
private: private:
// Overrides from QAbstractListModel // Overrides from QAbstractListModel
...@@ -63,6 +77,8 @@ private: ...@@ -63,6 +77,8 @@ private:
private: private:
QList<QObject*> _objectList; QList<QObject*> _objectList;
bool _dirty;
static const int ObjectRole; static const int ObjectRole;
static const int TextRole; static const int TextRole;
......
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