~ubuntu-branches/ubuntu/gutsy/kdebase-workspace/gutsy-backports

« back to all changes in this revision

Viewing changes to kdm/kfrontend/kgreeter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2007-09-05 20:45:14 UTC
  • Revision ID: james.westby@ubuntu.com-20070905204514-632hhspl0nvrc84i
Tags: upstream-3.93.0
ImportĀ upstreamĀ versionĀ 3.93.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
Greeter widget for kdm
 
4
 
 
5
Copyright (C) 1997, 1998, 2000 Steffen Hansen <hansen@kde.org>
 
6
Copyright (C) 2000-2004 Oswald Buddenhagen <ossi@kde.org>
 
7
 
 
8
 
 
9
This program is free software; you can redistribute it and/or modify
 
10
it under the terms of the GNU General Public License as published by
 
11
the Free Software Foundation; either version 2 of the License, or
 
12
(at your option) any later version.
 
13
 
 
14
This program is distributed in the hope that it will be useful,
 
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
GNU General Public License for more details.
 
18
 
 
19
You should have received a copy of the GNU General Public License
 
20
along with this program; if not, write to the Free Software
 
21
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
22
 
 
23
*/
 
24
 
 
25
#include "kgreeter.h"
 
26
#include "kconsole.h"
 
27
#include "kdmconfig.h"
 
28
#include "kdmclock.h"
 
29
#include "kdm_greet.h"
 
30
#include "themer/kdmthemer.h"
 
31
#include "themer/kdmitem.h"
 
32
#include "themer/kdmlabel.h"
 
33
 
 
34
#include <klocale.h>
 
35
#include <kseparator.h>
 
36
#include <kstandarddirs.h>
 
37
#include <kstringhandler.h>
 
38
#include <KConfigGroup>
 
39
 
 
40
#include <QAction>
 
41
#include <QDir>
 
42
#include <QFile>
 
43
#include <QKeyEvent>
 
44
#include <QLabel>
 
45
#include <QListWidget>
 
46
#include <QListWidgetItem>
 
47
#include <QMenu>
 
48
#include <QMovie>
 
49
#include <QPushButton>
 
50
#include <QStyle>
 
51
 
 
52
#include <sys/types.h>
 
53
#include <stdlib.h>
 
54
#include <unistd.h>
 
55
#include <pwd.h>
 
56
#include <grp.h>
 
57
 
 
58
#include <X11/Xlib.h>
 
59
 
 
60
class UserListView : public QListWidget {
 
61
  public:
 
62
        UserListView( QWidget *parent = 0 )
 
63
                : QListWidget( parent )
 
64
                , cachedSizeHint( -1, 0 )
 
65
        {
 
66
                setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Ignored );
 
67
                setUniformItemSizes( true );
 
68
                setIconSize( QSize( 48, 48 ) );
 
69
        }
 
70
 
 
71
        mutable QSize cachedSizeHint;
 
72
 
 
73
  protected:
 
74
        virtual QSize sizeHint() const
 
75
        {
 
76
                if (!cachedSizeHint.isValid()) {
 
77
                        ensurePolished();
 
78
                        QStyleOptionViewItem vo( viewOptions() );
 
79
                        QAbstractListModel *md( static_cast<QAbstractListModel *>(model()) );
 
80
                        uint maxw = 0, h = 0;
 
81
                        for (int i = 0, rc = md->rowCount(); i < rc; i++) {
 
82
                                QSize sh = itemDelegate()->sizeHint( vo, md->index( i ) );
 
83
                                uint thisw = sh.width();
 
84
                                if (thisw > maxw)
 
85
                                        maxw = thisw;
 
86
                                h += sh.height();
 
87
                        }
 
88
                        cachedSizeHint.setWidth(
 
89
                                style()->pixelMetric( QStyle::PM_ScrollBarExtent ) +
 
90
                                frameWidth() * 2 + maxw );
 
91
                        cachedSizeHint.setHeight( frameWidth() * 2 + h );
 
92
                }
 
93
                return cachedSizeHint;
 
94
        }
 
95
 
 
96
        virtual void keyPressEvent( QKeyEvent *event )
 
97
        {
 
98
                switch (event->key()) {
 
99
                case Qt::Key_Enter:
 
100
                case Qt::Key_Return:
 
101
                        if (currentIndex().isValid())
 
102
                                emit activated( currentIndex() );
 
103
                        event->accept();
 
104
                        break;
 
105
                default:
 
106
                        QListWidget::keyPressEvent( event );
 
107
                        break;
 
108
                }
 
109
        }
 
110
};
 
111
 
 
112
class UserListViewItem : public QListWidgetItem {
 
113
  public:
 
114
        UserListViewItem( UserListView *parent, const QString &text,
 
115
                          const QPixmap &pixmap, const QString &username )
 
116
                : QListWidgetItem( parent )
 
117
                , login( username )
 
118
        {
 
119
                setIcon( pixmap );
 
120
                setText( text );
 
121
                parent->cachedSizeHint.setWidth( -1 );
 
122
        }
 
123
 
 
124
        QString login;
 
125
};
 
