Logo Search packages:      
Sourcecode: lemonpos-kde4 version File versions  Download package

loginwindow.cpp

/***************************************************************************
 *   Copyright (C) 2007 by Miguel Chavez Gamboa                            *
 *   miguel.chavez.gamboa@gmail.com                                        *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *

 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.         *
 ***************************************************************************/

#include "loginwindow.h"
#include "hash.h"
#include "settings.h"

#include <QtGui>
#include <QPixmap>
#include <kiconloader.h>
#include <klocale.h>
#include <kstandarddirs.h>


#include <QSqlDatabase>
#include <QTimer>

LoginWindow::LoginWindow(QWidget *parent,
                         QString caption,
                         QString prompt,
                         LoginWindow::Mode mode)
{
  setWindowFlags(Qt::Dialog|Qt::FramelessWindowHint);
  setWindowModality(Qt::ApplicationModal);
  //setModal(true);

  //controls
  vLayout       = new QVBoxLayout(this);
  errorLayout   = new QHBoxLayout();
  editsLayout   = new QVBoxLayout();
  middleLayout  = new QHBoxLayout();
  userLayout    = new QHBoxLayout();
  passLayout    = new QHBoxLayout();
  imageError    = new QLabel(this);
  mainImage     = new QLabel(this);
  labelError    = new QLabel(this);
  labelUsername = new QLabel(this);
  labelPassword = new QLabel(this);
  labelCaption  = new QLabel(this);
  labelPrompt   = new QLabel(this);
  editUsername  = new QLineEdit(this);
  editPassword  = new QLineEdit(this);
  btnOk         = new QPushButton(DesktopIcon("ok", 48), i18n("&Ok"), this);
  spacerItemBottom= new QSpacerItem(20, 50, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding);
  spacerItemTop = new QSpacerItem(20, 110, QSizePolicy::Minimum, QSizePolicy::Maximum);
  QSpacerItem *spacerItemBtn = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Maximum);
  QSpacerItem *spacerItemBtn2 = new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Maximum);

  //layout
  vLayout->addWidget(labelCaption);
  vLayout->addWidget(labelPrompt);
  errorLayout->addStretch(200);
  errorLayout->addWidget(imageError);
  errorLayout->addWidget(labelError);

  if (mode == LoginWindow::FullScreen) vLayout->addItem(spacerItemTop);
  userLayout->addWidget(labelUsername);
  userLayout->addWidget(editUsername);
  passLayout->addWidget(labelPassword);
  passLayout->addWidget(editPassword);
  editsLayout->addItem(spacerItemBtn2);
  editsLayout->addLayout(userLayout);
  editsLayout->addLayout(passLayout);
  editsLayout->addWidget(btnOk);
  editsLayout->addItem(spacerItemBtn);
  middleLayout->addStretch(200);
  middleLayout->addWidget(mainImage);
  middleLayout->addLayout(editsLayout);
  vLayout->addLayout(middleLayout);
  vLayout->addLayout(errorLayout);
  if (mode == LoginWindow::FullScreen) vLayout->addItem(spacerItemBottom);

  //FIXME: Para el cuadro de login&password, se necesita un groupbox para ponerle el fondo semitransparente.
  //Porque para diferentes resoluciones de pantalla, se acomodara el layout de diferente forma.

  //ObjectName is needed for styling... via stylesheets.
  labelCaption->setObjectName("labelCaption");
  labelPrompt->setObjectName("labelPrompt");
  labelError->setObjectName("labelError");

  QRect geom = geometry();
  //qDebug()<<"Geometry:"<<geom;
  QString str("admin");
  QString path; QPixmap pixm;
  switch (mode)
  {
    case LoginWindow::FullScreen:
      setWindowState(Qt::WindowFullScreen);
      setObjectName("loginDialog");
      mainImage->setPixmap(DesktopIcon("lemon-user", 128));
      imageError->setPixmap(DesktopIcon("no", 48));
      setGeometry(QApplication::desktop()->screenGeometry(this));
      break;
    case LoginWindow::PasswordOnly:
      setObjectName("passwordDialog");
      labelUsername->hide();
      editUsername->hide();
      mainImage->setPixmap(DesktopIcon("lemon-user", 128));
      imageError->setPixmap(DesktopIcon("no", 22));
      QTimer::singleShot(3000, this, SLOT(showAdminPhoto()));
      path = KStandardDirs::locate("appdata", "styles/");
      pixm = QPixmap(path + Settings::styleName() + "/passwordBackground_wide.png");
      setMask(pixm.mask());
      //st = QString("QDialog#passwordDialog { background-image: url(%1);}").arg(path+Settings::styleName()+"/passwordBackground_wide.png");
      //setStyleSheet(st);
      //FIXME:Why at widescreen 1280x800, the dialogs moves to 0,0 ? -- only with compiz
      break;
    default:
      break;
  }

  mainImage->setAlignment(Qt::AlignHCenter);
  mainImage->setMinimumSize(QSize(128, 128));
  mainImage->setMaximumSize(QSize(128,128));
  mainImage->setGeometry(0,0,128,128);
  mainImage->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed));
  setCaption(caption);
  setPrompt(prompt);
  labelUsername->setText(i18n("Username:"));
  labelPassword->setText(i18n("Password:"));
  editPassword->setEchoMode(QLineEdit::Password);
  btnOk->setDefault(false);
  hideError();

  connect(editUsername, SIGNAL(returnPressed()), editPassword, SLOT(setFocus()));
  connect(editPassword, SIGNAL(returnPressed()),               SLOT(acceptIt()));
  connect(btnOk,        SIGNAL(clicked()),                     SLOT(acceptIt()));
  connect(editUsername, SIGNAL(textEdited(const QString &)),   SLOT(updateUserPhoto(const QString &)));

  uHash.clear();

}

