/*
* Copyright (c) 2012-2015 Christian Surlykke
* 2017 bwLehrpool project
*
* Based on qt-lightdm-greeter, stripped down to fit
* our specific needs.
* It is distributed under the LGPL 2.1 or later license.
* Please refer to the LICENSE file for a copy of the license.
*/
#include <QDebug>
#include <QAbstractListModel>
#include <QModelIndex>
#include <QPixmap>
#include <QMessageBox>
#include <QMenu>
#include "loginform.h"
#include "ui_loginform.h"
#include "settings.h"
LoginForm::LoginForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::LoginForm),
m_Greeter(),
power(this),
sessionsModel(),
clearMsg(false)
{
if (!m_Greeter.connectSync()) {
exit(0);
return;
}
ui->setupUi(this);
initialize();
}
LoginForm::~LoginForm()
{
delete ui;
}
void LoginForm::setFocus(Qt::FocusReason reason)
{
if (ui->userInput->text().isEmpty()) {
ui->userInput->setFocus(reason);
} else {
ui->passwordInput->setFocus(reason);
}
}
void LoginForm::initialize()
{
QPixmap icon(":/resources/rqt-2.png"); // This project came from Razor-qt
ui->iconLabel->setPixmap(icon.scaled(ui->iconLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
ui->hostnameLabel->setText(m_Greeter.hostname());
addLeaveEntry(power.canShutdown(), "system-shutdown", tr("Shutdown"), "shutdown");
addLeaveEntry(power.canRestart(), "system-reboot", tr("Restart"), "restart");
//addLeaveEntry(power.canHibernate(), "system-suspend-hibernate", tr("Hibernate"), "hibernate");
//addLeaveEntry(power.canSuspend(), "system-suspend", tr("Suspend"), "suspend");
ui->leaveComboBox->setDisabled(ui->leaveComboBox->count() <= 1);
cancelLoginTimer.setInterval(10000);
cancelLoginTimer.setSingleShot(true);
connect(&cancelLoginTimer, SIGNAL(timeout()), this, SLOT(cancelLogin()));
hideMessageTimer.setInterval(10000);
hideMessageTimer.setSingleShot(true);
connect(&hideMessageTimer, SIGNAL(timeout()), this, SLOT(hideMessage()));
//connect(ui->userInput, SIGNAL(editingFinished()), this, SLOT(userChanged()));
connect(ui->leaveComboBox, SIGNAL(activated(int)), this, SLOT(leaveDropDownActivated(int)));
connect(&m_Greeter, SIGNAL(showPrompt(QString, QLightDM::Greeter::PromptType)), this, SLOT(onPrompt(QString, QLightDM::Greeter::PromptType)));
connect(&m_Greeter, SIGNAL(showMessage(QString, QLightDM::Greeter::MessageType)), this, SLOT(onMessage(QString, QLightDM::Greeter::MessageType)));
connect(&m_Greeter, SIGNAL(authenticationComplete()), this, SLOT(onAuthenticationComplete()));
ui->passwordInput->clear();
}
void LoginForm::startAuthentication()
{
if (m_Greeter.inAuthentication()) {
m_Greeter.cancelAuthentication();
}
if (ui->userInput->text().isEmpty()) {
ui->userInput->setFocus();
return;
}
if (ui->passwordInput->text().isEmpty()) {
ui->passwordInput->setFocus();
return;
}
showMessage(tr("Logging in..."), false);
clearMsg = false;
ui->userInput->setEnabled(false);
ui->passwordInput->setEnabled(false);
cancelLoginTimer.start();
m_Greeter.authenticate(ui->userInput->text());
}
void LoginForm::onPrompt(QString prompt, QLightDM::Greeter::PromptType promptType)
{
qDebug() << "Prompt: " << prompt;
m_Greeter.respond(ui->passwordInput->text());
ui->passwordInput->clear();
}
void LoginForm::leaveDropDownActivated(int index)
{
QString actionName = ui->leaveComboBox->itemData(index).toString();
if (actionName == "shutdown") power.shutdown();
else if (actionName == "restart") power.restart();
else if (actionName == "hibernate") power.hibernate();
else if (actionName == "suspend") power.suspend();
}
void LoginForm::onMessage(QString message, QLightDM::Greeter::MessageType type)
{
qDebug() << "Message: " << message;
showMessage(message, false);
clearMsg = true;
}
void LoginForm::addLeaveEntry(bool canDo, QString iconName, QString text, QString actionName)
{
if (canDo) {
ui->leaveComboBox->addItem(QIcon::fromTheme(iconName), text, actionName);
}
}
void LoginForm::onAuthenticationComplete()
{
if (m_Greeter.isAuthenticated()) {
qDebug() << "Auth complete, start session";
showMessage(tr("Starting session..."), false);
QModelIndex i = sessionsModel.index(0, 0);
if (m_Greeter.startSessionSync(sessionsModel.data(i, QLightDM::SessionsModel::KeyRole).toString())) {
cancelLoginTimer.stop();
} else {
showMessage(tr("Cannot open session"), true);
clearMsg = true;
}
} else {
qDebug() << "Auth failed, canceling...";
cancelLogin();
}
}
void LoginForm::cancelLogin()
{
qDebug() << "Cancel login";
if (m_Greeter.inAuthentication()) {
qDebug() << "Was in authentication";
m_Greeter.cancelAuthentication();
}
cancelLoginTimer.stop();
ui->passwordInput->clear();
ui->userInput->setEnabled(true);
ui->passwordInput->setEnabled(true);
if (!clearMsg) {
showMessage(tr("Login failed"), true);
} else {
ui->messageLabel->setStyleSheet("color:red");
}
ui->userInput->setFocus();
ui->userInput->selectAll();
clearMsg = true;
}
void LoginForm::showMessage(QString message, bool error)
{
hideMessageTimer.stop();
ui->messageLabel->setText(message);
if (error) {
ui->messageLabel->setStyleSheet("color:red");
hideMessageTimer.start();
} else {
ui->messageLabel->setStyleSheet("");
}
}
void LoginForm::hideMessage()
{
hideMessageTimer.stop();
ui->messageLabel->clear();
}
void LoginForm::keyPressEvent(QKeyEvent *event)
{
if (clearMsg) {
clearMsg = false;
hideMessage();
}
if (event->key() == Qt::Key_Return || event->key() == Qt::Key_Enter) {
if (!ui->userInput->isEnabled()) {
// Ignore if auth in progress
return;
}
if (ui->userInput->hasFocus()) {
ui->passwordInput->setFocus();
return;
}
if (ui->passwordInput->hasFocus()) {
startAuthentication();
return;
}
}
// Fallback: Passthrough
QWidget::keyPressEvent(event);
}