126
 
 
127
 
 
128
int KGreeter::curPlugin = -1;
 
129
PluginList KGreeter::pluginList;
 
130
 
 
131
KGreeter::KGreeter( bool framed )
 
132
  : inherited( framed )
 
133
  , dName( dname )
 
134
  , userView( 0 )
 
135
  , userList( 0 )
 
136
  , nNormals( 0 )
 
137
  , nSpecials( 0 )
 
138
  , curPrev( 0 )
 
139
  , curSel( 0 )
 
140
  , prevValid( true )
 
141
  , needLoad( false )
 
142
{
 
143
        stsGroup = new KConfigGroup( KSharedConfig::openConfig( _stsFile ),
 
144
                                     "PrevUser" );
 
145
 
 
146
        if (_userList) {
 
147
                userView = new UserListView( this );
 
148
                connect( userView, SIGNAL(itemPressed( QListWidgetItem * )),
 
149
                         SLOT(slotUserClicked( QListWidgetItem * )) );
 
150
                connect( userView, SIGNAL(itemActivated( QListWidgetItem * )),
 
151
                         SLOT(accept()) );
 
152
        }
 
153
        if (_userCompletion)
 
154
                userList = new QStringList;
 
155
        if (userView || userList)
 
156
                insertUsers();
 
157
 
 
158
        sessMenu = new QMenu( this );
 
159
        connect( sessMenu, SIGNAL(triggered( QAction * )),
 
160
                 SLOT(slotSessionSelected( QAction * )) );
 
161
        insertSessions();
 
162
 
 
163
        if (curPlugin < 0) {
 
164
                curPlugin = 0;
 
165
                pluginList = KGVerify::init( _pluginsLogin );
 
166
        }
 
167
}
 
168
 
 
169
KGreeter::~KGreeter()
 
170
{
 
171
        hide();
 
172
        delete userList;
 
173
        delete verify;
 
174
        delete stsGroup;
 
175
}
 
176
 
 
177
void
 
178
KGreeter::insertUser( const QImage &default_pix,
 
179
                      const QString &username, struct passwd *ps )
 
180
{
 
181
        if (userList)
 
182
                userList->append( username );
 
183
        if (!userView)
 
184
                return;
 
185
 
 
186
        int dp = 0, nd = 0;
 
187
        if (_faceSource == FACE_USER_ONLY ||
 
188
            _faceSource == FACE_PREFER_USER)
 
189
                dp = 1;
 
190
        if (_faceSource != FACE_USER_ONLY &&
 
191
            _faceSource != FACE_ADMIN_ONLY)
 
192
                nd = 1;
 
193
        QImage p;
 
194
        do {
 
195
                QString fn = dp ?
 
196
                             QFile::decodeName( ps->pw_dir ) + "/.face" :
 
197
                             _faceDir + '/' + username + ".face";
 
198
                if (p.load( fn + ".icon" ) || p.load( fn )) {
 
199
                        QSize ns( 48, 48 );
 
200
                        if (p.size() != ns)
 
201
                                p = p.convertToFormat( QImage::Format_RGB32 ).scaled( ns, Qt::KeepAspectRatio, Qt::SmoothTransformation );
 
202
                        goto gotit;
 
203
                }
 
204
                dp = 1 - dp;
 
205
        } while (--nd >= 0);
 
206
        p = default_pix;
 
207
  gotit:
 
208
        QString realname = KStringHandler::from8Bit( ps->pw_gecos );
 
209
        realname.truncate( realname.indexOf( ',' ) & (~0U >> 1) );
 
210
        if (realname.isEmpty() || realname == username)
 
211
                new UserListViewItem( userView, username, QPixmap::fromImage( p ), username );
 
212
        else {
 
213
                realname.append( "\n" ).append( username );
 
214
                new UserListViewItem( userView, realname, QPixmap::fromImage( p ), username );
 
215
        }
 
216
}
 
217
 
 
218
class UserList {
 
219
  public:
 
220
        UserList( char **in );
 
221
        bool hasUser( const char *str ) const { return users.contains( str ); }
 
222
        bool hasGroup( gid_t gid ) const { return groups.contains( gid ); }
 
223
        bool hasGroups() const { return !groups.isEmpty(); }
 
224
 
 
225
  private:
 
226
        QSet<gid_t> groups;
 
227
        QSet<QByteArray> users;
 
228
};
 
229
 
 
230
UserList::UserList( char **in )
 
231
{
 
232
        struct group *grp;
 
233
 
 
234
        for (; *in; in++)
 
235
                if (**in == '@') {
 
236
                        if ((grp = getgrnam( *in + 1 ))) {
 
237
                                for (; *grp->gr_mem; grp->gr_mem++)
 
238
                                        users.insert( *grp->gr_mem );
 
239
                                groups.insert( grp->gr_gid );
 
240
                        }
 
241
                } else
 
242
                        users.insert( *in );
 
243
}
 
