--- kdm/kfrontend/kgreeter.cpp.old 2008-10-12 16:44:44.000000000 +0000 +++ kdm/kfrontend/kgreeter.cpp 2008-10-12 17:04:45.000000000 +0000 @@ -38,6 +38,7 @@ #include #include #include +#include #undef Unsorted // x headers suck - make qdir.h work with --enable-final #include @@ -46,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -63,27 +65,47 @@ #include #include #include +#include +#include #include class UserListView : public KListView { public: - UserListView( QWidget *parent = 0, const char *name = 0 ) + UserListView( bool _them, QWidget *parent = 0, const char *name = 0 ) : KListView( parent, name ) - , cachedSizeHint( -1, 0 ) + , themed(_them), cachedSizeHint( -1, 0 ) +) { setSizePolicy( QSizePolicy::Preferred, QSizePolicy::Ignored ); header()->hide(); addColumn( QString::null ); setColumnAlignment( 0, AlignVCenter ); setResizeMode( QListView::LastColumn ); + if (themed) { + setBackgroundMode( Qt::NoBackground ); + viewport()->setBackgroundMode( Qt::NoBackground ); + setFrameStyle( QFrame::NoFrame ); + } } + bool themed; mutable QSize cachedSizeHint; - protected: + int sumHeight() const + { + int sum = 0; + for (QListViewItem *itm = firstChild(); itm; itm = itm->nextSibling()) { + sum += itm->height(); + } + return sum; + } +public: virtual QSize sizeHint() const { + if (themed) + return KListView::sizeHint(); + if (!cachedSizeHint.isValid()) { constPolish(); uint maxw = 0; @@ -98,6 +120,22 @@ } return cachedSizeHint; } + virtual void paintEmptyArea ( QPainter * p, const QRect & rect ) + { + if (!themed) + return KListView::paintEmptyArea(p, rect ); + + const QPixmap *pm = paletteBackgroundPixmap(); + if (!pm || pm->isNull()) + return; + + kdDebug() << "paintEmpty " << rect << endl; + QRect devRect = p->xForm( rect ); + kdDebug() << "paintEmpty2 " << devRect << endl; + p->drawPixmap(0, 0, *pm, devRect.left(), devRect.top() ); + } + + QPixmap background; }; @@ -115,12 +153,14 @@ , curSel( -1 ) , prevValid( true ) , needLoad( false ) + , themed( framed ) { stsFile = new KSimpleConfig( _stsFile ); stsFile->setGroup( "PrevUser" ); if (_userList) { - userView = new UserListView( this ); + readFacesList(); + userView = new UserListView( framed, this ); connect( userView, SIGNAL(clicked( QListViewItem * )), SLOT(slotUserClicked( QListViewItem * )) ); connect( userView, SIGNAL(doubleClicked( QListViewItem * )), @@ -128,8 +168,6 @@ } if (_userCompletion) userList = new QStringList; - if (userView || userList) - insertUsers(); sessMenu = new QPopupMenu( this ); connect( sessMenu, SIGNAL(activated( int )), @@ -150,6 +188,33 @@ delete stsFile; } +void KGreeter::readFacesList() +{ + FILE *f = fopen( QFile::encodeName( _faceDir + "/.randomlist" ), "rt" ); + if ( !f ) + return; + QTextIStream is( f ); + while ( !is.eof() ) + { + QString line = is.readLine().simplifyWhiteSpace(); + if ( line.isEmpty() ) + continue; + QString icon; + int index = line.find( ' ' ); + if ( index > 0 ) { + icon = line.left( index ); + line = line.mid( index ); + } else { + icon = line; + line = QString::null; + } + randomFaces.push_back( icon ); + QStringList list = QStringList::split( ' ', line ); + for ( QStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) + randomFacesMap[*it] = icon; + } +} + class UserListViewItem : public KListViewItem { public: UserListViewItem( UserListView *parent, const QString &text, @@ -162,6 +227,14 @@ setText( 0, text ); parent->cachedSizeHint.setWidth( -1 ); } + virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment) + { + if (((UserListView*)listView())->themed) + QListViewItem::paintCell(p, cg, column, width, alignment); + else + KListViewItem::paintCell(p, cg, column, width, alignment); + } + QString login; }; @@ -224,10 +297,23 @@ QSize ns( 48, 48 ); if (p.size() != ns) p = p.convertDepth( 32 ).smoothScale( ns, QImage::ScaleMin ); - goto gotit; + break; } while (--nd >= 0); - p = default_pix; - gotit: + + if ( p.isNull() && randomFaces.count() ) { + QString randomFace = randomFacesMap[username]; + if ( randomFace.isNull() ) { + QStringList::size_type index = 0; + for ( size_t i = 0; i < username.length(); ++i ) + index += ( 0x7f - username.at( i ).latin1() ) % 37; + randomFace = randomFaces[ index % randomFaces.count() ]; + } + p.load( _faceDir + "/../pics/users/" + randomFace + ".png" ); + } + + if ( p.isNull() ) + p = default_pix; + QString realname = KStringHandler::from8Bit( ps->pw_gecos ); realname.truncate( realname.find( ',' ) ); if (realname.isEmpty() || realname == username) @@ -278,7 +364,7 @@ } void -KGreeter::insertUsers() +KGreeter::insertUsers(int limit_users) { struct passwd *ps; @@ -305,6 +391,8 @@ if (_showUsers == SHOW_ALL) { UserList noUsers( _noUsers ); QDict dupes( 1000 ); + QStringList toinsert; + int count = 0; for (setpwent(); (ps = getpwent()) != 0;) { if (*ps->pw_dir && *ps->pw_shell && (ps->pw_uid >= (unsigned)_lowUserId || @@ -316,10 +404,54 @@ QString username( QFile::decodeName( ps->pw_name ) ); if (!dupes.find( username )) { dupes.insert( username, (int *)-1 ); - insertUser( default_pix, username, ps ); + toinsert.append( username ); + + if ( limit_users >= 0 && ++count > limit_users ) + break; } } } + if ( limit_users >= 0 && ++count > limit_users ) { + utmpname( _PATH_WTMP ); + setutxent(); + toinsert = QStringList(); + dupes.clear(); + + for ( count = 0; count < limit_users; ) { + struct utmpx * ent = getutxent(); + if ( !ent ) + break; + struct passwd *ps = getpwnam( ent->ut_user ); + if (ps && *ps->pw_dir && *ps->pw_shell && + (ps->pw_uid >= (unsigned)_lowUserId || + !ps->pw_uid && _showRoot) && + ps->pw_uid <= (unsigned)_highUserId && + !noUsers.hasUser( ps->pw_name ) && + !noUsers.hasGroup( ps->pw_gid )) + { + QString username( QFile::decodeName( ent->ut_user ) ); + if (!dupes.find( username )) { + dupes.insert( username, (int *)-1 ); + toinsert.append( username ); + count++; + } + } + + + } + endutxent(); + } + + for ( QStringList::ConstIterator it = toinsert.begin(); + it != toinsert.end(); ++it ) + { + // pretty stupid to do another lookup round, but the number is limited + // and caching struct passwd is pretty ugly + struct passwd *ps = getpwnam( QFile::encodeName( *it ) ); + if ( ps ) + insertUser( default_pix, *it, ps ); + } + } else { UserList users( _users ); if (users.hasGroups()) { @@ -721,21 +853,25 @@ hbox2->addStretch( 1 ); if (sessMenu->count() > 1) { - inserten( i18n("Session &Type"), ALT+Key_T, sessMenu ); + inserten( i18n("Session &Type"), 0, sessMenu ); needSep = true; } if (plugMenu) { - inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu ); + inserten( i18n("&Authentication Method"), 0, plugMenu ); needSep = true; } #ifdef XDMCP - completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), ALT+Key_R ); + completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), 0 ); #else completeMenu(); #endif + if (userView || userList) + insertUsers(); + + if (optMenu) menuButton->setPopup( optMenu ); else @@ -829,6 +965,10 @@ if (xauth_warning && (_authorized || !_authComplain)) xauth_warning->hide( true ); + if (userView || userList) + insertUsers( 7 ); // TODO: find out how many are a good value + + // if (!_greetString.isEmpty()) { // } // clock = new KdmClock( this, "clock" ); @@ -854,34 +994,27 @@ if ((itm = themer->findNode( "session_button" ))) { if (sessMenu->count() <= 1) itm->hide( true ); - else { + else session_button = itm; - QAccel *accel = new QAccel( this ); - accel->insertItem( ALT+Key_T, 0 ); - connect( accel, SIGNAL(activated( int )), SLOT(slotSessMenu()) ); - } } else { if (sessMenu->count() > 1) { - inserten( i18n("Session &Type"), ALT+Key_T, sessMenu ); + inserten( i18n("Session &Type"), 0, sessMenu ); needSep = true; } } if (plugMenu) { - inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu ); + inserten( i18n("&Authentication Method"), 0, plugMenu ); needSep = true; } #ifdef XDMCP - completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), ALT+Key_R ); + completeMenu( LOGIN_LOCAL_ONLY, ex_choose, i18n("&Remote Login"), 0 ); #else completeMenu(); #endif system_button = themer->findNode( "system_button" ); - QAccel *accel = new QAccel( this ); - accel->insertItem( ALT+Key_M, 0 ); - connect( accel, SIGNAL(activated( int )), SLOT(slotActionMenu()) ); pluginSetup(); @@ -902,8 +1035,8 @@ inherited::pluginSetup(); if (userView && verify->entitiesLocal() && verify->entityPresettable() && userlist_rect) { + userView->setMaximumHeight( userView->sumHeight() ); userlist_rect->setWidget( userView ); - userView->show(); } else { if (userView) userView->hide(); @@ -919,12 +1052,17 @@ { // goButton->setEnabled( false ); inherited::verifyFailed(); + if (userView) + userView->setEnabled(false); } void KThemedGreeter::verifyRetry() { // goButton->setEnabled( true ); + if (userView) + userView->setEnabled(true); + } QString KThemedGreeter::timedUser = QString::null;