5 Copyright (C) 1997, 1998, 2000 Steffen Hansen <hansen@kde.org>
6 Copyright (C) 2000-2004 Oswald Buddenhagen <ossi@kde.org>
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.
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.
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.
27 #include "kdmconfig.h"
29 #include "kdm_greet.h"
30 #include "themer/kdmthemer.h"
31 #include "themer/kdmitem.h"
32 #include "themer/kdmlabel.h"
34 #include <KColorScheme>
35 #include <KConfigGroup>
37 #include <kseparator.h>
38 #include <kstandarddirs.h>
39 #include <kstringhandler.h>
45 #include <QImageReader>
48 #include <QListWidget>
49 #include <QListWidgetItem>
53 #include <QPushButton>
56 #include <sys/types.h>
65 class UserListView
: public QListWidget
{
67 UserListView( QWidget
*parent
= 0 )
68 : QListWidget( parent
)
69 , cachedSizeHint( -1, 0 )
71 setSizePolicy( QSizePolicy::Minimum
, QSizePolicy::Ignored
);
72 setUniformItemSizes( true );
73 setVerticalScrollMode( ScrollPerPixel
);
74 setIconSize( QSize( 48, 48 ) );
75 setAlternatingRowColors( true );
78 mutable QSize cachedSizeHint
;
81 virtual QSize
sizeHint() const
83 if (!cachedSizeHint
.isValid()) {
85 QStyleOptionViewItem
vo( viewOptions() );
86 QAbstractListModel
*md( static_cast<QAbstractListModel
*>(model()) );
88 for (int i
= 0, rc
= md
->rowCount(); i
< rc
; i
++) {
89 QSize sh
= itemDelegate()->sizeHint( vo
, md
->index( i
) );
90 uint thisw
= sh
.width();
95 cachedSizeHint
.setWidth(
96 style()->pixelMetric( QStyle::PM_ScrollBarExtent
) +
98 (style()->styleHint( QStyle::SH_ScrollView_FrameOnlyAroundContents
) ?
99 style()->pixelMetric(QStyle::PM_DefaultFrameWidth
) : 0)) * 2 +
101 cachedSizeHint
.setHeight( frameWidth() * 2 + h
);
103 return cachedSizeHint
;
106 virtual void keyPressEvent( QKeyEvent
*event
)
108 switch (event
->key()) {
112 emit
itemDoubleClicked( currentItem() );
117 emit
itemClicked( currentItem() );
121 QListWidget::keyPressEvent( event
);
126 virtual void mousePressEvent( QMouseEvent
*event
)
128 m_suppressClick
= false;
129 QListWidget::mousePressEvent(event
);
132 virtual void mouseReleaseEvent( QMouseEvent
*event
)
135 m_suppressClick
= false;
137 QListWidget::mouseReleaseEvent(event
);
140 virtual void mouseDoubleClickEvent( QMouseEvent
*event
)
142 m_suppressClick
= true;
143 QListWidget::mouseDoubleClickEvent(event
);
147 bool m_suppressClick
;
150 class UserListViewItem
: public QListWidgetItem
{
152 UserListViewItem( UserListView
*parent
, const QString
&text
,
153 const QPixmap
&pixmap
, const QString
&username
)
154 : QListWidgetItem( parent
)
159 parent
->cachedSizeHint
.setWidth( -1 );
166 int KGreeter::curPlugin
= -1;
167 PluginList
KGreeter::pluginList
;
169 KGreeter::KGreeter( bool framed
)
170 : inherited( framed
)
180 stsGroup
= new KConfigGroup( KSharedConfig::openConfig( _stsFile
),
184 userView
= new UserListView( this );
185 connect( userView
, SIGNAL(itemClicked( QListWidgetItem
* )),
186 SLOT(slotUserClicked( QListWidgetItem
* )) );
187 connect( userView
, SIGNAL(itemDoubleClicked( QListWidgetItem
* )),
191 userList
= new QStringList
;
192 if (userView
|| userList
)
195 sessMenu
= new QMenu( this );
196 connect( sessMenu
, SIGNAL(triggered( QAction
* )),
197 SLOT(slotSessionSelected()) );
199 sessGroup
= new QActionGroup( this );
204 pluginList
= KGVerify::init( _pluginsLogin
);
208 KGreeter::~KGreeter()
216 #define FILE_LIMIT_ICON 20
217 #define FILE_LIMIT_IMAGE 200
218 #define PIXEL_LIMIT_ICON 100
219 #define PIXEL_LIMIT_IMAGE 300
222 loadFace( QByteArray
&fn
, QImage
&p
)
225 if ((fd
= open( fn
.data(), O_RDONLY
| O_NONBLOCK
)) < 0) {
227 if ((fd
= open( fn
.data(), O_RDONLY
| O_NONBLOCK
)) < 0)
233 f
.open( fd
, QFile::ReadOnly
);
235 if (fs
> (ico
? FILE_LIMIT_ICON
: FILE_LIMIT_IMAGE
) * 1000) {
236 logWarn( "%s exceeds file size limit (%dkB)\n",
237 fn
.data(), ico
? FILE_LIMIT_ICON
: FILE_LIMIT_IMAGE
);
240 QByteArray fc
= f
.read( fs
);
243 buf
.open( QBuffer::ReadOnly
);
244 QImageReader
ir( &buf
);
245 QSize sz
= ir
.size();
246 int lim
= ico
? PIXEL_LIMIT_ICON
: PIXEL_LIMIT_IMAGE
;
247 if (sz
.width() > lim
|| sz
.height() > lim
) {
248 logWarn( "%s exceeds image dimension limit (%dx%d)\n",
249 fn
.data(), lim
, lim
);
252 sz
.scale( 48, 48, Qt::KeepAspectRatio
);
253 ir
.setScaledSize( sz
);
256 logInfo( "%s is no valid image\n", fn
.data() );
259 if (p
.width() < 48) {
260 QImage
np( 48, p
.height(), QImage::Format_ARGB32
);
263 pnt
.drawImage( (48 - p
.width()) / 2, 0, p
);
270 KGreeter::insertUser( const QImage
&default_pix
,
271 const QString
&username
, struct passwd
*ps
)
274 userList
->append( username
);
279 if (_faceSource
== FACE_USER_ONLY
||
280 _faceSource
== FACE_PREFER_USER
)
282 if (_faceSource
!= FACE_USER_ONLY
&&
283 _faceSource
!= FACE_ADMIN_ONLY
)
288 QByteArray fn
= !dp
?
289 QByteArray( ps
->pw_dir
) + '/' :
290 QFile::encodeName( _faceDir
+ '/' + username
);
292 if (loadFace( fn
, p
))
297 QString realname
= KStringHandler::from8Bit( ps
->pw_gecos
);
298 realname
.truncate( realname
.indexOf( ',' ) & (~0U >> 1) );
299 if (realname
.isEmpty() || realname
== username
)
300 new UserListViewItem( userView
, username
, QPixmap::fromImage( p
), username
);
302 realname
.append( "\n" ).append( username
);
303 new UserListViewItem( userView
, realname
, QPixmap::fromImage( p
), username
);
309 UserList( char **in
);
310 bool hasUser( const char *str
) const { return users
.contains( str
); }
311 bool hasGroup( gid_t gid
) const { return groups
.contains( gid
); }
312 bool hasGroups() const { return !groups
.isEmpty(); }
316 QSet
<QByteArray
> users
;
319 UserList::UserList( char **in
)
325 if ((grp
= getgrnam( *in
+ 1 ))) {
326 for (; *grp
->gr_mem
; grp
->gr_mem
++)
327 users
.insert( *grp
->gr_mem
);
328 groups
.insert( grp
->gr_gid
);
335 KGreeter::insertUsers()
339 // XXX remove seteuid-voodoo when we run as nobody
340 if (!(ps
= getpwnam( "nobody" )))
342 if (setegid( ps
->pw_gid
))
344 if (seteuid( ps
->pw_uid
)) {
351 QByteArray fn
= QFile::encodeName( _faceDir
+ "/.default.face.icon" );
352 if (!loadFace( fn
, default_pix
)) {
353 logError( "Cannot open default user face\n" );
354 default_pix
= QImage( 48, 48, QImage::Format_ARGB32
);
355 default_pix
.fill( 0 );
358 if (_showUsers
== SHOW_ALL
) {
359 UserList
noUsers( _noUsers
);
361 for (setpwent(); (ps
= getpwent()) != 0;) {
362 if (*ps
->pw_dir
&& *ps
->pw_shell
&&
363 (ps
->pw_uid
>= (unsigned)_lowUserId
||
364 (!ps
->pw_uid
&& _showRoot
)) &&
365 ps
->pw_uid
<= (unsigned)_highUserId
&&
366 !noUsers
.hasUser( ps
->pw_name
) &&
367 !noUsers
.hasGroup( ps
->pw_gid
))
369 QString
username( QFile::decodeName( ps
->pw_name
) );
370 if (!dupes
.contains( username
)) {
371 dupes
.insert( username
);
372 insertUser( default_pix
, username
, ps
);
377 UserList
users( _users
);
378 if (users
.hasGroups()) {
380 for (setpwent(); (ps
= getpwent()) != 0;) {
381 if (*ps
->pw_dir
&& *ps
->pw_shell
&&
382 (ps
->pw_uid
>= (unsigned)_lowUserId
||
383 (!ps
->pw_uid
&& _showRoot
)) &&
384 ps
->pw_uid
<= (unsigned)_highUserId
&&
385 (users
.hasUser( ps
->pw_name
) ||
386 users
.hasGroup( ps
->pw_gid
)))
388 QString
username( QFile::decodeName( ps
->pw_name
) );
389 if (!dupes
.contains( username
)) {
390 dupes
.insert( username
);
391 insertUser( default_pix
, username
, ps
);
396 for (int i
= 0; _users
[i
]; i
++)
397 if ((ps
= getpwnam( _users
[i
] )) && (ps
->pw_uid
|| _showRoot
))
398 insertUser( default_pix
, QFile::decodeName( _users
[i
] ), ps
);
405 userView
->sortItems();
410 // XXX remove seteuid-voodoo when we run as nobody
416 KGreeter::putSession( const QString
&type
, const QString
&name
, bool hid
, const char *exe
)
418 int prio
= exe
? (!strcmp( exe
, "default" ) ? 0 :
419 !strcmp( exe
, "custom" ) ? 1 :
420 !strcmp( exe
, "failsafe" ) ? 3 : 2) : 2;
421 for (int i
= 0; i
< sessionTypes
.size(); i
++)
422 if (sessionTypes
[i
].type
== type
) {
423 sessionTypes
[i
].prio
= prio
;
426 sessionTypes
.append( SessType( name
, type
, hid
, prio
) );
430 KGreeter::insertSessions()
432 for (char **dit
= _sessionsDirs
; *dit
; ++dit
)
433 foreach (QString ent
, QDir( *dit
).entryList())
434 if (ent
.endsWith( ".desktop" )) {
436 KSharedConfig::openConfig(
437 QString( *dit
).append( '/' ).append( ent
) ),
439 putSession( ent
.left( ent
.length() - 8 ),
440 dsk
.readEntry( "Name" ),
441 (dsk
.readEntry( "Hidden", false ) ||
442 (dsk
.hasKey( "TryExec" ) &&
443 KStandardDirs::findExe(
444 dsk
.readEntry( "TryExec" ) ).isEmpty())),
445 dsk
.readEntry( "Exec" ).toLatin1() );
447 putSession( "default", i18nc("@item:inlistbox session type", "Default"), false, "default" );
448 putSession( "custom", i18nc("@item:inlistbox session type", "Custom"), false, "custom" );
449 putSession( "failsafe", i18nc("@item:inlistbox session type", "Failsafe"), false, "failsafe" );
450 qSort( sessionTypes
);
451 for (int i
= 0; i
< sessionTypes
.size() && !sessionTypes
[i
].hid
; i
++) {
452 sessionTypes
[i
].action
= sessGroup
->addAction( sessionTypes
[i
].name
);
453 sessionTypes
[i
].action
->setData( i
);
454 sessionTypes
[i
].action
->setCheckable( true );
455 switch (sessionTypes
[i
].prio
) {
456 case 0: case 1: nSpecials
++; break;
457 case 2: nNormals
++; break;
460 sessMenu
->addActions( sessGroup
->actions() );
464 KGreeter::slotUserEntered()
469 if ((pw
= getpwnam( curUser
.toLocal8Bit().data() ))) {
470 QString theUser
= QString::fromLocal8Bit( pw
->pw_name
);
471 for (int i
= 0, rc
= userView
->model()->rowCount(); i
< rc
; i
++) {
472 UserListViewItem
*item
=
473 static_cast<UserListViewItem
*>(userView
->item( i
));
474 if (item
->login
== theUser
) {
475 userView
->setCurrentItem( item
);
480 userView
->clearSelection();
486 QTimer::singleShot( 0, this, SLOT(slotLoadPrevWM()) );
490 KGreeter::slotUserClicked( QListWidgetItem
*item
)
493 curUser
= ((UserListViewItem
*)item
)->login
;
494 verify
->setUser( curUser
);
500 KGreeter::slotSessionSelected()
502 verify
->gplugChanged();
518 KGreeter::setPrevWM( QAction
*wm
)
522 curPrev
->setText( sessionTypes
[curPrev
->data().toInt()].name
);
524 wm
->setText( i18nc( "@item:inmenu session type",
526 sessionTypes
[wm
->data().toInt()].name
) );
532 KGreeter::slotLoadPrevWM()
535 unsigned long crc
, by
;
539 if (verify
->coreLock
) {
546 name
= curUser
.toLocal8Bit();
547 gSendInt( G_ReadDmrc
);
548 gSendStr( name
.data() );
549 gRecvInt(); // ignore status code ...
550 if ((len
= name
.length())) {
551 gSendInt( G_GetDmrc
);
552 gSendStr( "Session" );
554 if (!sess
) { /* no such user */
555 if (!userView
&& !userList
) { // don't fake if user list shown
558 for (crc
= _forgingSeed
, i
= 0; i
< len
; i
++) {
559 by
= (crc
& 255) ^ name
[i
];
560 for (b
= 0; b
< 8; b
++)
561 by
= (by
>> 1) ^ (-(by
& 1) & 0xedb88320);
562 crc
= (crc
>> 8) ^ by
;
564 /* forge a session with this hash - default & custom more probable */
565 /* XXX - this should do a statistical analysis of the real users */
567 setPrevWM( sessionTypes
[crc
% (nSpecials
* 2 + nNormals
) % (nSpecials
+ nNormals
)].action
);
569 i
= crc
% (nSpecials
* 2 + nNormals
);
571 setPrevWM( sessionTypes
[i
+ nSpecials
].action
);
573 setPrevWM( sessionTypes
[(i
- nNormals
) / 2].action
);
578 for (int i
= 0; i
< sessionTypes
.count() && !sessionTypes
[i
].hid
; i
++)
579 if (sessionTypes
[i
].type
== sess
) {
581 setPrevWM( sessionTypes
[i
].action
);
584 if (!sessGroup
->checkedAction())
585 KFMsgBox::box( this, sorrybox
,
586 i18n("Your saved session type '%1' is not valid any more.\n"
587 "Please select a new one, otherwise 'default' will be used.", sess
) );
596 KGreeter::pluginSetup()
599 QString ent
, pn( verify
->pluginName() ), dn( dName
+ '_' + pn
);
601 if (_preselUser
!= PRESEL_PREV
)
602 stsGroup
->deleteEntry( verify
->entitiesLocal() ? dName
: dn
, false );
603 if (_preselUser
!= PRESEL_NONE
&& verify
->entityPresettable()) {
604 if (verify
->entitiesLocal())
605 ent
= _preselUser
== PRESEL_PREV
?
606 stsGroup
->readEntry( dName
, QString() ) : _defaultUser
;
608 ent
= _preselUser
== PRESEL_PREV
?
609 stsGroup
->readEntry( dn
, QString() ) :
610 verify
->getConf( 0, (pn
+ ".DefaultEntity").toLatin1(), QVariant() ).toString();
611 field
= verify
->entitiesFielded() ?
612 verify
->getConf( 0, (pn
+ ".FocusField").toLatin1(), QVariant( 0 ) ).toInt() :
615 verify
->presetEntity( ent
, field
);
617 verify
->loadUsers( *userList
);
621 KGreeter::verifyPluginChanged( int id
)
628 KGreeter::verifyClear()
632 if (QAction
*curSel
= sessGroup
->checkedAction())
633 curSel
->setChecked( false );
639 if (_preselUser
== PRESEL_PREV
&& verify
->entityPresettable())
640 stsGroup
->writeEntry( verify
->entitiesLocal() ?
642 dName
+ '_' + verify
->pluginName(),
643 verify
->getEntity() );
644 if (QAction
*curSel
= sessGroup
->checkedAction()) {
645 gSendInt( G_PutDmrc
);
646 gSendStr( "Session" );
647 gSendStr( sessionTypes
[curSel
->data().toInt()].type
.toUtf8() );
648 } else if (!prevValid
) {
649 gSendInt( G_PutDmrc
);
650 gSendStr( "Session" );
651 gSendStr( "default" );
657 KGreeter::verifyFailed()
660 userView
->setEnabled( false );
666 KGreeter::verifyRetry()
669 userView
->setEnabled( true );
673 KGreeter::verifySetUser( const QString
&user
)
680 KStdGreeter::KStdGreeter()
685 QBoxLayout
*main_box
;
686 #ifdef WITH_KDM_XCONSOLE
688 QBoxLayout
*ex_box
= new QVBoxLayout( this );
689 main_box
= new QHBoxLayout();
690 ex_box
->addLayout( main_box
);
691 ex_box
->addWidget( consoleView
);
695 main_box
= new QHBoxLayout( this );
697 int rs
= layout()->spacing();
698 main_box
->setSpacing( layout()->margin() );
701 main_box
->addWidget( userView
);
703 QBoxLayout
*inner_box
= new QVBoxLayout();
704 main_box
->addLayout( inner_box
);
705 inner_box
->setSpacing( rs
);
707 if (!_authorized
&& _authComplain
) {
708 QLabel
*complainLabel
= new QLabel(
709 i18n("Warning: this is an unsecured session"), this );
710 complainLabel
->setToolTip(
711 i18n("This display requires no X authorization.\n"
712 "This means that anybody can connect to it,\n"
713 "open windows on it or intercept your input.") );
714 complainLabel
->setAlignment( Qt::AlignCenter
);
715 complainLabel
->setFont( *_failFont
);
717 p
.setBrush( QPalette::WindowText
,
718 KColorScheme( QPalette::Active
, KColorScheme::Window
)
719 .foreground( KColorScheme::NegativeText
) );
720 complainLabel
->setPalette( p
);
721 inner_box
->addWidget( complainLabel
);
723 if (!_greetString
.isEmpty()) {
724 QLabel
*welcomeLabel
= new QLabel( _greetString
, this );
725 welcomeLabel
->setAlignment( Qt::AlignCenter
);
726 welcomeLabel
->setFont( *_greetFont
);
727 inner_box
->addWidget( welcomeLabel
);
732 clock
= new KdmClock( this );
736 QMovie
*movie
= new QMovie( this );
737 movie
->setFileName( _logo
);
738 if (movie
->isValid()) {
740 pixLabel
= new QLabel( this );
741 pixLabel
->setMovie( movie
);
742 if (!movie
->currentImage().hasAlphaChannel())
743 pixLabel
->setFrameStyle( QFrame::Panel
| QFrame::Sunken
);
744 pixLabel
->setIndent( 0 );
753 inner_box
->addWidget( clock
, 0, Qt::AlignCenter
);
755 inner_box
->addWidget( pixLabel
, 0, Qt::AlignCenter
);
756 inner_box
->addSpacing( inner_box
->spacing() );
759 main_box
->addWidget( clock
, 0, Qt::AlignCenter
);
761 main_box
->addWidget( pixLabel
, 0, Qt::AlignCenter
);
764 goButton
= new QPushButton( i18nc("@action:button", "L&ogin"), this );
765 goButton
->setDefault( true );
766 connect( goButton
, SIGNAL(clicked()), SLOT(accept()) );
767 QPushButton
*menuButton
= new QPushButton( i18nc("@action:button", "&Menu"), this );
773 #ifdef WITH_KDM_XCONSOLE
774 else if (consoleView
)
779 KGStdVerify
*sverify
=
780 new KGStdVerify( this, this, prec
, QString(),
781 pluginList
, KGreeterPlugin::Authenticate
,
782 KGreeterPlugin::Login
);
783 inner_box
->addLayout( sverify
->getLayout() );
784 QMenu
*plugMenu
= sverify
->getPlugMenu();
785 sverify
->selectPlugin( curPlugin
);
788 inner_box
->addWidget( new KSeparator( Qt::Horizontal
, this ) );
790 QBoxLayout
*hbox2
= new QHBoxLayout();
791 inner_box
->addLayout( hbox2
);
792 hbox2
->addWidget( goButton
);
793 hbox2
->addStretch( 1 );
794 hbox2
->addWidget( menuButton
);
795 hbox2
->addStretch( 1 );
797 if (sessMenu
->actions().count() > 1) {
798 inserten( i18nc("@title:menu", "Session &Type"), Qt::ALT
+Qt::Key_T
, sessMenu
);
803 inserten( i18nc("@title:menu", "&Authentication Method"), Qt::ALT
+Qt::Key_A
, plugMenu
);
808 completeMenu( LOGIN_LOCAL_ONLY
, ex_choose
, i18nc("@action:inmenu", "&Remote Login"), Qt::ALT
+Qt::Key_R
);
814 menuButton
->setMenu( optMenu
);
824 KStdGreeter::pluginSetup()
826 inherited::pluginSetup();
828 if (verify
->entitiesLocal() && verify
->entityPresettable())
838 KStdGreeter::verifyFailed()
840 goButton
->setEnabled( false );
841 inherited::verifyFailed();
845 KStdGreeter::verifyRetry()
847 goButton
->setEnabled( true );
848 inherited::verifyRetry();
852 KThemedGreeter::KThemedGreeter( KdmThemer
*_themer
)
857 // We do all painting ourselves
858 setAttribute( Qt::WA_NoSystemBackground
, true );
859 // Allow tracking the mouse position
860 setMouseTracking( true );
864 themer
->setWidget( this );
866 connect( themer
, SIGNAL(activated( const QString
& )),
867 SLOT(slotThemeActivated( const QString
& )) );
869 KdmItem
*console_node
= themer
->findNode( "xconsole" ); // kdm ext
870 KdmItem
*console_rect
= themer
->findNode( "xconsole-rect" ); // kdm ext
872 console_rect
= console_node
;
873 userlist_node
= themer
->findNode( "userlist" );
874 userlist_rect
= themer
->findNode( "userlist-rect" );
876 userlist_rect
= userlist_node
;
877 caps_warning
= themer
->findNode( "caps-lock-warning" );
878 xauth_warning
= themer
->findNode( "xauth-warning" ); // kdm ext
879 pam_error
= themer
->findNode( "pam-error" );
880 KdmLabel
*pam_error_label
= qobject_cast
<KdmLabel
*>(pam_error
);
882 pam_error_label
->setText( i18n("Login failed") );
883 timed_label
= themer
->findNode( "timed-label" );
886 if ((itm
= themer
->findNode( "pam-message" ))) // done via msgboxes
887 itm
->setVisible( false );
888 if ((itm
= themer
->findNode( "language_button" ))) // not implemented yet
889 itm
->setVisible( false );
892 #ifdef WITH_KDM_XCONSOLE
894 console_node
->setWidget( consoleView
);
897 console_rect
->setVisible( false );
900 if (xauth_warning
&& (_authorized
|| !_authComplain
))
901 xauth_warning
->setVisible( false );
903 // if (!_greetString.isEmpty()) {
905 // clock = new KdmClock( this, "clock" );
910 #ifdef WITH_KDM_XCONSOLE
911 else if (consoleView
)
916 KGThemedVerify
*tverify
=
917 new KGThemedVerify( this, themer
, this, prec
, QString(),
918 pluginList
, KGreeterPlugin::Authenticate
,
919 KGreeterPlugin::Login
);
920 QMenu
*plugMenu
= tverify
->getPlugMenu();
921 tverify
->selectPlugin( curPlugin
);
924 if ((session_button
= themer
->findNode( "session_button" ))) {
925 if (sessMenu
->actions().count() <= 1) {
926 session_button
->setVisible( false );
930 if (sessMenu
->actions().count() > 1) {
931 inserten( i18nc("@title:menu", "Session &Type"), Qt::ALT
+Qt::Key_T
, sessMenu
);
937 inserten( i18nc("@title:menu", "&Authentication Method"), Qt::ALT
+Qt::Key_A
, plugMenu
);
942 completeMenu( LOGIN_LOCAL_ONLY
, ex_choose
, i18nc("@action:inmenu", "&Remote Login"), Qt::ALT
+Qt::Key_R
);
947 if ((system_button
= themer
->findNode( "system_button" ))) {
949 addAction( optMenu
->menuAction() );
951 system_button
->setVisible( false );
959 KThemedGreeter::~KThemedGreeter()
961 themer
->setWidget( 0 );
965 KThemedGreeter::event( QEvent
*e
)
968 themer
->widgetEvent( e
);
969 return inherited::event( e
);
973 KThemedGreeter::pluginSetup()
975 inherited::pluginSetup();
977 if (userView
&& verify
->entitiesLocal() && verify
->entityPresettable() && userlist_node
) {
978 userlist_node
->setWidget( userView
);
979 userlist_rect
->setVisible( true );
984 userlist_rect
->setVisible( false );
990 KThemedGreeter::verifyFailed()
992 // goButton->setEnabled( false );
993 inherited::verifyFailed();
997 KThemedGreeter::verifyRetry()
999 // goButton->setEnabled( true );
1000 inherited::verifyRetry();
1005 KThemedGreeter::updateStatus( bool fail
, bool caps
, int timedleft
)
1008 pam_error
->setVisible( fail
);
1010 caps_warning
->setVisible( caps
);
1013 if (timedleft
!= KdmLabel::timedDelay
) {
1014 KdmLabel::timedDelay
= timedleft
;
1015 KdmLabel::timedUser
= curUser
;
1016 timed_label
->setVisible( true );
1017 timed_label
->update();
1020 KdmLabel::timedDelay
= -1;
1021 timed_label
->setVisible( false );
1027 KThemedGreeter::slotThemeActivated( const QString
&id
)
1029 if (id
== "login_button")
1031 else if (id
== "session_button")
1033 else if (id
== "system_button")
1038 KThemedGreeter::slotSessMenu()
1040 sessMenu
->popup( mapToGlobal( session_button
->rect().center() ) );
1044 KThemedGreeter::slotActionMenu()
1047 optMenu
->popup( mapToGlobal( system_button
->rect().center() ) );
1049 optMenu
->popup( mapToGlobal( rect().center() ) );
1053 KThemedGreeter::keyPressEvent( QKeyEvent
*e
)
1055 inherited::keyPressEvent( e
);
1056 if (!(e
->modifiers() & ~Qt::KeypadModifier
) &&
1057 (e
->key() == Qt::Key_Return
|| e
->key() == Qt::Key_Enter
))
1061 #include "kgreeter.moc"