244
 
 
245
void
 
246
KGreeter::insertUsers()
 
247
{
 
248
        struct passwd *ps;
 
249
 
 
250
        // XXX remove seteuid-voodoo when we run as nobody
 
251
        if (!(ps = getpwnam( "nobody" )))
 
252
                return;
 
253
        if (setegid( ps->pw_gid ))
 
254
                return;
 
255
        if (seteuid( ps->pw_uid )) {
 
256
                setegid( 0 );
 
257
                return;
 
258
        }
 
259
 
 
260
        QImage default_pix;
 
261
        if (userView) {
 
262
                if (!default_pix.load( _faceDir + "/.default.face.icon" ))
 
263
                        if (!default_pix.load( _faceDir + "/.default.face" ))
 
264
                                logError( "Can't open default user face\n" );
 
265
                QSize ns( 48, 48 );
 
266
                if (default_pix.size() != ns)
 
267
                        default_pix =
 
268
                          default_pix.convertToFormat( QImage::Format_RGB32 ).scaled( ns, Qt::KeepAspectRatio, Qt::SmoothTransformation );
 
269
        }
 
270
        if (_showUsers == SHOW_ALL) {
 
271
                UserList noUsers( _noUsers );
 
272
                QSet<QString> dupes;
 
273
                for (setpwent(); (ps = getpwent()) != 0;) {
 
274
                        if (*ps->pw_dir && *ps->pw_shell &&
 
275
                            (ps->pw_uid >= (unsigned)_lowUserId ||
 
276
                             !ps->pw_uid && _showRoot) &&
 
277
                            ps->pw_uid <= (unsigned)_highUserId &&
 
278
                            !noUsers.hasUser( ps->pw_name ) &&
 
279
                            !noUsers.hasGroup( ps->pw_gid ))
 
280
                        {
 
281
                                QString username( QFile::decodeName( ps->pw_name ) );
 
282
                                if (!dupes.contains( username )) {
 
283
                                        dupes.insert( username );
 
284
                                        insertUser( default_pix, username, ps );
 
285
                                }
 
286
                        }
 
287
                }
 
288
        } else {
 
289
                UserList users( _users );
 
290
                if (users.hasGroups()) {
 
291
                        QSet<QString> dupes;
 
292
                        for (setpwent(); (ps = getpwent()) != 0;) {
 
293
                                if (*ps->pw_dir && *ps->pw_shell &&
 
294
                                    (ps->pw_uid >= (unsigned)_lowUserId ||
 
295
                                     !ps->pw_uid && _showRoot) &&
 
296
                                    ps->pw_uid <= (unsigned)_highUserId &&
 
297
                                    (users.hasUser( ps->pw_name ) ||
 
298
                                     users.hasGroup( ps->pw_gid )))
 
299
                                {
 
300
                                        QString username( QFile::decodeName( ps->pw_name ) );
 
301
                                        if (!dupes.contains( username )) {
 
302
                                                dupes.insert( username );
 
303
                                                insertUser( default_pix, username, ps );
 
304
                                        }
 
305
                                }
 
306
                        }
 
307
                } else {
 
308
                        for (int i = 0; _users[i]; i++)
 
309
                                if ((ps = getpwnam( _users[i] )) && (ps->pw_uid || _showRoot))
 
310
                                        insertUser( default_pix, QFile::decodeName( _users[i] ), ps );
 
311
                }
 
312
        }
 
313
        endpwent();
 
314
        if (_sortUsers) {
 
315
                if (userView)
 
316
                        userView->sortItems();
 
317
                if (userList)
 
318
                        userList->sort();
 
319
        }
 
320
 
 
321
        // XXX remove seteuid-voodoo when we run as nobody
 
322
        seteuid( 0 );
 
323
        setegid( 0 );
 
324
}
 
325
 
 
326
void
 
327
KGreeter::putSession( const QString &type, const QString &name, bool hid, const char *exe )
 
328
{
 
329
        int prio = exe ? (!strcmp( exe, "default" ) ? 0 :
 
330
                          !strcmp( exe, "custom" ) ? 1 :
 
331
                          !strcmp( exe, "failsafe" ) ? 3 : 2) : 2;
 
332
        for (int i = 0; i < sessionTypes.size(); i++)
 
333
                if (sessionTypes[i].type == type) {
 
334
                        sessionTypes[i].prio = prio;
 
335
                        return;
 
336
                }
 
337
        sessionTypes.append( SessType( name, type, hid, prio ) );
 
338
}
 
339
 
 
340
void
 
341
KGreeter::insertSessions()
 
