mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-12-12 20:08:48 +01:00
353 lines
14 KiB
C++
353 lines
14 KiB
C++
/**
|
|
******************************************************************************
|
|
*
|
|
* @file modelmapproxy.cpp
|
|
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
|
|
* @addtogroup GCSPlugins GCS Plugins
|
|
* @{
|
|
* @addtogroup OPMapPlugin OpenPilot Map Plugin
|
|
* @{
|
|
* @brief The OpenPilot Map plugin
|
|
*****************************************************************************/
|
|
/*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along
|
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include "modelmapproxy.h"
|
|
|
|
modelMapProxy::modelMapProxy(QObject *parent, OPMapWidget *map, flightDataModel *model, QItemSelectionModel *selectionModel) : QObject(parent), myMap(map), model(model), selection(selectionModel)
|
|
{
|
|
connect(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(rowsInserted(const QModelIndex &, int, int)));
|
|
connect(model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(rowsRemoved(const QModelIndex &, int, int)));
|
|
connect(selection, SIGNAL(currentRowChanged(QModelIndex, QModelIndex)), this, SLOT(currentRowChanged(QModelIndex, QModelIndex)));
|
|
connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(dataChanged(QModelIndex, QModelIndex)));
|
|
connect(myMap, SIGNAL(selectedWPChanged(QList<WayPointItem *>)), this, SLOT(selectedWPChanged(QList<WayPointItem *>)));
|
|
connect(myMap, SIGNAL(WPValuesChanged(WayPointItem *)), this, SLOT(WPValuesChanged(WayPointItem *)));
|
|
}
|
|
|
|
void modelMapProxy::WPValuesChanged(WayPointItem *wp)
|
|
{
|
|
QModelIndex index;
|
|
|
|
index = model->index(wp->Number(), flightDataModel::LATPOSITION);
|
|
if (!index.isValid()) {
|
|
return;
|
|
}
|
|
model->setData(index, wp->Coord().Lat(), Qt::EditRole);
|
|
index = model->index(wp->Number(), flightDataModel::LNGPOSITION);
|
|
model->setData(index, wp->Coord().Lng(), Qt::EditRole);
|
|
|
|
index = model->index(wp->Number(), flightDataModel::ALTITUDE);
|
|
model->setData(index, wp->Altitude(), Qt::EditRole);
|
|
|
|
index = model->index(wp->Number(), flightDataModel::DISRELATIVE);
|
|
model->setData(index, wp->getRelativeCoord().distance, Qt::EditRole);
|
|
index = model->index(wp->Number(), flightDataModel::BEARELATIVE);
|
|
model->setData(index, wp->getRelativeCoord().bearingToDegrees(), Qt::EditRole);
|
|
index = model->index(wp->Number(), flightDataModel::ALTITUDERELATIVE);
|
|
model->setData(index, wp->getRelativeCoord().altitudeRelative, Qt::EditRole);
|
|
}
|
|
|
|
void modelMapProxy::currentRowChanged(QModelIndex current, QModelIndex previous)
|
|
{
|
|
Q_UNUSED(previous);
|
|
|
|
QList<WayPointItem *> list;
|
|
WayPointItem *wp = findWayPointNumber(current.row());
|
|
if (!wp) {
|
|
return;
|
|
}
|
|
list.append(wp);
|
|
myMap->setSelectedWP(list);
|
|
}
|
|
|
|
void modelMapProxy::selectedWPChanged(QList<WayPointItem *> list)
|
|
{
|
|
selection->clearSelection();
|
|
foreach(WayPointItem * wp, list) {
|
|
QModelIndex index = model->index(wp->Number(), 0);
|
|
|
|
selection->setCurrentIndex(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
|
}
|
|
}
|
|
|
|
modelMapProxy::overlayType modelMapProxy::overlayTranslate(int type)
|
|
{
|
|
switch (type) {
|
|
case MapDataDelegate::MODE_FLYENDPOINT:
|
|
case MapDataDelegate::MODE_FLYVECTOR:
|
|
case MapDataDelegate::MODE_DRIVEENDPOINT:
|
|
case MapDataDelegate::MODE_DRIVEVECTOR:
|
|
return OVERLAY_LINE;
|
|
|
|
case MapDataDelegate::MODE_FLYCIRCLERIGHT:
|
|
case MapDataDelegate::MODE_DRIVECIRCLERIGHT:
|
|
return OVERLAY_CIRCLE_RIGHT;
|
|
|
|
case MapDataDelegate::MODE_FLYCIRCLELEFT:
|
|
case MapDataDelegate::MODE_DRIVECIRCLELEFT:
|
|
default:
|
|
return OVERLAY_CIRCLE_LEFT;
|
|
}
|
|
}
|
|
|
|
void modelMapProxy::createOverlay(WayPointItem *from, WayPointItem *to, modelMapProxy::overlayType type, QColor color)
|
|
{
|
|
if (from == NULL || to == NULL || from == to) {
|
|
return;
|
|
}
|
|
switch (type) {
|
|
case OVERLAY_LINE:
|
|
myMap->WPLineCreate(from, to, color);
|
|
break;
|
|
case OVERLAY_CIRCLE_RIGHT:
|
|
myMap->WPCircleCreate(to, from, true, color);
|
|
break;
|
|
case OVERLAY_CIRCLE_LEFT:
|
|
myMap->WPCircleCreate(to, from, false, color);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
void modelMapProxy::createOverlay(WayPointItem *from, HomeItem *to, modelMapProxy::overlayType type, QColor color)
|
|
{
|
|
if (from == NULL || to == NULL) {
|
|
return;
|
|
}
|
|
switch (type) {
|
|
case OVERLAY_LINE:
|
|
myMap->WPLineCreate(to, from, color);
|
|
break;
|
|
case OVERLAY_CIRCLE_RIGHT:
|
|
myMap->WPCircleCreate(to, from, true, color);
|
|
break;
|
|
case OVERLAY_CIRCLE_LEFT:
|
|
myMap->WPCircleCreate(to, from, false, color);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
void modelMapProxy::refreshOverlays()
|
|
{
|
|
myMap->deleteAllOverlays();
|
|
if (model->rowCount() < 1) {
|
|
return;
|
|
}
|
|
WayPointItem *wp_current = NULL;
|
|
WayPointItem *wp_next = NULL;
|
|
int wp_jump;
|
|
int wp_error;
|
|
overlayType wp_next_overlay;
|
|
overlayType wp_jump_overlay;
|
|
overlayType wp_error_overlay;
|
|
wp_current = findWayPointNumber(0);
|
|
overlayType wp_current_overlay = overlayTranslate(model->data(model->index(0, flightDataModel::MODE)).toInt());
|
|
createOverlay(wp_current, myMap->Home, wp_current_overlay, Qt::green);
|
|
for (int x = 0; x < model->rowCount(); ++x) {
|
|
wp_current = findWayPointNumber(x);
|
|
wp_jump = model->data(model->index(x, flightDataModel::JUMPDESTINATION)).toInt() - 1;
|
|
wp_error = model->data(model->index(x, flightDataModel::ERRORDESTINATION)).toInt() - 1;
|
|
wp_next_overlay = overlayTranslate(model->data(model->index(x + 1, flightDataModel::MODE)).toInt());
|
|
wp_jump_overlay = overlayTranslate(model->data(model->index(wp_jump, flightDataModel::MODE)).toInt());
|
|
wp_error_overlay = overlayTranslate(model->data(model->index(wp_error, flightDataModel::MODE)).toInt());
|
|
createOverlay(wp_current, findWayPointNumber(wp_error), wp_error_overlay, Qt::red);
|
|
switch (model->data(model->index(x, flightDataModel::COMMAND)).toInt()) {
|
|
case MapDataDelegate::COMMAND_ONCONDITIONNEXTWAYPOINT:
|
|
wp_next = findWayPointNumber(x + 1);
|
|
createOverlay(wp_current, wp_next, wp_next_overlay, Qt::green);
|
|
break;
|
|
case MapDataDelegate::COMMAND_ONCONDITIONJUMPWAYPOINT:
|
|
wp_next = findWayPointNumber(wp_jump);
|
|
createOverlay(wp_current, wp_next, wp_jump_overlay, Qt::green);
|
|
break;
|
|
case MapDataDelegate::COMMAND_ONNOTCONDITIONJUMPWAYPOINT:
|
|
wp_next = findWayPointNumber(wp_jump);
|
|
createOverlay(wp_current, wp_next, wp_jump_overlay, Qt::yellow);
|
|
break;
|
|
case MapDataDelegate::COMMAND_ONNOTCONDITIONNEXTWAYPOINT:
|
|
wp_next = findWayPointNumber(x + 1);
|
|
createOverlay(wp_current, wp_next, wp_next_overlay, Qt::yellow);
|
|
break;
|
|
case MapDataDelegate::COMMAND_IFCONDITIONJUMPWAYPOINTELSENEXTWAYPOINT:
|
|
wp_next = findWayPointNumber(wp_jump);
|
|
createOverlay(wp_current, wp_next, wp_jump_overlay, Qt::green);
|
|
wp_next = findWayPointNumber(x + 1);
|
|
createOverlay(wp_current, wp_next, wp_next_overlay, Qt::green);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
WayPointItem *modelMapProxy::findWayPointNumber(int number)
|
|
{
|
|
if (number < 0) {
|
|
return NULL;
|
|
}
|
|
return myMap->WPFind(number);
|
|
}
|
|
|
|
void modelMapProxy::rowsRemoved(const QModelIndex &parent, int first, int last)
|
|
{
|
|
Q_UNUSED(parent);
|
|
|
|
for (int x = last; x > first - 1; x--) {
|
|
myMap->WPDelete(x);
|
|
}
|
|
refreshOverlays();
|
|
}
|
|
|
|
void modelMapProxy::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
|
|
{
|
|
Q_UNUSED(bottomRight);
|
|
|
|
WayPointItem *item = findWayPointNumber(topLeft.row());
|
|
if (!item) {
|
|
return;
|
|
}
|
|
internals::PointLatLng latlng;
|
|
int x = topLeft.row();
|
|
distBearingAltitude distBearing;
|
|
double altitude;
|
|
bool relative;
|
|
QModelIndex index;
|
|
QString desc;
|
|
switch (topLeft.column()) {
|
|
case flightDataModel::COMMAND:
|
|
case flightDataModel::CONDITION:
|
|
case flightDataModel::JUMPDESTINATION:
|
|
case flightDataModel::ERRORDESTINATION:
|
|
case flightDataModel::MODE:
|
|
refreshOverlays();
|
|
break;
|
|
case flightDataModel::WPDESCRITPTION:
|
|
index = model->index(x, flightDataModel::WPDESCRITPTION);
|
|
desc = index.data(Qt::DisplayRole).toString();
|
|
item->SetDescription(desc);
|
|
break;
|
|
case flightDataModel::LATPOSITION:
|
|
latlng = item->Coord();
|
|
index = model->index(x, flightDataModel::LATPOSITION);
|
|
latlng.SetLat(index.data(Qt::DisplayRole).toDouble());
|
|
item->SetCoord(latlng);
|
|
break;
|
|
case flightDataModel::LNGPOSITION:
|
|
latlng = item->Coord();
|
|
index = model->index(x, flightDataModel::LNGPOSITION);
|
|
latlng.SetLng(index.data(Qt::DisplayRole).toDouble());
|
|
item->SetCoord(latlng);
|
|
break;
|
|
case flightDataModel::BEARELATIVE:
|
|
distBearing = item->getRelativeCoord();
|
|
index = model->index(x, flightDataModel::BEARELATIVE);
|
|
distBearing.setBearingFromDegrees(index.data(Qt::DisplayRole).toDouble());
|
|
item->setRelativeCoord(distBearing);
|
|
break;
|
|
case flightDataModel::DISRELATIVE:
|
|
distBearing = item->getRelativeCoord();
|
|
index = model->index(x, flightDataModel::DISRELATIVE);
|
|
distBearing.distance = index.data(Qt::DisplayRole).toDouble();
|
|
item->setRelativeCoord(distBearing);
|
|
break;
|
|
case flightDataModel::ALTITUDERELATIVE:
|
|
distBearing = item->getRelativeCoord();
|
|
index = model->index(x, flightDataModel::ALTITUDERELATIVE);
|
|
distBearing.altitudeRelative = index.data(Qt::DisplayRole).toFloat();
|
|
item->setRelativeCoord(distBearing);
|
|
break;
|
|
case flightDataModel::ISRELATIVE:
|
|
index = model->index(x, flightDataModel::ISRELATIVE);
|
|
relative = index.data(Qt::DisplayRole).toBool();
|
|
if (relative) {
|
|
item->setWPType(mapcontrol::WayPointItem::relative);
|
|
} else {
|
|
item->setWPType(mapcontrol::WayPointItem::absolute);
|
|
}
|
|
break;
|
|
case flightDataModel::ALTITUDE:
|
|
index = model->index(x, flightDataModel::ALTITUDE);
|
|
altitude = index.data(Qt::DisplayRole).toDouble();
|
|
item->SetAltitude(altitude);
|
|
break;
|
|
case flightDataModel::LOCKED:
|
|
index = model->index(x, flightDataModel::LOCKED);
|
|
item->setFlag(QGraphicsItem::ItemIsMovable, !index.data(Qt::DisplayRole).toBool());
|
|
break;
|
|
}
|
|
}
|
|
|
|
void modelMapProxy::rowsInserted(const QModelIndex &parent, int first, int last)
|
|
{
|
|
Q_UNUSED(parent);
|
|
|
|
|
|
for (int x = first; x < last + 1; x++) {
|
|
QModelIndex index;
|
|
WayPointItem *item;
|
|
internals::PointLatLng latlng;
|
|
distBearingAltitude distBearing;
|
|
double altitude;
|
|
bool relative;
|
|
index = model->index(x, flightDataModel::WPDESCRITPTION);
|
|
QString desc = index.data(Qt::DisplayRole).toString();
|
|
index = model->index(x, flightDataModel::LATPOSITION);
|
|
latlng.SetLat(index.data(Qt::DisplayRole).toDouble());
|
|
index = model->index(x, flightDataModel::LNGPOSITION);
|
|
latlng.SetLng(index.data(Qt::DisplayRole).toDouble());
|
|
index = model->index(x, flightDataModel::DISRELATIVE);
|
|
distBearing.distance = index.data(Qt::DisplayRole).toDouble();
|
|
index = model->index(x, flightDataModel::BEARELATIVE);
|
|
distBearing.setBearingFromDegrees(index.data(Qt::DisplayRole).toDouble());
|
|
index = model->index(x, flightDataModel::ALTITUDERELATIVE);
|
|
distBearing.altitudeRelative = index.data(Qt::DisplayRole).toFloat();
|
|
index = model->index(x, flightDataModel::ISRELATIVE);
|
|
relative = index.data(Qt::DisplayRole).toBool();
|
|
index = model->index(x, flightDataModel::ALTITUDE);
|
|
altitude = index.data(Qt::DisplayRole).toDouble();
|
|
if (relative) {
|
|
item = myMap->WPInsert(distBearing, desc, x);
|
|
} else {
|
|
item = myMap->WPInsert(latlng, altitude, desc, x);
|
|
}
|
|
}
|
|
|
|
refreshOverlays();
|
|
}
|
|
void modelMapProxy::deleteWayPoint(int number)
|
|
{
|
|
model->removeRow(number, QModelIndex());
|
|
}
|
|
|
|
void modelMapProxy::createWayPoint(internals::PointLatLng coord)
|
|
{
|
|
model->insertRow(model->rowCount(), QModelIndex());
|
|
QModelIndex index = model->index(model->rowCount() - 1, flightDataModel::LATPOSITION, QModelIndex());
|
|
model->setData(index, coord.Lat(), Qt::EditRole);
|
|
index = model->index(model->rowCount() - 1, flightDataModel::LNGPOSITION, QModelIndex());
|
|
model->setData(index, coord.Lng(), Qt::EditRole);
|
|
index = model->index(model->rowCount() - 1, flightDataModel::JUMPDESTINATION, QModelIndex());
|
|
model->setData(index, 1, Qt::EditRole);
|
|
index = model->index(model->rowCount() - 1, flightDataModel::ERRORDESTINATION, QModelIndex());
|
|
model->setData(index, 1, Qt::EditRole);
|
|
}
|
|
|
|
void modelMapProxy::deleteAll()
|
|
{
|
|
if (model->rowCount() > 0) {
|
|
model->removeRows(0, model->rowCount(), QModelIndex());
|
|
}
|
|
}
|