577 lines
15 KiB
C++
Executable File
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
|
|
|
|
|