Files
qt5-legatus-legacy/Lts/Plugins/OperatorManagement/Gui/Login/opm_login_dialog.cpp
T
2026-08-13 18:33:10 +02:00

577 lines
15 KiB
C++
Executable File

/**
* @RDE_HEADER@
* Login Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Mike Wille, SLSE, 2016-05-05
*/
#include "opm_login_dialog.h"
#include "ui_opm_login_dialog.h"
#include <LtsSession/lts_session_manager.h>
#include <LtsSession/lts_session.h>
#include <LtsSession/lts_session_data.h>
#include <Services/OperatorManagement/opm_ftc.h>
#include <LtsMultiMonitor/lts_multi_monitor.h>
#include <StyleManager/style_manager.h>
#include <LtsWidgets/lts_base.h>
#include <ngltranslator/ngltranslator.h>
#include <LtsUtilsSettings/settings.h>
#include <LtsWidgets/lts_global_wait_dialog.h>
#include <QDebug>
#include <QMessageBox>
#include <QGuiApplication>
#include <QScreen>
#include <QStyle>
#include <QGraphicsDropShadowEffect>
#include <QProcess>
#include <QMenu>
#include <QFile>
#include <QUdpSocket>
#ifdef Q_OS_LINUX
#include <X11/Xlib.h>
#endif
namespace OperatorManagement
{
LoginWindow::LoginWindow(QWidget *parent, bool isAAR)
: QDialog(parent)
, m_ui(new Ui::LoginWindow)
, m_done(false)
, m_isAAR(isAAR)
{
setWindowFlag(Qt::WindowMinimizeButtonHint, false);
setWindowFlag(Qt::WindowCloseButtonHint, false);
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
m_ui->setupUi(this);
#ifdef Q_OS_LINUX
QTimer *t = new QTimer(this);
t->setInterval(1000);
connect(t, &QTimer::timeout,
this, [this]()
{
#ifndef LTS_DEBUG
if (LtsSessionData::LtsSessionData::getInstance()->debugFlagValue(QStringLiteral("Login.ShowFocus")) == QVariant(true))
#endif
{
Display *dp = XOpenDisplay(nullptr);
if (dp == nullptr)
{
m_ui->lbLoginText->setText(QStringLiteral("Unable to get screen!"));
return;
}
Window focused;
int revert = 0;
XGetInputFocus(dp, &focused, &revert);
XCloseDisplay(dp);
m_ui->lbLoginText->setText(QStringLiteral("Focused window id: 0x%1").arg(QString::number(focused, 16)));
}
});
t->start();
#endif
setWindowTitle(tr("Login"));
setMouseTracking(true); // register mouse movement
bool mmm = LtsMultiMonitor::LtsMultiMonitor::getInstance()->isActive();
if (mmm)
{
setWindowFlags(windowFlags() | /*Qt::WindowStaysOnTopHint | */Qt::FramelessWindowHint); // hints..
setAttribute(Qt::WA_TranslucentBackground);
}
m_hideTimer.setInterval(30000);
if(!LtsSessionData::LtsSessionData::getInstance()->isTablet())
connect(&m_hideTimer, &QTimer::timeout, this, &LoginWindow::slotHide);
connect(m_ui->leOperatorName, &QLineEdit::textChanged, this, [this]()
{
if (m_hideTimer.isActive())
m_hideTimer.start();
});
QList<QLabel *> labels = findChildren<QLabel *>();
for (QList<QLabel *>::const_iterator i = labels.constBegin(); i != labels.constEnd(); ++i)
{
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect(this); // cannot copy this..
shadow->setOffset(0, 0);
shadow->setBlurRadius(22);
shadow->setColor(QColor("white"));
(*i)->setGraphicsEffect(shadow);
}
LtsSessionData::LtsSessionData *sessionData = LtsSessionData::LtsSessionData::getInstance();
if (sessionData->isTablet())
{
setGeometry(QStyle::alignedRect(
Qt::LeftToRight,
Qt::AlignHCenter | Qt::AlignTop,
size(),
QGuiApplication::primaryScreen()->geometry()));
}
else
{
setGeometry(QStyle::alignedRect(
Qt::LeftToRight,
Qt::AlignHCenter | Qt::AlignVCenter,
size(),
QGuiApplication::primaryScreen()->geometry()));
}
QMenu *shutdownMenu = new QMenu(m_ui->pbShutdown);
QAction *action = shutdownMenu->addAction(tr("Shutdown"), this, &LoginWindow::slotShutdown );
QFont font = action->font();
#ifdef TABLET_MODE
font.setPointSizeF(font.pointSizeF()*1.5);
#endif
action->setFont(font);
action = shutdownMenu->addAction(tr("Reboot"), this, &LoginWindow::slotReboot );
action->setFont(font);
#ifndef GUEZ_MODE
#ifdef TABLET_MODE
if (PROJECTBUILD == "ahtc")
{
action = shutdownMenu->addAction(tr("Logout"), this, &LoginWindow::slotOperatorLogout );
action->setFont(font);
}
#endif
#endif
m_ui->pbShutdown->setMenu(shutdownMenu);
#ifdef TABLET_MODE
// m_ui->pbExit->setFont(font);
// m_ui->pbShutdown->setFont(font);
#endif
connect(m_ui->pbGo, &QPushButton::clicked,
this, &LoginWindow::slotLogin, Qt::QueuedConnection); // TODO: can be direct (?)
connect(m_ui->pbExit, &QPushButton::clicked,
this, &LoginWindow::slotExit);
// connect(m_ui->pbShutdown, &QPushButton::clicked,
// this, &LoginWindow::slotShutdown);
connect(m_ui->pbDe_DE, &QPushButton::clicked,
this, &LoginWindow::onLanguageChange);
connect(m_ui->pbEn_GB, &QPushButton::clicked,
this, &LoginWindow::onLanguageChange);
connect(m_ui->pbEn_US, &QPushButton::clicked,
this, &LoginWindow::onLanguageChange);
m_ui->pbDe_DE->hide();
m_ui->pbEn_GB->hide();
m_ui->pbEn_US->hide();
const QString languages = LtsUtils::ProjectSettings::getInstance()->value(QStringLiteral("pdm"), QStringLiteral("SystemLanguages")).toString();
const QVector<QStringRef> slLang = languages.splitRef(QLatin1Char(','), QString::SkipEmptyParts);
if (slLang.isEmpty())
{
qWarning() << "LoginWindow::c_tor: Missing 'SystemLanguages' entry in project settings file!";
}
else
{
if (slLang.size() > 1)
{
for (QStringRef lang : slLang)
{
lang = lang.trimmed();
// qWarning() << "available language:" << lang.toString();
if (lang == QLatin1String("de_DE"))
m_ui->pbDe_DE->show();
if (lang == QLatin1String("en_GB"))
m_ui->pbEn_GB->show();
if (lang == QLatin1String("en_US"))
m_ui->pbEn_US->show();
}
if (NGL::translationLocale() == "de_DE")
m_ui->pbDe_DE->click();
if (NGL::translationLocale() == "en_GB")
m_ui->pbEn_GB->click();
if (NGL::translationLocale() == "en_US")
m_ui->pbEn_US->click();
}
else
{
QString lang = slLang.at(0).toString().trimmed();
// qWarning() << "available language:" << slLang.at(0).toString();
if (lang.toLatin1() == "de_DE")
m_ui->pbDe_DE->click();
if (lang.toLatin1() == "en_GB")
m_ui->pbEn_GB->click();
if (lang.toLatin1() == "en_US")
m_ui->pbEn_US->click();
}
}
QMenu *styleMenu = new QMenu(m_ui->pbStyle);
styleMenu->addAction(tr("Light"), this, &LoginWindow::slotLightStyle);
styleMenu->addAction(tr("Dark"), this, &LoginWindow::slotDarkStyle);
m_ui->pbStyle->setMenu(styleMenu);
slotLightStyle();
// PROJECT LOGO
QString projectLogoFilename(QStringLiteral(":project/login_logo.png"));
if (!QFile(projectLogoFilename).exists())
projectLogoFilename = QStringLiteral(":/project/logo.png");
QPixmap pixmap(projectLogoFilename);
if (pixmap.isNull())
{
qWarning() << "LoginWindow::c_tor: (PROJECT LOGO) file missing or is not an valid image '" << projectLogoFilename << "'";
}
else
{
pixmap = pixmap.scaled(m_ui->lbRDELogo->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
m_ui->lbRDELogo->setPixmap(pixmap);
}
auto setFocusCb = [this]()
{
QApplication::setActiveWindow(this);
};
QTimer::singleShot(50, this, setFocusCb);
if (LtsSessionData::LtsSessionData::getInstance()->isTablet())
m_ui->leOperatorName->setFocusPolicy(Qt::ClickFocus);
else if (mmm && !LtsSessionData::LtsSessionData::getInstance()->isTablet())
m_hideTimer.start();
setMinimumSize(sizeHint());
m_ui->leOperatorName->setFocus();
}
LoginWindow::~LoginWindow()
{
delete m_ui;
// qCritical() << "~LoginWindow";
}
QString LoginWindow::getOperatorName() const
{
return m_ui->leOperatorName->text();
}
void LoginWindow::setAARLabel(bool isAAR, bool connectedLocal)
{
if (!isAAR)
m_ui->lblConnectedTo->hide();
else
{
m_ui->lblConnectedTo->setStyleSheet(QStringLiteral("background-color: white;"));
if (connectedLocal)
m_ui->lblConnectedTo->setText(tr("Connected to local database"));
else
m_ui->lblConnectedTo->setText(tr("Connected to network"));
}
}
void LoginWindow::setStyle(const QString &name)
{
#ifdef TABLET_MODE
LtsUtils::StyleManager::getInstance()->loadStyle(name, true);
#else
LtsUtils::StyleManager::getInstance()->loadStyle(name, false);
#endif
}
void LoginWindow::slotLightStyle()
{
setStyle(QStringLiteral("rme.light"));
}
void LoginWindow::slotDarkStyle()
{
setStyle(QStringLiteral("rme.dark"));
}
void LoginWindow::slotExit()
{
LtsWidgets::LtsGlobalWaitDialog::getInstance()->wait(tr("Shutting down ..."));
//QMetaObject::invokeMethod
QTimer::singleShot(500, this, [this]()
{
m_ui->pbExit->setText(tr("exiting ..."));
m_ui->pbExit->setEnabled(false);
m_ui->pbDe_DE->setEnabled(false);
m_ui->pbEn_GB->setEnabled(false);
m_ui->pbEn_US->setEnabled(false);
m_ui->pbGo->setEnabled(false);
m_ui->pbShutdown->setEnabled(false);
m_ui->leOperatorName->setEnabled(false);
if (m_isAAR)
{
QStringList args;
QString cmd = QStringLiteral("openbox");
args << QStringLiteral("--exit");
qWarning() << "start openbox --exit";
QProcess::startDetached(cmd, args);
}
//QCoreApplication::processEvents();
QCoreApplication::quit(); // simply exit event loop, cleanup is done by main() automatically (THIS is the only way to exit the application! via the Login Dialog)
});//, Qt::QueuedConnection);
}
void LoginWindow::slotShutdown()
{
QMessageBox msgBox;
QFont font = msgBox.font();
#ifdef TABLET_MODE
font.setPointSizeF(font.pointSizeF()*1.5);
#endif
msgBox.setWindowTitle(tr("Shutdown"));
msgBox.setText(tr("Are you sure you want to shut down the system?"));
QAbstractButton* pButtonYes = msgBox.addButton(QMessageBox::Yes);
pButtonYes->setMinimumWidth(150);
pButtonYes->setFont(font);
QAbstractButton* pButtonNo = msgBox.addButton(QMessageBox::No);
pButtonNo->setMinimumWidth(150);
pButtonNo->setFont(font);
int ret = msgBox.exec();
if (ret == QMessageBox::Yes)
{
#ifdef TABLET_MODE
if (strcmp(PROJECTBUILD, "commaster") == 0) // may add a new plugin or projectBuild for that? demotablet for now
{
QByteArray queryTimeline("$IIXDR,S,1,,SERVICE_CONTROL_PRESHUTDOWN*79");
QUdpSocket *socket = new QUdpSocket(this);
socket->writeDatagram(queryTimeline, QHostAddress(QStringLiteral("172.16.255.255")), 10110);
}
#endif
QString cmd;
#ifdef LTS_DEBUG
cmd = QStringLiteral("xeyes");
#else
#ifdef Q_OS_WIN
cmd = QStringLiteral("shutdown /s /t 0"); // s = shutdown t = time in seconds
#else
cmd = QStringLiteral("systemctl poweroff");
#endif
#endif
QProcess::startDetached(cmd);
QCoreApplication::quit();
}
}
void LoginWindow::slotReboot()
{
QMessageBox msgBox;
QFont font = msgBox.font();
#ifdef TABLET_MODE
font.setPointSizeF(font.pointSizeF()*1.5);
#endif
msgBox.setWindowTitle(tr("Reboot"));
msgBox.setText(tr("Are you sure you want to reboot the system?"));
QAbstractButton* pButtonYes = msgBox.addButton(QMessageBox::Yes);
pButtonYes->setMinimumWidth(150);
pButtonYes->setFont(font);
QAbstractButton* pButtonNo = msgBox.addButton(QMessageBox::No);
pButtonNo->setMinimumWidth(150);
pButtonNo->setFont(font);
int ret = msgBox.exec();
if (ret == QMessageBox::Yes)
{
QString cmd;
#ifdef LTS_DEBUG
cmd = QStringLiteral("xeyes");
#else
#ifdef Q_OS_WIN
cmd = QStringLiteral("shutdown /r /t 0"); // s = shutdown t = time in seconds
#else
cmd = QStringLiteral("systemctl reboot");
#endif
#endif
QProcess::startDetached(cmd);
QCoreApplication::quit();
}
}
void LoginWindow::slotOperatorLogout()
{
QMessageBox msgBox;
QFont font = msgBox.font();
#ifdef TABLET_MODE
font.setPointSizeF(font.pointSizeF()*1.5);
#endif
msgBox.setWindowTitle(tr("Shutdown"));
msgBox.setText(tr("Are you sure you want to shut down the system?"));
QAbstractButton* pButtonYes = msgBox.addButton(QMessageBox::Yes);
pButtonYes->setMinimumWidth(150);
pButtonYes->setFont(font);
QAbstractButton* pButtonNo = msgBox.addButton(QMessageBox::No);
pButtonNo->setMinimumWidth(150);
pButtonNo->setFont(font);
int ret = msgBox.exec();
if (ret == QMessageBox::Yes)
{
QString cmd;
/*
#ifdef LTS_DEBUG
cmd = QStringLiteral("xeyes");
#else
*/
#ifdef Q_OS_WIN
cmd = QStringLiteral("logoff"); // logoff
#else
cmd = QStringLiteral("loginctl terminate-user ctc_ws");
#endif
/*
#endif
*/
QProcess::startDetached(cmd);
QCoreApplication::quit();
}
}
void LoginWindow::slotOperatorAction() // TODO: can re-show already finished dialog when some there is NO modal window that inactivates the main background ???
{
if (m_done) // do NOT reshow after login (as window is hidden then) and the return key will be processed again, as we did not return from slotOperatorAction.... holy shit!
return;
//qWarning() << "slotOperatorAction";
if (LtsMultiMonitor::LtsMultiMonitor::getInstance()->isActive() && !LtsSessionData::LtsSessionData::getInstance()->isTablet())
m_hideTimer.start(); // restarts timer (hides window on timeout)
if (!isVisible()) // do not use isHidden (see F1)
{
// windows (linux ignores that and centers the dialog automatically):
setGeometry(QStyle::alignedRect(
Qt::LeftToRight,
Qt::AlignHCenter | Qt::AlignVCenter,
size(),
QGuiApplication::primaryScreen()->geometry()));
// m_ui->leOperatorName->setFocus();
show();
}
//raise();
QApplication::setActiveWindow(this);
m_ui->leOperatorName->setFocus();
}
bool LoginWindow::event(QEvent *event)
{
switch (event->type())
{
#undef KeyPress // X.h defines it
case QEvent::KeyPress: // respect typing into textfields
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseMove:
{
slotOperatorAction();
break;
}
default:
{
break;
}
}
return QDialog::event(event);
}
void LoginWindow::closeEvent(QCloseEvent *event) // TODO: override reject()
{
#ifdef DEVEL
(void)event;
// event->accept();
// emit signalSuccess(); // pretend we have chosen an exercise ..
// deleteLater(); // .. end don't come back
#else
event->ignore();
exit(0); // do not allow access to the opapp without login on NON-DEVEL
#endif
}
void LoginWindow::changeEvent(QEvent *e)
{
QDialog::changeEvent(e);
if (e->type() == QEvent::LanguageChange)
m_ui->retranslateUi(this);
}
void LoginWindow::slotHide()
{
m_hideTimer.stop(); // window hidden, no need to hide it by timeout
hide();
}
void LoginWindow::slotCancel() // TODO: override reject()
{
//#ifdef DEVEL
// emit signalQuit();
// //QCoreApplication::quit(); // end main event loop so that the applications ends when main() ends !
// //exit(0);
//#else
// slotHide();
//#endif
}
void LoginWindow::slotLogin()
{
if (m_ui->leOperatorName->text().isEmpty())
return;
onLanguageChange(); // not really needed
hide();
emit signalOperatorSelected(m_ui->leOperatorName->text());
}
void LoginWindow::onLanguageChange()
{
if (m_ui->pbDe_DE->isChecked())
NGL::setTranslationLocale(QByteArray("de_DE"));
if (m_ui->pbEn_GB->isChecked())
NGL::setTranslationLocale(QByteArray("en_GB"));
if (m_ui->pbEn_US->isChecked())
NGL::setTranslationLocale(QByteArray("en_US"));
}
} // namespace OperatorManagement