525 lines
16 KiB
C++
Executable File
525 lines
16 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* HMI Plugin for Observer Controller - BaseDownloader Dialog
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Patric Karwat, SLSE, 2018-03-17
|
|
*/
|
|
|
|
#include "obd_base_downloader.h"
|
|
#include "ui_obd_base_downloader.h"
|
|
#include "obd_base_downloader_pdf_selector.h"
|
|
|
|
#include <LtsSession/lts_session_data.h>
|
|
#include <nglsettings/nglsettings_connections.h>
|
|
#include <LtsUtilsSettings/settings.h>
|
|
#include <QJsonArray>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QTimer>
|
|
#include <QWebSocket>
|
|
|
|
namespace OcBaseDownload
|
|
{
|
|
|
|
BaseDownloader::BaseDownloader(const QString &menuGroup, LtsSession::LtsSession *session, QWidget *parent)
|
|
: LtsWidgets::LtsDialog(parent, LtsWidgets::ButtonCombination::SeamlessDialog)
|
|
, m_menuGroup(menuGroup)
|
|
, m_errorMsg(QString())
|
|
, m_model(new ExModel(this))
|
|
, m_session(session)
|
|
, m_messageDlg(nullptr)
|
|
, m_state(ConnectionState::Start)
|
|
, m_socket(new QWebSocket(QString(), QWebSocketProtocol::Version13, this))
|
|
, m_timer(new QTimer(this))
|
|
, m_ftcTimer(new QTimer(this))
|
|
, m_exmDtc(nullptr)
|
|
, m_requestHelper(new LtsUtils::RequestHelper(this))
|
|
, m_ui(new Ui::BaseDownloader)
|
|
, m_logger(getLogger("BaseDownloaderDialog"))
|
|
{
|
|
m_ui->setupUi(this);
|
|
m_ui->leStatus->setText(tr("Not Connected"));
|
|
|
|
|
|
#ifndef LTS_DEBUG
|
|
//hide server things
|
|
m_ui->leServer->setVisible(false);
|
|
m_ui->lblServer->setVisible(false);
|
|
m_ui->spPort->setVisible(false);
|
|
#endif
|
|
|
|
setUnchangeable(true);
|
|
m_timer->setSingleShot(true);
|
|
m_timer->setInterval(5000);
|
|
connect(m_timer, &QTimer::timeout, this, &BaseDownloader::onTimerTimeout);
|
|
|
|
m_ftcTimer->setInterval(5*60*1000);
|
|
connect(m_ftcTimer, &QTimer::timeout, this, &BaseDownloader::onFtcTimerTimeout);
|
|
|
|
connect(m_ui->pbDownload, &QPushButton::clicked, this, &BaseDownloader::startBaseDownload);
|
|
connect(m_ui->tvExercises, &LtsDataView::LtsDataView::selectionChanged, this, &BaseDownloader::selectionChanged);
|
|
connect(m_ui->pbConnect, &QPushButton::clicked, this, &BaseDownloader::downloadExercises);
|
|
//connect(m_ui->leServer, &QLineEdit::editingFinished , this, &BaseDownloader::downloadExercises);
|
|
|
|
|
|
connect(m_ui->leServer, &QLineEdit::textChanged, this, [this]
|
|
{
|
|
m_ui->pbConnect->setEnabled(!m_ui->leServer->text().isEmpty());
|
|
});
|
|
|
|
connect(m_socket, &QWebSocket::stateChanged,
|
|
this, &BaseDownloader::onNewSocketState);
|
|
connect(m_socket, &QWebSocket::textMessageReceived,
|
|
this, &BaseDownloader::onNewTextMessageFromSocket);
|
|
} // end of ctor()
|
|
|
|
BaseDownloader::~BaseDownloader()
|
|
{
|
|
m_socket->disconnect(this);
|
|
delete m_ui;
|
|
delete m_messageDlg;
|
|
}
|
|
|
|
bool BaseDownloader::init()
|
|
{
|
|
if (!m_session->getFtc<OcBaseDownload::DataInterface>(m_ftc))
|
|
return false;
|
|
|
|
if (!m_session->getDtc<ExerciseManagement::DataInterface>(m_exmDtc))
|
|
return false;
|
|
|
|
if (strcmp(PROJECTBUILD, "guez") == 0)
|
|
m_ui->pbPdfDownload->hide();
|
|
|
|
m_proxyModel = new ExProxyModel(this);
|
|
m_proxyModel->setSourceModel(m_model);
|
|
m_ui->tvExercises->setModel(m_proxyModel);
|
|
|
|
#ifndef LTS_DEBUG
|
|
m_ui->tvExercises->setColumnHidden(ExModel::Id, true);
|
|
#endif
|
|
m_ui->leServer->setText(NGL::Connections::hostName(NGL::Connections::eConnection::SCM_WEBSOCKET));
|
|
m_ui->spPort->setValue(NGL::Connections::port(NGL::Connections::eConnection::SCM_WEBSOCKET));
|
|
|
|
selectionChanged();
|
|
|
|
m_messageDlg = new BaseDownloaderMessage(this);
|
|
connect(m_messageDlg, &BaseDownloaderMessage::finished, this, [this]
|
|
{
|
|
if (m_ui)
|
|
{
|
|
m_ui->pbDownload->setEnabled(true);
|
|
m_ui->pbPdfDownload->setEnabled(true);
|
|
}
|
|
});
|
|
|
|
connect(m_ui->pbPdfDownload, &QPushButton::clicked,
|
|
this, &BaseDownloader::onPdfDownloadClicked);
|
|
|
|
connect(m_ui->pbOcPdfDownload, &QPushButton::clicked,
|
|
this, &BaseDownloader::onOcPdfDownloadClicked);
|
|
|
|
m_ui->pbOcPdfDownload->hide();
|
|
return true;
|
|
}
|
|
|
|
void BaseDownloader::onStartBaseDownloadReply(const BaseDownloadReply &replyObject)
|
|
{
|
|
DEBUG_LOG(m_logger) << "NEW STATE REPLY: " << replyObject.currentStep() << " \n" << replyObject.progress();
|
|
switch (replyObject.replyState().underlying())
|
|
{
|
|
case Core::FtReplyState::InProgress:
|
|
{
|
|
//restart Timer
|
|
m_ftcTimer->start();
|
|
m_messageDlg->setText(tr("Download in Progress <br> %1").arg(QCoreApplication::translate("dds", replyObject.currentStep().c_str())));
|
|
m_messageDlg->setProgress(replyObject.progress());
|
|
break;
|
|
}
|
|
case Core::FtReplyState::Completed:
|
|
{
|
|
m_ftcTimer->stop();
|
|
m_messageDlg->setText(tr("Download Complete"));
|
|
m_messageDlg->setCloseable(true);
|
|
m_messageDlg->setProgress(100);
|
|
m_ui->pbDownload->setEnabled(true);
|
|
m_ui->pbPdfDownload->setEnabled(true);
|
|
break;
|
|
}
|
|
case Core::FtReplyState::NotStarted:
|
|
break;
|
|
case Core::FtReplyState::Error:
|
|
{
|
|
m_ftcTimer->stop();
|
|
m_messageDlg->setText(tr("Error Downloading Base Data for Exercise %1 <br> Error: %2").arg(m_exerciseId).arg(QString::fromStdString(replyObject.errorString())));
|
|
m_messageDlg->setCloseable(true);
|
|
m_ui->pbDownload->setEnabled(true);
|
|
m_ui->pbPdfDownload->setEnabled(true);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void BaseDownloader::onStartPdfDownloadReply(const PdfDownloadReply &reply)
|
|
{
|
|
m_messageDlg->setText(QString::fromStdString(reply.currentStep()) + QStringLiteral(" ") + QString::number(reply.replyState().underlying()));
|
|
switch (reply.replyState().underlying())
|
|
{
|
|
case Core::FtReplyState::InProgress:
|
|
//restart Timer
|
|
m_ftcTimer->start();
|
|
m_messageDlg->setText(tr("Download in Progress <br> %1").arg(QCoreApplication::translate("dds", reply.currentStep().c_str())));
|
|
m_messageDlg->setProgress(reply.progress());
|
|
break;
|
|
case Core::FtReplyState::Completed:
|
|
{
|
|
m_ftcTimer->stop();
|
|
m_messageDlg->setText(tr("Download Complete"));
|
|
m_messageDlg->setCloseable(true);
|
|
m_messageDlg->setProgress(100);
|
|
m_ui->pbDownload->setEnabled(true);
|
|
m_ui->pbPdfDownload->setEnabled(true);
|
|
break;
|
|
}
|
|
case Core::FtReplyState::NotStarted:
|
|
break;
|
|
case Core::FtReplyState::Error:
|
|
m_ftcTimer->stop();
|
|
m_messageDlg->setText(tr("Error Downloading PDF data"));
|
|
m_messageDlg->setCloseable(true);
|
|
m_ui->pbDownload->setEnabled(true);
|
|
m_ui->pbPdfDownload->setEnabled(true);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void BaseDownloader::startBaseDownload()
|
|
{
|
|
auto ret = LtsWidgets::LtsMessageDialog::showMessage(this,
|
|
tr("Currently downloaded exercise will be deleted. This may take some time."),
|
|
windowTitle(),
|
|
LtsWidgets::Behaviour::Modal,
|
|
LtsWidgets::Button::Ok | LtsWidgets::Button::Cancel);
|
|
if (ret != LtsWidgets::Button::Ok)
|
|
return;
|
|
|
|
m_exerciseId = m_model->getRowData(m_ui->tvExercises->currentIndex().row()).id();
|
|
|
|
|
|
const StartBaseDownloadRequest req(m_exerciseId,
|
|
LtsSessionData::LtsSessionData::getInstance()->getOperatorId(),
|
|
m_ui->spPort->value(),
|
|
m_ui->leServer->text().toStdString(),
|
|
QDateTime::currentMSecsSinceEpoch());
|
|
|
|
DEBUG_LOG(m_logger) << "EXERCISE ID: " << m_exerciseId;
|
|
// NO request helper here, as we got a custom function with a state
|
|
if (m_ftc->startBaseDownloadRequest(req, this))
|
|
{
|
|
m_ui->pbDownload->setEnabled(false);
|
|
m_ui->pbPdfDownload->setEnabled(false);
|
|
m_messageDlg->setText(tr("Start Base Download for Exercise %1").arg(m_exerciseId));
|
|
m_messageDlg->show();
|
|
}
|
|
|
|
}
|
|
|
|
void BaseDownloader::selectionChanged()
|
|
{
|
|
bool isEnabled = m_ui->tvExercises->selectionModel()->selectedRows().size() == 1;
|
|
|
|
m_ui->pbDownload->setEnabled(isEnabled);
|
|
m_ui->pbPdfDownload->setEnabled(isEnabled);
|
|
}
|
|
|
|
void BaseDownloader::downloadExercises()
|
|
{
|
|
if (m_state != ConnectionState::Start)
|
|
{
|
|
m_socket->close();
|
|
m_state = ConnectionState::Start;
|
|
}
|
|
else
|
|
m_socket->open(getUrl(m_ui->leServer->text(), m_ui->spPort->value()));
|
|
}
|
|
|
|
void BaseDownloader::onNewSocketState(QAbstractSocket::SocketState state)
|
|
{
|
|
|
|
bool enable = true;
|
|
|
|
switch (state)
|
|
{
|
|
case QAbstractSocket::UnconnectedState:
|
|
{
|
|
m_ui->leStatus->setText(tr("Not Connected: %1").arg(m_errorMsg));
|
|
break;
|
|
}
|
|
case QAbstractSocket::ConnectingState:
|
|
{
|
|
enable = false;
|
|
m_errorMsg.clear();
|
|
m_ui->leStatus->setText(tr("Connecting to: %1").arg(m_ui->leServer->text()));
|
|
m_ui->pbDownload->setEnabled(false);
|
|
m_ui->pbPdfDownload->setEnabled(false);
|
|
break;
|
|
}
|
|
case QAbstractSocket::ConnectedState:
|
|
{
|
|
enable = false;
|
|
if (m_state == ConnectionState::Start)
|
|
{
|
|
m_state = ConnectionState::ConnectedToExternalServer;
|
|
m_ui->leStatus->setText(tr("Connected to: %1 (Service Management").arg(m_ui->leServer->text()));
|
|
sendProcessListRequest();
|
|
}
|
|
else if (m_state == ConnectionState::ConnectedToExternalServer)
|
|
{
|
|
m_state = ConnectionState::ConnectedToExerciseManagement;
|
|
m_ui->leStatus->setText(tr("Connected to: %1 (Exercise Management").arg(m_ui->leServer->text()));
|
|
sendExerciseListRequest();
|
|
}
|
|
m_ui->pbConnect->setEnabled(true);
|
|
m_ui->pbConnect->setText(tr("Disconnect"));
|
|
|
|
break;
|
|
}
|
|
case QAbstractSocket::ClosingState:
|
|
{
|
|
if (m_state == ConnectionState::ConnectedToExerciseManagement)
|
|
{
|
|
//go back to start
|
|
m_state = ConnectionState::Start;
|
|
}
|
|
m_model->clear();
|
|
m_ui->pbConnect->setEnabled(true);
|
|
m_ui->pbConnect->setText(tr("Get Exercises"));
|
|
m_ui->pbDownload->setEnabled(false);
|
|
m_ui->pbPdfDownload->setEnabled(false);
|
|
break;
|
|
|
|
}
|
|
case QAbstractSocket::HostLookupState:
|
|
{
|
|
m_errorMsg = QStringLiteral(": ") + tr("Can't connect to: %1").arg(m_ui->leServer->text());
|
|
break;
|
|
}
|
|
case QAbstractSocket::ListeningState:
|
|
case QAbstractSocket::BoundState:
|
|
break;
|
|
}
|
|
|
|
m_ui->leServer->setEnabled(enable);
|
|
m_ui->spPort->setEnabled(enable);
|
|
|
|
}
|
|
|
|
void BaseDownloader::onNewTextMessageFromSocket(const QString &message)
|
|
{
|
|
|
|
// stop timer first then handle message
|
|
m_timer->stop();
|
|
if (m_state == ConnectionState::ConnectedToExternalServer)
|
|
{
|
|
DEBUG_LOG(m_logger) << "message from SVC " << message;
|
|
|
|
doConnectToExerciseManagement(message);
|
|
}
|
|
else if (m_state == ConnectionState::ConnectedToExerciseManagement)
|
|
{
|
|
DEBUG_LOG(m_logger) << "message from EXM " << message;
|
|
fillExerciseModel(message);
|
|
}
|
|
}
|
|
|
|
void BaseDownloader::onTimerTimeout()
|
|
{
|
|
QString processName = m_state == ConnectionState::ConnectedToExerciseManagement ? tr("Exercise Management") : tr("Service Management");
|
|
m_errorMsg = QStringLiteral(": ") + tr("No Answer from %1 (%2)").arg(m_ui->leServer->text(), processName);
|
|
m_socket->close();
|
|
}
|
|
|
|
void BaseDownloader::onFtcTimerTimeout()
|
|
{
|
|
//can't use singleshot
|
|
m_ftcTimer->stop();
|
|
m_messageDlg->setText(tr("Error while downloading data: bailing out."));
|
|
m_messageDlg->setCloseable(true);
|
|
m_ui->pbDownload->setEnabled(true);
|
|
m_ui->pbPdfDownload->setEnabled(true);
|
|
}
|
|
|
|
void BaseDownloader::onPdfDownloadClicked()
|
|
{
|
|
m_exerciseId = m_model->getRowData(m_ui->tvExercises->currentIndex().row()).id();
|
|
|
|
if (m_exmDtc->exercise(m_exerciseId).id() != m_exerciseId)
|
|
{
|
|
LtsWidgets::LtsMessageDialog::showMessage(this,
|
|
tr("Make sure to download exercise with ID %1 first.").arg(m_exerciseId),
|
|
windowTitle(),
|
|
LtsWidgets::Behaviour::Modal,
|
|
LtsWidgets::Button::Ok);
|
|
return;
|
|
}
|
|
|
|
BaseDownloaderPdfSelector *pdfSel = new BaseDownloaderPdfSelector(this);
|
|
|
|
pdfSel->show();
|
|
|
|
GetPdfListRequest req(m_exerciseId,
|
|
m_ui->leServer->text().toStdString(),
|
|
m_ui->spPort->value());
|
|
|
|
m_ftc->getPdfListRequest(req, pdfSel);
|
|
|
|
connect(pdfSel, &BaseDownloaderPdfSelector::ok,
|
|
this, [this, pdfSel]()
|
|
{
|
|
|
|
if (m_ftc->startPdfDownloadRequest({pdfSel->checkedPdfIds(),
|
|
m_ui->leServer->text().toStdString(),
|
|
m_model->getRowData(m_ui->tvExercises->currentIndex().row()).id()
|
|
},
|
|
this))
|
|
{
|
|
m_ui->pbDownload->setEnabled(false);
|
|
m_ui->pbPdfDownload->setEnabled(false);
|
|
m_messageDlg->setText(tr("Start PDF download for Exercise %1").arg(m_exerciseId));
|
|
m_messageDlg->show();
|
|
}
|
|
|
|
pdfSel->close();
|
|
});
|
|
}
|
|
|
|
void BaseDownloader::onOcPdfDownloadClicked()
|
|
{
|
|
LtsUtils::ProjectSettings *ps = LtsUtils::ProjectSettings::getInstance();
|
|
const int folderId = ps->value(QStringLiteral("obd"), QStringLiteral("ocPdfDownloadFolderId")).toInt();
|
|
if(folderId <= 0)
|
|
{
|
|
LtsWidgets::LtsMessageDialog::showMessage(this, tr("Couldn't download pdf files: Folder id invalid!"));
|
|
return;
|
|
}
|
|
const QString matrixOperator = LtsSessionData::LtsSessionData::getInstance()->getOperatorName();
|
|
|
|
DEBUG_LOG(m_logger)<<LOGFUNCTION<<" folderId:" <<folderId<<" operatorName: "<<matrixOperator;
|
|
OcPdfDownloadRequest req(folderId,matrixOperator.toStdString());
|
|
m_ftc->ocPdfDownloadRequest(req, this);
|
|
}
|
|
|
|
void BaseDownloader::retranslate()
|
|
{
|
|
translate(m_ui, tr("Base Downloader"));
|
|
}
|
|
|
|
void BaseDownloader::doConnectToExerciseManagement(const QString &message)
|
|
{
|
|
m_socket->close();
|
|
int exPort = -1;
|
|
QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8());
|
|
if (!doc.isObject())
|
|
{
|
|
WARNING_LOG(m_logger) << "No Valid Object in " << message;
|
|
return;
|
|
}
|
|
if (!doc.object().value(QStringLiteral("data")).isArray())
|
|
{
|
|
WARNING_LOG(m_logger) << "No Data Array in" << message;
|
|
return;
|
|
}
|
|
|
|
const QJsonArray exercises = doc.object().value(QStringLiteral("data")).toArray();
|
|
QJsonArray services;
|
|
|
|
for (const QJsonValue &exercise : exercises)
|
|
{
|
|
const QJsonObject &exe = exercise.toObject();
|
|
if (exe.value(QStringLiteral("exerciseId")).toInt(-1) == 0)
|
|
{
|
|
services = exe.value(QStringLiteral("services")).toArray();
|
|
break;
|
|
}
|
|
}
|
|
|
|
for (const QJsonValue &service : qAsConst(services))
|
|
{
|
|
const QJsonObject &obj = service.toObject();
|
|
|
|
if (obj.value(QStringLiteral("name")).toString() == QStringLiteral("ExerciseManagement"))
|
|
{
|
|
const QJsonArray ports = obj.value(QStringLiteral("ports")).toArray();
|
|
for (const QJsonValue &port : ports)
|
|
{
|
|
if (port.toObject().value(QStringLiteral("typeId")).toInt() == 1)
|
|
exPort = port.toObject().value(QStringLiteral("number")).toInt(-1);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (exPort > 0)
|
|
{
|
|
DEBUG_LOG(m_logger) << "Connect To EXM";
|
|
m_socket->open(getUrl(m_ui->leServer->text(), exPort));
|
|
}
|
|
|
|
}
|
|
|
|
QUrl BaseDownloader::getUrl(const QString &adress, unsigned short port) const
|
|
{
|
|
QString url = QLatin1String("ws://") + adress + QLatin1Char(':') + QString::number(port);
|
|
DEBUG_LOG(m_logger) << "Connect to: " << url;
|
|
|
|
return QUrl(url);
|
|
}
|
|
|
|
void BaseDownloader::sendProcessListRequest()
|
|
{
|
|
DEBUG_LOG(m_logger) << "send processListRequest message to SVC";
|
|
m_timer->start();
|
|
m_socket->sendTextMessage(QStringLiteral("{\"type\": \"servicePortsInformationRequest\",\"uuid\": \"7777\"}"));
|
|
m_ui->leStatus->setText(tr("Wait for Service Data."));
|
|
|
|
}
|
|
|
|
void BaseDownloader::sendExerciseListRequest()
|
|
{
|
|
DEBUG_LOG(m_logger) << "send exerciseListRequest message to EXM";
|
|
m_timer->start();
|
|
m_ftcTimer->start();
|
|
m_socket->sendTextMessage(QStringLiteral("{\"type\": \"exerciseInformationRequest\",\"uuid\": \"7777\"}"));
|
|
|
|
m_ui->leStatus->setText(tr("Wait for Exercise Data."));
|
|
}
|
|
|
|
void BaseDownloader::fillExerciseModel(const QString &exerciseList)
|
|
{
|
|
//Exercise{"data":[{"description":"","endTime":1523688359000,"id":35,"name":"Test Exercise 35","startTime":1522824359000,"status":1,"timeZone":"Z"},{"description":"","endTime":1523688359000,"id":42,"name":"Test Exercise 42","startTime":1522824359000,"status":2,"timeZone":"Z"}],"type":"exerciseInformation","uuid":"7777"} (OcBaseDownload/Gui/BaseDownloader/obd_ex_model.cpp:45)
|
|
|
|
m_ui->leStatus->setText(tr("Got Data from Exercise Management."));
|
|
|
|
QJsonDocument doc = QJsonDocument::fromJson(exerciseList.toUtf8());
|
|
if (!doc.isObject() || !doc.object().value(QStringLiteral("data")).isArray())
|
|
{
|
|
WARNING_LOG(m_logger) << "No Valid Object in " << exerciseList;
|
|
m_ui->leStatus->setText(tr("Got Invalid Data from Exercise Management."));
|
|
return;
|
|
}
|
|
|
|
m_model->clear();
|
|
const QJsonArray exercises = doc.object().value(QStringLiteral("data")).toArray();
|
|
|
|
for (const QJsonValue &exercise : exercises)
|
|
{
|
|
const QJsonObject &exe = exercise.toObject();
|
|
m_model->addExercise(exe);
|
|
|
|
}
|
|
}
|
|
|
|
} // namespace OcBaseDownload
|
|
|