342
{
 
343
        for (char **dit = _sessionsDirs; *dit; ++dit)
 
344
                foreach (QString ent, QDir( *dit ).entryList())
 
345
                        if (ent.endsWith( ".desktop" )) {
 
346
                                KConfigGroup dsk(
 
347
                                    KSharedConfig::openConfig(
 
348
                                        QString( *dit ).append( '/' ).append( ent ) ),
 
349
                                    "Desktop Entry" );
 
350
                                putSession( ent.left( ent.length() - 8 ),
 
351
                                            dsk.readEntry( "Name" ),
 
352
                                            (dsk.readEntry( "Hidden", false ) ||
 
353
                                             (dsk.hasKey( "TryExec" ) &&
 
354
                                              KStandardDirs::findExe(
 
355
                                                  dsk.readEntry( "TryExec" ) ).isEmpty())),
 
356
                                            dsk.readEntry( "Exec" ).toLatin1() );
 
357
                        }
 
358
        putSession( "default", i18n("Default"), false, "default" );
 
359
        putSession( "custom", i18n("Custom"), false, "custom" );
 
360
        putSession( "failsafe", i18n("Failsafe"), false, "failsafe" );
 
361
        qSort( sessionTypes );
 
362
        for (int i = 0; i < sessionTypes.size() && !sessionTypes[i].hid; i++) {
 
363
                sessionTypes[i].action = sessMenu->addAction( sessionTypes[i].name );
 
364
                sessionTypes[i].action->setData( i );
 
365
                sessionTypes[i].action->setCheckable( true );
 
366
                switch (sessionTypes[i].prio) {
 
367
                case 0: case 1: nSpecials++; break;
 
368
                case 2: nNormals++; break;
 
369
                }
 
370
        }
 
371
}
 
372
 
 
373
void
 
374
KGreeter::slotUserEntered()
 
375
{
 
376
        if (userView) {
 
377
                for (int i = 0, rc = userView->model()->rowCount(); i < rc; i++) {
 
378
                        UserListViewItem *item =
 
379
                                static_cast<UserListViewItem *>(userView->item( i ));
 
380
                        if (item->login == curUser) {
 
381
                                userView->setCurrentItem( item );
 
382
                                goto oke;
 
383
                        }
 
384
                }
 
385
                userView->clearSelection();
 
386
        }
 
387
  oke:
 
388
        if (isVisible())
 
389
                slotLoadPrevWM();
 
390
        else
 
391
                QTimer::singleShot( 0, this, SLOT(slotLoadPrevWM()) );
 
392
}
 
393
 
 
394
void
 
395
KGreeter::slotUserClicked( QListWidgetItem *item )
 
396
{
 
397
        if (item) {
 
398
                curUser = ((UserListViewItem *)item)->login;
 
399
                verify->setUser( curUser );
 
400
                slotLoadPrevWM();
 
401
        }
 
402
}
 
403
 
 
404
void
 
405
KGreeter::slotSessionSelected( QAction *action )
 
406
{
 
407
        if (action != curSel) {
 
408
                if (curSel)
 
409
                        curSel->setChecked( false );
 
410
                if (action)
 
411
                        action->setChecked( true );
 
412
                curSel = action;
 
413
                verify->gplugActivity();
 
414
        }
 
415
}
 
416
 
 
417
void
 
418
KGreeter::reject()
 
419
{
 
420
        verify->reject();
 
421
}
 
422
 
 
423
void
 
424
KGreeter::accept()
 
425
{
 
426
        if (userView && userView->hasFocus())
 
427
                slotUserClicked( userView->currentItem() );
 
428
        else
 
429
                verify->accept();
 
430
}
 
431
 
 
432
void // private
 
433
KGreeter::setPrevWM( QAction *wm )
 
434
{
 
435
        if (curPrev != wm) {
 
436
                if (curPrev)
 
437
                        curPrev->setText( sessionTypes[curPrev->data().toInt()].name );
 
438
                if (wm)
 
439
                        wm->setText( sessionTypes[wm->data().toInt()].name + i18n(" (previous)") );
 
440
                curPrev = wm;
 
441
        }
 
442
}
 
443
 
 
444
void
 
445
KGreeter::slotLoadPrevWM()
 