void LoginWindow::setDb(QSqlDatabase database)
{
  db = database;
  if (!db.isOpen()) db.open();
}

LoginWindow::~LoginWindow()
{
}

QString LoginWindow::username()
{
  return editUsername->text();
}

QString LoginWindow::password()
{
  return editPassword->text();
}

void LoginWindow::clearLines()
{
  editUsername->clear();
  editPassword->clear();
  editUsername->setFocus();
}

void LoginWindow::setPrompt(QString text)
{
  labelPrompt->setText(text);
}

void LoginWindow::setCaption(QString text)
{
  labelCaption->setText(text);
}

bool LoginWindow::checkPassword()
{
  if (uHash.isEmpty()) uHash = getUsers();
  bool result=false;
  bool showError=false;
  QString user;
  if (editUsername->isHidden()) user = "admin";
  else user = username();

  //FIXME: Update uHash from database?..
  if (uHash.contains(user)) {
    UserInfo uInfo = uHash.value(user);
    QString givenPass = Hash::password2hash((uInfo.salt+password()).toLocal8Bit());
    //qDebug()<<"GivenPassword hash:"<<givenPass<<" savedPassword hash:"<<uInfo.password;
    if (givenPass == uInfo.password) {
      result = true;
      qDebug()<<"login::Username and password OK...";
    }
    else {
      showError = true;
    }
  } else showError = true;
  if (showError) showErrorMessage(i18n("Invalid username or password"));
  return result;
}

void LoginWindow::showErrorMessage(QString text)
{
  labelError->setText(text);
  //labelError->show();
  imageError->show();
  QTimer::singleShot(3000, this, SLOT(hideError()));
}

void LoginWindow::hideError()
{
  labelError->clear();
  imageError->hide();
}

void LoginWindow::acceptIt()
{
  if (checkPassword()) QDialog::accept();
}


void LoginWindow::updateUserPhoto(const QString &text)
{

//   QByteArray salt = getSalt();
//   QString    pass = password2hash((salt+"mangostan"));
//   qDebug()<<"creating new salt:"<<salt;
//   qDebug()<<"creating new hashed password:"<<pass;

  if (uHash.isEmpty()) uHash = getUsers();
  if (uHash.contains(text)) {
    UserInfo info = uHash.value(text);
    QPixmap pix;
    pix.loadFromData(info.photo); //Photos are saved as 128x128 pngs or jpgs...
    if (!pix.isNull()) mainImage->setPixmap(pix);
  }
  else {
    //Repaint image if it is the same??? how to know it is the same?
    mainImage->setPixmap(DesktopIcon("lemon-user", 128));
  }
  mainImage->setAlignment(Qt::AlignCenter);
}

void LoginWindow::showAdminPhoto()
{
  updateUserPhoto("admin");
}


QHash<QString, UserInfo> LoginWindow::getUsers()
{
  QHash<QString,UserInfo> hash;
  hash.clear();
  //get database data
  if (!db.isOpen()) db.open();
  QSqlQuery query(db);
  QString qry = "SELECT * FROM users;";
  if (query.exec(qry)) {
    while (query.next()) {
      int fielduId       = query.record().indexOf("id");
      int fieldUsername  = query.record().indexOf("username");
      int fieldPassword  = query.record().indexOf("password");
      int fieldSalt      = query.record().indexOf("salt");
      int fieldName      = query.record().indexOf("name");
      int fieldRole      = query.record().indexOf("role"); // see role numbers at enums.h
      int fieldPhoto     = query.record().indexOf("photo");
      //more fields, now im not interested in that...
      UserInfo info;
      info.id       = query.value(fielduId).toInt();
      info.username = query.value(fieldUsername).toString();
      info.password = query.value(fieldPassword).toString();
      info.salt     = query.value(fieldSalt).toString();
      info.name     = query.value(fieldName).toString();
      info.photo    = query.value(fieldPhoto).toByteArray();
      info.role     = query.value(fieldRole).toInt();
      hash.insert(info.username, info);
      qDebug()<<"got user:"<<info.username;
    }
  }
  else { qDebug()<<"Error:"<<query.lastError(); }
  return hash;
}



#include "loginwindow.moc"

Generated by  Doxygen 1.6.0   Back to index