Commit 51a6792a authored by Gus Grubba's avatar Gus Grubba

Handling Date/Time

Flight management with date range, delete flights.
parent 60453a88
...@@ -35,6 +35,27 @@ AirMapFlightInfo::AirMapFlightInfo(const airmap::Flight& flight, QObject *parent ...@@ -35,6 +35,27 @@ AirMapFlightInfo::AirMapFlightInfo(const airmap::Flight& flight, QObject *parent
} }
//-----------------------------------------------------------------------------
QString
AirMapFlightInfo::createdTime()
{
return QDateTime::fromMSecsSinceEpoch((quint64)airmap::milliseconds_since_epoch(_flight.created_at)).toString("yyyy MM dd - hh:mm:ss");
}
//-----------------------------------------------------------------------------
QString
AirMapFlightInfo::startTime()
{
return QDateTime::fromMSecsSinceEpoch((quint64)airmap::milliseconds_since_epoch(_flight.start_time)).toString("yyyy MM dd - hh:mm:ss");
}
//-----------------------------------------------------------------------------
QString
AirMapFlightInfo::endTime()
{
return QDateTime::fromMSecsSinceEpoch((quint64)airmap::milliseconds_since_epoch(_flight.end_time)).toString("yyyy MM dd - hh:mm:ss");
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
AirMapFlightPlanManager::AirMapFlightPlanManager(AirMapSharedState& shared, QObject *parent) AirMapFlightPlanManager::AirMapFlightPlanManager(AirMapSharedState& shared, QObject *parent)
: AirspaceFlightPlanProvider(parent) : AirspaceFlightPlanProvider(parent)
...@@ -159,6 +180,113 @@ AirMapFlightPlanManager::updateFlightPlan() ...@@ -159,6 +180,113 @@ AirMapFlightPlanManager::updateFlightPlan()
_updateFlightPlan(); _updateFlightPlan();
} }
//-----------------------------------------------------------------------------
void
AirMapFlightPlanManager::deleteSelectedFlightPlans()
{
qCDebug(AirMapManagerLog) << "Delete flight plan";
_flightsToDelete.clear();
for(int i = 0; i < _flightList.count(); i++) {
AirspaceFlightInfo* pInfo = _flightList.get(i);
if(pInfo && pInfo->selected()) {
_flightsToDelete << pInfo->flightPlanID();
}
}
if(_flightsToDelete.count()) {
deleteFlightPlan(QString());
}
}
//-----------------------------------------------------------------------------
void
AirMapFlightPlanManager::deleteFlightPlan(QString flightPlanID)
{
qCDebug(AirMapManagerLog) << "Delete flight plan";
if(!flightPlanID.isEmpty()) {
_flightsToDelete.clear();
_flightsToDelete << flightPlanID;
}
if (_pilotID == "") {
//-- Need to get the pilot id
qCDebug(AirMapManagerLog) << "Getting pilot ID";
_state = State::GetPilotID;
std::weak_ptr<LifetimeChecker> isAlive(_instance);
_shared.doRequestWithLogin([this, isAlive](const QString& login_token) {
if (!isAlive.lock()) return;
Pilots::Authenticated::Parameters params;
params.authorization = login_token.toStdString();
_shared.client()->pilots().authenticated(params, [this, isAlive](const Pilots::Authenticated::Result& result) {
if (!isAlive.lock()) return;
if (_state != State::GetPilotID) return;
if (result) {
_pilotID = QString::fromStdString(result.value().id);
qCDebug(AirMapManagerLog) << "Got Pilot ID:"<<_pilotID;
_state = State::Idle;
_deleteFlightPlan();
} else {
_state = State::Idle;
QString description = QString::fromStdString(result.error().description() ? result.error().description().get() : "");
emit error("Failed to get pilot ID", QString::fromStdString(result.error().message()), description);
return;
}
});
});
} else {
_deleteFlightPlan();
}
}
//-----------------------------------------------------------------------------
void
AirMapFlightPlanManager::_deleteFlightPlan()
{
if(_flightsToDelete.count() < 1) {
qCDebug(AirMapManagerLog) << "Delete non existing flight plan";
return;
}
if(_state != State::Idle) {
QTimer::singleShot(100, this, &AirMapFlightPlanManager::_deleteFlightPlan);
return;
}
int idx = _flightList.findFlightPlanID(_flightsToDelete.last());
if(idx >= 0) {
AirspaceFlightInfo* pInfo = _flightList.get(idx);
if(pInfo) {
pInfo->setBeingDeleted(true);
}
}
qCDebug(AirMapManagerLog) << "Deleting flight plan:" << _flightsToDelete.last();
_state = State::FlightDelete;
std::weak_ptr<LifetimeChecker> isAlive(_instance);
FlightPlans::Delete::Parameters params;
params.authorization = _shared.loginToken().toStdString();
params.id = _flightsToDelete.last().toStdString();
//-- Delete flight plan
_shared.client()->flight_plans().delete_(params, [this, isAlive](const FlightPlans::Delete::Result& result) {
if (!isAlive.lock()) return;
if (_state != State::FlightDelete) return;
if (result) {
qCDebug(AirMapManagerLog) << "Flight plan deleted";
_flightList.remove(_flightsToDelete.last());
} else {
QString description = QString::fromStdString(result.error().description() ? result.error().description().get() : "");
emit error("Flight Plan deletion failed", QString::fromStdString(result.error().message()), description);
AirspaceFlightInfo* pFlight = _flightList.get(_flightList.findFlightPlanID(_flightsToDelete.last()));
if(pFlight) {
pFlight->setBeingDeleted(false);
}
}
_flightsToDelete.removeLast();
//-- Keep at it until all flights are deleted
// TODO: This is ineficient. These whole airmapd transactions need to be moved into a separate
// worker thread.
if(_flightsToDelete.count()) {
QTimer::singleShot(10, this, &AirMapFlightPlanManager::_deleteFlightPlan);
}
_state = State::Idle;
});
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
bool bool
AirMapFlightPlanManager::_collectFlightDtata() AirMapFlightPlanManager::_collectFlightDtata()
...@@ -250,6 +378,10 @@ void ...@@ -250,6 +378,10 @@ void
AirMapFlightPlanManager::_uploadFlightPlan() AirMapFlightPlanManager::_uploadFlightPlan()
{ {
qCDebug(AirMapManagerLog) << "Uploading flight plan"; qCDebug(AirMapManagerLog) << "Uploading flight plan";
if(_state != State::Idle) {
QTimer::singleShot(100, this, &AirMapFlightPlanManager::_uploadFlightPlan);
return;
}
_state = State::FlightUpload; _state = State::FlightUpload;
std::weak_ptr<LifetimeChecker> isAlive(_instance); std::weak_ptr<LifetimeChecker> isAlive(_instance);
_shared.doRequestWithLogin([this, isAlive](const QString& login_token) { _shared.doRequestWithLogin([this, isAlive](const QString& login_token) {
...@@ -262,16 +394,10 @@ AirMapFlightPlanManager::_uploadFlightPlan() ...@@ -262,16 +394,10 @@ AirMapFlightPlanManager::_uploadFlightPlan()
params.latitude = _flight.takeoffCoord.latitude(); params.latitude = _flight.takeoffCoord.latitude();
params.longitude = _flight.takeoffCoord.longitude(); params.longitude = _flight.takeoffCoord.longitude();
params.pilot.id = _pilotID.toStdString(); params.pilot.id = _pilotID.toStdString();
/* quint64 start = _flightStartTime.toUTC().toMSecsSinceEpoch();
quint64 end = _flightEndTime.toUTC().toMSecsSinceEpoch();
TODO: Convert this to fucking boost params.start_time = airmap::from_milliseconds_since_epoch(airmap::Milliseconds{(long long)start});
params.end_time = airmap::from_milliseconds_since_epoch(airmap::Milliseconds{(long long)end});
quint64 start = _flightStartTime.toUTC().toMSecsSinceEpoch();
quint64 end = _flightEndTime.toUTC().toMSecsSinceEpoch();
*/
params.start_time = Clock::universal_time() + Minutes{5};
params.end_time = Clock::universal_time() + Hours{2};
//-- Rules //-- Rules
AirMapRulesetsManager* pRulesMgr = dynamic_cast<AirMapRulesetsManager*>(qgcApp()->toolbox()->airspaceManager()->ruleSets()); AirMapRulesetsManager* pRulesMgr = dynamic_cast<AirMapRulesetsManager*>(qgcApp()->toolbox()->airspaceManager()->ruleSets());
if(pRulesMgr) { if(pRulesMgr) {
...@@ -345,12 +471,16 @@ AirMapFlightPlanManager::_updateFlightPlan() ...@@ -345,12 +471,16 @@ AirMapFlightPlanManager::_updateFlightPlan()
// little to do with those used when creating it. // little to do with those used when creating it.
qCDebug(AirMapManagerLog) << "Updating flight plan"; qCDebug(AirMapManagerLog) << "Updating flight plan";
if(_state != State::Idle) {
QTimer::singleShot(100, this, &AirMapFlightPlanManager::_updateFlightPlan);
return;
}
//-- Get flight data //-- Get flight data
if(!_collectFlightDtata()) { if(!_collectFlightDtata()) {
return; return;
} }
qCDebug(AirMapManagerLog) << "About to update the flight plan";
qCDebug(AirMapManagerLog) << "Takeoff: " << _flight.takeoffCoord; qCDebug(AirMapManagerLog) << "Takeoff: " << _flight.takeoffCoord;
qCDebug(AirMapManagerLog) << "Bounding box:" << _flight.bc.pointNW << _flight.bc.pointSE; qCDebug(AirMapManagerLog) << "Bounding box:" << _flight.bc.pointNW << _flight.bc.pointSE;
qCDebug(AirMapManagerLog) << "Flight Start:" << _flightStartTime; qCDebug(AirMapManagerLog) << "Flight Start:" << _flightStartTime;
...@@ -370,16 +500,10 @@ AirMapFlightPlanManager::_updateFlightPlan() ...@@ -370,16 +500,10 @@ AirMapFlightPlanManager::_updateFlightPlan()
params.flight_plan.buffer = 2.f; params.flight_plan.buffer = 2.f;
params.flight_plan.takeoff.latitude = _flight.takeoffCoord.latitude(); params.flight_plan.takeoff.latitude = _flight.takeoffCoord.latitude();
params.flight_plan.takeoff.longitude = _flight.takeoffCoord.longitude(); params.flight_plan.takeoff.longitude = _flight.takeoffCoord.longitude();
/* quint64 start = _flightStartTime.toUTC().toMSecsSinceEpoch();
quint64 end = _flightEndTime.toUTC().toMSecsSinceEpoch();
TODO: Convert this to fucking boost params.flight_plan.start_time = airmap::from_milliseconds_since_epoch(airmap::Milliseconds{(long long)start});
params.flight_plan.end_time = airmap::from_milliseconds_since_epoch(airmap::Milliseconds{(long long)end});
quint64 start = _flightStartTime.toUTC().toMSecsSinceEpoch();
quint64 end = _flightEndTime.toUTC().toMSecsSinceEpoch();
*/
params.flight_plan.start_time = Clock::universal_time() + Minutes{5};
params.flight_plan.end_time = Clock::universal_time() + Hours{2};
//-- Rules //-- Rules
/* /*
AirMapRulesetsManager* pRulesMgr = dynamic_cast<AirMapRulesetsManager*>(qgcApp()->toolbox()->airspaceManager()->ruleSets()); AirMapRulesetsManager* pRulesMgr = dynamic_cast<AirMapRulesetsManager*>(qgcApp()->toolbox()->airspaceManager()->ruleSets());
...@@ -566,36 +690,6 @@ AirMapFlightPlanManager::_pollBriefing() ...@@ -566,36 +690,6 @@ AirMapFlightPlanManager::_pollBriefing()
}); });
} }
//-----------------------------------------------------------------------------
void
AirMapFlightPlanManager::_deleteFlightPlan()
{
if(_flightPlan.isEmpty()) {
qCDebug(AirMapManagerLog) << "Delete non existing flight plan";
return;
}
qCDebug(AirMapManagerLog) << "Deleting flight plan";
_state = State::FlightDelete;
std::weak_ptr<LifetimeChecker> isAlive(_instance);
FlightPlans::Delete::Parameters params;
params.authorization = _shared.loginToken().toStdString();
params.id = _flightPlan.toStdString();
//-- Delete flight plan
_shared.client()->flight_plans().delete_(params, [this, isAlive](const FlightPlans::Delete::Result& result) {
if (!isAlive.lock()) return;
if (_state != State::FlightDelete) return;
if (result) {
_flightPlan.clear();
qCDebug(AirMapManagerLog) << "Flight plan deleted";
_state = State::Idle;
} else {
_state = State::Idle;
QString description = QString::fromStdString(result.error().description() ? result.error().description().get() : "");
emit error("Flight Plan deletion failed", QString::fromStdString(result.error().message()), description);
}
});
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
AirMapFlightPlanManager::_missionChanged() AirMapFlightPlanManager::_missionChanged()
...@@ -621,9 +715,16 @@ AirMapFlightPlanManager::_missionChanged() ...@@ -621,9 +715,16 @@ AirMapFlightPlanManager::_missionChanged()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
AirMapFlightPlanManager::loadFlightList() AirMapFlightPlanManager::loadFlightList(QDateTime startTime, QDateTime endTime)
{ {
qCDebug(AirMapManagerLog) << "Search flights"; //-- TODO: This is not checking if the state is Idle. Again, these need to
// queued up and handled by a worker thread.
qCDebug(AirMapManagerLog) << "Preparing load flight list";
_loadingFlightList = true;
emit loadingFlightListChanged();
_rangeStart = startTime;
_rangeEnd = endTime;
qCDebug(AirMapManagerLog) << "List flights from:" << _rangeStart.toString("yyyy MM dd - hh:mm:ss") << "to" << _rangeEnd.toString("yyyy MM dd - hh:mm:ss");
if (_pilotID == "") { if (_pilotID == "") {
//-- Need to get the pilot id //-- Need to get the pilot id
qCDebug(AirMapManagerLog) << "Getting pilot ID"; qCDebug(AirMapManagerLog) << "Getting pilot ID";
...@@ -645,6 +746,8 @@ AirMapFlightPlanManager::loadFlightList() ...@@ -645,6 +746,8 @@ AirMapFlightPlanManager::loadFlightList()
_state = State::Idle; _state = State::Idle;
QString description = QString::fromStdString(result.error().description() ? result.error().description().get() : ""); QString description = QString::fromStdString(result.error().description() ? result.error().description().get() : "");
emit error("Failed to get pilot ID", QString::fromStdString(result.error().message()), description); emit error("Failed to get pilot ID", QString::fromStdString(result.error().message()), description);
_loadingFlightList = false;
emit loadingFlightListChanged();
return; return;
} }
}); });
...@@ -658,6 +761,11 @@ AirMapFlightPlanManager::loadFlightList() ...@@ -658,6 +761,11 @@ AirMapFlightPlanManager::loadFlightList()
void void
AirMapFlightPlanManager::_loadFlightList() AirMapFlightPlanManager::_loadFlightList()
{ {
qCDebug(AirMapManagerLog) << "Load flight list";
if(_state != State::Idle) {
QTimer::singleShot(100, this, &AirMapFlightPlanManager::_loadFlightList);
return;
}
_flightList.clear(); _flightList.clear();
emit flightListChanged(); emit flightListChanged();
_state = State::LoadFlightList; _state = State::LoadFlightList;
...@@ -667,8 +775,13 @@ AirMapFlightPlanManager::_loadFlightList() ...@@ -667,8 +775,13 @@ AirMapFlightPlanManager::_loadFlightList()
if (_state != State::LoadFlightList) return; if (_state != State::LoadFlightList) return;
Flights::Search::Parameters params; Flights::Search::Parameters params;
params.authorization = login_token.toStdString(); params.authorization = login_token.toStdString();
params.limit = 60; quint64 start = _rangeStart.toUTC().toMSecsSinceEpoch();
quint64 end = _rangeEnd.toUTC().toMSecsSinceEpoch();
params.start_after = airmap::from_milliseconds_since_epoch(airmap::Milliseconds{(long long)start});
params.start_before = airmap::from_milliseconds_since_epoch(airmap::Milliseconds{(long long)end});
params.limit = 250;
params.pilot_id = _pilotID.toStdString(); params.pilot_id = _pilotID.toStdString();
qCDebug(AirMapManagerLog) << "List flights from:" << _rangeStart.toUTC().toString("yyyy MM dd - hh:mm:ss") << "to" << _rangeEnd.toUTC().toString("yyyy MM dd - hh:mm:ss");
_shared.client()->flights().search(params, [this, isAlive](const Flights::Search::Result& result) { _shared.client()->flights().search(params, [this, isAlive](const Flights::Search::Result& result) {
if (!isAlive.lock()) return; if (!isAlive.lock()) return;
if (_state != State::LoadFlightList) return; if (_state != State::LoadFlightList) return;
...@@ -686,6 +799,9 @@ AirMapFlightPlanManager::_loadFlightList() ...@@ -686,6 +799,9 @@ AirMapFlightPlanManager::_loadFlightList()
emit error("Flight search failed", QString::fromStdString(result.error().message()), description); emit error("Flight search failed", QString::fromStdString(result.error().message()), description);
} }
} }
_state = State::Idle;
_loadingFlightList = false;
emit loadingFlightListChanged();
}); });
}); });
} }
......
...@@ -29,10 +29,10 @@ class AirMapFlightInfo : public AirspaceFlightInfo ...@@ -29,10 +29,10 @@ class AirMapFlightInfo : public AirspaceFlightInfo
public: public:
AirMapFlightInfo (const airmap::Flight& flight, QObject *parent = nullptr); AirMapFlightInfo (const airmap::Flight& flight, QObject *parent = nullptr);
QString flightID () override { return QString::fromStdString(_flight.id); } QString flightID () override { return QString::fromStdString(_flight.id); }
QString flightPlanID () override { return QString::fromStdString(_flight.flight_plan_id.get()); } QString flightPlanID () override { return _flight.flight_plan_id ? QString::fromStdString(_flight.flight_plan_id.get()) : QString(); }
QString createdTime () override { return QDateTime::currentDateTime().toString(Qt::SystemLocaleShortDate); } //-- TODO: Need to get rid of boost first QString createdTime () override;
QString startTime () override { return QDateTime::currentDateTime().toString(Qt::SystemLocaleShortDate); } //-- TODO: Need to get rid of boost first QString startTime () override;
QString endTime () override { return QDateTime::currentDateTime().toString(Qt::SystemLocaleShortDate); } //-- TODO: Need to get rid of boost first QString endTime () override;
QGeoCoordinate takeOff () override { return QGeoCoordinate(_flight.latitude, _flight.longitude);} QGeoCoordinate takeOff () override { return QGeoCoordinate(_flight.latitude, _flight.longitude);}
QmlObjectListModel* boundingBox () override { return &_boundingBox; } QmlObjectListModel* boundingBox () override { return &_boundingBox; }
private: private:
...@@ -66,13 +66,17 @@ public: ...@@ -66,13 +66,17 @@ public:
QmlObjectListModel* rulesFollowing () override { return &_rulesFollowing; } QmlObjectListModel* rulesFollowing () override { return &_rulesFollowing; }
QmlObjectListModel* briefFeatures () override { return &_briefFeatures; } QmlObjectListModel* briefFeatures () override { return &_briefFeatures; }
AirspaceFlightModel*flightList () override { return &_flightList; } AirspaceFlightModel*flightList () override { return &_flightList; }
bool loadingFlightList () override { return _loadingFlightList; }
void updateFlightPlan () override; void updateFlightPlan () override;
void submitFlightPlan () override; void submitFlightPlan () override;
void startFlightPlanning (PlanMasterController* planController) override; void startFlightPlanning (PlanMasterController* planController) override;
void setFlightStartTime (QDateTime start) override; void setFlightStartTime (QDateTime start) override;
void setFlightEndTime (QDateTime end) override; void setFlightEndTime (QDateTime end) override;
void loadFlightList () override; void loadFlightList (QDateTime startTime, QDateTime endTime) override;
void deleteFlightPlan (QString flightPlanID) override;
void deleteSelectedFlightPlans() override;
signals: signals:
void error (const QString& what, const QString& airmapdMessage, const QString& airmapdDetails); void error (const QString& what, const QString& airmapdMessage, const QString& airmapdDetails);
...@@ -80,14 +84,14 @@ signals: ...@@ -80,14 +84,14 @@ signals:
private slots: private slots:
void _pollBriefing (); void _pollBriefing ();
void _missionChanged (); void _missionChanged ();
void _deleteFlightPlan ();
private:
void _uploadFlightPlan (); void _uploadFlightPlan ();
void _updateFlightPlan (); void _updateFlightPlan ();
void _loadFlightList ();
private:
void _createFlightPlan (); void _createFlightPlan ();
void _deleteFlightPlan ();
bool _collectFlightDtata (); bool _collectFlightDtata ();
void _loadFlightList ();
private: private:
enum class State { enum class State {
...@@ -121,8 +125,10 @@ private: ...@@ -121,8 +125,10 @@ private:
QString _flightPlan; ///< Current flight plan QString _flightPlan; ///< Current flight plan
QString _flightId; ///< Current flight ID, not necessarily accepted yet QString _flightId; ///< Current flight ID, not necessarily accepted yet
QString _pilotID; ///< Pilot ID in the form "auth0|abc123" QString _pilotID; ///< Pilot ID in the form "auth0|abc123"
QStringList _flightsToDelete;
PlanMasterController* _planController = nullptr; PlanMasterController* _planController = nullptr;
bool _valid = false; bool _valid = false;
bool _loadingFlightList = false;
QDateTime _flightStartTime; QDateTime _flightStartTime;
QDateTime _flightEndTime; QDateTime _flightEndTime;
QmlObjectListModel _advisories; QmlObjectListModel _advisories;
...@@ -133,6 +139,8 @@ private: ...@@ -133,6 +139,8 @@ private:
QmlObjectListModel _rulesFollowing; QmlObjectListModel _rulesFollowing;
QmlObjectListModel _briefFeatures; QmlObjectListModel _briefFeatures;
AirspaceFlightModel _flightList; AirspaceFlightModel _flightList;
QDateTime _rangeStart;
QDateTime _rangeEnd;
AirspaceAdvisoryProvider::AdvisoryColor _airspaceColor; AirspaceAdvisoryProvider::AdvisoryColor _airspaceColor;
AirspaceFlightPlanProvider::PermitStatus _flightPermitStatus = AirspaceFlightPlanProvider::PermitNone; AirspaceFlightPlanProvider::PermitStatus _flightPermitStatus = AirspaceFlightPlanProvider::PermitNone;
......
...@@ -37,8 +37,8 @@ AirMapManager::AirMapManager(QGCApplication* app, QGCToolbox* toolbox) ...@@ -37,8 +37,8 @@ AirMapManager::AirMapManager(QGCApplication* app, QGCToolbox* toolbox)
{ {
_logger = std::make_shared<qt::Logger>(); _logger = std::make_shared<qt::Logger>();
qt::register_types(); // TODO: still needed? qt::register_types(); // TODO: still needed?
_logger->logging_category().setEnabled(QtDebugMsg, false); _logger->logging_category().setEnabled(QtDebugMsg, true);
_logger->logging_category().setEnabled(QtInfoMsg, false); _logger->logging_category().setEnabled(QtInfoMsg, true);
_logger->logging_category().setEnabled(QtWarningMsg, true); _logger->logging_category().setEnabled(QtWarningMsg, true);
_dispatchingLogger = std::make_shared<qt::DispatchingLogger>(_logger); _dispatchingLogger = std::make_shared<qt::DispatchingLogger>(_logger);
connect(&_shared, &AirMapSharedState::error, this, &AirMapManager::_error); connect(&_shared, &AirMapSharedState::error, this, &AirMapManager::_error);
......
...@@ -125,6 +125,7 @@ QGCView { ...@@ -125,6 +125,7 @@ QGCView {
QGCLabel { text: qsTr("Email:") } QGCLabel { text: qsTr("Email:") }
FactTextField { FactTextField {
fact: _loginEmailFact fact: _loginEmailFact
width: _editFieldWidth
enabled: _airMapEnabled enabled: _airMapEnabled
visible: _loginEmailFact.visible visible: _loginEmailFact.visible
property Fact _loginEmailFact: QGroundControl.settingsManager.airMapSettings.loginEmail property Fact _loginEmailFact: QGroundControl.settingsManager.airMapSettings.loginEmail
...@@ -132,6 +133,7 @@ QGCView { ...@@ -132,6 +133,7 @@ QGCView {
QGCLabel { text: qsTr("Password:") } QGCLabel { text: qsTr("Password:") }
FactTextField { FactTextField {
fact: _loginPasswordFact fact: _loginPasswordFact
width: _editFieldWidth
enabled: _airMapEnabled enabled: _airMapEnabled
visible: _loginPasswordFact.visible visible: _loginPasswordFact.visible
property Fact _loginPasswordFact: QGroundControl.settingsManager.airMapSettings.loginPassword property Fact _loginPasswordFact: QGroundControl.settingsManager.airMapSettings.loginPassword
...@@ -225,13 +227,13 @@ QGCView { ...@@ -225,13 +227,13 @@ QGCView {
rowSpacing: ScreenTools.defaultFontPixelWidth * 0.25 rowSpacing: ScreenTools.defaultFontPixelWidth * 0.25
anchors.centerIn: parent anchors.centerIn: parent
QGCLabel { text: qsTr("API Key:") } QGCLabel { text: qsTr("API Key:") }
FactTextField { fact: QGroundControl.settingsManager.airMapSettings.apiKey; } FactTextField { fact: QGroundControl.settingsManager.airMapSettings.apiKey; width: _editFieldWidth; }
QGCLabel { text: qsTr("Client ID:") } QGCLabel { text: qsTr("Client ID:") }
FactTextField { fact: QGroundControl.settingsManager.airMapSettings.clientID; } FactTextField { fact: QGroundControl.settingsManager.airMapSettings.clientID; width: _editFieldWidth; }
QGCLabel { text: qsTr("User Name:") } QGCLabel { text: qsTr("User Name:") }
FactTextField { fact: QGroundControl.settingsManager.airMapSettings.userName; } FactTextField { fact: QGroundControl.settingsManager.airMapSettings.userName; width: _editFieldWidth; }
QGCLabel { text: qsTr("Password:") } QGCLabel { text: qsTr("Password:") }
FactTextField { fact: QGroundControl.settingsManager.airMapSettings.password; echoMode: TextInput.Password } FactTextField { fact: QGroundControl.settingsManager.airMapSettings.password; width: _editFieldWidth; echoMode: TextInput.Password }
} }
} }
//----------------------------------------------------------------- //-----------------------------------------------------------------
...@@ -283,16 +285,8 @@ QGCView { ...@@ -283,16 +285,8 @@ QGCView {
width: _qgcView.width width: _qgcView.width
height: _qgcView.height height: _qgcView.height
color: qgcPal.window color: qgcPal.window
property var _flightList: QGroundControl.airspaceManager.flightPlan.flightList property var _flightList: QGroundControl.airspaceManager.flightPlan.flightList
Component.onCompleted: { property real _mapWidth: ScreenTools.defaultFontPixelWidth * 40
QGroundControl.airspaceManager.flightPlan.loadFlightList()
}
Connections {
target: _flightList
onCountChanged: {
tableView.resizeColumnsToContents()
}
}
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
...@@ -300,6 +294,18 @@ QGCView { ...@@ -300,6 +294,18 @@ QGCView {
onPressed: { mouse.accepted = true; } onPressed: { mouse.accepted = true; }
onReleased: { mouse.accepted = true; } onReleased: { mouse.accepted = true; }
} }
function updateSelection() {
//-- Clear selection
for(var i = 0; i < _flightList.count; i++) {
var o = _flightList.get(i)
if (o) o.selected = false
}
//-- Flag selected flights
tableView.selection.forEach(function(rowIndex){
var o = _flightList.get(rowIndex)
if (o) o.selected = true
})
}
//--------------------------------------------------------- //---------------------------------------------------------
//-- Flight List //-- Flight List
RowLayout { RowLayout {
...@@ -312,8 +318,20 @@ QGCView { ...@@ -312,8 +318,20 @@ QGCView {
selectionMode: SelectionMode.MultiSelection selectionMode: SelectionMode.MultiSelection
Layout.fillWidth: true Layout.fillWidth: true
TableViewColumn { TableViewColumn {
title: qsTr("Created") title: qsTr("No")
width: ScreenTools.defaultFontPixelWidth * 20 width: ScreenTools.defaultFontPixelWidth * 3
horizontalAlignment: Text.AlignHCenter
delegate : Text {
horizontalAlignment: Text.AlignHCenter
text: (styleData.row + 1)
color: tableView.currentRow === styleData.row ? qgcPal.colorBlue : "black"
font.family: ScreenTools.fixedFontFamily
font.pixelSize: ScreenTools.smallFontPointSize
}
}
TableViewColumn {
title: qsTr("Created")
width: ScreenTools.defaultFontPixelWidth * 20
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
delegate : Text { delegate : Text {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
...@@ -321,11 +339,14 @@ QGCView { ...@@ -321,11 +339,14 @@ QGCView {
var o = _flightList.get(styleData.row) var o = _flightList.get(styleData.row)
return o ? o.createdTime : "" return o ? o.createdTime : ""
} }
color: tableView.currentRow === styleData.row ? qgcPal.colorBlue : "black"
font.family: ScreenTools.fixedFontFamily
font.pixelSize: ScreenTools.smallFontPointSize
} }
} }
TableViewColumn { TableViewColumn {
title: qsTr("Flight Start") title: qsTr("Flight Start")
width: ScreenTools.defaultFontPixelWidth * 20 width: ScreenTools.defaultFontPixelWidth * 20
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
delegate : Text { delegate : Text {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
...@@ -333,33 +354,126 @@ QGCView { ...@@ -333,33 +354,126 @@ QGCView {
var o = _flightList.get(styleData.row) var o = _flightList.get(styleData.row)
return o ? o.startTime : "" return o ? o.startTime : ""
} }
color: tableView.currentRow === styleData.row ? qgcPal.colorBlue : "black"
font.family: ScreenTools.fixedFontFamily
font.pixelSize: ScreenTools.smallFontPointSize
} }
} }
TableViewColumn { TableViewColumn {
title: qsTr("Take Off") title: qsTr("State")
width: ScreenTools.defaultFontPixelWidth * 22 width: ScreenTools.defaultFontPixelWidth * 22
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
delegate : Text { delegate : Text {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
text: { text: {
var o = _flightList.get(styleData.row) var o = _flightList.get(styleData.row)
return o ? o.takeOff.latitude.toFixed(6) + ', ' + o.takeOff.longitude.toFixed(6) : "" return o ? (o.beingDeleted ? qsTr("Deleting") : qsTr("Valid")) : qsTr("Unknown")
} }
color: tableView.currentRow === styleData.row ? qgcPal.colorBlue : "black"
font.family: ScreenTools.fixedFontFamily
font.pixelSize: ScreenTools.smallFontPointSize
} }
} }
} }
Item { Item {
width: map.width width: flightListRoot._mapWidth
height: parent.height height: parent.height
Layout.alignment: Qt.AlignTop | Qt.AlignLeft Layout.alignment: Qt.AlignTop | Qt.AlignLeft
QGCLabel {
id: loadingLabel
text: qsTr("Loading Flight List")
visible: QGroundControl.airspaceManager.flightPlan.loadingFlightList
anchors.centerIn: parent
}
QGCColoredImage {
id: busyIndicator
height: ScreenTools.defaultFontPixelHeight * 2.5
width: height
source: "/qmlimages/MapSync.svg"
sourceSize.height: height
fillMode: Image.PreserveAspectFit
mipmap: true
smooth: true
color: qgcPal.colorGreen
visible: loadingLabel.visible
anchors.top: loadingLabel.bottom
anchors.topMargin: ScreenTools.defaultFontPixelHeight
anchors.horizontalCenter: parent.horizontalCenter
RotationAnimation on rotation {
loops: Animation.Infinite
from: 360
to: 0
duration: 740
running: busyIndicator.visible
}
}
Column { Column {
spacing: ScreenTools.defaultFontPixelHeight spacing: ScreenTools.defaultFontPixelHeight * 0.75
visible: !QGroundControl.airspaceManager.flightPlan.loadingFlightList
anchors.top: parent.top anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
QGCLabel { QGCLabel {
text: qsTr("Flight List") text: qsTr("Flight List")
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
} }
Rectangle {
color: qgcPal.window
border.color: qgcPal.globalTheme === QGCPalette.Dark ? Qt.rgba(1,1,1,0.25) : Qt.rgba(0,0,0,0.25)
border.width: 1
radius: 4
width: _mapWidth - (ScreenTools.defaultFontPixelWidth * 2)
height: rangeCol.height + (ScreenTools.defaultFontPixelHeight * 2)
Column {
id: rangeCol
anchors.centerIn: parent
spacing: ScreenTools.defaultFontPixelHeight * 0.5
QGCLabel {
text: qsTr("Range")
anchors.horizontalCenter: parent.horizontalCenter
}
Row {
spacing: ScreenTools.defaultFontPixelWidth * 2
anchors.horizontalCenter: parent.horizontalCenter
Column {
spacing: ScreenTools.defaultFontPixelHeight * 0.5
QGCButton {
text: qsTr("From")
backRadius: 4
heightFactor: 0.3333
showBorder: true
width: _buttonWidth * 0.5
onClicked: fromPicker.visible = true
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
anchors.horizontalCenter: parent.horizontalCenter
text: fromPicker.selectedDate.toLocaleDateString(Qt.locale())
}
}
Rectangle {
width: 1
height: parent.height
color: qgcPal.globalTheme === QGCPalette.Dark ? Qt.rgba(1,1,1,0.25) : Qt.rgba(0,0,0,0.25)
}
Column {
spacing: ScreenTools.defaultFontPixelHeight * 0.5
QGCButton {
text: qsTr("To")
backRadius: 4
heightFactor: 0.3333
showBorder: true
width: _buttonWidth * 0.5
onClicked: toPicker.visible = true
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
anchors.horizontalCenter: parent.horizontalCenter
text: toPicker.selectedDate.toLocaleDateString(Qt.locale())
}
}
}
}
}
QGCButton { QGCButton {
text: qsTr("Refresh") text: qsTr("Refresh")
backRadius: 4 backRadius: 4
...@@ -369,7 +483,11 @@ QGCView { ...@@ -369,7 +483,11 @@ QGCView {
enabled: true enabled: true
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
onClicked: { onClicked: {
QGroundControl.airspaceManager.flightPlan.loadFlightList() var start = fromPicker.selectedDate
var end = toPicker.selectedDate
start.setHours(0,0,0,0)
end.setHours(23,59,59,0)
QGroundControl.airspaceManager.flightPlan.loadFlightList(start, end)
} }
} }
QGCButton { QGCButton {
...@@ -402,20 +520,11 @@ QGCView { ...@@ -402,20 +520,11 @@ QGCView {
heightFactor: 0.3333 heightFactor: 0.3333
showBorder: true showBorder: true
width: _buttonWidth width: _buttonWidth
enabled: false enabled: tableView.selection.count > 0
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
onClicked: { onClicked: {
//-- Clear selection flightListRoot.updateSelection();
for(var i = 0; i < _flightList.count; i++) { QGroundControl.airspaceManager.flightPlan.deleteSelectedFlightPlans()
var o = _flightList.get(i)
if (o) o.selected = false
}
//-- Flag selected flights
tableView.selection.forEach(function(rowIndex){
var o = _flightList.get(rowIndex)
if (o) o.selected = true
})
//TODO:
} }
} }
QGCButton { QGCButton {
...@@ -429,9 +538,21 @@ QGCView { ...@@ -429,9 +538,21 @@ QGCView {
panelLoader.sourceComponent = null panelLoader.sourceComponent = null
} }
} }
QGCLabel {
text: _flightList.count > 0 ? tableView.selection.count + '/' + _flightList.count + qsTr(" Flights Selected") : qsTr("No Flights Loaded")
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
text: qsTr("A maximum of 250 flights were loaded")
color: qgcPal.colorOrange
font.pixelSize: ScreenTools.smallFontPointSize
visible: _flightList.count >= 250
anchors.horizontalCenter: parent.horizontalCenter
}
} }
QGCLabel { QGCLabel {
text: qsTr("Flight Area") text: qsTr("Flight Area ") + (tableView.currentRow + 1)
visible: !QGroundControl.airspaceManager.flightPlan.loadingFlightList && _flightList.count > 0 && tableView.currentRow >= 0
anchors.bottom: map.top anchors.bottom: map.top
anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * 0.25 anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * 0.25
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
...@@ -446,6 +567,7 @@ QGCView { ...@@ -446,6 +567,7 @@ QGCView {
center: QGroundControl.flightMapPosition center: QGroundControl.flightMapPosition
gesture.acceptedGestures: MapGestureArea.PinchGesture gesture.acceptedGestures: MapGestureArea.PinchGesture
plugin: Plugin { name: "QGroundControl" } plugin: Plugin { name: "QGroundControl" }
visible: !QGroundControl.airspaceManager.flightPlan.loadingFlightList && _flightList.count > 0 && tableView.currentRow >= 0
function updateActiveMapType() { function updateActiveMapType() {
var settings = QGroundControl.settingsManager.flightMapSettings var settings = QGroundControl.settingsManager.flightMapSettings
var fullMapName = settings.mapProvider.enumStringValue + " " + settings.mapType.enumStringValue var fullMapName = settings.mapProvider.enumStringValue + " " + settings.mapType.enumStringValue
...@@ -470,6 +592,23 @@ QGCView { ...@@ -470,6 +592,23 @@ QGCView {
} }
} }
Calendar {
id: fromPicker
anchors.centerIn: parent
visible: false;
onClicked: {
visible = false;
}
}
Calendar {
id: toPicker
anchors.centerIn: parent
visible: false;
minimumDate: fromPicker.selectedDate
onClicked: {
visible = false;
}
}
} }
} }
} }
......
...@@ -7,12 +7,14 @@ ...@@ -7,12 +7,14 @@
* *
****************************************************************************/ ****************************************************************************/
#include "AirspaceManager.h"
#include "AirspaceFlightPlanProvider.h" #include "AirspaceFlightPlanProvider.h"
#include <QQmlEngine> #include <QQmlEngine>
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
AirspaceFlightInfo::AirspaceFlightInfo(QObject *parent) AirspaceFlightInfo::AirspaceFlightInfo(QObject *parent)
: QObject(parent) : QObject(parent)
, _beingDeleted(false)
, _selected(false) , _selected(false)
{ {
} }
...@@ -40,6 +42,18 @@ AirspaceFlightModel::get(int index) ...@@ -40,6 +42,18 @@ AirspaceFlightModel::get(int index)
return _flightEntries[index]; return _flightEntries[index];
} }
//-----------------------------------------------------------------------------
int
AirspaceFlightModel::findFlightPlanID(QString flightPlanID)
{
for(int i = 0; i < _flightEntries.count(); i++) {
if(_flightEntries[i]->flightPlanID() == flightPlanID) {
return i;
}
}
return -1;
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
int int
AirspaceFlightModel::count() const AirspaceFlightModel::count() const
...@@ -58,6 +72,30 @@ AirspaceFlightModel::append(AirspaceFlightInfo* object) ...@@ -58,6 +72,30 @@ AirspaceFlightModel::append(AirspaceFlightInfo* object)
emit countChanged(); emit countChanged();
} }
//-----------------------------------------------------------------------------
void
AirspaceFlightModel::remove(const QString& flightPlanID)
{
remove(findFlightPlanID(flightPlanID));
}
//-----------------------------------------------------------------------------
void
AirspaceFlightModel::remove(int index)
{
if (index >= 0 && index < _flightEntries.count()) {
beginRemoveRows(QModelIndex(), index, index);
AirspaceFlightInfo* entry = _flightEntries[index];
if(entry) {
qCDebug(AirspaceManagementLog) << "Deleting flight plan" << entry->flightPlanID();
entry->deleteLater();
}
_flightEntries.removeAt(index);
endRemoveRows();
emit countChanged();
}
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
AirspaceFlightModel::clear(void) AirspaceFlightModel::clear(void)
......
...@@ -38,7 +38,8 @@ public: ...@@ -38,7 +38,8 @@ public:
Q_PROPERTY(QString endTime READ endTime CONSTANT) Q_PROPERTY(QString endTime READ endTime CONSTANT)
Q_PROPERTY(QGeoCoordinate takeOff READ takeOff CONSTANT) Q_PROPERTY(QGeoCoordinate takeOff READ takeOff CONSTANT)
Q_PROPERTY(QmlObjectListModel* boundingBox READ boundingBox CONSTANT) Q_PROPERTY(QmlObjectListModel* boundingBox READ boundingBox CONSTANT)
Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectedChanged) Q_PROPERTY(bool beingDeleted READ beingDeleted WRITE setBeingDeleted NOTIFY beingDeletedChanged)
Q_PROPERTY(bool selected READ selected WRITE setSelected NOTIFY selectedChanged)
virtual QString flightID () = 0; virtual QString flightID () = 0;
virtual QString flightPlanID () = 0; virtual QString flightPlanID () = 0;
...@@ -48,13 +49,17 @@ public: ...@@ -48,13 +49,17 @@ public:
virtual QGeoCoordinate takeOff () = 0; virtual QGeoCoordinate takeOff () = 0;
virtual QmlObjectListModel* boundingBox () = 0; virtual QmlObjectListModel* boundingBox () = 0;
virtual bool beingDeleted () { return _beingDeleted; }
virtual void setBeingDeleted (bool val) { _beingDeleted = val; emit beingDeletedChanged(); }
virtual bool selected () { return _selected; } virtual bool selected () { return _selected; }
virtual void setSelected (bool sel) { _selected = sel; emit selectedChanged(); } virtual void setSelected (bool sel) { _selected = sel; emit selectedChanged(); }
signals: signals:
void selectedChanged (); void selectedChanged ();
void beingDeletedChanged ();
protected: protected:
bool _beingDeleted;
bool _selected; bool _selected;
}; };
...@@ -71,10 +76,14 @@ public: ...@@ -71,10 +76,14 @@ public:
AirspaceFlightModel(QObject *parent = 0); AirspaceFlightModel(QObject *parent = 0);
Q_PROPERTY(int count READ count NOTIFY countChanged) Q_PROPERTY(int count READ count NOTIFY countChanged)
Q_INVOKABLE AirspaceFlightInfo* get(int index);
Q_INVOKABLE AirspaceFlightInfo* get (int index);
Q_INVOKABLE int findFlightPlanID (QString flightPlanID);
int count (void) const; int count (void) const;
void append (AirspaceFlightInfo *entry); void append (AirspaceFlightInfo *entry);
void remove (const QString& flightPlanID);
void remove (int index);
void clear (void); void clear (void);
AirspaceFlightInfo* AirspaceFlightInfo*
...@@ -124,11 +133,14 @@ public: ...@@ -124,11 +133,14 @@ public:
Q_PROPERTY(QmlObjectListModel* rulesFollowing READ rulesFollowing NOTIFY rulesChanged) Q_PROPERTY(QmlObjectListModel* rulesFollowing READ rulesFollowing NOTIFY rulesChanged)
Q_PROPERTY(QmlObjectListModel* briefFeatures READ briefFeatures NOTIFY rulesChanged) Q_PROPERTY(QmlObjectListModel* briefFeatures READ briefFeatures NOTIFY rulesChanged)
Q_PROPERTY(AirspaceFlightModel* flightList READ flightList NOTIFY flightListChanged) Q_PROPERTY(AirspaceFlightModel* flightList READ flightList NOTIFY flightListChanged)
Q_PROPERTY(bool loadingFlightList READ loadingFlightList NOTIFY loadingFlightListChanged)
//-- TODO: This will submit the current flight plan in memory. //-- TODO: This will submit the current flight plan in memory.
Q_INVOKABLE virtual void submitFlightPlan () = 0; Q_INVOKABLE virtual void submitFlightPlan () = 0;
Q_INVOKABLE virtual void updateFlightPlan () = 0; Q_INVOKABLE virtual void updateFlightPlan () = 0;
Q_INVOKABLE virtual void loadFlightList () = 0; Q_INVOKABLE virtual void loadFlightList (QDateTime startTime, QDateTime endTime) = 0;
Q_INVOKABLE virtual void deleteFlightPlan (QString flighPlanID) = 0;
Q_INVOKABLE virtual void deleteSelectedFlightPlans () = 0;
virtual PermitStatus flightPermitStatus () const { return PermitNone; } virtual PermitStatus flightPermitStatus () const { return PermitNone; }
virtual QDateTime flightStartTime () const = 0; virtual QDateTime flightStartTime () const = 0;
...@@ -145,6 +157,7 @@ public: ...@@ -145,6 +157,7 @@ public:
virtual QmlObjectListModel* rulesFollowing () = 0; ///< List of AirspaceRule following virtual QmlObjectListModel* rulesFollowing () = 0; ///< List of AirspaceRule following
virtual QmlObjectListModel* briefFeatures () = 0; ///< List of AirspaceRule in violation virtual QmlObjectListModel* briefFeatures () = 0; ///< List of AirspaceRule in violation
virtual AirspaceFlightModel*flightList () = 0; ///< List of AirspaceFlightInfo virtual AirspaceFlightModel*flightList () = 0; ///< List of AirspaceFlightInfo
virtual bool loadingFlightList () = 0;
virtual void setFlightStartTime (QDateTime start) = 0; virtual void setFlightStartTime (QDateTime start) = 0;
virtual void setFlightEndTime (QDateTime end) = 0; virtual void setFlightEndTime (QDateTime end) = 0;
...@@ -158,4 +171,5 @@ signals: ...@@ -158,4 +171,5 @@ signals:
void missionAreaChanged (); void missionAreaChanged ();
void rulesChanged (); void rulesChanged ();
void flightListChanged (); void flightListChanged ();
void loadingFlightListChanged ();
}; };
...@@ -32,7 +32,7 @@ QGCTextField { ...@@ -32,7 +32,7 @@ QGCTextField {
} }
if (typeof qgcView !== 'undefined' && qgcView) { if (typeof qgcView !== 'undefined' && qgcView) {
var errorString = fact.validate(text, false /* convertOnly */) var errorString = fact.validate(text, false /* convertOnly */)
if (errorString == "") { if (errorString === "") {
fact.value = text fact.value = text
} else { } else {
_validateString = text _validateString = text
......
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