446
{
 
447
        int len, i, b;
 
448
        unsigned long crc, by;
 
449
        QByteArray name;
 
450
        char *sess;
 
451
 
 
452
        if (verify->coreLock) {
 
453
                needLoad = true;
 
454
                return;
 
455
        }
 
456
        needLoad = false;
 
457
 
 
458
        prevValid = true;
 
459
        name = curUser.toLocal8Bit();
 
460
        gSendInt( G_ReadDmrc );
 
461
        gSendStr( name.data() );
 
462
        gRecvInt(); // ignore status code ...
 
463
        if ((len = name.length())) {
 
464
                gSendInt( G_GetDmrc );
 
465
                gSendStr( "Session" );
 
466
                sess = gRecvStr();
 
467
                if (!sess) { /* no such user */
 
468
                        if (!userView && !userList) { // don't fake if user list shown
 
469
                                prevValid = false;
 
470
                                /* simple crc32 */
 
471
                                for (crc = _forgingSeed, i = 0; i < len; i++) {
 
472
                                        by = (crc & 255) ^ name[i];
 
473
                                        for (b = 0; b < 8; b++)
 
474
                                                by = (by >> 1) ^ (-(by & 1) & 0xedb88320);
 
475
                                        crc = (crc >> 8) ^ by;
 
476
                                }
 
477
                                /* forge a session with this hash - default & custom more probable */
 
478
                                /* XXX - this should do a statistical analysis of the real users */
 
479
#if 1
 
480
                                setPrevWM( sessionTypes[crc % (nSpecials * 2 + nNormals) % (nSpecials + nNormals)].action );
 
481
#else
 
482
                                i = crc % (nSpecials * 2 + nNormals);
 
483
                                if (i < nNormals)
 
484
                                        setPrevWM( sessionTypes[i + nSpecials].action );
 
485
                                else
 
486
                                        setPrevWM( sessionTypes[(i - nNormals) / 2].action );
 
487
#endif
 
488
                                return;
 
489
                        }
 
490
                } else {
 
491
                        for (int i = 0; i < sessionTypes.count() && !sessionTypes[i].hid; i++)
 
492
                                if (sessionTypes[i].type == sess) {
 
493
                                        free( sess );
 
494
                                        setPrevWM( sessionTypes[i].action );
 
495
                                        return;
 
496
                                }
 
497
                        if (!curSel)
 
498
                                msgBox( sorrybox, i18n("Your saved session type '%1' is not valid any more.\n"
 
499
                                                       "Please select a new one, otherwise 'default' will be used.", sess ) );
 
500
                        free( sess );
 
501
                        prevValid = false;
 
502
                }
 
503
        }
 
504
        setPrevWM( 0 );
 
505
}
 
506
 
 
507
void // protected
 
508
KGreeter::pluginSetup()
 
509
{
 
510
        int field = 0;
 
511
        QString ent, pn( verify->pluginName() ), dn( dName + '_' + pn );
 
512
 
 
513
        if (_preselUser != PRESEL_PREV)
 
514
                stsGroup->deleteEntry( verify->entitiesLocal() ? dName : dn, false );
 
515
        if (_preselUser != PRESEL_NONE && verify->entityPresettable()) {
 
516
                if (verify->entitiesLocal())
 
517
                        ent = _preselUser == PRESEL_PREV ?
 
518
                                stsGroup->readEntry( dName, QString() ) : _defaultUser;
 
519
                else
 
520
                        ent = _preselUser == PRESEL_PREV ?
 
521
                                stsGroup->readEntry( dn, QString() ) :
 
522
                                verify->getConf( 0, (pn + ".DefaultEntity").toLatin1(), QVariant() ).toString();
 
523
                field = verify->entitiesFielded() ?
 
524
                        verify->getConf( 0, (pn + ".FocusField").toLatin1(), QVariant( 0 ) ).toInt() :
 
525
                        _focusPasswd;
 
526
        }
 
527
        verify->presetEntity( ent, field );
 
528
        if (userList)
 
529
                verify->loadUsers( *userList );
 
530
}
 
531
 
 
532
void
 
533
KGreeter::verifyPluginChanged( int id )
 
534
{
 
535
        curPlugin = id;
 
536
        pluginSetup();
 
537
}
 
538
 
 
539
void
 
540
KGreeter::verifyClear()
 
541
{
 
542
        curUser.clear();
 
543
        slotUserEntered();
 
544
        slotSessionSelected( 0 );
 
545
}
 
546
 
 
547
void
 
548
KGreeter::verifyOk()
 
549
{
 
550
        if (_preselUser == PRESEL_PREV && verify->entityPresettable())
 
551
                stsGroup->writeEntry( verify->entitiesLocal() ?
 
552
                                         dName :
 
553
                                         dName + '_' + verify->pluginName(),
 
554
                                      verify->getEntity() );
 
555
        if (curSel) {
 
556
                gSendInt( G_PutDmrc );
 
557
                gSendStr( "Session" );
 
558
                gSendStr( sessionTypes[curSel->data().toInt()].type.toUtf8() );
 
559
        } else if (!prevValid) {
 
560
                gSendInt( G_PutDmrc );
 
561
                gSendStr( "Session" );
 
562
                gSendStr( "default" );
 
563
        }
 
564
        done( ex_login );
 
565
}
 
566
 
 
567
void
 
568
KGreeter::verifyFailed()
 
569
{
 
570
        if (userView)
 
571
                userView->setEnabled( false );
 
572
        if (needLoad)
 
573
                slotLoadPrevWM();
 
574
}
 
575
 
 
576
void
 
577
KGreeter::verifyRetry()
 
578
{
 
579
        if (userView)
 
580
                userView->setEnabled( true );
 
581
}
 
582
 
 
583
void
 
584
KGreeter::verifySetUser( const QString &user )
 
585
{
 
586
        curUser = user;
 
587
        slotUserEntered();
 
588
}
 
589
 
 
590
 
 
591
KStdGreeter::KStdGreeter()
 
592
  : KGreeter()
 
593
  , clock( 0 )
 
594
  , pixLabel( 0 )
 
