diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-09-03 09:14:57 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-09-03 09:14:57 +0000 |
commit | 27856879bf962f178d88e79144e37a47e731b122 (patch) | |
tree | a3bd3f489b755cd2941e7c53b90d12d6bfd4fbe3 /kdm | |
parent | c5228d52f504d6d2c0fefdd625ec08ebb8e91f85 (diff) | |
download | tdebase-27856879bf962f178d88e79144e37a47e731b122.tar.gz tdebase-27856879bf962f178d88e79144e37a47e731b122.zip |
* Massive import of OpenSUSE patches, primarily for bugfixes
* Added some infrastructure created by OpenSUSE to allow for future addition of the Kickoff menu as an option
* Minor Slackware compilation fixes
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdebase@1171255 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kdm')
27 files changed, 985 insertions, 112 deletions
diff --git a/kdm/backend/client.c b/kdm/backend/client.c index b2e7ebbc7..0807b2ce7 100644 --- a/kdm/backend/client.c +++ b/kdm/backend/client.c @@ -87,6 +87,18 @@ extern int loginsuccess( const char *User, const char *Host, const char *Tty, ch #include "consolekit.h" #endif +#define AU_FAILED 0 +#define AU_SUCCESS 1 +#ifdef HAVE_LIBAUDIT +#include <libaudit.h> +#else +#define log_to_audit_system(l,h,d,s) do { ; } while (0) +#endif + +#ifdef WITH_CONSOLE_KIT +#include "consolekit.h" +#endif + /* * Session data, mostly what struct verify_info was for */ @@ -291,6 +303,56 @@ fail_delay( int retval ATTR_UNUSED, unsigned usec_delay ATTR_UNUSED, {} # endif + /** + * log_to_audit_system: + * @login: Name of user + * @hostname: Name of host machine + * @tty: Name of display + * @success: 1 for success, 0 for failure + * + * Logs the success or failure of the login attempt with the linux kernel + * audit system. The intent is to capture failed events where the user + * fails authentication or otherwise is not permitted to login. There are + * many other places where pam could potentially fail and cause login to + * fail, but these are system failures rather than the signs of an account + * being hacked. + * + * Returns nothing. + */ + +#ifdef HAVE_LIBAUDIT +static void +log_to_audit_system (const char *loginname, + const char *hostname, + const char *tty, + int success) +{ + struct passwd *pw; + char buf[64]; + int audit_fd; + + audit_fd = audit_open(); + if (loginname) + pw = getpwnam(loginname); + else { + loginname = "unknown"; + pw = NULL; + } + Debug("log_to_audit %p %s\n", pw, loginname); + + if (pw) { + snprintf(buf, sizeof(buf), "uid=%d", pw->pw_uid); + audit_log_user_message(audit_fd, AUDIT_USER_LOGIN, + buf, hostname, NULL, tty, (int)success); + } else { + snprintf(buf, sizeof(buf), "acct=%s", loginname); + audit_log_user_message(audit_fd, AUDIT_USER_LOGIN, + buf, hostname, NULL, tty, (int)success); + } + close(audit_fd); +} +#endif + static int doPAMAuth( const char *psrv, struct pam_data *pdata ) { @@ -349,6 +411,8 @@ doPAMAuth( const char *psrv, struct pam_data *pdata ) GSendStr( curuser ); } if (pretc != PAM_SUCCESS) { + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); switch (pretc) { case PAM_USER_UNKNOWN: case PAM_AUTH_ERR: @@ -484,6 +548,9 @@ Verify( GConvFunc gconv, int rootok ) } else psrv = PAMService; pdata.usecur = TRUE; + } else if (!strcmp( curtype, "pam" )) { + psrv = PAMService; + pdata.usecur = FALSE; } else { sprintf( psrvb, "%.31s-%.31s", PAMService, curtype ); psrv = psrvb; @@ -553,7 +620,7 @@ Verify( GConvFunc gconv, int rootok ) free( msg ); V_RET_FAIL( 0 ); } - } else if (!strcmp( curtype, "generic" )) { + } else if (!strcmp( curtype, "generic" ) || !strcmp(curtype, "pam")) { if (!gconv( GCONV_USER, 0 )) return 0; for (curret = 0;;) { @@ -699,6 +766,8 @@ Verify( GConvFunc gconv, int rootok ) if (!p->pw_uid) { if (!rootok && !td->allowRootLogin) V_RET_FAIL( "Root logins are not allowed" ); + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); return 1; /* don't deny root to log in */ } @@ -735,6 +804,8 @@ Verify( GConvFunc gconv, int rootok ) } if (pretc == PAM_SUCCESS) break; + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); /* effectively there is only PAM_AUTHTOK_ERR */ GSendInt( V_FAIL ); } @@ -824,6 +895,8 @@ Verify( GConvFunc gconv, int rootok ) GSendInt( V_MSG_ERR ); GSendStr( "Your account has expired;" " please contact your system administrator" ); + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); GSendInt( V_FAIL ); LC_RET0; } else if (tim > (expir - warntime) && !quietlog) { @@ -858,6 +931,8 @@ Verify( GConvFunc gconv, int rootok ) GSendInt( V_MSG_ERR ); GSendStr( "Your account has expired;" " please contact your system administrator" ); + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); GSendInt( V_FAIL ); LC_RET0; } @@ -917,6 +992,8 @@ Verify( GConvFunc gconv, int rootok ) close( fd ); } GSendStr( "Logins are not allowed at the moment.\nTry again later" ); + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); GSendInt( V_FAIL ); LC_RET0; } @@ -927,6 +1004,8 @@ Verify( GConvFunc gconv, int rootok ) PrepErrorGreet(); GSendInt( V_MSG_ERR ); GSendStr( "You are not allowed to login at the moment" ); + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); GSendInt( V_FAIL ); LC_RET0; } @@ -938,6 +1017,8 @@ Verify( GConvFunc gconv, int rootok ) Debug( "shell not in /etc/shells\n" ); endusershell(); V_RET_FAIL( "Your login shell is not listed in /etc/shells" ); + /* Log the failed login attempt */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_FAILED); } if (!strcmp( s, p->pw_shell )) { endusershell(); @@ -1223,6 +1304,8 @@ StartClient() env = setEnv( env, "PATH", curuid ? td->userPath : td->systemPath ); env = setEnv( env, "SHELL", p->pw_shell ); env = setEnv( env, "HOME", p->pw_dir ); + if (cursource == PWSRC_AUTOLOGIN) + env = setEnv (env, "KDM_AUTOLOGIN", curuser); #if !defined(USE_PAM) && !defined(_AIX) && defined(KERBEROS) if (krbtkfile[0] != '\0') env = setEnv( env, "KRBTKFILE", krbtkfile ); @@ -1232,6 +1315,11 @@ StartClient() env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie ); } #endif +#ifdef WITH_CONSOLE_KIT + if (ck_session_cookie != NULL) { + env = setEnv ( env, "XDG_SESSION_COOKIE", ck_session_cookie ); + } +#endif userEnviron = inheritEnv( env, envvars ); env = systemEnv( p->pw_name ); systemEnviron = setEnv( env, "HOME", p->pw_dir ); @@ -1360,6 +1448,9 @@ StartClient() # define D_LOGIN_SETGROUP 0 #endif /* USE_PAM */ + /* Login succeeded */ + log_to_audit_system (curuser, td->remoteHost, td->name, AU_SUCCESS); + removeAuth = 1; chownCtrl( &td->ctrl, curuid ); endpwent(); diff --git a/kdm/config.def b/kdm/config.def index ab1adac84..7bc39b36d 100644 --- a/kdm/config.def +++ b/kdm/config.def @@ -1985,6 +1985,17 @@ Description: Specify the widget style for the greeter. Empty means to use the built-in default which currently is <literal>Plastik</literal>. +Key: UseAdminSession +Type: bool +Default: false +User: greeter +Instance: #*/! +Comment: + Admin session +Description: + If given there will be a special button that requires root password + and starts the given session + Key: ColorScheme Type: string Default: "" diff --git a/kdm/configure.in.in b/kdm/configure.in.in index 4b6972178..da741e7f9 100644 --- a/kdm/configure.in.in +++ b/kdm/configure.in.in @@ -287,4 +287,75 @@ fi AC_SUBST(DBUS_INCS) AC_SUBST(DBUS_LIBS) +########### Check for DBus + + AC_MSG_CHECKING(for DBus) + + dbus_inc=NOTFOUND + dbus_lib=NOTFOUND + dbus=NOTFOUND + + search_incs="$kde_includes $kde_extra_includes /usr/include /usr/include/dbus-1.0 /usr/local/include /usr/local/include/dbus-1.0" + AC_FIND_FILE(dbus/dbus.h, $search_incs, dbus_incdir) + + search_incs_arch_deps="$kde_includes $kde_extra_includes /usr/lib$kdelibsuff/dbus-1.0/include /usr/local/lib$kdelibsuff/dbus-1.0/include" + AC_FIND_FILE(dbus/dbus-arch-deps.h, $search_incs_arch_deps, dbus_incdir_arch_deps) + + if test -r $dbus_incdir/dbus/dbus.h && test -r $dbus_incdir_arch_deps/dbus/dbus-arch-deps.h ; then + DBUS_INCS="-I$dbus_incdir -I$dbus_incdir_arch_deps" + dbus_inc=FOUND + fi + + search_libs="$kde_libraries $kde_extra_libs /usr/lib$kdelibsuff /usr/local/lib$kdelibsuff" + AC_FIND_FILE(libdbus-1.so, $search_libs, dbus_libdir) + + if test -r $dbus_libdir/libdbus-1.so ; then + DBUS_LIBS="-L$dbus_libdir -ldbus-1" + dbus_lib=FOUND + fi + + if test $dbus_inc != FOUND || test $dbus_lib != FOUND ; then + KDE_PKG_CHECK_MODULES( DBUS, "dbus-1", [ DBUS_INCS=$DBUS_CFLAGS; dbus_inc=FOUND; dbus_lib=FOUND; ] , AC_MSG_RESULT( Nothing found on PKG_CONFIG_PATH ) ) + fi + + dbus_bus_var=`pkg-config --variable=system_bus_default_address dbus-1 2>/dev/null` + if test -z "$dbus_bus_var"; then + dbus_bus_var="unix:path=/var/run/dbus/system_bus_socket" + fi + AC_DEFINE_UNQUOTED(DBUS_SYSTEM_BUS, "$dbus_bus_var", [Define the unix domain path for dbus system bus]) + + if test $dbus_inc = FOUND && test $dbus_lib = FOUND ; then + AC_MSG_RESULT(headers $DBUS_INCS libraries $DBUS_LIBS) + dbus=FOUND + else + AC_MSG_RESULT(searched but not found) + fi + + AC_SUBST(DBUS_INCS) + AC_SUBST(DBUS_LIBS) + dnl AC_OUTPUT(kdm/kfrontend/sessions/kde.desktop) + + +AC_ARG_WITH(libaudit, + [ --with-libaudit=[auto/yes/no] Add Linux audit support [default=auto]],, + with_libaudit=auto) + +# Check for Linux auditing API +# +# libaudit detection +if test x$with_libaudit = xno ; then + have_libaudit=no; +else + # See if we have audit daemon library + AC_CHECK_LIB(audit, audit_log_user_message, + have_libaudit=yes, have_libaudit=no) +fi + +AM_CONDITIONAL(HAVE_LIBAUDIT, test x$have_libaudit = xyes) + +if test x$have_libaudit = xyes ; then + EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -laudit" + AC_DEFINE(HAVE_LIBAUDIT,1,[linux audit support]) +fi + diff --git a/kdm/kfrontend/Makefile.am b/kdm/kfrontend/Makefile.am index 5c5dfd61a..6d4fed27b 100644 --- a/kdm/kfrontend/Makefile.am +++ b/kdm/kfrontend/Makefile.am @@ -21,6 +21,7 @@ kdm_greet_SOURCES = \ kchooser.cpp \ kgverify.cpp \ kdmshutdown.cpp \ + kdmadmindialog.cpp \ kgreeter.cpp \ kgapp.cpp kdm_greet_LDFLAGS = $(all_libraries) $(KDE_RPATH) diff --git a/kdm/kfrontend/kdm_greet.c b/kdm/kfrontend/kdm_greet.c index 53d164f45..b03d96e15 100644 --- a/kdm/kfrontend/kdm_greet.c +++ b/kdm/kfrontend/kdm_greet.c @@ -44,8 +44,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # include <sched.h> #endif -#if defined(HAVE_XTEST) || defined(HAVE_XKB) # include <X11/Xlib.h> +#if defined(HAVE_XTEST) || defined(HAVE_XKB) # include <X11/keysym.h> #endif diff --git a/kdm/kfrontend/kdmadmindialog.cpp b/kdm/kfrontend/kdmadmindialog.cpp new file mode 100644 index 000000000..637d6dd90 --- /dev/null +++ b/kdm/kfrontend/kdmadmindialog.cpp @@ -0,0 +1,176 @@ + /* + + Admin dialog + + Copyright (C) 1997, 1998, 2000 Steffen Hansen <hansen@kde.org> + Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org> + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + +#include "kdmadmindialog.h" +#include "kdmconfig.h" +#include "kgdialog.h" +#include "kdm_greet.h" +#include <stdlib.h> + +#include <kapplication.h> +#include <kseparator.h> +#include <klocale.h> +#include <kpushbutton.h> +#include <kstdguiitem.h> + +#include <tqcombobox.h> +#include <tqvbuttongroup.h> +#include <tqstyle.h> +#include <tqlayout.h> +#include <tqaccel.h> +#include <tqpopupmenu.h> + +int KDMAdmin::curPlugin = -1; +PluginList KDMAdmin::pluginList; + +KDMAdmin::KDMAdmin( const TQString &user, TQWidget *_parent ) + : inherited( _parent ) + , verify( 0 ), curUser(user) +{ + TQSizePolicy fp( TQSizePolicy::Fixed, TQSizePolicy::Fixed ); + + TQVBoxLayout *box = new TQVBoxLayout( this, 10 ); + + TQHBoxLayout *hlay = new TQHBoxLayout( box ); + + GSendInt( G_ReadDmrc ); + GSendStr( "root" ); + GRecvInt(); // ignore status code ... + + if (curPlugin < 0) { + curPlugin = 0; + pluginList = KGVerify::init( "classic" ); + } + verify = new KGStdVerify( this, this, + this, "root", + pluginList, KGreeterPlugin::Authenticate, + KGreeterPlugin::Shutdown ); + verify->selectPlugin( curPlugin ); + box->addLayout( verify->getLayout() ); + TQAccel *accel = new TQAccel( this ); + accel->insertItem( ALT+Key_A, 0 ); + connect( accel, TQT_SIGNAL(activated(int)), TQT_SLOT(slotActivatePlugMenu()) ); + + box->addWidget( new KSeparator( KSeparator::HLine, this ) ); + + okButton = new KPushButton( KStdGuiItem::ok(), this ); + okButton->setSizePolicy( fp ); + okButton->setDefault( true ); + cancelButton = new KPushButton( KStdGuiItem::cancel(), this ); + cancelButton->setSizePolicy( fp ); + + hlay = new TQHBoxLayout( box ); + hlay->addStretch( 1 ); + hlay->addWidget( okButton ); + hlay->addStretch( 1 ); + hlay->addWidget( cancelButton ); + hlay->addStretch( 1 ); + + connect( okButton, TQT_SIGNAL(clicked()), TQT_SLOT(accept()) ); + connect( cancelButton, TQT_SIGNAL(clicked()), TQT_SLOT(reject()) ); + + slotWhenChanged(); +} + +KDMAdmin::~KDMAdmin() +{ + hide(); + delete verify; +} + +void +KDMAdmin::slotActivatePlugMenu() +{ + TQPopupMenu *cmnu = verify->getPlugMenu(); + TQSize sh( cmnu->sizeHint() / 2 ); + cmnu->exec( geometry().center() - TQPoint( sh.width(), sh.height() ) ); +} + +void +KDMAdmin::accept() +{ + verify->accept(); +} + +void +KDMAdmin::slotWhenChanged() +{ + verify->abort(); + verify->setEnabled( 1 ); + verify->start(); +} + +void +KDMAdmin::bye_bye() +{ + GSendInt( G_GetDmrc ); + GSendStr( "Session" ); + char *sess = GRecvStr(); + if (sess && strcmp(sess, "admin")) { + GSendInt( G_PutDmrc ); + GSendStr( "OrigSession"); + GSendStr( sess); + free(sess); + } + + GSendInt( G_PutDmrc ); + GSendStr( "Session" ); + GSendStr( "admin" ); + inherited::accept(); +} + +void +KDMAdmin::verifyPluginChanged( int id ) +{ + curPlugin = id; + adjustSize(); +} + +void +KDMAdmin::verifyOk() +{ + bye_bye(); +} + +void +KDMAdmin::verifyFailed() +{ + okButton->setEnabled( false ); + cancelButton->setEnabled( false ); +} + +void +KDMAdmin::verifyRetry() +{ + okButton->setEnabled( true ); + cancelButton->setEnabled( true ); +} + +void +KDMAdmin::verifySetUser( const TQString & ) +{ +} + + +#include "kdmadmindialog.moc" diff --git a/kdm/kfrontend/kdmadmindialog.h b/kdm/kfrontend/kdmadmindialog.h new file mode 100644 index 000000000..91f1ed3a6 --- /dev/null +++ b/kdm/kfrontend/kdmadmindialog.h @@ -0,0 +1,70 @@ + /* + + Shutdown dialog + + Copyright (C) 1997, 1998 Steffen Hansen <hansen@kde.org> + Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org> + + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + */ + + +#ifndef KDMADMIN_H +#define KDMADMIN_H + +#include "kgverify.h" + +#include <tqradiobutton.h> + +class LiloInfo; +class TQLabel; +class KPushButton; +class TQButtonGroup; +class TQComboBox; + +class KDMAdmin : public FDialog, public KGVerifyHandler { + Q_OBJECT + typedef FDialog inherited; + +public: + KDMAdmin( const TQString &user, TQWidget *_parent = 0 ); + ~KDMAdmin(); + +public slots: + void accept(); + void slotWhenChanged(); + void slotActivatePlugMenu(); + +private: + void bye_bye(); + + KPushButton *okButton, *cancelButton; + KGStdVerify *verify; + TQString curUser; + + static int curPlugin; + static PluginList pluginList; + +public: // from KGVerifyHandler + virtual void verifyPluginChanged( int id ); + virtual void verifyOk(); + virtual void verifyFailed(); + virtual void verifyRetry(); + virtual void verifySetUser( const TQString &user ); +}; + +#endif diff --git a/kdm/kfrontend/kdmconfig.cpp b/kdm/kfrontend/kdmconfig.cpp index 6f4c14031..15a63fa67 100644 --- a/kdm/kfrontend/kdmconfig.cpp +++ b/kdm/kfrontend/kdmconfig.cpp @@ -33,6 +33,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <unistd.h> #include <sys/utsname.h> +struct timeval st = {0, 0}; + CONF_GREET_DEFS TQString _stsFile; diff --git a/kdm/kfrontend/kdmconfig.h b/kdm/kfrontend/kdmconfig.h index f5420bcc4..52e054af6 100644 --- a/kdm/kfrontend/kdmconfig.h +++ b/kdm/kfrontend/kdmconfig.h @@ -35,6 +35,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <tqstring.h> #include <tqstringlist.h> #include <tqfont.h> +#include <sys/time.h> extern TQString _stsFile; extern bool _isLocal; @@ -46,6 +47,19 @@ CONF_GREET_CPP_DECLS struct dpySpec; void decodeSess( dpySpec *sess, TQString &user, TQString &loc ); +extern struct timeval st; + +inline TQString timestamp() { + struct timeval nst; + gettimeofday(&nst, 0); + if (!st.tv_sec) + gettimeofday(&st, 0); + + TQString ret; + ret.sprintf("[%07ld]", (nst.tv_sec - st.tv_sec) * 1000 + (nst.tv_usec - st.tv_usec) / 1000); + return ret; +} + extern "C" #endif void init_config( void ); diff --git a/kdm/kfrontend/kfdialog.cpp b/kdm/kfrontend/kfdialog.cpp index 62a4acb22..78359e237 100644 --- a/kdm/kfrontend/kfdialog.cpp +++ b/kdm/kfrontend/kfdialog.cpp @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <klocale.h> #include <kpushbutton.h> #include <kstdguiitem.h> +#include <kglobalsettings.h> #include <tqlabel.h> #include <tqlayout.h> @@ -137,6 +138,9 @@ KFMsgBox::KFMsgBox( TQWidget *parent, TQMessageBox::Icon type, const TQString &t TQLabel *label1 = new TQLabel( this ); label1->setPixmap( TQMessageBox::standardIcon( type ) ); TQLabel *label2 = new TQLabel( text, this ); + TQRect d = KGlobalSettings::desktopGeometry(this); + if ( label2->fontMetrics().size( 0, text).width() > d.width() * 3 / 5) + label2->setAlignment(Qt::WordBreak | Qt::AlignAuto ); KPushButton *button = new KPushButton( KStdGuiItem::ok(), this ); button->setDefault( true ); button->setSizePolicy( TQSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Preferred ) ); diff --git a/kdm/kfrontend/kgapp.cpp b/kdm/kfrontend/kgapp.cpp index 70b510645..50e65e916 100644 --- a/kdm/kfrontend/kgapp.cpp +++ b/kdm/kfrontend/kgapp.cpp @@ -36,6 +36,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <kcrash.h> #include <kstandarddirs.h> #include <ksimpleconfig.h> +#include <klocale.h> +#include <kdebug.h> #include <tqtimer.h> #include <tqstring.h> @@ -133,6 +135,7 @@ kg_main( const char *argv0 ) static char *argv[] = { (char *)"kdmgreet", 0 }; KCmdLineArgs::init( 1, argv, *argv, 0, 0, 0, true ); + kdDebug() << timestamp() << "start" << endl; kde_have_kipc = false; KApplication::disableAutoDcopRegistration(); KCrash::setSafer( true ); @@ -180,6 +183,7 @@ kg_main( const char *argv0 ) GSendInt( G_Ready ); + kdDebug() << timestamp() << " main1" << endl; setCursor( dpy, app.desktop()->winId(), XC_left_ptr ); for (;;) { @@ -220,6 +224,7 @@ kg_main( const char *argv0 ) if (_useTheme && !_theme.isEmpty()) { KThemedGreeter *tgrt; dialog = tgrt = new KThemedGreeter; + kdDebug() << timestamp() << " themed" << endl; if (!tgrt->isOK()) { delete tgrt; dialog = new KStdGreeter; diff --git a/kdm/kfrontend/kgdialog.cpp b/kdm/kfrontend/kgdialog.cpp index 1981eea83..f4ed918c6 100644 --- a/kdm/kfrontend/kgdialog.cpp +++ b/kdm/kfrontend/kgdialog.cpp @@ -29,6 +29,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "kdm_greet.h" #include <klocale.h> +#include <kiconloader.h> #include <tqaccel.h> #include <tqlayout.h> @@ -84,7 +85,8 @@ KGDialog::completeMenu() inserten( i18n("Co&nsole Login"), ALT+Key_N, TQT_SLOT(slotConsole()) ); if (_allowShutdown != SHUT_NONE) { - inserten( i18n("&Shutdown..."), ALT+Key_S, TQT_SLOT(slotShutdown( int )) ); + ensureMenu(); + optMenu->insertItem(SmallIconSet( "exit" ), i18n("&Shutdown..."), this, TQT_SLOT(slotShutdown(int)), ALT+Key_S ); TQAccel *accel = new TQAccel( this ); accel->insertItem( ALT+CTRL+Key_Delete ); connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotShutdown( int )) ); diff --git a/kdm/kfrontend/kgreeter.cpp b/kdm/kfrontend/kgreeter.cpp index ebd303525..74fc6b090 100644 --- a/kdm/kfrontend/kgreeter.cpp +++ b/kdm/kfrontend/kgreeter.cpp @@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "kdmconfig.h" #include "kdmclock.h" #include "kdm_greet.h" +#include "kdmadmindialog.h" #include "themer/kdmthemer.h" #include "themer/kdmitem.h" #include "themer/kdmlabel.h" @@ -38,6 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <klistview.h> #include <ksimpleconfig.h> #include <kstringhandler.h> +#include <kdebug.h> #undef Unsorted // x headers suck - make tqdir.h work with --enable-final #include <tqdir.h> @@ -46,6 +48,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <tqmemarray.h> #include <tqimage.h> #include <tqmovie.h> +#include <tqpainter.h> #include <tqpopupmenu.h> #include <tqtimer.h> #include <tqheader.h> @@ -57,6 +60,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <tqaccel.h> #include <tqstring.h> #include <tqeventloop.h> +#include <tqbitmap.h> #include <pwd.h> #include <grp.h> @@ -64,27 +68,46 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include <unistd.h> #include <fcntl.h> #include <sys/types.h> +#include <utmp.h> +#include <utmpx.h> #include <X11/Xlib.h> class UserListView : public KListView { public: - UserListView( TQWidget *parent = 0, const char *name = 0 ) + UserListView( bool _them, TQWidget *parent = 0, const char *name = 0 ) : KListView( parent, name ) - , cachedSizeHint( -1, 0 ) + , themed(_them), cachedSizeHint( -1, 0 ) { setSizePolicy( TQSizePolicy::Preferred, TQSizePolicy::Ignored ); header()->hide(); addColumn( TQString::null ); setColumnAlignment( 0, AlignVCenter ); setResizeMode( TQListView::LastColumn ); + if (themed) { + setBackgroundMode( Qt::NoBackground ); + viewport()->setBackgroundMode( Qt::NoBackground ); + setFrameStyle( TQFrame::NoFrame ); + } } + bool themed; mutable TQSize cachedSizeHint; - protected: + int sumHeight() const + { + int sum = 0; + for (TQListViewItem *itm = firstChild(); itm; itm = itm->nextSibling()) { + sum += itm->height(); + } + return sum; + } +public: virtual TQSize sizeHint() const { + if (themed) + return KListView::sizeHint(); + if (!cachedSizeHint.isValid()) { constPolish(); uint maxw = 0; @@ -99,9 +122,24 @@ class UserListView : public KListView { } return cachedSizeHint; } + virtual void paintEmptyArea ( TQPainter * p, const TQRect & rect ) + { + if (!themed) + return KListView::paintEmptyArea(p, rect ); + + const TQPixmap *pm = paletteBackgroundPixmap(); + if (!pm || pm->isNull()) + return; + + kdDebug() << "paintEmpty " << rect << endl; + TQRect devRect = p->xForm( rect ); + kdDebug() << "paintEmpty2 " << devRect << endl; + p->drawPixmap(0, 0, *pm, devRect.left(), devRect.top() ); + } + + TQPixmap background; }; - int KGreeter::curPlugin = -1; PluginList KGreeter::pluginList; @@ -116,12 +154,14 @@ KGreeter::KGreeter( bool framed ) , 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, TQT_SIGNAL(clicked( TQListViewItem * )), TQT_SLOT(slotUserClicked( TQListViewItem * )) ); connect( userView, TQT_SIGNAL(doubleClicked( TQListViewItem * )), @@ -129,10 +169,8 @@ KGreeter::KGreeter( bool framed ) } if (_userCompletion) userList = new TQStringList; - if (userView || userList) - insertUsers(); - sessMenu = new TQPopupMenu( this ); + sessMenu = new TQPopupMenu( this ); connect( sessMenu, TQT_SIGNAL(activated( int )), TQT_SLOT(slotSessionSelected( int )) ); insertSessions(); @@ -151,6 +189,33 @@ KGreeter::~KGreeter() delete stsFile; } +void KGreeter::readFacesList() +{ + FILE *f = fopen( TQFile::encodeName( _faceDir + "/.randomlist" ), "rt" ); + if ( !f ) + return; + TQTextIStream is( f ); + while ( !is.eof() ) + { + TQString line = is.readLine().simplifyWhiteSpace(); + if ( line.isEmpty() ) + continue; + TQString icon; + int index = line.find( ' ' ); + if ( index > 0 ) { + icon = line.left( index ); + line = line.mid( index ); + } else { + icon = line; + line = TQString::null; + } + randomFaces.push_back( icon ); + TQStringList list = TQStringList::split( ' ', line ); + for ( TQStringList::ConstIterator it = list.begin(); it != list.end(); ++it ) + randomFacesMap[*it] = icon; + } +} + class UserListViewItem : public KListViewItem { public: UserListViewItem( UserListView *parent, const TQString &text, @@ -164,6 +229,14 @@ class UserListViewItem : public KListViewItem { parent->cachedSizeHint.setWidth( -1 ); } + virtual void paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int alignment) + { + if (((UserListView*)listView())->themed) + TQListViewItem::paintCell(p, cg, column, width, alignment); + else + KListViewItem::paintCell(p, cg, column, width, alignment); + } + TQString login; }; @@ -232,10 +305,23 @@ KGreeter::insertUser( const TQImage &default_pix, TQSize ns( 48, 48 ); if (p.size() != ns) p = p.convertDepth( 32 ).smoothScale( ns, TQImage::ScaleMin ); - goto gotit; + break; } while (--nd >= 0); - p = default_pix; - gotit: + + if ( p.isNull() && randomFaces.count() ) { + TQString randomFace = randomFacesMap[username]; + if ( randomFace.isNull() ) { + TQStringList::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; + TQString realname = KStringHandler::from8Bit( ps->pw_gecos ); realname.truncate( realname.find( ',' ) ); if (realname.isEmpty() || realname == username) @@ -289,7 +375,7 @@ UserList::UserList( char **in ) } void -KGreeter::insertUsers() +KGreeter::insertUsers(int limit_users) { struct passwd *ps; @@ -309,6 +395,8 @@ KGreeter::insertUsers() if (_showUsers == SHOW_ALL) { UserList noUsers( _noUsers ); TQDict<int> dupes( 1000 ); + TQStringList toinsert; + int count = 0; for (setpwent(); (ps = getpwent()) != 0;) { if (*ps->pw_dir && *ps->pw_shell && (ps->pw_uid >= (unsigned)_lowUserId || @@ -320,10 +408,53 @@ KGreeter::insertUsers() TQString username( TQFile::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 = TQStringList(); + 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 )) + { + TQString username( TQFile::decodeName( ent->ut_user ) ); + if (!dupes.find( username )) { + dupes.insert( username, (int *)-1 ); + toinsert.append( username ); + count++; + } + } + + + } + endutxent(); + } + + for ( TQStringList::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( TQFile::encodeName( *it ) ); + if ( ps ) + insertUser( default_pix, *it, ps ); + } } else { UserList users( _users ); if (users.hasGroups()) { @@ -379,7 +510,7 @@ KGreeter::insertSessions() for (char **dit = _sessionsDirs; *dit; ++dit) { TQStringList ents = TQDir( *dit ).entryList(); for (TQStringList::ConstIterator it = ents.begin(); it != ents.end(); ++it) - if ((*it).endsWith( ".desktop" )) { + if ((*it).endsWith( ".desktop" ) && !(*it).endsWith("admin.desktop")) { KSimpleConfig dsk( TQString( *dit ).append( '/' ).append( *it ) ); dsk.setGroup( "Desktop Entry" ); putSession( (*it).left( (*it).length() - 8 ), @@ -517,6 +648,17 @@ KGreeter::slotLoadPrevWM() return; } } else { + if (!strcmp(sess, "admin")) { + // need to get the original + GSendInt( G_GetDmrc); + GSendStr( "OrigSession"); + sess = GRecvStr(); + if (!sess) { + free(sess); + sess = strdup("default"); + } + } + for (uint i = 0; i < sessionTypes.count() && !sessionTypes[i].hid; i++) if (sessionTypes[i].type == sess) { free( sess ); @@ -718,21 +860,24 @@ KStdGreeter::KStdGreeter() 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 @@ -826,6 +971,9 @@ KThemedGreeter::KThemedGreeter() 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" ); @@ -851,12 +999,8 @@ KThemedGreeter::KThemedGreeter() if ((itm = themer->findNode( "session_button" ))) { if (sessMenu->count() <= 1) itm->hide( true ); - else { + else session_button = itm; - TQAccel *accel = new TQAccel( this ); - accel->insertItem( ALT+Key_T, 0 ); - connect( accel, TQT_SIGNAL(activated( int )), TQT_SLOT(slotSessMenu()) ); - } } else { if (sessMenu->count() > 1) { inserten( i18n("Session &Type"), ALT+Key_T, sessMenu ); @@ -864,6 +1008,12 @@ KThemedGreeter::KThemedGreeter() } } + admin_button = themer->findNode( "admin_button"); + if ( admin_button ) { + if ( !_useAdminSession ) + admin_button->hide( true ); + } + if (plugMenu) { inserten( i18n("&Authentication Method"), ALT+Key_A, plugMenu ); needSep = true; @@ -899,8 +1049,8 @@ KThemedGreeter::pluginSetup() 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(); @@ -916,12 +1066,17 @@ KThemedGreeter::verifyFailed() { // goButton->setEnabled( false ); inherited::verifyFailed(); + if (userView) + userView->setEnabled(false); } void KThemedGreeter::verifyRetry() { // goButton->setEnabled( true ); + if (userView) + userView->setEnabled(true); + } TQString KThemedGreeter::timedUser = TQString::null; @@ -966,6 +1121,8 @@ KThemedGreeter::slotThemeActivated( const TQString &id ) slotSessMenu(); else if (id == "system_button") slotActionMenu(); + else if (id == "admin_button") + slotAskAdminPassword(); } void @@ -992,4 +1149,15 @@ KThemedGreeter::keyPressEvent( TQKeyEvent *e ) accept(); } +void +KThemedGreeter::slotAskAdminPassword() +{ + KDMAdmin k(curUser, this); + if (k.exec()) { + GSendInt(G_Ready); + hide(); + done(ex_exit); + } +} + #include "kgreeter.moc" diff --git a/kdm/kfrontend/kgreeter.h b/kdm/kfrontend/kgreeter.h index 61673badf..fdbd56209 100644 --- a/kdm/kfrontend/kgreeter.h +++ b/kdm/kfrontend/kgreeter.h @@ -73,9 +73,10 @@ class KGreeter : public KGDialog, public KGVerifyHandler { void slotUserEntered(); protected: + void readFacesList(); void installUserList(); void insertUser( const TQImage &, const TQString &, struct passwd * ); - void insertUsers(); + void insertUsers( int limit = -1); void putSession( const TQString &, const TQString &, bool, const char * ); void insertSessions(); virtual void pluginSetup(); @@ -87,10 +88,13 @@ class KGreeter : public KGDialog, public KGVerifyHandler { TQStringList *userList; TQPopupMenu *sessMenu; TQValueVector<SessType> sessionTypes; + TQStringList randomFaces; + TQMap<TQString, TQString> randomFacesMap; int nNormals, nSpecials; int curPrev, curSel; bool prevValid; bool needLoad; + bool themed; static int curPlugin; static PluginList pluginList; @@ -142,6 +146,7 @@ class KThemedGreeter : public KGreeter { void slotThemeActivated( const TQString &id ); void slotSessMenu(); void slotActionMenu(); + void slotAskAdminPassword(); protected: virtual void updateStatus( bool fail, bool caps, int timedleft ); @@ -154,7 +159,7 @@ class KThemedGreeter : public KGreeter { KdmThemer *themer; KdmItem *caps_warning, *xauth_warning, *pam_error, *timed_label, *console_rect, *userlist_rect, - *session_button, *system_button; + *session_button, *system_button, *admin_button; public: // from KGVerifyHandler virtual void verifyFailed(); diff --git a/kdm/kfrontend/sessions/Makefile.am b/kdm/kfrontend/sessions/Makefile.am index 14577ac42..71655c9a4 100644 --- a/kdm/kfrontend/sessions/Makefile.am +++ b/kdm/kfrontend/sessions/Makefile.am @@ -1,6 +1,6 @@ sessionsdir = $(kde_datadir)/kdm/sessions sessions_DATA = \ - kde.desktop gnome.desktop \ + admin.desktop kde.desktop gnome.desktop \ 9wm.desktop \ aewm++.desktop \ aewm.desktop \ diff --git a/kdm/kfrontend/sessions/admin.desktop b/kdm/kfrontend/sessions/admin.desktop new file mode 100644 index 000000000..73e6ae3bf --- /dev/null +++ b/kdm/kfrontend/sessions/admin.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Encoding=UTF-8 +Type=XSession +Exec=YaSTadminSession +TryExec=YaSTadminSession +Name=admin +Comment=Yast Admin Session diff --git a/kdm/kfrontend/themer/kdmitem.cpp b/kdm/kfrontend/themer/kdmitem.cpp index 38af9d0aa..d47c0242d 100644 --- a/kdm/kfrontend/themer/kdmitem.cpp +++ b/kdm/kfrontend/themer/kdmitem.cpp @@ -23,10 +23,11 @@ * Generic Kdm Item */ -//#define DRAW_OUTLINE 1 // for debugging only +// #define DRAW_OUTLINE 1 // for debugging only #include "kdmitem.h" #include "kdmlayout.h" +#include "kdmconfig.h" #include <kglobal.h> #include <kdebug.h> @@ -35,9 +36,7 @@ #include <tqwidget.h> #include <tqlayout.h> #include <tqimage.h> -#ifdef DRAW_OUTLINE -# include <tqpainter.h> -#endif +#include <tqpainter.h> KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name ) : TQObject( parent, name ) @@ -48,6 +47,25 @@ KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name ) , myLayoutItem( 0 ) , buttonParent( 0 ) { + init(node, name); +} + + +KdmItem::KdmItem( TQWidget *parent, const TQDomNode &node, const char *name ) + : TQObject( parent, name ) + , boxManager( 0 ) + , fixedManager( 0 ) + , image( 0 ) + , myWidget( 0 ) + , myLayoutItem( 0 ) + , buttonParent( 0 ) +{ + init(node, name); +} + +void +KdmItem::init( const TQDomNode &node, const char * ) +{ // Set default layout for every item currentManager = MNone; pos.x = pos.y = 0; @@ -62,7 +80,7 @@ KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name ) state = Snormal; // The "toplevel" node (the screen) is really just like a fixed node - if (!parent || !parent->inherits( "KdmItem" )) { + if (!parent() || !parent()->inherits( "KdmItem" )) { setFixedLayout(); return; } @@ -87,7 +105,7 @@ KdmItem::KdmItem( KdmItem *parent, const TQDomNode &node, const char *name ) id = tnode.toElement().attribute( "id", TQString::number( (ulong)this, 16 ) ); // Tell 'parent' to add 'me' to its children - KdmItem *parentItem = static_cast<KdmItem *>( parent ); + KdmItem *parentItem = static_cast<KdmItem *>( parent() ); parentItem->addChildItem( this ); } @@ -195,7 +213,7 @@ KdmItem::setWidget( TQWidget *widget ) if (frame) frame->setFrameStyle( TQFrame::NoFrame ); - myWidget->setGeometry(area); + setGeometry(area, true); connect( myWidget, TQT_SIGNAL(destroyed()), TQT_SLOT(widgetGone()) ); } @@ -236,15 +254,21 @@ KdmItem::setGeometry( const TQRect &newGeometry, bool force ) area = newGeometry; - if (myWidget) - myWidget->setGeometry( newGeometry ); + if (myWidget) { + TQRect widGeo = newGeometry; + if ( widGeo.height() > myWidget->maximumHeight() ) { + widGeo.moveTop( widGeo.top() + ( widGeo.height() - myWidget->maximumHeight() ) / 2 ); + widGeo.setHeight( myWidget->maximumHeight() ); + } + myWidget->setGeometry( widGeo ); + } if (myLayoutItem) myLayoutItem->setGeometry( newGeometry ); // recurr to all boxed children if (boxManager && !boxManager->isEmpty()) boxManager->update( newGeometry, force ); - + // recurr to all fixed children if (fixedManager && !fixedManager->isEmpty()) fixedManager->update( newGeometry, force ); @@ -258,8 +282,16 @@ KdmItem::paint( TQPainter *p, const TQRect &rect ) if (isHidden()) return; - if (myWidget || (myLayoutItem && myLayoutItem->widget())) - return; + if (myWidget || (myLayoutItem && myLayoutItem->widget())) { + // KListView because it's missing a Q_OBJECT + if ( myWidget && myWidget->isA( "KListView" ) ) { + TQPixmap copy( myWidget->size() ); + kdDebug() << myWidget->geometry() << " " << area << " " << myWidget->size() << endl; + bitBlt( ©, TQPoint( 0, 0), p->device(), myWidget->geometry(), Qt::CopyROP ); + myWidget->setPaletteBackgroundPixmap( copy ); + } + return; + } if (area.intersects( rect )) { TQRect contentsRect = area.intersect( rect ); @@ -280,6 +312,8 @@ KdmItem::paint( TQPainter *p, const TQRect &rect ) TQValueList<KdmItem *>::Iterator it; for (it = m_children.begin(); it != m_children.end(); ++it) (*it)->paint( p, rect ); + + } KdmItem *KdmItem::currentActive = 0; @@ -287,8 +321,11 @@ KdmItem *KdmItem::currentActive = 0; void KdmItem::mouseEvent( int x, int y, bool pressed, bool released ) { + if (isShown == ExplicitlyHidden) + return; + if (buttonParent && buttonParent != this) { - buttonParent->mouseEvent( x, y, pressed, released ); + buttonParent->mouseEvent( x, y, pressed, released ); return; } @@ -362,7 +399,8 @@ KdmItem::placementHint( const TQRect &parentRect ) w = parentRect.width(), h = parentRect.height(); - kdDebug() << "KdmItem::placementHint parentRect=" << id << parentRect << " hintedSize=" << hintedSize << endl; + kdDebug() << timestamp() << " KdmItem::placementHint parentRect=" << parentRect << " hintedSize=" << hintedSize << endl; + // check if width or height are set to "box" if (pos.wType == DTbox || pos.hType == DTbox) { if (myLayoutItem || myWidget) @@ -372,7 +410,7 @@ KdmItem::placementHint( const TQRect &parentRect ) return parentRect; boxHint = boxManager->sizeHint(); } - kdDebug() << " => boxHint " << boxHint << endl; + kdDebug() << timestamp() << " boxHint " << boxHint << endl; } if (pos.xType == DTpixel) @@ -380,25 +418,25 @@ KdmItem::placementHint( const TQRect &parentRect ) else if (pos.xType == DTnpixel) x = parentRect.right() - pos.x; else if (pos.xType == DTpercent) - x += int( parentRect.width() / 100.0 * pos.x ); + x += qRound( parentRect.width() / 100.0 * pos.x ); if (pos.yType == DTpixel) y += pos.y; else if (pos.yType == DTnpixel) y = parentRect.bottom() - pos.y; else if (pos.yType == DTpercent) - y += int( parentRect.height() / 100.0 * pos.y ); + y += qRound( parentRect.height() / 100.0 * pos.y ); if (pos.wType == DTpixel) w = pos.width; else if (pos.wType == DTnpixel) w -= pos.width; else if (pos.wType == DTpercent) - w = int( parentRect.width() / 100.0 * pos.width ); + w = qRound( parentRect.width() / 100.0 * pos.width ); else if (pos.wType == DTbox) w = boxHint.width(); else if (hintedSize.width() > 0) - w = hintedSize.width(); + w = hintedSize.width(); else w = 0; @@ -407,14 +445,22 @@ KdmItem::placementHint( const TQRect &parentRect ) else if (pos.hType == DTnpixel) h -= pos.height; else if (pos.hType == DTpercent) - h = int( parentRect.height() / 100.0 * pos.height ); + h = qRound( parentRect.height() / 100.0 * pos.height ); else if (pos.hType == DTbox) h = boxHint.height(); - else if (hintedSize.height() > 0) - h = hintedSize.height(); - else + else if (hintedSize.height() > 0) { + if (w && pos.wType != DTnone) + h = (hintedSize.height() * w) / hintedSize.width(); + else + h = hintedSize.height(); + } else h = 0; + // we choose to take the hinted size, but it's better to listen to the aspect ratio + if (pos.wType == DTnone && pos.hType != DTnone && h && w) { + w = qRound(float(hintedSize.width() * h) / hintedSize.height()); + } + // defaults to center int dx = -w / 2, dy = -h / 2; @@ -430,7 +476,7 @@ KdmItem::placementHint( const TQRect &parentRect ) dx = -w; } // KdmItem *p = static_cast<KdmItem*>( parent() ); - kdDebug() << "KdmItem::placementHint " << id << " x=" << x << " dx=" << dx << " w=" << w << " y=" << y << " dy=" << dy << " h=" << h << " " << parentRect << endl; + kdDebug() << timestamp() << " placementHint " << this << " x=" << x << " dx=" << dx << " w=" << w << " y=" << y << " dy=" << dy << " h=" << h << " " << parentRect << endl; y += dy; x += dx; @@ -529,4 +575,17 @@ KdmItem::setFixedLayout( const TQDomNode &node ) currentManager = MFixed; } +TQWidget * +KdmItem::parentWidget() const +{ + if (myWidget) + return myWidget; + if (!this->parent()) + return 0; + + if (parent()->qt_cast("TQWidget")) + return (TQWidget*)parent(); + return ((KdmItem*)parent())->parentWidget(); +} + #include "kdmitem.moc" diff --git a/kdm/kfrontend/themer/kdmitem.h b/kdm/kfrontend/themer/kdmitem.h index 6a73c889f..98b876977 100644 --- a/kdm/kfrontend/themer/kdmitem.h +++ b/kdm/kfrontend/themer/kdmitem.h @@ -90,6 +90,8 @@ public: * Item constructor and destructor */ KdmItem( KdmItem *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 ); + KdmItem( TQWidget *parent, const TQDomNode &node = TQDomNode(), const char *name = 0 ); // for the root + virtual ~KdmItem(); /** @@ -151,6 +153,7 @@ public: KdmItem *findNode( const TQString &id ) const; virtual void setWidget( TQWidget *widget ); + TQWidget *widget() const { return myWidget; } virtual void setLayoutItem( TQLayoutItem *item ); virtual void hide( bool force = false ); @@ -160,6 +163,9 @@ public: bool isExplicitlyHidden() const { return isShown == ExplicitlyHidden; } TQRect rect() const { return area; } + TQWidget *parentWidget() const; + TQString getId() const { return id; } + signals: void needUpdate( int x, int y, int w, int h ); void activated( const TQString &id ); @@ -237,6 +243,7 @@ protected: void parseColor( const TQString &, TQColor & ); void inheritFromButton( KdmItem *button ); + void init( const TQDomNode &node = TQDomNode(), const char *name = 0 ); TQString itemType, id; TQValueList<KdmItem *> m_children; diff --git a/kdm/kfrontend/themer/kdmlabel.cpp b/kdm/kfrontend/themer/kdmlabel.cpp index 297b7cc48..e83ae9dc7 100644 --- a/kdm/kfrontend/themer/kdmlabel.cpp +++ b/kdm/kfrontend/themer/kdmlabel.cpp @@ -19,8 +19,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include <config.h> #include "kdmlabel.h" -#include <kgreeter.h> +#include "kdmconfig.h" +#include "../kgreeter.h" #include <kglobal.h> #include <klocale.h> @@ -31,6 +33,7 @@ #include <tqpainter.h> #include <tqfontmetrics.h> #include <tqtimer.h> +#include <tqaccel.h> #include <unistd.h> #include <sys/utsname.h> @@ -39,7 +42,7 @@ #endif KdmLabel::KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name ) - : KdmItem( parent, node, name ) + : KdmItem( parent, node, name ), myAccel(0) { itemType = "label"; @@ -92,21 +95,46 @@ KdmLabel::KdmLabel( KdmItem *parent, const TQDomNode &node, const char *name ) } } - // Check if this is a timer label + // Check if this is a timer label) label.isTimer = label.text.find( "%c" ) >= 0; if (label.isTimer) { timer = new TQTimer( this ); timer->start( 1000 ); connect( timer, TQT_SIGNAL(timeout()), TQT_SLOT(update()) ); } - cText = lookupText( label.text ); + setTextInt( lookupText( label.text ) ); +} + +void +KdmLabel::setTextInt( const TQString &txt) +{ + // TODO: catch && + cText = txt; + cAccel = txt.find('&'); + delete myAccel; + myAccel = 0; + if (cAccel != -1) { + cText.remove('&'); + myAccel = new TQAccel(parentWidget()); + myAccel->insertItem(ALT + UNICODE_ACCEL + cText.at(cAccel).lower().unicode()); + connect(myAccel, TQT_SIGNAL(activated(int)), TQT_SLOT(slotAccel())); + } +} + +void +KdmLabel::slotAccel() +{ + if (buttonParent) + emit activated(buttonParent->getId()); + else + emit activated(id); } void KdmLabel::setText( const TQString &txt ) { label.text = txt; - update(); + setTextInt( lookupText( label.text ) ); } QSize @@ -139,7 +167,23 @@ KdmLabel::drawContents( TQPainter *p, const TQRect &/*r*/ ) p->setFont( l->font ); p->setPen( l->color ); //TODO paint clipped (tested but not working..) - p->drawText( area, AlignLeft | SingleLine, cText ); + if (cAccel != -1 && (!id.isEmpty() || buttonParent) ) { + TQString left = cText.left(cAccel); + TQString right = cText.mid(cAccel + 1); + p->drawText( area, AlignLeft | SingleLine, left ); + TQRect tarea = area; + TQFontMetrics fm(l->font); + tarea.rLeft() += fm.width(left); + TQFont f(l->font); + f.setUnderline(true); + p->setFont ( f ); + p->drawText( tarea, AlignLeft | SingleLine, TQString(cText.at(cAccel))); + tarea.rLeft() += fm.width(cText.at(cAccel)); + p->setFont( l->font ); + p->drawText( tarea, AlignLeft | SingleLine, right); + } else { + p->drawText( area, AlignLeft | SingleLine, cText); + } } void @@ -159,7 +203,7 @@ KdmLabel::update() { TQString text = lookupText( label.text ); if (text != cText) { - cText = text; + setTextInt(text); needUpdate(); } } @@ -170,18 +214,20 @@ static const struct { { "language", I18N_NOOP("Language") }, { "session", I18N_NOOP("Session Type") }, { "system", I18N_NOOP("Menu") }, // i18n("Actions"); + { "admin", I18N_NOOP("&Administration") }, { "disconnect", I18N_NOOP("Disconnect") }, { "quit", I18N_NOOP("Quit") }, - { "halt", I18N_NOOP("Power off") }, + { "halt", I18N_NOOP("Power Off") }, { "suspend", I18N_NOOP("Suspend") }, { "reboot", I18N_NOOP("Reboot") }, { "chooser", I18N_NOOP("XDMCP Chooser") }, { "config", I18N_NOOP("Configure") }, - { "caps-lock-warning", I18N_NOOP("You have got caps lock on.") }, + { "caps-lock-warning", I18N_NOOP("Caps Lock is enabled.") }, { "timed-label", I18N_NOOP("User %s will login in %d seconds") }, { "welcome-label", I18N_NOOP("Welcome to %h") }, // _greetString { "username-label", I18N_NOOP("Username:") }, { "password-label", I18N_NOOP("Password:") }, + { "domain-label", I18N_NOOP("Domain:") }, { "login", I18N_NOOP("Login") } }; @@ -195,7 +241,7 @@ KdmLabel::lookupStock( const TQString &stock ) if (type == stocks[i].type) return i18n(stocks[i].text); - kdDebug() << "Invalid <stock> element. Check your theme!" << endl; + kdDebug() << timestamp() << " Invalid <stock> element. Check your theme!" << endl; return stock; } @@ -205,7 +251,6 @@ KdmLabel::lookupText( const TQString &t ) TQString text = t; text.replace( '_', '&' ); -// text.remove( '_' ); // FIXME add key accels, remove underscores for now TQMap<TQChar,TQString> m; struct utsname uts; diff --git a/kdm/kfrontend/themer/kdmlabel.h b/kdm/kfrontend/themer/kdmlabel.h index 0770259c0..1ec2f88ec 100644 --- a/kdm/kfrontend/themer/kdmlabel.h +++ b/kdm/kfrontend/themer/kdmlabel.h @@ -50,6 +50,7 @@ protected: // handle switching between normal / active / prelight configurations virtual void statusChanged(); +public: struct LabelStruct { TQString text; bool isTimer; @@ -67,6 +68,7 @@ protected: public slots: void update(); + void slotAccel(); private: /* Method to lookup the caption associated with an item */ @@ -76,6 +78,10 @@ private: TQString lookupText( const TQString &t ); TQString cText; + int cAccel; + TQAccel *myAccel; + + void setTextInt(const TQString &); }; #endif diff --git a/kdm/kfrontend/themer/kdmlayout.cpp b/kdm/kfrontend/themer/kdmlayout.cpp index 00ca693ae..b17d2e7b7 100644 --- a/kdm/kfrontend/themer/kdmlayout.cpp +++ b/kdm/kfrontend/themer/kdmlayout.cpp @@ -20,6 +20,7 @@ */ #include "kdmlayout.h" +#include "kdmconfig.h" #include "kdmitem.h" #include <kdebug.h> @@ -35,11 +36,11 @@ KdmLayoutFixed::KdmLayoutFixed( const TQDomNode &/*node*/ ) void KdmLayoutFixed::update( const TQRect &parentGeometry, bool force ) { - kdDebug() << "KdmLayoutFixed::update " << parentGeometry << endl; + kdDebug() << timestamp() << " KdmLayoutFixed::update " << parentGeometry << endl; // I can't layout children if the parent rectangle is not valid if (parentGeometry.width() < 0 || parentGeometry.height() < 0) { - kdDebug() << "invalid\n"; + kdDebug() << timestamp() << " invalid\n"; return; } // For each child in list I ask their hinted size and set it! @@ -102,7 +103,7 @@ KdmLayoutBox::update( const TQRect &parentGeometry, bool force ) childrenRect.setTop( childrenRect.top() + height + box.spacing ); } else { TQRect temp( childrenRect.left(), childrenRect.top(), width, childrenRect.height() ); - kdDebug() << "placement " << *it << " " << temp << " " << (*it)->placementHint( temp ) << endl; + kdDebug() << timestamp() << " placement " << *it << " " << temp << " " << (*it)->placementHint( temp ) << endl; temp = (*it)->placementHint( temp ); (*it)->setGeometry( temp, force ); childrenRect.setLeft( childrenRect.left() + width + box.spacing ); @@ -125,7 +126,7 @@ KdmLayoutBox::update( const TQRect &parentGeometry, bool force ) kdDebug() << this << " placementHint " << *it << " " << temp << " " << itemRect << endl; temp.setWidth( itemRect.width() ); childrenRect.setLeft( childrenRect.left() + itemRect.size().width() + box.spacing ); - kdDebug() << "childrenRect after " << *it << " " << childrenRect << endl; + kdDebug() << timestamp() << " childrenRect after " << *it << " " << childrenRect << endl; } itemRect = (*it)->placementHint( temp ); kdDebug() << this << " placementHint2 " << *it << " " << temp << " " << itemRect << endl; diff --git a/kdm/kfrontend/themer/kdmpixmap.cpp b/kdm/kfrontend/themer/kdmpixmap.cpp index 07077e4a1..f18194f53 100644 --- a/kdm/kfrontend/themer/kdmpixmap.cpp +++ b/kdm/kfrontend/themer/kdmpixmap.cpp @@ -22,6 +22,7 @@ #include <config.h> #include "kdmpixmap.h" +#include <kdmconfig.h> #include <kimageeffect.h> #ifdef HAVE_LIBART @@ -29,6 +30,7 @@ #endif #include <kdebug.h> +#include <kstandarddirs.h> #include <tqpainter.h> #include <tqpixmap.h> @@ -58,21 +60,28 @@ KdmPixmap::KdmPixmap( KdmItem *parent, const TQDomNode &node, const char *name ) TQString tagName = el.tagName(); if (tagName == "normal") { - loadPixmap( el.attribute( "file", "" ), pixmap.normal.pixmap, pixmap.normal.fullpath ); + pixmap.normal.fullpath = fullPath( el.attribute( "file", "" ) ); parseColor( el.attribute( "tint", "#ffffff" ), pixmap.normal.tint ); pixmap.normal.alpha = el.attribute( "alpha", "1.0" ).toFloat(); } else if (tagName == "active") { pixmap.active.present = true; - loadPixmap( el.attribute( "file", "" ), pixmap.active.pixmap, pixmap.active.fullpath ); + pixmap.active.fullpath = fullPath( el.attribute( "file", "" ) ); parseColor( el.attribute( "tint", "#ffffff" ), pixmap.active.tint ); pixmap.active.alpha = el.attribute( "alpha", "1.0" ).toFloat(); } else if (tagName == "prelight") { pixmap.prelight.present = true; - loadPixmap( el.attribute( "file", "" ), pixmap.prelight.pixmap, pixmap.prelight.fullpath ); + pixmap.prelight.fullpath = fullPath(el.attribute( "file", "" ) ); parseColor( el.attribute( "tint", "#ffffff" ), pixmap.prelight.tint ); pixmap.prelight.alpha = el.attribute( "alpha", "1.0" ).toFloat(); } } + + // look if we have to have the aspect ratio ready + if (((pos.wType == DTnone && pos.hType != DTnone) || + (pos.wType != DTnone && pos.hType == DTnone) || + (pos.wType == DTnone && pos.hType == DTnone)) && + !pixmap.normal.fullpath.endsWith( ".svg" )) + loadPixmap( &pixmap.normal ); } QSize @@ -100,19 +109,16 @@ KdmPixmap::setGeometry( const TQRect &newGeometry, bool force ) } -void -KdmPixmap::loadPixmap( const TQString &fileName, TQPixmap &map, TQString &fullName ) +TQString +KdmPixmap::fullPath( const TQString &fileName) { - if (fileName.isEmpty()) - return; + if (fileName.isEmpty()) + return TQString::null; - fullName = fileName; + TQString fullName = fileName; if (fullName.at( 0 ) != '/') fullName = baseDir() + "/" + fileName; - - if (!fullName.endsWith( ".svg" )) // we delay it for svgs - if (!map.load( fullName )) - fullName = TQString::null; + return fullName; } void @@ -140,6 +146,25 @@ KdmPixmap::renderSvg( PixmapStruct::PixmapClass *pClass, const TQRect &area ) } void +KdmPixmap::loadPixmap( PixmapStruct::PixmapClass *pClass ) +{ + TQString fullpath = pClass->fullpath; + + kdDebug() << timestamp() << " load " << fullpath << endl; + int index = fullpath.findRev('.'); + TQString ext = fullpath.right(fullpath.length() - index); + fullpath = fullpath.left(index); + kdDebug() << timestamp() << " ext " << ext << " " << fullpath << endl; + TQString testpath = TQString("-%1x%2").arg(area.width()).arg(area.height()) + ext; + kdDebug() << timestamp() << " testing for " << fullpath + testpath << endl; + if (KStandardDirs::exists(fullpath + testpath)) + pClass->pixmap.load(fullpath + testpath); + else + pClass->pixmap.load( fullpath + ext ); + kdDebug() << timestamp() << " done\n"; +} + +void KdmPixmap::drawContents( TQPainter *p, const TQRect &r ) { // choose the correct pixmap class @@ -149,12 +174,20 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r ) if (state == Sprelight && pixmap.prelight.present) pClass = &pixmap.prelight; + kdDebug() << "draw " << id << " " << pClass->pixmap.isNull() << endl; + if (pClass->pixmap.isNull()) { - if (pClass->fullpath.isEmpty()) // if neither is set, we're empty + + if (pClass->fullpath.isEmpty()) // if neither is set, we're empty return; - - kdDebug() << "renderSVG\n"; - renderSvg( pClass, area ); + + if (!pClass->fullpath.endsWith( ".svg" ) ) { + loadPixmap(pClass); + } else { + kdDebug() << timestamp() << " renderSVG\n"; + renderSvg( pClass, area ); + kdDebug() << timestamp() << " done\n"; + } } int px = area.left() + r.left(); @@ -176,25 +209,37 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r ) if (pClass->readyPixmap.isNull()) { - TQImage scaledImage; + + bool haveTint = pClass->tint.rgb() != 0xFFFFFF; + bool haveAlpha = pClass->alpha < 1.0; + TQImage scaledImage; + // use the loaded pixmap or a scaled version if needed + kdDebug() << timestamp() << " prepare readyPixmap " << pClass->fullpath << " " << area.size() << " " << pClass->pixmap.size() << endl; if (area.size() != pClass->pixmap.size()) { if (pClass->fullpath.endsWith( ".svg" )) { - kdDebug() << "renderSVG\n"; + kdDebug() << timestamp() << " renderSVG\n"; renderSvg( pClass, area ); scaledImage = pClass->pixmap.convertToImage(); } else { - kdDebug() << "convertFromImage\n"; + kdDebug() << timestamp() << " convertFromImage smoothscale\n"; TQImage tempImage = pClass->pixmap.convertToImage(); + kdDebug() << timestamp() << " convertToImage done\n"; scaledImage = tempImage.smoothScale( area.width(), area.height() ); + kdDebug() << timestamp() << " done\n"; } - } else + } else { + if (haveTint || haveAlpha) + { scaledImage = pClass->pixmap.convertToImage(); - - bool haveTint = pClass->tint.rgb() != 0xFFFFFF; - bool haveAlpha = pClass->alpha < 1.0; + // enforce rgba values for the later + scaledImage = scaledImage.convertDepth( 32 ); + } + else + pClass->readyPixmap = pClass->pixmap; + } if (haveTint || haveAlpha) { // blend image(pix) with the given tint @@ -221,9 +266,12 @@ KdmPixmap::drawContents( TQPainter *p, const TQRect &r ) } - pClass->readyPixmap.convertFromImage( scaledImage ); + if (!scaledImage.isNull()) { + kdDebug() << timestamp() << " convertFromImage " << id << " " << area << endl; + pClass->readyPixmap.convertFromImage( scaledImage ); + } } - // kdDebug() << "Pixmap::drawContents " << pClass->readyPixmap.size() << " " << px << " " << py << " " << sx << " " << sy << " " << sw << " " << sh << endl; + kdDebug() << timestamp() << " Pixmap::drawContents " << pClass->readyPixmap.size() << " " << px << " " << py << " " << sx << " " << sy << " " << sw << " " << sh << endl; p->drawPixmap( px, py, pClass->readyPixmap, sx, sy, sw, sh ); } diff --git a/kdm/kfrontend/themer/kdmpixmap.h b/kdm/kfrontend/themer/kdmpixmap.h index 479ef0f8d..92d4895d0 100644 --- a/kdm/kfrontend/themer/kdmpixmap.h +++ b/kdm/kfrontend/themer/kdmpixmap.h @@ -61,9 +61,10 @@ protected: } pixmap; private: - // Method to load the pixmap given by the theme - void loadPixmap( const TQString &fileName, TQPixmap &p, TQString &path ); + // Method to load the pixmap path given by the theme + TQString fullPath( const TQString &fileName ); void renderSvg( PixmapStruct::PixmapClass *pClass, const TQRect &area ); + void loadPixmap( PixmapStruct::PixmapClass *pClass ); }; #endif diff --git a/kdm/kfrontend/themer/kdmrect.cpp b/kdm/kfrontend/themer/kdmrect.cpp index 961809a37..1d854d213 100644 --- a/kdm/kfrontend/themer/kdmrect.cpp +++ b/kdm/kfrontend/themer/kdmrect.cpp @@ -33,6 +33,18 @@ KdmRect::KdmRect( KdmItem *parent, const TQDomNode &node, const char *name ) : KdmItem( parent, node, name ) { + init( node, name ); +} + +KdmRect::KdmRect( TQWidget *parent, const TQDomNode &node, const char *name ) + : KdmItem( parent, node, name ) +{ + init( node, name ); +} + +void +KdmRect::init( const TQDomNode &node, const char * ) +{ itemType = "rect"; // Set default values for rect (note: strings are already Null) @@ -137,13 +149,6 @@ KdmRect::recursiveSetAttribs( TQLayoutItem *li ) } void -KdmRect::setWidget( TQWidget *widget ) -{ - KdmItem::setWidget( widget ); - setAttribs( widget ); -} - -void KdmRect::setLayoutItem( TQLayoutItem *item ) { KdmItem::setLayoutItem( item ); @@ -151,4 +156,17 @@ KdmRect::setLayoutItem( TQLayoutItem *item ) } */ +void +KdmRect::setWidget( TQWidget *widget ) +{ + if ( rect.normal.color.isValid() && widget ) + { + TQPalette p = widget->palette(); + p.setColor( TQPalette::Normal, TQColorGroup::Text, rect.normal.color ); + widget->setPalette(p); + } + KdmItem::setWidget( widget ); + //setAttribs( widget ); +} + #include "kdmrect.moc" diff --git a/kdm/kfrontend/themer/kdmrect.h b/kdm/kfrontend/themer/kdmrect.h index 7e4776233..a505e1921 100644 --- a/kdm/kfrontend/themer/kdmrect.h +++ b/kdm/kfrontend/themer/kdmrect.h @@ -36,6 +36,7 @@ class KdmRect : public KdmItem { public: KdmRect( KdmItem *parent, const TQDomNode &node, const char *name = 0 ); + KdmRect( TQWidget *parent, const TQDomNode &node, const char *name = 0 ); protected: // draw the rect @@ -54,8 +55,9 @@ protected: bool hasBorder; } rect; -// virtual void setWidget( TQWidget *widget ); + virtual void setWidget( TQWidget *widget ); // virtual void setLayoutItem( TQLayoutItem *item ); + void init( const TQDomNode &node, const char *name ); private: void setAttribs( TQWidget *widget ); diff --git a/kdm/kfrontend/themer/kdmthemer.cpp b/kdm/kfrontend/themer/kdmthemer.cpp index aca43e45d..9e6db33db 100644 --- a/kdm/kfrontend/themer/kdmthemer.cpp +++ b/kdm/kfrontend/themer/kdmthemer.cpp @@ -36,11 +36,13 @@ #include <tqfile.h> #include <tqfileinfo.h> -//#include <tqtimer.h> // animation timer - TODO +#include <tqtimer.h> // animation timer - TODO #include <tqobjectlist.h> #include <tqpainter.h> #include <tqwidget.h> #include <tqregion.h> +#include <tqlineedit.h> +#include <tqapplication.h> #include <unistd.h> @@ -72,7 +74,8 @@ KdmThemer::KdmThemer( const TQString &_filename, const TQString &mode, TQWidget return; } // Set the root (screen) item - rootItem = new KdmRect( 0, TQDomNode(), "kdm root" ); + rootItem = new KdmRect( parent, TQDomNode(), "kdm root" ); + connect( rootItem, TQT_SIGNAL(needUpdate( int, int, int, int )), widget(), TQT_SLOT(update( int, int, int, int )) ); @@ -82,6 +85,9 @@ KdmThemer::KdmThemer( const TQString &_filename, const TQString &mode, TQWidget generateItems( rootItem ); connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SIGNAL(activated( const TQString & )) ); + connect( rootItem, TQT_SIGNAL(activated( const TQString & )), TQT_SLOT(slotActivated( const TQString & )) ); + + TQTimer::singleShot(800, this, TQT_SLOT(slotPaintRoot())); /* *TODO* // Animation timer @@ -151,7 +157,7 @@ KdmThemer::widgetEvent( TQEvent *e ) case TQEvent::Paint: { TQRect paintRect = static_cast<TQPaintEvent *>(e)->rect(); - kdDebug() << "paint on: " << paintRect << endl; + kdDebug() << timestamp() << " paint on: " << paintRect << endl; if (!backBuffer) backBuffer = new TQPixmap( widget()->size() ); @@ -195,7 +201,7 @@ KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node ) // Get its tag, and check it's correct ("greeter") if (theme.tagName() != "greeter") { - kdDebug() << "This does not seem to be a correct theme file." << endl; + kdDebug() << timestamp() << " This does not seem to be a correct theme file." << endl; return; } // Get the list of child nodes @@ -214,6 +220,13 @@ KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node ) if (tagName == "item") { if (!willDisplay( subnode )) continue; + TQString id = el.attribute("id"); + if (id.startsWith("plugin-specific-")) { + id = id.mid(strlen("plugin-specific-")); + if (!_pluginsLogin.contains(id)) + continue; + } + // It's a new item. Draw it TQString type = el.attribute( "type" ); @@ -225,13 +238,11 @@ KdmThemer::generateItems( KdmItem *parent, const TQDomNode &node ) newItem = new KdmPixmap( parent, subnode ); else if (type == "rect") newItem = new KdmRect( parent, subnode ); - else if (type == "entry") { + else if (type == "entry" || type == "list") { newItem = new KdmRect( parent, subnode ); newItem->setType( type ); } // newItem = new KdmEntry( parent, subnode ); - //else if (type=="list") - // newItem = new KdmList( parent, subnode ); else if (type == "svg") newItem = new KdmPixmap( parent, subnode ); if (newItem) { @@ -287,6 +298,11 @@ bool KdmThemer::willDisplay( const TQDomNode &node ) #endif if (type == "halt" || type == "reboot") return _allowShutdown != SHUT_NONE; + else if (type == "userlist") + return _userList; + else if ( type == "!userlist" ) + return !_userList; + // if (type == "system") // return true; @@ -301,7 +317,7 @@ KdmThemer::showStructure( TQObject *obj ) const TQObjectList *wlist = obj->children(); static int counter = 0; if (counter == 0) - kdDebug() << "\n\n<======= Widget tree =================" << endl; + kdDebug() << timestamp() << " \n\n<======= Widget tree =================" << endl; if (wlist) { counter++; TQObjectListIterator it( *wlist ); @@ -323,7 +339,46 @@ KdmThemer::showStructure( TQObject *obj ) counter--; } if (counter == 0) - kdDebug() << "\n\n<======= Widget tree =================\n\n" << endl; + kdDebug() << timestamp() << " \n\n<======= Widget tree =================\n\n" << endl; +} + +void +KdmThemer::slotActivated( const TQString &id ) +{ + TQString toactivate; + if (id == "username-label") + toactivate = "user-entry"; + else if (id == "password-label") + toactivate = "pw-entry"; + else + return; + + KdmItem *item = findNode(toactivate); + if (!item || !item->widget()) + return; + + item->widget()->setFocus(); + TQLineEdit *le = (TQLineEdit*)item->widget()->qt_cast("TQLineEdit"); + if (le) + le->selectAll(); +} + +void +KdmThemer::slotPaintRoot() +{ + KdmItem *back_item = findNode("background"); + if (!back_item) + return; + + TQRect screen = TQApplication::desktop()->screenGeometry(0); + TQPixmap pm(screen.size()); + + TQPainter painter( &pm, true ); + back_item->paint( &painter, back_item->rect()); + painter.end(); + + TQApplication::desktop()->screen()->setErasePixmap(pm); + TQApplication::desktop()->screen()->erase(); } #include "kdmthemer.moc" diff --git a/kdm/kfrontend/themer/kdmthemer.h b/kdm/kfrontend/themer/kdmthemer.h index 6bf6af00d..6dc2318dd 100644 --- a/kdm/kfrontend/themer/kdmthemer.h +++ b/kdm/kfrontend/themer/kdmthemer.h @@ -80,6 +80,10 @@ public: signals: void activated( const TQString &id ); +protected slots: + void slotActivated( const TQString &id ); + void slotPaintRoot(); + private: /* * Our display mode (e.g. console, remote, ...) |