LP-56 - Better txpid option namings, fix tabs-spaces, tooltips. headers, variable...
[librepilot.git] / ground / openpilotgcs / src / plugins / opmap / modelmapproxy.cpp
blobfb56c0081df4844b8f4f5aa8f897126e8e6ade2b
1 /**
2 ******************************************************************************
4 * @file modelmapproxy.cpp
5 * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2012.
6 * @addtogroup GCSPlugins GCS Plugins
7 * @{
8 * @addtogroup OPMapPlugin OpenPilot Map Plugin
9 * @{
10 * @brief The OpenPilot Map plugin
11 *****************************************************************************/
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 * for more details.
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 #include "modelmapproxy.h"
30 modelMapProxy::modelMapProxy(QObject *parent, OPMapWidget *map, flightDataModel *model, QItemSelectionModel *selectionModel) : QObject(parent), myMap(map), model(model), selection(selectionModel)
32 connect(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(rowsInserted(const QModelIndex &, int, int)));
33 connect(model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(rowsRemoved(const QModelIndex &, int, int)));
34 connect(selection, SIGNAL(currentRowChanged(QModelIndex, QModelIndex)), this, SLOT(currentRowChanged(QModelIndex, QModelIndex)));
35 connect(model, SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(dataChanged(QModelIndex, QModelIndex)));
36 connect(myMap, SIGNAL(selectedWPChanged(QList<WayPointItem *>)), this, SLOT(selectedWPChanged(QList<WayPointItem *>)));
37 connect(myMap, SIGNAL(WPValuesChanged(WayPointItem *)), this, SLOT(WPValuesChanged(WayPointItem *)));
40 void modelMapProxy::WPValuesChanged(WayPointItem *wp)
42 QModelIndex index;
44 index = model->index(wp->Number(), flightDataModel::LATPOSITION);
45 if (!index.isValid()) {
46 return;
48 model->setData(index, wp->Coord().Lat(), Qt::EditRole);
49 index = model->index(wp->Number(), flightDataModel::LNGPOSITION);
50 model->setData(index, wp->Coord().Lng(), Qt::EditRole);
52 index = model->index(wp->Number(), flightDataModel::ALTITUDE);
53 model->setData(index, wp->Altitude(), Qt::EditRole);
55 index = model->index(wp->Number(), flightDataModel::DISRELATIVE);
56 model->setData(index, wp->getRelativeCoord().distance, Qt::EditRole);
57 index = model->index(wp->Number(), flightDataModel::BEARELATIVE);
58 model->setData(index, wp->getRelativeCoord().bearingToDegrees(), Qt::EditRole);
59 index = model->index(wp->Number(), flightDataModel::ALTITUDERELATIVE);
60 model->setData(index, wp->getRelativeCoord().altitudeRelative, Qt::EditRole);
63 void modelMapProxy::currentRowChanged(QModelIndex current, QModelIndex previous)
65 Q_UNUSED(previous);
67 QList<WayPointItem *> list;
68 WayPointItem *wp = findWayPointNumber(current.row());
69 if (!wp) {
70 return;
72 list.append(wp);
73 myMap->setSelectedWP(list);
76 void modelMapProxy::selectedWPChanged(QList<WayPointItem *> list)
78 selection->clearSelection();
79 foreach(WayPointItem * wp, list) {
80 QModelIndex index = model->index(wp->Number(), 0);
82 selection->setCurrentIndex(index, QItemSelectionModel::Select | QItemSelectionModel::Rows);
86 modelMapProxy::overlayType modelMapProxy::overlayTranslate(int type)
88 switch (type) {
89 case MapDataDelegate::MODE_GOTOENDPOINT:
90 case MapDataDelegate::MODE_FOLLOWVECTOR:
91 case MapDataDelegate::MODE_VELOCITY:
92 case MapDataDelegate::MODE_LAND:
93 case MapDataDelegate::MODE_AUTOTAKEOFF:
94 case MapDataDelegate::MODE_BRAKE:
95 return OVERLAY_LINE;
97 case MapDataDelegate::MODE_CIRCLERIGHT:
98 return OVERLAY_CIRCLE_RIGHT;
100 case MapDataDelegate::MODE_CIRCLELEFT:
101 default:
102 return OVERLAY_CIRCLE_LEFT;
106 void modelMapProxy::createOverlay(WayPointItem *from, WayPointItem *to, modelMapProxy::overlayType type, QColor color, bool dashed, int width)
108 if (from == NULL || to == NULL || from == to) {
109 return;
111 switch (type) {
112 case OVERLAY_LINE:
113 myMap->WPLineCreate(from, to, color, dashed, width);
114 break;
115 case OVERLAY_CIRCLE_RIGHT:
116 myMap->WPCircleCreate(to, from, true, color, dashed, width);
117 break;
118 case OVERLAY_CIRCLE_LEFT:
119 myMap->WPCircleCreate(to, from, false, color, dashed, width);
120 break;
121 default:
122 break;
125 void modelMapProxy::createOverlay(WayPointItem *from, HomeItem *to, modelMapProxy::overlayType type, QColor color, bool dashed, int width)
127 if (from == NULL || to == NULL) {
128 return;
130 switch (type) {
131 case OVERLAY_LINE:
132 myMap->WPLineCreate(to, from, color, dashed, width);
133 break;
134 case OVERLAY_CIRCLE_RIGHT:
135 myMap->WPCircleCreate(to, from, true, color, dashed, width);
136 break;
137 case OVERLAY_CIRCLE_LEFT:
138 myMap->WPCircleCreate(to, from, false, color, dashed, width);
139 break;
140 default:
141 break;
144 void modelMapProxy::refreshOverlays()
146 myMap->deleteAllOverlays();
147 if (model->rowCount() < 1) {
148 return;
150 WayPointItem *wp_current = NULL;
151 WayPointItem *wp_next = NULL;
152 int wp_jump;
153 int wp_error;
154 overlayType wp_next_overlay;
155 overlayType wp_jump_overlay;
156 overlayType wp_error_overlay;
157 wp_current = findWayPointNumber(0);
158 overlayType wp_current_overlay = overlayTranslate(model->data(model->index(0, flightDataModel::MODE)).toInt());
159 createOverlay(wp_current, myMap->Home, wp_current_overlay, Qt::green);
160 for (int x = 0; x < model->rowCount(); ++x) {
161 wp_current = findWayPointNumber(x);
162 wp_jump = model->data(model->index(x, flightDataModel::JUMPDESTINATION)).toInt() - 1;
163 wp_error = model->data(model->index(x, flightDataModel::ERRORDESTINATION)).toInt() - 1;
164 wp_next_overlay = overlayTranslate(model->data(model->index(x + 1, flightDataModel::MODE)).toInt());
165 wp_jump_overlay = overlayTranslate(model->data(model->index(wp_jump, flightDataModel::MODE)).toInt());
166 wp_error_overlay = overlayTranslate(model->data(model->index(wp_error, flightDataModel::MODE)).toInt());
167 createOverlay(wp_current, findWayPointNumber(wp_error), wp_error_overlay, Qt::red, true, 1);
168 switch (model->data(model->index(x, flightDataModel::COMMAND)).toInt()) {
169 case MapDataDelegate::COMMAND_ONCONDITIONNEXTWAYPOINT:
170 wp_next = findWayPointNumber(x + 1);
171 createOverlay(wp_current, wp_next, wp_next_overlay, Qt::green);
172 break;
173 case MapDataDelegate::COMMAND_ONCONDITIONJUMPWAYPOINT:
174 wp_next = findWayPointNumber(wp_jump);
175 createOverlay(wp_current, wp_next, wp_jump_overlay, Qt::green);
176 break;
177 case MapDataDelegate::COMMAND_ONNOTCONDITIONJUMPWAYPOINT:
178 wp_next = findWayPointNumber(wp_jump);
179 createOverlay(wp_current, wp_next, wp_jump_overlay, Qt::yellow);
180 break;
181 case MapDataDelegate::COMMAND_ONNOTCONDITIONNEXTWAYPOINT:
182 wp_next = findWayPointNumber(x + 1);
183 createOverlay(wp_current, wp_next, wp_next_overlay, Qt::yellow);
184 break;
185 case MapDataDelegate::COMMAND_IFCONDITIONJUMPWAYPOINTELSENEXTWAYPOINT:
186 wp_next = findWayPointNumber(wp_jump);
187 createOverlay(wp_current, wp_next, wp_jump_overlay, Qt::green);
188 wp_next = findWayPointNumber(x + 1);
189 createOverlay(wp_current, wp_next, wp_next_overlay, Qt::green);
190 break;
195 WayPointItem *modelMapProxy::findWayPointNumber(int number)
197 if (number < 0) {
198 return NULL;
200 return myMap->WPFind(number);
203 void modelMapProxy::rowsRemoved(const QModelIndex &parent, int first, int last)
205 Q_UNUSED(parent);
207 for (int x = last; x > first - 1; x--) {
208 myMap->WPDelete(x);
210 refreshOverlays();
213 void modelMapProxy::dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
215 Q_UNUSED(bottomRight);
217 WayPointItem *item = findWayPointNumber(topLeft.row());
218 if (!item) {
219 return;
221 internals::PointLatLng latlng;
222 int x = topLeft.row();
223 distBearingAltitude distBearing;
224 double altitude;
225 bool relative;
226 QModelIndex index;
227 QString desc;
228 switch (topLeft.column()) {
229 case flightDataModel::COMMAND:
230 case flightDataModel::CONDITION:
231 case flightDataModel::JUMPDESTINATION:
232 case flightDataModel::ERRORDESTINATION:
233 case flightDataModel::MODE:
234 refreshOverlays();
235 break;
236 case flightDataModel::WPDESCRITPTION:
237 index = model->index(x, flightDataModel::WPDESCRITPTION);
238 desc = index.data(Qt::DisplayRole).toString();
239 item->SetDescription(desc);
240 break;
241 case flightDataModel::LATPOSITION:
242 latlng = item->Coord();
243 index = model->index(x, flightDataModel::LATPOSITION);
244 latlng.SetLat(index.data(Qt::DisplayRole).toDouble());
245 item->SetCoord(latlng);
246 break;
247 case flightDataModel::LNGPOSITION:
248 latlng = item->Coord();
249 index = model->index(x, flightDataModel::LNGPOSITION);
250 latlng.SetLng(index.data(Qt::DisplayRole).toDouble());
251 item->SetCoord(latlng);
252 break;
253 case flightDataModel::BEARELATIVE:
254 distBearing = item->getRelativeCoord();
255 index = model->index(x, flightDataModel::BEARELATIVE);
256 distBearing.setBearingFromDegrees(index.data(Qt::DisplayRole).toDouble());
257 item->setRelativeCoord(distBearing);
258 break;
259 case flightDataModel::DISRELATIVE:
260 distBearing = item->getRelativeCoord();
261 index = model->index(x, flightDataModel::DISRELATIVE);
262 distBearing.distance = index.data(Qt::DisplayRole).toDouble();
263 item->setRelativeCoord(distBearing);
264 break;
265 case flightDataModel::ALTITUDERELATIVE:
266 distBearing = item->getRelativeCoord();
267 index = model->index(x, flightDataModel::ALTITUDERELATIVE);
268 distBearing.altitudeRelative = index.data(Qt::DisplayRole).toFloat();
269 item->setRelativeCoord(distBearing);
270 break;
271 case flightDataModel::ISRELATIVE:
272 index = model->index(x, flightDataModel::ISRELATIVE);
273 relative = index.data(Qt::DisplayRole).toBool();
274 if (relative) {
275 item->setWPType(mapcontrol::WayPointItem::relative);
276 } else {
277 item->setWPType(mapcontrol::WayPointItem::absolute);
279 break;
280 case flightDataModel::ALTITUDE:
281 index = model->index(x, flightDataModel::ALTITUDE);
282 altitude = index.data(Qt::DisplayRole).toDouble();
283 item->SetAltitude(altitude);
284 break;
285 case flightDataModel::LOCKED:
286 index = model->index(x, flightDataModel::LOCKED);
287 item->setFlag(QGraphicsItem::ItemIsMovable, !index.data(Qt::DisplayRole).toBool());
288 break;
292 void modelMapProxy::rowsInserted(const QModelIndex &parent, int first, int last)
294 Q_UNUSED(parent);
297 for (int x = first; x < last + 1; x++) {
298 QModelIndex index;
299 WayPointItem *item;
300 internals::PointLatLng latlng;
301 distBearingAltitude distBearing;
302 double altitude;
303 bool relative;
304 index = model->index(x, flightDataModel::WPDESCRITPTION);
305 QString desc = index.data(Qt::DisplayRole).toString();
306 index = model->index(x, flightDataModel::LATPOSITION);
307 latlng.SetLat(index.data(Qt::DisplayRole).toDouble());
308 index = model->index(x, flightDataModel::LNGPOSITION);
309 latlng.SetLng(index.data(Qt::DisplayRole).toDouble());
310 index = model->index(x, flightDataModel::DISRELATIVE);
311 distBearing.distance = index.data(Qt::DisplayRole).toDouble();
312 index = model->index(x, flightDataModel::BEARELATIVE);
313 distBearing.setBearingFromDegrees(index.data(Qt::DisplayRole).toDouble());
314 index = model->index(x, flightDataModel::ALTITUDERELATIVE);
315 distBearing.altitudeRelative = index.data(Qt::DisplayRole).toFloat();
316 index = model->index(x, flightDataModel::ISRELATIVE);
317 relative = index.data(Qt::DisplayRole).toBool();
318 index = model->index(x, flightDataModel::ALTITUDE);
319 altitude = index.data(Qt::DisplayRole).toDouble();
320 if (relative) {
321 item = myMap->WPInsert(distBearing, desc, x);
322 } else {
323 item = myMap->WPInsert(latlng, altitude, desc, x);
327 refreshOverlays();
329 void modelMapProxy::deleteWayPoint(int number)
331 model->removeRow(number, QModelIndex());
334 void modelMapProxy::createWayPoint(internals::PointLatLng coord)
336 model->insertRow(model->rowCount(), QModelIndex());
337 QModelIndex index = model->index(model->rowCount() - 1, flightDataModel::LATPOSITION, QModelIndex());
338 model->setData(index, coord.Lat(), Qt::EditRole);
339 index = model->index(model->rowCount() - 1, flightDataModel::LNGPOSITION, QModelIndex());
340 model->setData(index, coord.Lng(), Qt::EditRole);
341 index = model->index(model->rowCount() - 1, flightDataModel::JUMPDESTINATION, QModelIndex());
342 model->setData(index, 1, Qt::EditRole);
343 index = model->index(model->rowCount() - 1, flightDataModel::ERRORDESTINATION, QModelIndex());
344 model->setData(index, 1, Qt::EditRole);
347 void modelMapProxy::deleteAll()
349 if (model->rowCount() > 0) {
350 model->removeRows(0, model->rowCount(), QModelIndex());