595
{
 
596
        QBoxLayout *main_box;
 
597
#ifdef WITH_KDM_XCONSOLE
 
598
        if (consoleView) {
 
599
                QBoxLayout *ex_box = new QVBoxLayout( this );
 
600
                main_box = new QHBoxLayout();
 
601
                ex_box->addLayout( main_box );
 
602
                main_box->setParent( ex_box );
 
603
                ex_box->addWidget( consoleView );
 
604
        } else
 
605
#endif
 
606
        {
 
607
                main_box = new QHBoxLayout( this );
 
608
        }
 
609
        int rs = layout()->spacing();
 
610
        main_box->setSpacing( layout()->margin() );
 
611
 
 
612
        if (userView) {
 
613
                userView->setAlternatingRowColors( true );
 
614
                main_box->addWidget( userView );
 
615
        }
 
616
 
 
617
        QBoxLayout *inner_box = new QVBoxLayout();
 
618
        main_box->addLayout( inner_box );
 
619
        inner_box->setParent( main_box );
 
620
        inner_box->setSpacing( rs );
 
621
 
 
622
        if (!_authorized && _authComplain) {
 
623
                QLabel *complainLabel = new QLabel(
 
624
                        i18n("Warning: this is an unsecured session"), this );
 
625
                complainLabel->setToolTip(
 
626
                        i18n("This display requires no X authorization.\n"
 
627
                             "This means that anybody can connect to it,\n"
 
628
                             "open windows on it or intercept your input.") );
 
629
                complainLabel->setAlignment( Qt::AlignCenter );
 
630
                complainLabel->setFont( *_failFont );
 
631
                QPalette p;
 
632
                p.setColor( QPalette::WindowText, Qt::red );
 
633
                complainLabel->setPalette( p );
 
634
                inner_box->addWidget( complainLabel );
 
635
        }
 
636
        if (!_greetString.isEmpty()) {
 
637
                QLabel *welcomeLabel = new QLabel( _greetString, this );
 
638
                welcomeLabel->setAlignment( Qt::AlignCenter );
 
639
                welcomeLabel->setFont( *_greetFont );
 
640
                inner_box->addWidget( welcomeLabel );
 
641
        }
 
642
 
 
643
        switch (_logoArea) {
 
644
                case LOGO_CLOCK:
 
645
                        clock = new KdmClock( this );
 
646
                        break;
 
647
                case LOGO_LOGO:
 
648
                        {
 
649
                                QMovie *movie = new QMovie( this );
 
650
                                movie->setFileName( _logo );
 
651
                                if (movie->isValid()) {
 
652
                                        movie->start();
 
653
                                        pixLabel = new QLabel( this );
 
654
                                        pixLabel->setMovie( movie );
 
655
                                        if (!movie->currentImage().hasAlphaChannel())
 
656
                                                pixLabel->setFrameStyle( QFrame::Panel | QFrame::Sunken );
 
657
                                        pixLabel->setIndent( 0 );
 
658
                                } else
 
659
                                        delete movie;
 
660
                        }
 
661
                        break;
 
662
        }
 
663
 
 
664
        if (userView) {
 
665
                if (clock)
 
666
                        inner_box->addWidget( clock, 0, Qt::AlignCenter );
 
667
                else if (pixLabel)
 
668
                        inner_box->addWidget( pixLabel, 0, Qt::AlignCenter );
 
669
                inner_box->addSpacing( inner_box->spacing() );
 
670
        } else {
 
671
                if (clock)
 
672
                        main_box->addWidget( clock, 0, Qt::AlignCenter );
 
673
                else if (pixLabel)
 
674
                        main_box->addWidget( pixLabel, 0, Qt::AlignCenter );
 
675
        }
 
676
 
 
677
        goButton = new QPushButton( i18n("L&ogin"), this );
 
678
        goButton->setDefault( true );
 
679
        connect( goButton, SIGNAL(clicked()), SLOT(accept()) );
 
680
        QPushButton *menuButton = new QPushButton( i18n("&Menu"), this );
 
681
        //helpButton
 
682
 
 
683
        QWidget *prec;
 
684
        if (userView)
 
685
                prec = userView;
 
686
#ifdef WITH_KDM_XCONSOLE
 
687
        else if (consoleView)
 
688
                prec = consoleView;
 
689
#endif
 
690
        else
 
691
                prec = menuButton;
 
692
        KGStdVerify *sverify =
 
693
                new KGStdVerify( this, this, prec, QString(),
 
694
                                 pluginList, KGreeterPlugin::Authenticate,
 
695
                                 KGreeterPlugin::Login );
 
696
        inner_box->addLayout( sverify->getLayout() );
 
697
        sverify->getLayout()->setParent( inner_box );
 
698
        QMenu *plugMenu = sverify->getPlugMenu();
 
699
        sverify->selectPlugin( curPlugin );
 
700
        verify = sverify;
 
701
 
 
702
        inner_box->addWidget( new KSeparator( Qt::Horizontal, this ) );
 
703
 
 
704
        QBoxLayout *hbox2 = new QHBoxLayout();
 
705
        inner_box->addLayout( hbox2 );
 
706
        hbox2->setParent( inner_box );
 
707
        hbox2->addWidget( goButton );
 
708
        hbox2->addStretch( 1 );
 
709
        hbox2->addWidget( menuButton );
 
710
        hbox2->addStretch( 1 );
 
711
 
 
712
        if (sessMenu->actions().count() > 1) {
 
713
                inserten( i18n("Session &Type"), Qt::ALT+Qt::Key_T, sessMenu );
 
714
                needSep = true;
 
715
        }
 
716
 
 
717
        if (plugMenu) {
 
718
                inserten( i18n("&Authentication Method"), Qt::ALT+Qt::Key_A, plugMenu );
 
719
                needSep = true;
 
720
        }
 
721
 
 
722
#ifdef XDMCP
 
723
        completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), Qt::ALT+Qt::Key_R );
 
