WimaController.cc 22.5 KB
Newer Older
1
#include "WimaController.h"
2

3 4 5
const char* WimaController::wimaFileExtension   = "wima";
const char* WimaController::areaItemsName       = "AreaItems";
const char* WimaController::missionItemsName    = "MissionItems";
6

7 8
WimaController::WimaController(QObject *parent) :
    QObject             (parent)
9
  ,_flyView            (true)
10
  ,_currentPolygonIndex (-1)
11
  ,_container(nullptr)
12 13 14 15
{
    connect(this, &WimaController::currentPolygonIndexChanged, this, &WimaController::recalcPolygonInteractivity);
}

Valentin Platzgummer's avatar
Valentin Platzgummer committed
16 17 18 19
QStringList WimaController::loadNameFilters() const
{
    QStringList filters;

20
    filters << tr("Supported types (*.%1 *.%2)").arg(wimaFileExtension).arg(AppSettings::planFileExtension) <<
Valentin Platzgummer's avatar
Valentin Platzgummer committed
21 22
               tr("All Files (*.*)");
    return filters;
23 24 25 26 27
}

QStringList WimaController::saveNameFilters() const
{
    QStringList filters;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
28

29 30
    filters << tr("Supported types (*.%1 *.%2)").arg(wimaFileExtension).arg(AppSettings::planFileExtension);
    return filters;
Valentin Platzgummer's avatar
Valentin Platzgummer committed
31 32
}

33 34 35 36 37 38 39 40 41 42 43 44 45 46
void WimaController::setMasterController(PlanMasterController *masterC)
{
    _masterController = masterC;
    emit masterControllerChanged();
}

void WimaController::setMissionController(MissionController *missionC)
{
    _missionController = missionC;
    emit missionControllerChanged();
}

void WimaController::setCurrentPolygonIndex(int index)
{
47
    if(_container != nullptr && index >= 0 && index < _container->visualItems()->count() && index != _currentPolygonIndex){
48 49 50 51 52 53
        _currentPolygonIndex = index;

        emit currentPolygonIndexChanged(index);
    }
}

54 55 56 57 58 59 60 61 62 63 64 65 66 67
void WimaController::setDataContainer(WimaDataContainer *container)
{
    if (container != nullptr && _container != container) {
        _container = container;

        emit dataContainerChanged();
    }
}

void WimaController::startWimaController(bool flyView)
{
    _flyView = flyView;
}

68 69
void WimaController::removeArea(int index)
{
70 71
    if(_container != nullptr && index >= 0 && index < _container->visualItems()->count()){
        WimaArea* area = qobject_cast<WimaArea*>(_container->visualItems()->removeAt(index));
72 73 74 75 76 77

        if ( area == nullptr) {
            qWarning("WimaController::removeArea(): nullptr catched, internal error.");
            return;
        }

78 79
        emit visualItemsChanged();

80
        if (_container->visualItems()->count() == 0) {
81 82 83 84 85 86
            // this branch is reached if all items are removed
            // to guarentee proper behavior, _currentPolygonIndex must be set to a invalid value, as on constructor init.
            _currentPolygonIndex = -1;
            return;
        }

87 88
        if(_currentPolygonIndex >= _container->visualItems()->count()){
            setCurrentPolygonIndex(_container->visualItems()->count() - 1);
89 90 91 92 93 94 95 96 97
        }else{
            recalcPolygonInteractivity(_currentPolygonIndex);
        }
    }else{
        qWarning("Index out of bounds!");
    }

}

98
bool WimaController::addGOperationArea()
99
{
100 101 102 103 104
    if (_container == nullptr) {
        qWarning("WimaController::addGOperationArea(): container not initialized!");
        return false;
    }

105 106
    // check if opArea exists already
    WimaGOperationArea* opArea = nullptr;
107 108
    for (int i = 0; i < _container->visualItems()->count(); i++) {
        WimaGOperationArea* currentArea = qobject_cast<WimaGOperationArea*>(_container->visualItems()->get(i));
109 110 111 112 113 114 115 116
        if ( currentArea != nullptr ) {
            opArea = currentArea;
            return false;
        }
    }

    // create one if no opArea available
    opArea = new WimaGOperationArea(this);
117 118
    _container->visualItems()->append(opArea);
    int newIndex = _container->visualItems()->count()-1;
119
    setCurrentPolygonIndex(newIndex);
120

121
    emit visualItemsChanged();
122
    return true;
123 124
}

