Initial commit
This commit is contained in:
commit
b7d90b9afe
16245 files changed
+3396666
No files matched your search
@@ -0,0 +1,416 @@
|
||||
/**
|
||||
* @RDE_HEADER@
|
||||
* $Id$
|
||||
* $HeadURL$
|
||||
* $Author$
|
||||
*/
|
||||
#include "pws_control_dialog.h"
|
||||
#include "ui_pws_control_dialog.h"
|
||||
|
||||
#include "pws_vnc_viewer_dialog.h"
|
||||
|
||||
#include <LtsUtilsSettings/settings.h>
|
||||
#include <LtsSession/lts_session.h>
|
||||
#include <LtsSession/lts_session_data.h>
|
||||
#include <LtsProjectionWorkstation/vnc_server_manager.h>
|
||||
|
||||
#include <nglsettings/nglsettings_connections.h>
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QUuid>
|
||||
#include <QHostInfo>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace ProjectionWorkstation
|
||||
{
|
||||
|
||||
ControlDialog::ControlDialog(const QString &menuGroup, QWidget *parent)
|
||||
: LtsWidgets::LtsDialog(parent)
|
||||
, m_ui(new Ui::ControlDialog)
|
||||
, m_logger(LtsProjectionWorkstation::getLogger(QStringLiteral("ControlDialog")))
|
||||
, m_messageFactory(nullptr)
|
||||
, m_webSocketClient(nullptr)
|
||||
, m_session(nullptr)
|
||||
, m_menuGroup(menuGroup)
|
||||
, m_exerciseId(-1)
|
||||
, m_locationId(-1)
|
||||
, m_isConnected(false)
|
||||
{
|
||||
m_ui->setupUi(this);
|
||||
|
||||
connect(m_ui->pbnConnect, &QPushButton::clicked, this, &ControlDialog::slotOnConnectClicked);
|
||||
connect(m_ui->pbnLogout, &QPushButton::clicked, this, &ControlDialog::slotOnLogoutClicked);
|
||||
connect(m_ui->chbInThisLocationOnly, &QCheckBox::toggled, this, &ControlDialog::fillCombobox);
|
||||
connect(m_ui->chbProjectionWSOnly, &QCheckBox::toggled, this, &ControlDialog::fillCombobox);
|
||||
|
||||
connect(m_ui->cbxWorkstations, QOverload<int>::of(&QComboBox::currentIndexChanged),
|
||||
this, &ControlDialog::slotCbxWorkstationsChanged);
|
||||
|
||||
m_ui->pbnLogout->setEnabled(m_isConnected);
|
||||
m_ui->chbProjectionWSOnly->setVisible(false);
|
||||
|
||||
#ifdef LTS_DEBUG
|
||||
m_ui->chbProjectionWSOnly->setVisible(true);
|
||||
#endif
|
||||
|
||||
setOnlineHelpFilename(QStringLiteral("Situation-Projection_Control"));
|
||||
}
|
||||
|
||||
|
||||
ControlDialog::~ControlDialog()
|
||||
{
|
||||
if (m_webSocketClient)
|
||||
{
|
||||
// NLDEVCTRL-808: OpApp stürzt ab beim beenden (ProjWS)
|
||||
// at initWebSocketHandler the underlying QWebSocket is used for several
|
||||
// connections. But the disconnect was missing. Cleanup a little bit...
|
||||
|
||||
// disconnect in reverse order:
|
||||
// 1) disconnect from underlying QWebSocket
|
||||
if (m_webSocketClient->webSocket())
|
||||
m_webSocketClient->webSocket()->disconnect(); // to avoid our slots to be called
|
||||
|
||||
// 2) disconnect from m_webSocketClient
|
||||
m_webSocketClient->disconnect(this);
|
||||
|
||||
// add reply while destroying?
|
||||
const int userId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
||||
m_webSocketClient->addReply((new LtsProjectionWorkstation::CTS::DisconnectRequest(QUuid::createUuid().toString(), userId))->toReplyMessage());
|
||||
|
||||
// m_webSocketClient->deleteLater(); // ControlDialog is parent of WebSocketClient, therefore useless!?!
|
||||
}
|
||||
delete m_messageFactory;
|
||||
delete m_ui;
|
||||
}
|
||||
|
||||
|
||||
void ControlDialog::initWebSocketHandler()
|
||||
{
|
||||
if (!m_messageFactory)
|
||||
m_messageFactory = new LtsProjectionWorkstation::MessageFactory(this, m_logger);
|
||||
delete m_webSocketClient;
|
||||
m_webSocketClient = new WebSocketClient(m_messageFactory, this);
|
||||
auto s = m_webSocketClient->webSocket();
|
||||
connect(s, &QWebSocket::connected, this, &ControlDialog::slotOnWebSocketConnected);
|
||||
connect(s, QOverload<QAbstractSocket::SocketError>::of(&QWebSocket::error), this, &ControlDialog::slotOnWebSocketError);
|
||||
connect(s, QOverload<const QList<QSslError>&>::of(&QWebSocket::sslErrors), this, &ControlDialog::slotOnWebSocketSslError);
|
||||
connect(s, &QWebSocket::disconnected, this, &ControlDialog::slotOnWebSocketDisconnected);
|
||||
}
|
||||
|
||||
|
||||
bool ControlDialog::init(LtsSession::LtsSession *session,
|
||||
const std::shared_ptr<OperatorManagement::Interface::Dtc> &opmDtc,
|
||||
const std::shared_ptr<OperatorManagement::ForeignSettingsGuiInterface> &opmIfc,
|
||||
const std::shared_ptr<AssetManagement::Interface::Dtc> &asmDtc, int exerciseId)
|
||||
{
|
||||
if (!session)
|
||||
return false;
|
||||
|
||||
m_session = session;
|
||||
|
||||
m_opmDtc = opmDtc;
|
||||
m_opmIfc = opmIfc;
|
||||
m_asmDtc = asmDtc;
|
||||
|
||||
if (exerciseId < 0) return false;
|
||||
m_exerciseId = exerciseId;
|
||||
|
||||
LtsSessionData::LtsSessionData *sessionData = LtsSessionData::LtsSessionData::getInstance();
|
||||
auto getLocationIdFunc =
|
||||
[sessionData, this](const AssetManagement::Asset & data) -> bool
|
||||
{
|
||||
if (data.id() == sessionData->getWorkstationId())
|
||||
{
|
||||
m_locationId = data.locationId();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
m_asmDtc->assets(std::function<bool(const AssetManagement::Asset &data)>(getLocationIdFunc));
|
||||
|
||||
fillCombobox();
|
||||
|
||||
QString txt = m_ui->cbxWorkstations->currentText();
|
||||
|
||||
if (!txt.isEmpty())
|
||||
{
|
||||
QHostInfo info = QHostInfo::fromName(txt);
|
||||
if (info.addresses().size() > 0)
|
||||
m_host = info.addresses().at(0);
|
||||
else
|
||||
ERROR_LOG(m_logger) << "Address for host " << m_ui->cbxWorkstations->currentText() << " not found!";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void ControlDialog::aboutToClose()
|
||||
{
|
||||
for (VncViewerDialog *diag : qAsConst(m_viewers))
|
||||
diag->closeRequest();
|
||||
m_viewers.clear();
|
||||
|
||||
if (m_webSocketClient)
|
||||
{
|
||||
const int userId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
||||
m_webSocketClient->addReply((new LtsProjectionWorkstation::CTS::DisconnectRequest(QUuid::createUuid().toString(), userId))->toReplyMessage());
|
||||
m_webSocketClient->webSocket()->disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ControlDialog::slotOnConnectClicked()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this;
|
||||
if (!m_isConnected)
|
||||
{
|
||||
initWebSocketHandler();
|
||||
int port = NGL::Connections::port(NGL::Connections::eConnection::PWS_WEBSOCKET);
|
||||
if (m_webSocketClient)
|
||||
m_webSocketClient->webSocket()->open(QUrl(QStringLiteral("ws://%1:%2/").arg(m_host.toString()).arg(port)));
|
||||
m_ui->pbnConnect->setEnabled(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_webSocketClient)
|
||||
{
|
||||
const int userId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
||||
m_webSocketClient->addReply((new LtsProjectionWorkstation::CTS::DisconnectRequest(QUuid::createUuid().toString(), userId))->toReplyMessage());
|
||||
m_webSocketClient->webSocket()->close();
|
||||
}
|
||||
}
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " connect clicked, this=" << this;
|
||||
updateConnectButton();
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this;
|
||||
}
|
||||
|
||||
void ControlDialog::slotOnLogoutClicked()
|
||||
{
|
||||
if (m_webSocketClient)
|
||||
{
|
||||
m_webSocketClient->addReply((new LtsProjectionWorkstation::CTS::LogoutRequest(QUuid::createUuid().toString()))->toReplyMessage());
|
||||
m_webSocketClient->webSocket()->close();
|
||||
}
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " logout clicked, this=" << this;
|
||||
updateConnectButton();
|
||||
}
|
||||
|
||||
|
||||
void ControlDialog::slotOnWebSocketConnected()
|
||||
{
|
||||
LtsSessionData::LtsSessionData *sessioData = LtsSessionData::LtsSessionData::getInstance();
|
||||
int userId = sessioData->getOperatorId();
|
||||
int exerciseId = m_exerciseId;
|
||||
OperatorManagement::User user = m_opmDtc->user(userId);
|
||||
if (user.id() > 0)
|
||||
{
|
||||
// NLDEVCTRL-445: Projektion Filter und Kartenausschnitt
|
||||
// very new app 'Lage', workspace isn`t saved yet and therefore no workspaceId.
|
||||
// But callWorkspaceSaveUnsaved needs an workspaceId for transfering the workspace with filter:
|
||||
QString workspaceIdToUse = m_session->workspaceId();
|
||||
if (workspaceIdToUse.isEmpty())
|
||||
{
|
||||
workspaceIdToUse = QUuid::createUuid().toString();
|
||||
INFO_LOG(m_logger) << "workspaceIdToUse " << workspaceIdToUse;
|
||||
}
|
||||
m_opmIfc->callWorkspaceSaveUnsaved(workspaceIdToUse);
|
||||
LtsUtils::OperatorSettings* opSettings = LtsUtils::OperatorSettings::getInstance();
|
||||
opSettings->setValue(QStringLiteral("PwsWorkspace"), QStringLiteral("CurrentId"), workspaceIdToUse);
|
||||
QByteArray opSettingsData = LtsUtils::OperatorSettings::getInstance()->exportSettings();
|
||||
|
||||
// This does not work since m_session->setWorkspaceId() triggers loading of filters on controlling WS :-(
|
||||
// if (m_session->workspaceId().isEmpty())
|
||||
// {
|
||||
// const QString newId(QUuid::createUuid().toString());
|
||||
// INFO_LOG(m_logger) << "new WsId" << newId;
|
||||
// m_session->setWorkspaceId(newId);
|
||||
// }
|
||||
// m_opmIfc->callWorkspaceSaveUnsaved();
|
||||
// LtsUtils::OperatorSettings* opSettings = LtsUtils::OperatorSettings::getInstance();
|
||||
// opSettings->setValue(QStringLiteral("PwsWorkspace"), QStringLiteral("CurrentId"), m_session->workspaceId());
|
||||
// QByteArray opSettingsData = LtsUtils::OperatorSettings::getInstance()->exportSettings();
|
||||
|
||||
INFO_LOG(m_logger) << " connect userId=" << userId
|
||||
<< ", with prio=" << user.projectionPriority()
|
||||
<< ", PwsWorkspace/Id='" << workspaceIdToUse << "'";
|
||||
|
||||
LtsProjectionWorkstation::CTS::LoginRequest req(QUuid::createUuid().toString(),
|
||||
userId,
|
||||
user.projectionPriority(),
|
||||
exerciseId, opSettingsData);
|
||||
m_webSocketClient->addReply(req.toReplyMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ControlDialog::slotOnVncDisconnected()
|
||||
{
|
||||
INFO_LOG(m_logger) << " slotOnVncDisconnected";
|
||||
|
||||
if (m_webSocketClient)
|
||||
{
|
||||
const int userId = LtsSessionData::LtsSessionData::getInstance()->getOperatorId();
|
||||
m_webSocketClient->addReply((new LtsProjectionWorkstation::CTS::DisconnectRequest(QUuid::createUuid().toString(), userId))->toReplyMessage());
|
||||
}
|
||||
m_isConnected = false;
|
||||
if (!m_ui || !m_ui->pbnConnect)
|
||||
return;
|
||||
m_ui->pbnConnect->setEnabled(true);
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " VNC disconnected, this=" << this;
|
||||
updateConnectButton();
|
||||
}
|
||||
|
||||
void ControlDialog::slotOnWebSocketDisconnected()
|
||||
{
|
||||
for (VncViewerDialog *diag : qAsConst(m_viewers))
|
||||
diag->closeRequest(); // will be deleted automatically
|
||||
m_viewers.clear();
|
||||
m_isConnected = false;
|
||||
if (m_ui && m_ui->pbnConnect)
|
||||
m_ui->pbnConnect->setEnabled(true);
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " WEBSOCKET disconnected, this=" << this;
|
||||
updateConnectButton();
|
||||
}
|
||||
|
||||
|
||||
void ControlDialog::slotOnWebSocketError()
|
||||
{
|
||||
ERROR_LOG(m_logger) << m_webSocketClient->webSocket()->errorString();
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, m_webSocketClient->webSocket()->errorString(), tr("Connection to the presentation workstation failed!"));
|
||||
m_isConnected = false;
|
||||
m_ui->pbnConnect->setEnabled(true);
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " VWEBSOCKET ERROR, this=" << this;
|
||||
updateConnectButton();
|
||||
}
|
||||
|
||||
|
||||
void ControlDialog::slotOnWebSocketSslError()
|
||||
{
|
||||
if (m_webSocketClient)
|
||||
m_webSocketClient->webSocket()->ignoreSslErrors();
|
||||
}
|
||||
|
||||
|
||||
void ControlDialog::slotCbxWorkstationsChanged()
|
||||
{
|
||||
QString txt = m_ui->cbxWorkstations->currentText();
|
||||
if (txt.isEmpty())
|
||||
return;
|
||||
QHostInfo info = QHostInfo::fromName(txt);
|
||||
if (info.addresses().size() > 0)
|
||||
m_host = info.addresses().at(0);
|
||||
else
|
||||
ERROR_LOG(m_logger) << "Address for host " << m_ui->cbxWorkstations->currentText() << " not found!";
|
||||
}
|
||||
|
||||
|
||||
void ControlDialog::fillCombobox()
|
||||
{
|
||||
m_ui->cbxWorkstations->clear();
|
||||
|
||||
m_asmDtc->assets([this](const AssetManagement::Asset & data)
|
||||
{
|
||||
if (m_ui->chbProjectionWSOnly->isChecked() &&
|
||||
data.assetTypeId() != AssetManagement::AssetType_def::ProjectionWorkstation)
|
||||
return;
|
||||
if (m_ui->chbInThisLocationOnly->isChecked() &&
|
||||
data.locationId() != m_locationId)
|
||||
return;
|
||||
|
||||
m_ui->cbxWorkstations->addItem(QString::fromStdString(data.name()));
|
||||
});
|
||||
m_ui->cbxWorkstations->model()->sort(0);
|
||||
|
||||
}
|
||||
|
||||
void ControlDialog::updateConnectButton()
|
||||
{
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " START, this=" << this
|
||||
<< ", m_isConnected=" << m_isConnected
|
||||
<< ", pbnConnect->text()=" << m_ui->pbnConnect->text();
|
||||
if (!m_ui)
|
||||
return;
|
||||
m_ui->pbnConnect->setText(m_isConnected ? tr("Disonnect") : tr("Connect"));
|
||||
m_ui->pbnLogout->setEnabled(m_isConnected);
|
||||
TRACE_LOG(m_logger) << LOGFUNCTION << " END, this=" << this
|
||||
<< ", m_isConnected=" << m_isConnected
|
||||
<< ", pbnConnect->text()=" << m_ui->pbnConnect->text();
|
||||
}
|
||||
|
||||
|
||||
void ControlDialog::handleMessage(LtsWebSocket::AbstractClientMessage *message)
|
||||
{
|
||||
using namespace LtsProjectionWorkstation::STC;
|
||||
LoginRequestReply *login = dynamic_cast<LtsProjectionWorkstation::STC::LoginRequestReply *>(message);
|
||||
if (login)
|
||||
{
|
||||
if (login->reason() == LoginRequestReply::LoginSuccessful)
|
||||
{
|
||||
for (const LtsProjectionWorkstation::VncScreen &screen : login->screens())
|
||||
{
|
||||
VncViewerDialog *vnc = new VncViewerDialog(screen.name, this);
|
||||
if (vnc->init(m_host, screen.port, screen.geometry.size()))
|
||||
{
|
||||
m_viewers.append(vnc);
|
||||
connect(vnc, &VncViewerDialog::disconnected, this, &ControlDialog::slotOnVncDisconnected);
|
||||
QString name = screen.name;
|
||||
name.remove(QLatin1Char(' '));
|
||||
addDialog(vnc, m_menuGroup, name,
|
||||
LtsWidgets::LayoutArea::eDialogTab, false, false);
|
||||
}
|
||||
}
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " LoginSuccessful YES, this=" << this;
|
||||
m_isConnected = true;
|
||||
m_ui->pbnConnect->setEnabled(true);
|
||||
updateConnectButton();
|
||||
}
|
||||
else
|
||||
{
|
||||
QString errMsg;
|
||||
switch (login->reason())
|
||||
{
|
||||
case LoginRequestReply::LoginSuccessful:
|
||||
break;
|
||||
case LoginRequestReply::OtherUser:
|
||||
errMsg = tr("The connection is blocked by user %1")
|
||||
.arg(QString::fromStdString(m_opmDtc->user(login->reasonUserId()).name()));
|
||||
break;
|
||||
}
|
||||
|
||||
LtsWidgets::LtsMessageDialog::showMessage(this, errMsg, tr("Login failed!"));
|
||||
DEBUG_LOG(m_logger) << LOGFUNCTION << " LoginSuccessful NO, this=" << this;
|
||||
m_isConnected = false;
|
||||
m_ui->pbnConnect->setEnabled(true);
|
||||
updateConnectButton();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
LtsProjectionWorkstation::STC::DedicatedDisconnect *disconnect = dynamic_cast<LtsProjectionWorkstation::STC::DedicatedDisconnect *>(message);
|
||||
if (disconnect)
|
||||
{
|
||||
INFO_LOG(m_logger) << " DedicatedDisconnect.. "
|
||||
<< ", getOperatorId=" << LtsSessionData::LtsSessionData::getInstance()->getOperatorId()
|
||||
<< ", disconnect->userid()=" << disconnect->userid();
|
||||
if ( (disconnect->userid() != LtsSessionData::LtsSessionData::getInstance()->getOperatorId()) && m_isConnected)
|
||||
{
|
||||
slotOnWebSocketDisconnected();
|
||||
INFO_LOG(m_logger) << " DedicatedDisconnect.. done";
|
||||
|
||||
// NLDEVCTRL-445: Projektion Filter und Kartenausschnitt:
|
||||
// LtsWidgets::LtsMessageDialog::showMessage(this, tr("There is already a user with a higher priority connected. Please wait until the user has ended the session."), tr("Disconnected"));
|
||||
// LtsMessageDialog is blocking ; but we need unblocking:
|
||||
new LtsWidgets::LtsMessageDialogNew(this, tr("There is already a user with a higher priority connected. Please wait until the user has ended the session."), tr("Disconnected"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ControlDialog::retranslate()
|
||||
{
|
||||
translate(m_ui, tr("Control Projection"));
|
||||
}
|
||||
|
||||
} // ProjectionWorkstation
|
||||
Reference in new issue
Block a user