724
#else
 
725
        completeMenu();
 
726
#endif
 
727
 
 
728
        if (optMenu)
 
729
                menuButton->setMenu( optMenu );
 
730
        else
 
731
                menuButton->hide();
 
732
 
 
733
        pluginSetup();
 
734
 
 
735
        verify->start();
 
736
}
 
737
 
 
738
void
 
739
KStdGreeter::pluginSetup()
 
740
{
 
741
        inherited::pluginSetup();
 
742
        if (userView) {
 
743
                if (verify->entitiesLocal() && verify->entityPresettable())
 
744
                        userView->show();
 
745
                else
 
746
                        userView->hide();
 
747
        }
 
748
        adjustGeometry();
 
749
        update();
 
750
}
 
751
 
 
752
void
 
753
KStdGreeter::verifyFailed()
 
754
{
 
755
        goButton->setEnabled( false );
 
756
        inherited::verifyFailed();
 
757
}
 
758
 
 
759
void
 
760
KStdGreeter::verifyRetry()
 
761
{
 
762
        goButton->setEnabled( true );
 
763
        inherited::verifyRetry();
 
764
}
 
765
 
 
766
 
 
767
KThemedGreeter::KThemedGreeter( KdmThemer *_themer )
 
768
        : KGreeter( true )
 
769
        , themer( _themer )
 
770
//      , clock( 0 )
 
771
{
 
772
        // We do all painting ourselves
 
773
        setAttribute( Qt::WA_NoSystemBackground, true );
 
774
        // Allow tracking the mouse position
 
775
        setMouseTracking( true );
 
776
 
 
777
        adjustGeometry();
 
778
 
 
779
        themer->setWidget( this );
 
780
 
 
781
        connect( themer, SIGNAL(activated( const QString & )),
 
782
                 SLOT(slotThemeActivated( const QString & )) );
 
783
 
 
784
        console_rect = themer->findNode( "xconsole" ); // kdm ext
 
785
        userlist_rect = themer->findNode( "userlist" );
 
786
        caps_warning = themer->findNode( "caps-lock-warning" );
 
787
        xauth_warning = themer->findNode( "xauth-warning" ); // kdm ext
 
788
        pam_error = themer->findNode( "pam-error" );
 
789
        KdmLabel *pam_error_label = qobject_cast<KdmLabel *>(pam_error);
 
790
        if (pam_error_label)
 
791
                pam_error_label->setText( i18n("Login Failed.") );
 
792
        timed_label = themer->findNode( "timed-label" );
 
793
 
 
794
        KdmItem *itm;
 
795
        if ((itm = themer->findNode( "pam-message" ))) // done via msgboxes
 
796
                itm->setVisible( false );
 
797
        if ((itm = themer->findNode( "language_button" ))) // not implemented yet
 
798
                itm->setVisible( false );
 
799
 
 
800
#ifdef WITH_KDM_XCONSOLE
 
801
        if (console_rect) {
 
802
                if (consoleView)
 
803
                        console_rect->setWidget( consoleView );
 
804
                else
 
805
                        console_rect->setVisible( false );
 
806
        }
 
807
#endif
 
808
 
 
809
        if (xauth_warning && (_authorized || !_authComplain))
 
810
                xauth_warning->setVisible( false );
 
811
 
 
812
//      if (!_greetString.isEmpty()) {
 
813
//      }
 
814
//      clock = new KdmClock( this, "clock" );
 
815
 
 
816
        QWidget *prec;
 
817
        if (userView)
 
818
                prec = userView;
 
819
#ifdef WITH_KDM_XCONSOLE
 
820
        else if (consoleView)
 
821
                prec = consoleView;
 
822
#endif
 
823
        else
 
824
                prec = 0;
 
825
        KGThemedVerify *tverify =
 
826
                new KGThemedVerify( this, themer, this, prec, QString(),
 
827
                                    pluginList, KGreeterPlugin::Authenticate,
 
828
                                    KGreeterPlugin::Login );
 
829
        QMenu *plugMenu = tverify->getPlugMenu();
 
830
        tverify->selectPlugin( curPlugin );
 
831
        verify = tverify;
 
832
 
 
833
        if ((session_button = themer->findNode( "session_button" ))) {
 
834
                if (sessMenu->actions().count() <= 1) {
 
835
                        session_button->setVisible( false );
 
836
                        session_button = 0;
 
837
                }
 
838
        } else {
 
839
                if (sessMenu->actions().count() > 1) {
 
840
                        inserten( i18n("Session &Type"), Qt::ALT+Qt::Key_T, sessMenu );
 
841
                        needSep = true;
 
842
                }
 
843
        }
 
844
 
 
845
        if (plugMenu) {
 
846
                inserten( i18n("&Authentication Method"), Qt::ALT+Qt::Key_A, plugMenu );
 
847
                needSep = true;
 
848
        }
 
849
 
 
850
#ifdef XDMCP
 
851
        completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), Qt::ALT+Qt::Key_R );
 