125
bool WimaController::addServiceArea()
126
{
127 128 129 130 131
    if (_container == nullptr) {
        qWarning("WimaController::addGOperationArea(): container not initialized!");
        return false;
    }

132 133
    // check if serArea exists already
    WimaServiceArea* serArea = nullptr;
134 135
    for (int i = 0; i < _container->visualItems()->count(); i++) {
        WimaServiceArea* currentArea = qobject_cast<WimaServiceArea*>(_container->visualItems()->get(i));
136 137 138 139 140 141 142 143 144
        if ( currentArea != nullptr ) {
            serArea = currentArea;
            return false;
        }
    }

    // create one if no serArea available
    serArea = new WimaServiceArea(this);

145 146
    _container->visualItems()->append(serArea);
    int newIndex = _container->visualItems()->count()-1;
147
    setCurrentPolygonIndex(newIndex);
148

149
    emit visualItemsChanged();
150
    return true;
151 152
}

153
bool WimaController::addVehicleCorridor()
154
{
155 156 157 158 159
    if (_container == nullptr) {
        qWarning("WimaController::addGOperationArea(): container not initialized!");
        return false;
    }

160 161
    // check if corridor exists already
    WimaVCorridor* corridor = nullptr;
162 163
    for (int i = 0; i < _container->visualItems()->count(); i++) {
        WimaVCorridor* currentArea = qobject_cast<WimaVCorridor*>(_container->visualItems()->get(i));
164 165 166 167 168 169 170 171 172
        if ( currentArea != nullptr ) {
            corridor = currentArea;
            return false;
        }
    }

    // create one if no corridor available
    corridor = new WimaVCorridor(this);

173 174
    _container->visualItems()->append(corridor);
    int newIndex = _container->visualItems()->count()-1;
175
    setCurrentPolygonIndex(newIndex);
176

177
    emit visualItemsChanged();
178
    return true;
179 180
}

181
void WimaController::removeAll()
Valentin Platzgummer's avatar
Valentin Platzgummer committed
182
{
183 184 185 186 187
    if (_container == nullptr) {
        qWarning("WimaController::addGOperationArea(): container not initialized!");
        return;
    }

Valentin Platzgummer's avatar
Valentin Platzgummer committed
188
    bool changesApplied = false;
189
    while (_container->visualItems()->count() > 0) {
190
        removeArea(0);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
191 192 193
        changesApplied = true;
    }

194 195
    _missionController->removeAll();

Valentin Platzgummer's avatar
Valentin Platzgummer committed
196 197 198 199 200 201 202
    _currentFile = "";

    emit currentFileChanged();
    if ( changesApplied )
         emit visualItemsChanged();
}

203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222
void WimaController::startMission()
{

}

void WimaController::abortMission()
{

}

void WimaController::pauseMission()
{

}

void WimaController::resumeMission()
{

}

