LP-56 - Better txpid option namings, fix tabs-spaces, tooltips. headers, variable...
[librepilot.git] / ground / openpilotgcs / src / plugins / opmap / flightdatamodel.cpp
blob674f4e09278b28162b3290184386bd125013e5f4
1 /**
2 ******************************************************************************
4 * @file flightdatamodel.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 "flightdatamodel.h"
29 #include <QMessageBox>
30 #include <QDomDocument>
32 flightDataModel::flightDataModel(QObject *parent) : QAbstractTableModel(parent)
35 int flightDataModel::rowCount(const QModelIndex & /*parent*/) const
37 return dataStorage.length();
40 int flightDataModel::columnCount(const QModelIndex &parent) const
42 if (parent.isValid()) {
43 return 0;
45 return 23;
48 QVariant flightDataModel::data(const QModelIndex &index, int role) const
50 if (role == Qt::DisplayRole || role == Qt::EditRole) {
51 int rowNumber = index.row();
52 int columnNumber = index.column();
53 if (rowNumber > dataStorage.length() - 1 || rowNumber < 0) {
54 return QVariant::Invalid;
56 pathPlanData *myRow = dataStorage.at(rowNumber);
57 QVariant ret = getColumnByIndex(myRow, columnNumber);
58 return ret;
61 else if (role == Qt::BackgroundRole) {
62 // WaypointActive::DataFields waypointActive = waypointActiveObj->getData();
64 if(index.row() == waypointActive.Index) {
65 return QBrush(Qt::lightGray);
66 } else
67 return QVariant::Invalid;
68 }*/
69 else {
70 return QVariant::Invalid;
74 bool flightDataModel::setColumnByIndex(pathPlanData *row, const int index, const QVariant value)
76 bool b;
78 switch (index) {
79 case WPDESCRITPTION:
80 row->wpDescritption = value.toString();
81 b = true;
82 break;
83 case LATPOSITION:
84 row->latPosition = value.toDouble();
85 b = true;
86 break;
87 case LNGPOSITION:
88 row->lngPosition = value.toDouble();
89 b = true;
90 break;
91 case DISRELATIVE:
92 row->disRelative = value.toDouble();
93 b = true;
94 break;
95 case BEARELATIVE:
96 row->beaRelative = value.toDouble();
97 b = true;
98 break;
99 case ALTITUDERELATIVE:
100 row->altitudeRelative = value.toFloat();
101 b = true;
102 break;
103 case ISRELATIVE:
104 row->isRelative = value.toBool();
105 b = true;
106 break;
107 case ALTITUDE:
108 row->altitude = value.toDouble();
109 b = true;
110 break;
111 case VELOCITY:
112 row->velocity = value.toFloat();
113 b = true;
114 break;
115 case MODE:
116 row->mode = value.toInt();
117 b = true;
118 break;
119 case MODE_PARAMS0:
120 row->mode_params[0] = value.toFloat();
121 b = true;
122 break;
123 case MODE_PARAMS1:
124 row->mode_params[1] = value.toFloat();
125 b = true;
126 break;
127 case MODE_PARAMS2:
128 row->mode_params[2] = value.toFloat();
129 b = true;
130 break;
131 case MODE_PARAMS3:
132 row->mode_params[3] = value.toFloat();
133 b = true;
134 break;
135 case CONDITION:
136 row->condition = value.toInt();
137 b = true;
138 break;
139 case CONDITION_PARAMS0:
140 row->condition_params[0] = value.toFloat();
141 b = true;
142 break;
143 case CONDITION_PARAMS1:
144 row->condition_params[1] = value.toFloat();
145 b = true;
146 break;
147 case CONDITION_PARAMS2:
148 row->condition_params[2] = value.toFloat();
149 b = true;
150 break;
151 case CONDITION_PARAMS3:
152 row->condition_params[3] = value.toFloat();
153 b = true;
154 break;
155 case COMMAND:
156 row->command = value.toInt();
157 b = true;
158 break;
159 case JUMPDESTINATION:
160 row->jumpdestination = value.toInt();
161 b = true;
162 break;
163 case ERRORDESTINATION:
164 row->errordestination = value.toInt();
165 b = true;
166 break;
167 case LOCKED:
168 row->locked = value.toBool();
169 b = true;
170 break;
171 default:
172 b = false;
173 break;
175 return b;
178 QVariant flightDataModel::getColumnByIndex(const pathPlanData *row, const int index) const
180 QVariant value;
182 switch (index) {
183 case WPDESCRITPTION:
184 value = row->wpDescritption;
185 break;
186 case LATPOSITION:
187 value = row->latPosition;
188 break;
189 case LNGPOSITION:
190 value = row->lngPosition;
191 break;
192 case DISRELATIVE:
193 value = row->disRelative;
194 break;
195 case BEARELATIVE:
196 value = row->beaRelative;
197 break;
198 case ALTITUDERELATIVE:
199 value = row->altitudeRelative;
200 break;
201 case ISRELATIVE:
202 value = row->isRelative;
203 break;
204 case ALTITUDE:
205 value = row->altitude;
206 break;
207 case VELOCITY:
208 value = row->velocity;
209 break;
210 case MODE:
211 value = row->mode;
212 break;
213 case MODE_PARAMS0:
214 value = row->mode_params[0];
215 break;
216 case MODE_PARAMS1:
217 value = row->mode_params[1];
218 break;
219 case MODE_PARAMS2:
220 value = row->mode_params[2];
221 break;
222 case MODE_PARAMS3:
223 value = row->mode_params[3];
224 break;
225 case CONDITION:
226 value = row->condition;
227 break;
228 case CONDITION_PARAMS0:
229 value = row->condition_params[0];
230 break;
231 case CONDITION_PARAMS1:
232 value = row->condition_params[1];
233 break;
234 case CONDITION_PARAMS2:
235 value = row->condition_params[2];
236 break;
237 case CONDITION_PARAMS3:
238 value = row->condition_params[3];
239 break;
240 case COMMAND:
241 value = row->command;
242 break;
243 case JUMPDESTINATION:
244 value = row->jumpdestination;
245 break;
246 case ERRORDESTINATION:
247 value = row->errordestination;
248 break;
249 case LOCKED:
250 value = row->locked;
251 break;
253 return value;
256 QVariant flightDataModel::headerData(int section, Qt::Orientation orientation, int role) const
258 QVariant value;
260 if (role == Qt::DisplayRole) {
261 if (orientation == Qt::Vertical) {
262 value = QString::number(section + 1);
263 } else if (orientation == Qt::Horizontal) {
264 switch (section) {
265 case WPDESCRITPTION:
266 value = QString("Description");
267 break;
268 case LATPOSITION:
269 value = QString("Latitude");
270 break;
271 case LNGPOSITION:
272 value = QString("Longitude");
273 break;
274 case DISRELATIVE:
275 value = QString("Distance to home");
276 break;
277 case BEARELATIVE:
278 value = QString("Bearing from home");
279 break;
280 case ALTITUDERELATIVE:
281 value = QString("Altitude above home");
282 break;
283 case ISRELATIVE:
284 value = QString("Relative to home");
285 break;
286 case ALTITUDE:
287 value = QString("Altitude");
288 break;
289 case VELOCITY:
290 value = QString("Velocity");
291 break;
292 case MODE:
293 value = QString("Mode");
294 break;
295 case MODE_PARAMS0:
296 value = QString("Mode parameter 0");
297 break;
298 case MODE_PARAMS1:
299 value = QString("Mode parameter 1");
300 break;
301 case MODE_PARAMS2:
302 value = QString("Mode parameter 2");
303 break;
304 case MODE_PARAMS3:
305 value = QString("Mode parameter 3");
306 break;
307 case CONDITION:
308 value = QString("Condition");
309 break;
310 case CONDITION_PARAMS0:
311 value = QString("Condition parameter 0");
312 break;
313 case CONDITION_PARAMS1:
314 value = QString("Condition parameter 1");
315 break;
316 case CONDITION_PARAMS2:
317 value = QString("Condition parameter 2");
318 break;
319 case CONDITION_PARAMS3:
320 value = QString("Condition parameter 3");
321 break;
322 case COMMAND:
323 value = QString("Command");
324 break;
325 case JUMPDESTINATION:
326 value = QString("Jump Destination");
327 break;
328 case ERRORDESTINATION:
329 value = QString("Error Destination");
330 break;
331 case LOCKED:
332 value = QString("Locked");
333 break;
334 default:
335 value = QString();
336 break;
339 } else {
340 value = QAbstractTableModel::headerData(section, orientation, role);
342 return value;
345 bool flightDataModel::setData(const QModelIndex &index, const QVariant &value, int role)
347 if (role == Qt::EditRole) {
348 int columnIndex = index.column();
349 int rowIndex = index.row();
350 if (rowIndex > dataStorage.length() - 1) {
351 return false;
353 pathPlanData *myRow = dataStorage.at(rowIndex);
354 setColumnByIndex(myRow, columnIndex, value);
355 emit dataChanged(index, index);
357 return true;
360 Qt::ItemFlags flightDataModel::flags(const QModelIndex & /*index*/) const
362 return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
365 bool flightDataModel::insertRows(int row, int count, const QModelIndex & /*parent*/)
367 pathPlanData *data;
369 beginInsertRows(QModelIndex(), row, row + count - 1);
370 for (int x = 0; x < count; ++x) {
371 data = new pathPlanData;
372 data->latPosition = 0;
373 data->lngPosition = 0;
374 data->disRelative = 0;
375 data->beaRelative = 0;
376 data->altitudeRelative = 0;
377 data->isRelative = true;
378 data->altitude = 0;
379 data->velocity = 0;
380 data->mode = 1;
381 data->mode_params[0] = 0;
382 data->mode_params[1] = 0;
383 data->mode_params[2] = 0;
384 data->mode_params[3] = 0;
385 data->condition = 3;
386 data->condition_params[0] = 0;
387 data->condition_params[1] = 0;
388 data->condition_params[2] = 0;
389 data->condition_params[3] = 0;
390 data->command = 0;
391 data->jumpdestination = 0;
392 data->errordestination = 0;
393 data->locked = false;
394 if (rowCount() > 0) {
395 data->altitude = this->data(this->index(rowCount() - 1, ALTITUDE)).toDouble();
396 data->altitudeRelative = this->data(this->index(rowCount() - 1, ALTITUDERELATIVE)).toDouble();
397 data->isRelative = this->data(this->index(rowCount() - 1, ISRELATIVE)).toBool();
398 data->velocity = this->data(this->index(rowCount() - 1, VELOCITY)).toFloat();
399 data->mode = this->data(this->index(rowCount() - 1, MODE)).toInt();
400 data->mode_params[0] = this->data(this->index(rowCount() - 1, MODE_PARAMS0)).toFloat();
401 data->mode_params[1] = this->data(this->index(rowCount() - 1, MODE_PARAMS1)).toFloat();
402 data->mode_params[2] = this->data(this->index(rowCount() - 1, MODE_PARAMS2)).toFloat();
403 data->mode_params[3] = this->data(this->index(rowCount() - 1, MODE_PARAMS3)).toFloat();
404 data->condition = this->data(this->index(rowCount() - 1, CONDITION)).toInt();
405 data->condition_params[0] = this->data(this->index(rowCount() - 1, CONDITION_PARAMS0)).toFloat();
406 data->condition_params[1] = this->data(this->index(rowCount() - 1, CONDITION_PARAMS1)).toFloat();
407 data->condition_params[2] = this->data(this->index(rowCount() - 1, CONDITION_PARAMS2)).toFloat();
408 data->condition_params[3] = this->data(this->index(rowCount() - 1, CONDITION_PARAMS3)).toFloat();
409 data->command = this->data(this->index(rowCount() - 1, COMMAND)).toInt();
410 data->errordestination = this->data(this->index(rowCount() - 1, ERRORDESTINATION)).toInt();
412 dataStorage.insert(row, data);
414 endInsertRows();
415 return true;
418 bool flightDataModel::removeRows(int row, int count, const QModelIndex & /*parent*/)
420 if (row < 0 || count <= 0) {
421 return false;
423 beginRemoveRows(QModelIndex(), row, row + count - 1);
424 for (int x = 0; x < count; ++x) {
425 delete dataStorage.at(row);
426 dataStorage.removeAt(row);
428 endRemoveRows();
429 return true;
432 bool flightDataModel::writeToFile(QString fileName)
434 QFile file(fileName);
436 if (!file.open(QIODevice::WriteOnly)) {
437 QMessageBox::information(NULL, tr("Unable to open file"), file.errorString());
438 return false;
440 QDataStream out(&file);
441 QDomDocument doc("PathPlan");
442 QDomElement root = doc.createElement("waypoints");
443 doc.appendChild(root);
445 foreach(pathPlanData * obj, dataStorage) {
446 QDomElement waypoint = doc.createElement("waypoint");
448 waypoint.setAttribute("number", dataStorage.indexOf(obj));
449 root.appendChild(waypoint);
450 QDomElement field = doc.createElement("field");
451 field.setAttribute("value", obj->wpDescritption);
452 field.setAttribute("name", "description");
453 waypoint.appendChild(field);
455 field = doc.createElement("field");
456 field.setAttribute("value", obj->latPosition);
457 field.setAttribute("name", "latitude");
458 waypoint.appendChild(field);
460 field = doc.createElement("field");
461 field.setAttribute("value", obj->lngPosition);
462 field.setAttribute("name", "longitude");
463 waypoint.appendChild(field);
465 field = doc.createElement("field");
466 field.setAttribute("value", obj->disRelative);
467 field.setAttribute("name", "distance_to_home");
468 waypoint.appendChild(field);
470 field = doc.createElement("field");
471 field.setAttribute("value", obj->beaRelative);
472 field.setAttribute("name", "bearing_from_home");
473 waypoint.appendChild(field);
475 field = doc.createElement("field");
476 field.setAttribute("value", obj->altitudeRelative);
477 field.setAttribute("name", "altitude_above_home");
478 waypoint.appendChild(field);
480 field = doc.createElement("field");
481 field.setAttribute("value", obj->isRelative);
482 field.setAttribute("name", "is_relative_to_home");
483 waypoint.appendChild(field);
485 field = doc.createElement("field");
486 field.setAttribute("value", obj->altitude);
487 field.setAttribute("name", "altitude");
488 waypoint.appendChild(field);
490 field = doc.createElement("field");
491 field.setAttribute("value", obj->velocity);
492 field.setAttribute("name", "velocity");
493 waypoint.appendChild(field);
495 field = doc.createElement("field");
496 field.setAttribute("value", obj->mode);
497 field.setAttribute("name", "mode");
498 waypoint.appendChild(field);
500 field = doc.createElement("field");
501 field.setAttribute("value", obj->mode_params[0]);
502 field.setAttribute("name", "mode_param0");
503 waypoint.appendChild(field);
505 field = doc.createElement("field");
506 field.setAttribute("value", obj->mode_params[1]);
507 field.setAttribute("name", "mode_param1");
508 waypoint.appendChild(field);
510 field = doc.createElement("field");
511 field.setAttribute("value", obj->mode_params[2]);
512 field.setAttribute("name", "mode_param2");
513 waypoint.appendChild(field);
515 field = doc.createElement("field");
516 field.setAttribute("value", obj->mode_params[3]);
517 field.setAttribute("name", "mode_param3");
518 waypoint.appendChild(field);
520 field = doc.createElement("field");
521 field.setAttribute("value", obj->condition);
522 field.setAttribute("name", "condition");
523 waypoint.appendChild(field);
525 field = doc.createElement("field");
526 field.setAttribute("value", obj->condition_params[0]);
527 field.setAttribute("name", "condition_param0");
528 waypoint.appendChild(field);
530 field = doc.createElement("field");
531 field.setAttribute("value", obj->condition_params[1]);
532 field.setAttribute("name", "condition_param1");
533 waypoint.appendChild(field);
535 field = doc.createElement("field");
536 field.setAttribute("value", obj->condition_params[2]);
537 field.setAttribute("name", "condition_param2");
538 waypoint.appendChild(field);
540 field = doc.createElement("field");
541 field.setAttribute("value", obj->condition_params[3]);
542 field.setAttribute("name", "condition_param3");
543 waypoint.appendChild(field);
545 field = doc.createElement("field");
546 field.setAttribute("value", obj->command);
547 field.setAttribute("name", "command");
548 waypoint.appendChild(field);
550 field = doc.createElement("field");
551 field.setAttribute("value", obj->jumpdestination);
552 field.setAttribute("name", "jumpdestination");
553 waypoint.appendChild(field);
555 field = doc.createElement("field");
556 field.setAttribute("value", obj->errordestination);
557 field.setAttribute("name", "errordestination");
558 waypoint.appendChild(field);
560 field = doc.createElement("field");
561 field.setAttribute("value", obj->locked);
562 field.setAttribute("name", "is_locked");
563 waypoint.appendChild(field);
565 file.write(doc.toString().toLatin1());
566 file.close();
567 return true;
570 void flightDataModel::readFromFile(QString fileName)
572 // TODO warning message
573 removeRows(0, rowCount());
574 QFile file(fileName);
575 file.open(QIODevice::ReadOnly);
576 QDomDocument doc("PathPlan");
577 QByteArray array = file.readAll();
578 QString error;
579 if (!doc.setContent(array, &error)) {
580 QMessageBox msgBox;
581 msgBox.setText(tr("File Parsing Failed."));
582 msgBox.setInformativeText(QString(tr("This file is not a correct XML file:%0")).arg(error));
583 msgBox.setStandardButtons(QMessageBox::Ok);
584 msgBox.exec();
585 return;
587 file.close();
589 QDomElement root = doc.documentElement();
591 if (root.isNull() || (root.tagName() != "waypoints")) {
592 QMessageBox msgBox;
593 msgBox.setText(tr("Wrong file contents"));
594 msgBox.setInformativeText(tr("This file does not contain correct UAVSettings"));
595 msgBox.setStandardButtons(QMessageBox::Ok);
596 msgBox.exec();
597 return;
600 pathPlanData *data = NULL;
601 QDomNode node = root.firstChild();
602 while (!node.isNull()) {
603 QDomElement e = node.toElement();
604 if (e.tagName() == "waypoint") {
605 QDomNode fieldNode = e.firstChild();
606 data = new pathPlanData;
607 while (!fieldNode.isNull()) {
608 QDomElement field = fieldNode.toElement();
609 if (field.tagName() == "field") {
610 QString name = field.attribute("name");
611 QString value = field.attribute("value");
612 if (name == "altitude") {
613 data->altitude = value.toDouble();
614 } else if (name == "description") {
615 data->wpDescritption = value;
616 } else if (name == "latitude") {
617 data->latPosition = value.toDouble();
618 } else if (name == "longitude") {
619 data->lngPosition = value.toDouble();
620 } else if (name == "distance_to_home") {
621 data->disRelative = value.toDouble();
622 } else if (name == "bearing_from_home") {
623 data->beaRelative = value.toDouble();
624 } else if (name == "altitude_above_home") {
625 data->altitudeRelative = value.toFloat();
626 } else if (name == "is_relative_to_home") {
627 data->isRelative = value.toInt();
628 } else if (name == "altitude") {
629 data->altitude = value.toDouble();
630 } else if (name == "velocity") {
631 data->velocity = value.toFloat();
632 } else if (name == "mode") {
633 data->mode = value.toInt();
634 } else if (name == "mode_param0") {
635 data->mode_params[0] = value.toFloat();
636 } else if (name == "mode_param1") {
637 data->mode_params[1] = value.toFloat();
638 } else if (name == "mode_param2") {
639 data->mode_params[2] = value.toFloat();
640 } else if (name == "mode_param3") {
641 data->mode_params[3] = value.toFloat();
642 } else if (name == "condition") {
643 data->condition = value.toDouble();
644 } else if (name == "condition_param0") {
645 data->condition_params[0] = value.toFloat();
646 } else if (name == "condition_param1") {
647 data->condition_params[1] = value.toFloat();
648 } else if (name == "condition_param2") {
649 data->condition_params[2] = value.toFloat();
650 } else if (name == "condition_param3") {
651 data->condition_params[3] = value.toFloat();
652 } else if (name == "command") {
653 data->command = value.toInt();
654 } else if (name == "jumpdestination") {
655 data->jumpdestination = value.toInt();
656 } else if (name == "errordestination") {
657 data->errordestination = value.toInt();
658 } else if (name == "is_locked") {
659 data->locked = value.toInt();
662 fieldNode = fieldNode.nextSibling();
664 beginInsertRows(QModelIndex(), dataStorage.length(), dataStorage.length());
665 dataStorage.append(data);
666 endInsertRows();
668 node = node.nextSibling();