852
#else
 
853
        completeMenu();
 
854
#endif
 
855
 
 
856
        if ((system_button = themer->findNode( "system_button" ))) {
 
857
                if (optMenu)
 
858
                        addAction( optMenu->menuAction() );
 
859
                else
 
860
                        system_button->setVisible( false );
 
861
        }
 
862
 
 
863
        pluginSetup();
 
864
 
 
865
        verify->start();
 
866
}
 
867
 
 
868
KThemedGreeter::~KThemedGreeter()
 
869
{
 
870
        themer->setWidget( 0 );
 
871
}
 
872
 
 
873
bool
 
874
KThemedGreeter::event( QEvent *e )
 
875
{
 
876
        if (themer)
 
877
                themer->widgetEvent( e );
 
878
        return inherited::event( e );
 
879
}
 
880
 
 
881
void
 
882
KThemedGreeter::pluginSetup()
 
883
{
 
884
        inherited::pluginSetup();
 
885
 
 
886
        if (userView && verify->entitiesLocal() && verify->entityPresettable() && userlist_rect) {
 
887
                userlist_rect->setWidget( userView );
 
888
                userlist_rect->setVisible( true );
 
889
        } else {
 
890
                if (userView)
 
891
                        userView->hide();
 
892
                if (userlist_rect)
 
893
                        userlist_rect->setVisible( false );
 
894
        }
 
895
}
 
896
 
 
897
void
 
898
KThemedGreeter::verifyFailed()
 
899
{
 
900
//      goButton->setEnabled( false );
 
901
        if (userView)
 
902
                userView->setEnabled( false );
 
903
        inherited::verifyFailed();
 
904
}
 
905
 
 
906
void
 
907
KThemedGreeter::verifyRetry()
 
908
{
 
909
//      goButton->setEnabled( true );
 
910
        if (userView)
 
911
                userView->setEnabled( true );
 
912
        inherited::verifyRetry();
 
913
}
 
914
 
 
915
void
 
916
KThemedGreeter::updateStatus( bool fail, bool caps, int timedleft )
 
917
{
 
918
        if (pam_error)
 
919
                pam_error->setVisible( fail );
 
920
        if (caps_warning)
 
921
                caps_warning->setVisible( caps );
 
922
        if (timed_label) {
 
923
                if (timedleft) {
 
924
                        if (timedleft != KdmLabel::timedDelay) {
 
925
                                KdmLabel::timedDelay = timedleft;
 
926
                                KdmLabel::timedUser = curUser;
 
927
                                timed_label->setVisible( true );
 
928
                                timed_label->update();
 
929
                        }
 
930
                } else {
 
931
                        KdmLabel::timedDelay = -1;
 
932
                        timed_label->setVisible( false );
 
933
                }
 
934
        }
 
935
}
 
936
 
 
937
void
 
938
KThemedGreeter::slotThemeActivated( const QString &id )
 
939
{
 
940
        if (id == "login_button")
 
941
                accept();
 
942
        else if (id == "session_button")
 
943
                slotSessMenu();
 
944
        else if (id == "system_button")
 
945
                slotActionMenu();
 
946
}
 
947
 
 
948
void
 
949
KThemedGreeter::slotSessMenu()
 
950
{
 
951
        sessMenu->popup( mapToGlobal( session_button->rect().center() ) );
 
952
}
 
953
 
 
954
void
 
955
KThemedGreeter::slotActionMenu()
 
956
{
 
957
        if (system_button)
 
958
                optMenu->popup( mapToGlobal( system_button->rect().center() ) );
 
959
        else
 
960
                optMenu->popup( mapToGlobal( rect().center() ) );
 
961
}
 
962
 
 
963
void
 
964
KThemedGreeter::keyPressEvent( QKeyEvent *e )
 
965
{
 
966
        inherited::keyPressEvent( e );
 
967
        if (!(e->modifiers() & Qt::KeyboardModifierMask) &&
 
968
            (e->key() == Qt::Key_Return || e->key() == Qt::Key_Enter))
 
969
                accept();
 
970
}
 
971
 
 
972
#include "kgreeter.moc"