223 224
bool WimaController::updateMission()
{
225 226 227 228 229
    if (_container == nullptr) {
        qWarning("WimaController::addGOperationArea(): container not initialized!");
        return false;
    }

Valentin Platzgummer's avatar
Valentin Platzgummer committed
230
    #define debug 0
231
    // pick first WimaGOperationArea
232
    WimaGOperationArea* opArea = nullptr;
233 234
    for (int i = 0; i < _container->visualItems()->count(); i++) {
        WimaGOperationArea* currentArea = qobject_cast<WimaGOperationArea*>(_container->visualItems()->get(i));
235 236 237 238 239
        if (currentArea != nullptr){
            opArea = currentArea;
            break;
        }
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
240 241
    if (opArea == nullptr)
        return false;
242

243
    // pick first WimaServiceArea
244
    WimaServiceArea* serArea = nullptr;
245 246
    for (int i = 0; i < _container->visualItems()->count(); i++) {
        WimaServiceArea* currentArea = qobject_cast<WimaServiceArea*>(_container->visualItems()->get(i));
247 248 249 250 251
        if (currentArea != nullptr){
            serArea = currentArea;
            break;
        }
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
252 253
    if ( serArea == nullptr )
        return false;
254

255 256
    // pick first WimaVCorridor
    WimaVCorridor* corridor = nullptr;
257 258
    for (int i = 0; i < _container->visualItems()->count(); i++) {
        WimaVCorridor* currentArea = qobject_cast<WimaVCorridor*>(_container->visualItems()->get(i));
259 260 261
        if (currentArea != nullptr){
            corridor = currentArea;
            break;
262 263
        }
    }
264

Valentin Platzgummer's avatar
Valentin Platzgummer committed
265

266 267
    updateJoinedArea();

Valentin Platzgummer's avatar
Valentin Platzgummer committed
268
    #if debug
269
        _container->visualItems()->append(&_joinedArea);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
270
    #endif
271

272

273 274
    // reset visual items
    _missionController->removeAll();
275
    QmlObjectListModel* missionItems = _missionController->visualItems();
276 277 278 279 280 281
    // set home position to serArea center
    MissionSettingsItem* settingsItem= qobject_cast<MissionSettingsItem*>(missionItems->get(0));
    if (settingsItem == nullptr){
        qWarning("WimaController::updateMission(): settingsItem == nullptr");
        return false;
    }
282 283 284 285 286 287 288 289 290 291 292 293 294
    // set altitudes, temporary measure to solve bugs
    QGeoCoordinate center = serArea->center();
    center.setAltitude(0);
    serArea->setCenter(center);
    center = opArea->center();
    center.setAltitude(0);
    opArea->setCenter(center);
    center = corridor->center();
    center.setAltitude(0);
    corridor->setCenter(center);


    // set HomePos. to serArea center
295
    settingsItem->setCoordinate(serArea->center());
Valentin Platzgummer's avatar
Valentin Platzgummer committed
296 297

    // create take off position item
298 299 300
    int sequenceNumber = _missionController->insertSimpleMissionItem(serArea->center(), missionItems->count());
    _missionController->setCurrentPlanViewIndex(sequenceNumber, true);

Valentin Platzgummer's avatar
Valentin Platzgummer committed
301

302
    // create survey item, will be extened with more mission types in the future
303
    _missionController->insertComplexMissionItem(_missionController->surveyComplexItemName(), opArea->center(), missionItems->count());
304 305 306
    SurveyComplexItem* survey = qobject_cast<SurveyComplexItem*>(missionItems->get(missionItems->count()-1));
    if (survey == nullptr){
        qWarning("WimaController::updateMission(): survey == nullptr");
307
        return false;
308 309 310
    } else {
        survey->surveyAreaPolygon()->clear();
        survey->surveyAreaPolygon()->appendVertices(opArea->coordinateList());
311
        //survey->
312
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
313 314 315 316 317

    // calculate path from take off to opArea
    QGeoCoordinate start = serArea->center();
    QGeoCoordinate end = survey->visualTransectPoints().first().value<QGeoCoordinate>();
    QList<QGeoCoordinate> path;
318
    WimaArea::dijkstraPath(start, end, *_container->joinedArea(), path);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
319
    for (int i = 1; i < path.count()-1; i++) {
320 321
        sequenceNumber = _missionController->insertSimpleMissionItem(path.value(i), missionItems->count()-1);
        _missionController->setCurrentPlanViewIndex(sequenceNumber, true);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
322 323 324 325 326 327
    }

    // calculate return path
    start   = survey->visualTransectPoints().last().value<QGeoCoordinate>();
    end     = serArea->center();
    path.clear();
328
    WimaArea::dijkstraPath(start, end, *_container->joinedArea(), path);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
329
    for (int i = 1; i < path.count()-1; i++) {
330 331
        sequenceNumber = _missionController->insertSimpleMissionItem(path.value(i), missionItems->count());
        _missionController->setCurrentPlanViewIndex(sequenceNumber, true);
Valentin Platzgummer's avatar
Valentin Platzgummer committed
332 333
    }

334
    // create land position item
335 336
    sequenceNumber = _missionController->insertSimpleMissionItem(serArea->center(), missionItems->count());
    _missionController->setCurrentPlanViewIndex(sequenceNumber, true);
337 338 339 340 341 342 343 344 345 346
    SimpleMissionItem* landItem = qobject_cast<SimpleMissionItem*>(missionItems->get(missionItems->count()-1));
    if (landItem == nullptr){
        qWarning("WimaController::updateMission(): landItem == nullptr");
        return false;
    } else {
        Vehicle* controllerVehicle = _masterController->controllerVehicle();
        MAV_CMD landCmd = controllerVehicle->vtol() ? MAV_CMD_NAV_VTOL_LAND : MAV_CMD_NAV_LAND;
        if (controllerVehicle->firmwarePlugin()->supportedMissionCommands().contains(landCmd)) {
            landItem->setCommand(landCmd);
        }
347
    }
Valentin Platzgummer's avatar
Valentin Platzgummer committed
348

349
    return true;
350 351
}

352
void WimaController::saveToCurrent()
353
{
Valentin Platzgummer's avatar
Valentin Platzgummer committed
354
    saveToFile(_currentFile);
355 356
}

357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
void WimaController::saveToFile(const QString& filename)
{
    if (filename.isEmpty()) {
        return;
    }

    QString planFilename = filename;
    if (!QFileInfo(filename).fileName().contains(".")) {
        planFilename += QString(".%1").arg(wimaFileExtension);
    }

    QFile file(planFilename);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
        qgcApp()->showMessage(tr("Plan save error %1 : %2").arg(filename).arg(file.errorString()));
        _currentFile.clear();
        emit currentFileChanged();
    } else {
374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
        FileType fileType = FileType::WimaFile;
        if ( planFilename.contains(QString(".%1").arg(wimaFileExtension)) ) {
            fileType = FileType::WimaFile;
        } else if ( planFilename.contains(QString(".%1").arg(AppSettings::planFileExtension)) ) {
            fileType = FileType::PlanFile;
        } else {
            if ( planFilename.contains(".") ) {
                qgcApp()->showMessage(tr("File format not supported"));
            } else {
                qgcApp()->showMessage(tr("File without file extension not accepted."));
                return;
            }
        }

        QJsonDocument saveDoc = saveToJson(fileType);
389 390 391 392 393 394 395 396
        file.write(saveDoc.toJson());
        if(_currentFile != planFilename) {
            _currentFile = planFilename;
            emit currentFileChanged();
        }
    }
}

397
bool WimaController::loadFromCurrent()
398
{
399 400 401 402 403
    return loadFromFile(_currentFile);
}

bool WimaController::loadFromFile(const QString &filename)
{
404 405 406 407 408
    if (_container == nullptr) {
        qWarning("WimaController::addGOperationArea(): container not initialized!");
        return false;
    }

409
    #define debug 0
410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428
    QString errorString;
    QString errorMessage = tr("Error loading Plan file (%1). %2").arg(filename).arg("%1");

    if (filename.isEmpty()) {
        return false;
    }

    QFileInfo fileInfo(filename);
    QFile file(filename);

    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        errorString = file.errorString() + QStringLiteral(" ") + filename;
        qgcApp()->showMessage(errorMessage.arg(errorString));
        return false;
    }

    if(fileInfo.suffix() == wimaFileExtension) {
        QJsonDocument   jsonDoc;
        QByteArray      bytes = file.readAll();
429

430 431 432 433 434 435
        if (!JsonHelper::isJsonFile(bytes, jsonDoc, errorString)) {
            qgcApp()->showMessage(errorMessage.arg(errorString));
            return false;
        }

        QJsonObject json = jsonDoc.object();
436 437 438

        // AreaItems
        QJsonArray areaArray = json[areaItemsName].toArray();
439
        _container->visualItems()->clear();
440 441 442 443 444 445 446 447 448 449 450 451 452 453

        for( int i = 0; i < areaArray.size(); i++) {
            QJsonObject jsonArea = areaArray[i].toObject();

            if (jsonArea.contains(WimaArea::areaTypeName) && jsonArea[WimaArea::areaTypeName].isString()) {
                if ( jsonArea[WimaArea::areaTypeName] == WimaArea::wimaAreaName ) {
                    WimaArea* area = new WimaArea(this);
                    bool success = area->loadFromJson(jsonArea, errorString);

                    if ( !success ) {
                        qgcApp()->showMessage(errorMessage.arg(errorString));
                        return false;
                    }

454
                    _container->visualItems()->append(area);
455 456 457 458 459 460 461 462 463 464
                    emit visualItemsChanged();
                } else if ( jsonArea[WimaArea::areaTypeName] == WimaGOperationArea::wimaGOperationAreaName) {
                    WimaGOperationArea* opArea = new WimaGOperationArea(this);
                    bool success = opArea->loadFromJson(jsonArea, errorString);

                    if ( !success ) {
                        qgcApp()->showMessage(errorMessage.arg(errorString));
                        return false;
                    }

465
                    _container->visualItems()->append(opArea);
466 467 468 469 470 471 472 473 474 475
                    emit visualItemsChanged();
                } else if ( jsonArea[WimaArea::areaTypeName] == WimaServiceArea::wimaServiceAreaName) {
                    WimaServiceArea* serArea = new WimaServiceArea(this);
                    bool success = serArea->loadFromJson(jsonArea, errorString);

                    if ( !success ) {
                        qgcApp()->showMessage(errorMessage.arg(errorString));
                        return false;
                    }

476
                    _container->visualItems()->append(serArea);
477 478 479 480 481 482 483 484 485 486
                    emit visualItemsChanged();
                } else if ( jsonArea[WimaArea::areaTypeName] == WimaVCorridor::wimaVCorridorName) {
                    WimaVCorridor* corridor = new WimaVCorridor(this);
                    bool success = corridor->loadFromJson(jsonArea, errorString);

                    if ( !success ) {
                        qgcApp()->showMessage(errorMessage.arg(errorString));
                        return false;
                    }

487
                    _container->visualItems()->append(corridor);
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
                    emit visualItemsChanged();
                } else {
                    errorString += QString(tr("%s not supported.\n").arg(WimaArea::areaTypeName));
                    qgcApp()->showMessage(errorMessage.arg(errorString));
                    return false;
                }
            } else {
                errorString += QString(tr("Invalid or non existing entry for %s.\n").arg(WimaArea::areaTypeName));
                return false;
            }
        }

        _currentFile.sprintf("%s/%s.%s", fileInfo.path().toLocal8Bit().data(), fileInfo.completeBaseName().toLocal8Bit().data(), wimaFileExtension);

        emit currentFileChanged();
503
        updateJoinedArea();
504

505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540
        // MissionItems
        // extrac MissionItems part
        QJsonDocument missionJsonDoc = QJsonDocument(json[missionItemsName].toObject());
        // create temporary file with missionItems
        QFile temporaryFile;
        QString cropedFileName = filename.section("/",0,-2);
        #if debug
            qWarning() << cropedFileName;
        #endif
        QString temporaryFileName;
        for (int i = 0; ; i++) {
            temporaryFileName = cropedFileName.append("/temp%1.%2").arg(i).arg(AppSettings::planFileExtension);

            if ( !QFile::exists(temporaryFileName) ) {
                temporaryFile.setFileName(temporaryFileName);
                if ( temporaryFile.open(QIODevice::WriteOnly | QIODevice::Text) ) {
                    break;
                }
            }

            if ( i > 1000) {
                qWarning("WimaController::loadFromFile(): not able to create temporary file.");
                return false;
            }
        }

        temporaryFile.write(missionJsonDoc.toJson());

        // load from temporary file
        _masterController->loadFromFile(temporaryFileName);

        // remove temporary file
        if ( !temporaryFile.remove() ){
            qWarning("WimaController::loadFromFile(): not able to remove temporary file.");
        }

541 542
        return true;

543 544 545 546
    } else if ( fileInfo.suffix() == AppSettings::planFileExtension ){
        _masterController->loadFromFile(filename);

        return true;// might be wrong return value
547 548 549
    } else {
        errorString += QString(tr("File extension not supported.\n"));
        qgcApp()->showMessage(errorMessage.arg(errorString));
550

551 552
        return false;
    }
553 554 555
}

void WimaController::recalcVehicleCorridor()
556 557 558
{

}
559 560 561 562 563 564 565 566 567 568 569 570 571

void WimaController::recalcVehicleMeasurementAreas()
{

}

void WimaController::recalcAll()
{

}

void WimaController::recalcPolygonInteractivity(int index)
{
572
    if (_container != nullptr && index >= 0 && index < _container->visualItems()->count()) {
573
        resetAllInteractive();
574
        WimaArea* interactivePoly = qobject_cast<WimaArea*>(_container->visualItems()->get(index));
575 576
        interactivePoly->setInteractive(true);
    }
577 578
}

579 580
void WimaController::updateJoinedArea()
{
581 582 583 584 585
    if (_container == nullptr) {
        qWarning("WimaController::addGOperationArea(): container not initialized!");
        return;
    }

586 587
    // pick first WimaGOperationArea
    WimaGOperationArea* opArea = nullptr;
588 589
    for (int i = 0; i < _container->visualItems()->count(); i++) {
        WimaGOperationArea* currentArea = qobject_cast<WimaGOperationArea*>(_container->visualItems()->get(i));
590 591 592 593 594 595 596 597 598 599
        if (currentArea != nullptr){
            opArea = currentArea;
            break;
        }
    }
    if (opArea == nullptr)
        return;

    // pick first WimaServiceArea
    WimaServiceArea* serArea = nullptr;
600 601
    for (int i = 0; i < _container->visualItems()->count(); i++) {
        WimaServiceArea* currentArea = qobject_cast<WimaServiceArea*>(_container->visualItems()->get(i));
602 603 604 605 606 607 608 609 610 611
        if (currentArea != nullptr){
            serArea = currentArea;
            break;
        }
    }
    if ( serArea == nullptr )
        return;

    // pick first WimaVCorridor
    WimaVCorridor* corridor = nullptr;
612 613
    for (int i = 0; i < _container->visualItems()->count(); i++) {
        WimaVCorridor* currentArea = qobject_cast<WimaVCorridor*>(_container->visualItems()->get(i));
614 615 616 617 618 619 620 621
        if (currentArea != nullptr){
            corridor = currentArea;
            break;
        }
    }

    // join service area, op area and corridor
    if (corridor != nullptr) {
622 623
        WimaArea::join(*serArea, *corridor, *_container->joinedArea());
        _container->joinedArea()->join(*opArea);
624
    } else {
625
        WimaArea::join(*serArea, *opArea, *_container->joinedArea());
626
    }
627 628

    emit joinedAreaChanged() ;
629 630
}

631
void WimaController::resetAllInteractive()
632
{
633 634 635 636 637 638
    if (_container == nullptr) {
        qWarning("WimaController::addGOperationArea(): container not initialized!");
        return ;
    }

    int itemCount = _container->visualItems()->count();
639 640
    if (itemCount > 0){
        for (int i = 0; i < itemCount; i++) {
641
            WimaArea* iteratorPoly = qobject_cast<WimaArea*>(_container->visualItems()->get(i));
642 643
            iteratorPoly->setInteractive(false);
        }
644 645 646
    }
}

647 648 649 650 651
void WimaController::setInteractive()
{
    recalcPolygonInteractivity(_currentPolygonIndex);
}

652
QJsonDocument WimaController::saveToJson(FileType fileType)
653
{
654 655 656 657 658
    if (_container == nullptr) {
        qWarning("WimaController::addGOperationArea(): container not initialized!");
        return QJsonDocument();
    }

659
    QJsonObject json;
660

661 662
    if ( fileType == FileType::WimaFile ) {
        QJsonArray jsonArray;
663

664
        for (int i = 0; i < _container->visualItems()->count(); i++) {
665
            QJsonObject json;
666

667
            WimaArea* area = qobject_cast<WimaArea*>(_container->visualItems()->get(i));
668

669 670 671 672
            if (area == nullptr) {
                qWarning("WimaController::saveToJson(): Internal error, area == nullptr!");
                return QJsonDocument();
            }
673

674 675 676 677 678 679 680 681 682 683 684 685 686
            WimaGOperationArea* opArea =  qobject_cast<WimaGOperationArea*>(area);
            if (opArea != nullptr) {
                opArea->saveToJson(json);
                jsonArray.append(json);
                continue;
            }

            WimaServiceArea* serArea =  qobject_cast<WimaServiceArea*>(area);
            if (serArea != nullptr) {
                serArea->saveToJson(json);
                jsonArray.append(json);
                continue;
            }
687

688 689 690 691 692 693 694 695 696
            WimaVCorridor* corridor =  qobject_cast<WimaVCorridor*>(area);
            if (corridor != nullptr) {
                corridor->saveToJson(json);
                jsonArray.append(json);
                continue;
            }

            // if non of the obove branches was trigger, type must be WimaArea
            area->saveToJson(json);
697 698 699
            jsonArray.append(json);
        }

700 701 702 703 704 705
        json[areaItemsName] = jsonArray;
        json[missionItemsName] = _masterController->saveToJson().object();

        return QJsonDocument(json);
    } else if (fileType == FileType::PlanFile) {
        return _masterController->saveToJson();
706 707
    }

708
    return QJsonDocument(json);
709 710
}

711 712