summaryrefslogblamecommitdiffstats
path: root/src/loginform.cpp
blob: 0a65bdd9c2b36ab6772727e61dc7cb8b7d2b8e5d (plain) (tree)
1
2
3
4
5
6
7
8
9

                                            
                         
 

                                                   


                                                             

                             


                      
 

                   



                         
                                                      

                          


                           
                   
 






                                                            

                







                       
 














                                                
                                                                            
                                                                                                                
 

                                                                                                     
 


                                                                             
 



                                                                             

                                                          
 










                                                                                                                                                         
                               

 
                                     
 




                                          



                                          
     


                                              
     
 
                                            



                                         
                                                   



                                                                                  
                                                                     
                                                  
                                   




                                                                       



                                                           

 
                                                                               
 
                                                                       
                                    
                        

 






                                                                                             
                                          
 
                                       
                                                                 
                                                      

                                                                                        
                                                  
                                             

                                        
                                                             
                                
         
            
                                                               
                      


     
                             
 
                                                 
                                        
                                                                  
                                          





                                            


                                                             



                                   

 

















                                                             

                                               

                                 
                              
         
                                                                          











                                              
     

                                  

 
/*
* 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 <QAbstractListModel>
#include <QModelIndex>
#include <QPixmap>
#include <QMessageBox>
#include <QMenu>

#include <iostream>

#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);
}