| Tutorial | Classes | Functions | QSA Developer | Language | Library | Qt API Qt Script for Applications

User Management Example

This example is a small fake application to administer user accounts. You can log on as super user (root) and create accounts or log on as an ordinary user and do a limited range of things.

The application is written in C++ and allows all users to write scripts for their accounts. The application's interfaces provide signals such as loggedIn() and loggedOut(), so that a user could connect a script function to, for example loggedIn(), to execute some functionality every time they log in.

This example also demonstrates how to work with multiple QSA projects in a single application. Every user has their own scripting project, which is loaded at login. Another feature of this example is that the project is not saved in a stand-alone file, but attached to the user's data as a binary data block.


Header file:

#ifndef USERMANAGEMENTINTERFACE
#define USERMANAGEMENTINTERFACE

#include <qobject.h>
#include <qstring.h>

class UserManagementInterface : public QObject
{
    Q_OBJECT

public:
    UserManagementInterface( QObject *parent, const char *name ) : QObject( parent, name ) {}

    void emitLoggedIn() { emit loggedIn(); }
    void emitLoggedOff() { emit loggedOff(); }
    void emitUserAdded( const QString &user, const QString &passwd, const QString &email )
    { emit userAdded( user, passwd, email ); }

signals:
    void loggedIn();
    void loggedOff();
    void userAdded( const QString &user, const QString &passwd, const QString &email );

};

#endif


Implementation files:

/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you wish to add, delete or rename slots use Qt Designer which will
** update this file, preserving your code. Create an init() slot in place of
** a constructor, and a destroy() slot in place of a destructor.
*****************************************************************************/

#include <qsinterpreter.h>
#include <qsproject.h>
#include  "usermanagementinterface.h"
#include  "adduserdialog.h"
#include <qlineedit.h>
#include <qmessagebox.h>
#include <qfile.h>

void UserManager::setLogin( const QString &user, const QString &passwd )
{
    bool superUser = user == "root" && passwd == "toor";

    labelUser->setText( user );

    iface = new UserManagementInterface( 0, "UserManagementInterface" );
    interpreter.addObject( iface );

    password = passwd;

    if ( superUser ) {
        // if the super user logged in, open its script project
        interpreter.currentProject()->open( "root.qsa" );

        labelEmail->setText( "root@yourcompany.com" );
    } else {
        // if somebody else logged in, open the user description file
        QFile f( user );
        f.open( IO_ReadOnly );

        // read in some user data....
        QString dummy;
        f.readLine( dummy, 1024 );
        dummy.remove( dummy.length() - 1, 1 );

        QString email;
        f.readLine( email, 1024 );
        email.remove( email.length() - 1, 1 );
        labelEmail->setText( email );

        QString len;
        f.readLine( len, 1024 );
        len.remove( len.length() - 1, 1 );

        // ...and finally read in the script project from the user file...
        QByteArray ba( len.toInt() );
        if ( ba.size() )
            f.readBlock( ba.data(), ba.size() );
        // ...and let the engine open and run that one
        interpreter.currentProject()->open( ba, user );
    }

    iface->emitLoggedIn();
}

void UserManager::buttonScript_clicked()
{
    interpreter.currentProject()->openDeveloper();
}

void UserManager::destroy()
{
    bool superUser = labelUser->text() == "root" && password == "toor";
    if ( !superUser ) {
        // if we are not the super user, we have to save the project,
        // which we can get as one data block from the engine, into
        // the user file

        // so get the data of the project....
        QByteArray ba = interpreter.currentProject()->projectData();
        QFile f( labelUser->text() );
        if ( f.open( IO_WriteOnly ) ) {
            // ...and save some user data...
            f.writeBlock( password.latin1(), password.length() );
            f.writeBlock( "\n", 1 );
            f.writeBlock( labelEmail->text().latin1(), labelEmail->text().length() );
            f.writeBlock( "\n", 1 );
            QString s = QString::number( ba.size() );
            f.writeBlock( s, s.length() );
            f.writeBlock( "\n", 1 );
            // ...and finally the script project data
            f.writeBlock( ba.data(), ba.size() );
            f.close();
        }
    }

    iface->emitLoggedOff();

    delete iface;
}

void UserManager::buttonAddUser_clicked()
{
    AddUserDialog dlg( this, 0, TRUE );
    if ( dlg.exec() == QDialog::Accepted ) {
        QFile f( dlg.editUser->text() );
        if ( !f.open( IO_WriteOnly ) ) {
            QMessageBox::critical( this, "Add User Error", QString( "Couldn't add User " ) + dlg.editUser->text() );
            return;
        }

        f.writeBlock( dlg.editPasswd->text().latin1(), dlg.editPasswd->text().length() );
        f.writeBlock( "\n", 1 );
        f.writeBlock( dlg.editEmail->text().latin1(), dlg.editEmail->text().length() );
        f.writeBlock( "\n", 1 );
        f.writeBlock( "0\n", 2 );
        f.close();

        iface->emitUserAdded( dlg.editUser->text(), dlg.editPasswd->text(), dlg.editEmail->text() );
    }
}


void UserManager::buttonPasswd_clicked()
{
    QMessageBox::information( this, "Not implemented", "This function is not implemented" );
}

void UserManager::buttonEmail_clicked()
{
    QMessageBox::information( this, "Not implemented", "This function is not implemented" );
}
/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you wish to add, delete or rename slots use Qt Designer which will
** update this file, preserving your code. Create an init() slot in place of
** a constructor, and a destroy() slot in place of a destructor.
*****************************************************************************/

#include <qmessagebox.h>
#include <qfile.h>
#include "usermanager.h"
#include <qapplication.h>


void LoginDialog::init()
{
    connect( buttonQuit, SIGNAL( clicked() ), qApp, SLOT( quit() ) );
}


void LoginDialog::buttonLogin_clicked()
{
    if ( editUser->text() != "root" ) {
        QFile f( editUser->text() );
        if ( !f.open( IO_ReadOnly ) ) {
            QMessageBox::critical( this, "Could not login", QString( "No such User: " ) + editUser->text() );
            editUser->clear();
            editPasswd->clear();
            editUser->setFocus();
            return;
        }
        QString passwd;
        f.readLine( passwd, 1024 );
        passwd.remove( passwd.length() - 1, 1 );
        if ( passwd != editUser->text() ) {
            QMessageBox::critical( this, "Could not login", "Incorrect Password " );
            editUser->clear();
            editPasswd->clear();
            editUser->setFocus();
            return;
        }
    } else if ( editPasswd->text() != "toor" ) {
            QMessageBox::critical( this, "Could not login", "Incorrect Password " );
            editUser->clear();
            editPasswd->clear();
            editUser->setFocus();
            return;
   }

    UserManager mgr( this, 0, TRUE );
    mgr.setLogin( editUser->text(), editPasswd->text() );
    mgr.exec();
    editUser->clear();
    editPasswd->clear();
    editUser->setFocus();
}


Main:

#include <qapplication.h>
#include "logindialog.h"

int main( int argc, char ** argv )
{
    QApplication a( argc, argv );
    LoginDialog *w = new LoginDialog;
    w->show();
    a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
    return a.exec();
}

See also QSA Examples.


Copyright © 2001-2002 TrolltechTrademarks
QSA version 1.0.0-beta1