/* * 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 #include #include #include #include #include #include "loginform.h" #include "ui_loginform.h" #include "settings.h" LoginForm::LoginForm(bool testMode, QWidget *parent) : QWidget(parent), ui(new Ui::LoginForm), m_Greeter(nullptr), power(nullptr), sessionsModel(nullptr), clearMsg(false) { if (!testMode) { m_Greeter = new QLightDM::Greeter(this); power = new QLightDM::PowerInterface(this); sessionsModel = new QLightDM::SessionsModel(this); } if (m_Greeter != nullptr && !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/bwlp.svg"); // This project came from Razor-qt ui->iconLabel->setPixmap(icon.scaled(ui->iconLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation)); //addLeaveEntry(power->canHibernate(), "system-suspend-hibernate", tr("Hibernate"), "hibernate"); //addLeaveEntry(power->canSuspend(), "system-suspend", tr("Suspend"), "suspend"); 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())); if (m_Greeter != nullptr) { ui->hostnameLabel->setText(m_Greeter->hostname()); addLeaveEntry(power->canShutdown(), "system-shutdown", tr("Shutdown"), "shutdown"); addLeaveEntry(power->canRestart(), "system-reboot", tr("Restart"), "restart"); //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->leaveComboBox->setDisabled(ui->leaveComboBox->count() <= 1); ui->passwordInput->clear(); } void LoginForm::startAuthentication() { if (m_Greeter == nullptr) { return; } 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) { std::cerr << "Prompt: " << prompt.toStdString() << std::endl; 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) { std::cerr << "Message: " << message.toStdString() << std::endl; 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()) { std::cerr << "Auth complete, start session" << std::endl; showMessage(tr("Starting session..."), false); QModelIndex i = sessionsModel->index(0, 0); QString s = sessionsModel->data(i, QLightDM::SessionsModel::KeyRole).toString(); std::cerr << s.toStdString() << std::endl; if (m_Greeter->startSessionSync(s)) { cancelLoginTimer.stop(); } else { showMessage(tr("Cannot open session"), true); clearMsg = true; } } else { std::cerr << "Auth failed, cancelling..." << std::endl; cancelLogin(); } } void LoginForm::cancelLogin() { std::cerr << "Cancel login" << std::endl; if (m_Greeter->inAuthentication()) { std::cerr << "Was in authentication" << std::endl; 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); }