add more spacing
[personal-kdebase.git] / workspace / libs / kdm / kgreet_classic.cpp
blob6222bbde3cf811b4740306fe7cf82c73ef2a33dd
1 /*
3 Conversation widget for kdm greeter
5 Copyright (C) 1997, 1998, 2000 Steffen Hansen <hansen@kde.org>
6 Copyright (C) 2000-2003 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.
25 #include "kgreet_classic.h"
26 #include "themer/kdmthemer.h"
27 #include "themer/kdmitem.h"
29 #include <kglobal.h>
30 #include <klocale.h>
31 #include <klineedit.h>
32 #include <kuser.h>
34 #include <QRegExp>
35 #include <QLayout>
36 #include <QLabel>
38 static int echoMode;
40 class KDMPasswordEdit : public KLineEdit {
41 public:
42 KDMPasswordEdit( QWidget *parent ) : KLineEdit( parent )
44 if (::echoMode == -1)
45 setPasswordMode(true);
46 else
47 setEchoMode( ::echoMode ? Password : NoEcho );
48 setContextMenuPolicy( Qt::NoContextMenu );
52 KClassicGreeter::KClassicGreeter( KGreeterPluginHandler *_handler,
53 QWidget *parent,
54 const QString &_fixedEntity,
55 Function _func, Context _ctx ) :
56 QObject(),
57 KGreeterPlugin( _handler ),
58 fixedUser( _fixedEntity ),
59 func( _func ),
60 ctx( _ctx ),
61 exp( -1 ),
62 pExp( -1 ),
63 running( false )
65 QGridLayout *grid = 0;
66 int line = 0;
68 if (!_handler->gplugHasNode( "user-entry" ) ||
69 !_handler->gplugHasNode( "pw-entry" ))
71 parent = new QWidget( parent );
72 parent->setObjectName( "talker" );
73 widgetList << parent;
74 grid = new QGridLayout( parent );
75 grid->setMargin( 0 );
78 loginLabel = passwdLabel = passwd1Label = passwd2Label = 0;
79 loginEdit = 0;
80 passwdEdit = passwd1Edit = passwd2Edit = 0;
81 if (ctx == ExUnlock || ctx == ExChangeTok)
82 fixedUser = KUser().loginName();
83 if (func != ChAuthTok) {
84 if (fixedUser.isEmpty()) {
85 loginEdit = new KLineEdit( parent );
86 loginEdit->setContextMenuPolicy( Qt::NoContextMenu );
87 connect( loginEdit, SIGNAL(editingFinished()), SLOT(slotLoginLostFocus()) );
88 connect( loginEdit, SIGNAL(editingFinished()), SLOT(slotChanged()) );
89 connect( loginEdit, SIGNAL(textChanged( const QString & )), SLOT(slotChanged()) );
90 connect( loginEdit, SIGNAL(selectionChanged()), SLOT(slotChanged()) );
91 if (!grid) {
92 loginEdit->setObjectName( "user-entry" );
93 widgetList << loginEdit;
94 } else {
95 loginLabel = new QLabel( i18n("&Username:"), parent );
96 loginLabel->setBuddy( loginEdit );
97 grid->addWidget( loginLabel, line, 0 );
98 grid->addWidget( loginEdit, line++, 1 );
100 } else if (ctx != Login && ctx != Shutdown && grid) {
101 loginLabel = new QLabel( i18n("Username:"), parent );
102 grid->addWidget( loginLabel, line, 0 );
103 grid->addWidget( new QLabel( fixedUser, parent ), line++, 1 );
105 passwdEdit = new KDMPasswordEdit( parent );
106 connect( passwdEdit, SIGNAL(textChanged( const QString & )),
107 SLOT(slotChanged()) );
108 connect( passwdEdit, SIGNAL(editingFinished()), SLOT(slotChanged()) );
109 if (!grid) {
110 passwdEdit->setObjectName( "pw-entry" );
111 widgetList << passwdEdit;
112 } else {
113 passwdLabel = new QLabel( func == Authenticate ?
114 i18n("&Password:") :
115 i18n("Current &password:"),
116 parent );
117 passwdLabel->setBuddy( passwdEdit );
118 grid->addWidget( passwdLabel, line, 0 );
119 grid->addWidget( passwdEdit, line++, 1 );
121 if (loginEdit)
122 loginEdit->setFocus();
123 else
124 passwdEdit->setFocus();
126 if (func != Authenticate) {
127 passwd1Edit = new KDMPasswordEdit( parent );
128 passwd1Label = new QLabel( i18n("&New password:"), parent );
129 passwd1Label->setBuddy( passwd1Edit );
130 passwd2Edit = new KDMPasswordEdit( parent );
131 passwd2Label = new QLabel( i18n("Con&firm password:"), parent );
132 passwd2Label->setBuddy( passwd2Edit );
133 if (grid) {
134 grid->addWidget( passwd1Label, line, 0 );
135 grid->addWidget( passwd1Edit, line++, 1 );
136 grid->addWidget( passwd2Label, line, 0 );
137 grid->addWidget( passwd2Edit, line, 1 );
139 if (!passwdEdit)
140 passwd1Edit->setFocus();
144 // virtual
145 KClassicGreeter::~KClassicGreeter()
147 abort();
148 qDeleteAll( widgetList );
151 void // virtual
152 KClassicGreeter::loadUsers( const QStringList &users )
154 KCompletion *userNamesCompletion = new KCompletion;
155 userNamesCompletion->setItems( users );
156 loginEdit->setCompletionObject( userNamesCompletion );
157 loginEdit->setAutoDeleteCompletionObject( true );
158 loginEdit->setCompletionMode( KGlobalSettings::CompletionAuto );
161 void // virtual
162 KClassicGreeter::presetEntity( const QString &entity, int field )
164 loginEdit->setText( entity );
165 if (field == 1)
166 passwdEdit->setFocus();
167 else {
168 loginEdit->setFocus();
169 loginEdit->selectAll();
170 if (field == -1) {
171 passwdEdit->setText( " " );
172 passwdEdit->setEnabled( false );
173 authTok = false;
176 curUser = entity;
179 QString // virtual
180 KClassicGreeter::getEntity() const
182 return fixedUser.isEmpty() ? loginEdit->text() : fixedUser;
185 void // virtual
186 KClassicGreeter::setUser( const QString &user )
188 // assert( fixedUser.isEmpty() );
189 curUser = user;
190 loginEdit->setText( user );
191 passwdEdit->setFocus();
192 passwdEdit->selectAll();
195 void // virtual
196 KClassicGreeter::setEnabled( bool enable )
198 // assert( !passwd1Label );
199 // assert( func == Authenticate && ctx == Shutdown );
200 // if (loginLabel)
201 // loginLabel->setEnabled( enable );
202 passwdLabel->setEnabled( enable );
203 setActive( enable );
204 if (enable)
205 passwdEdit->setFocus();
208 void // private
209 KClassicGreeter::returnData()
211 switch (exp) {
212 case 0:
213 handler->gplugReturnText( (loginEdit ? loginEdit->text() :
214 fixedUser).toLocal8Bit(),
215 KGreeterPluginHandler::IsUser );
216 break;
217 case 1:
218 Q_ASSERT(passwdEdit);
219 handler->gplugReturnText( passwdEdit->text().toLocal8Bit() ,
220 KGreeterPluginHandler::IsPassword |
221 KGreeterPluginHandler::IsSecret );
222 break;
223 case 2:
224 Q_ASSERT(passwd1Edit);
225 handler->gplugReturnText( passwd1Edit->text().toLocal8Bit(),
226 KGreeterPluginHandler::IsSecret );
227 break;
228 default: // case 3:
229 Q_ASSERT(passwd2Edit);
230 handler->gplugReturnText( passwd2Edit->text().toLocal8Bit(),
231 KGreeterPluginHandler::IsNewPassword |
232 KGreeterPluginHandler::IsSecret );
233 break;
237 bool // virtual
238 KClassicGreeter::textMessage( const char *text, bool err )
240 if (!err &&
241 QString( text ).indexOf( QRegExp( "^Changing password for [^ ]+$" ) ) >= 0)
242 return true;
243 return false;
246 void // virtual
247 KClassicGreeter::textPrompt( const char *prompt, bool echo, bool nonBlocking )
249 pExp = exp;
250 if (echo)
251 exp = 0;
252 else if (!authTok)
253 exp = 1;
254 else {
255 QString pr( prompt );
256 if (pr.indexOf( QRegExp( "\\bpassword\\b", Qt::CaseInsensitive ) ) >= 0) {
257 if (pr.indexOf( QRegExp( "\\b(re-?(enter|type)|again|confirm|repeat)\\b",
258 Qt::CaseInsensitive ) ) >= 0)
259 exp = 3;
260 else if (pr.indexOf( QRegExp( "\\bnew\\b", Qt::CaseInsensitive ) ) >= 0)
261 exp = 2;
262 else { // QRegExp( "\\b(old|current)\\b", Qt::CaseInsensitive ) is too strict
263 handler->gplugReturnText( "",
264 KGreeterPluginHandler::IsOldPassword |
265 KGreeterPluginHandler::IsSecret );
266 return;
268 } else {
269 handler->gplugMsgBox( QMessageBox::Critical,
270 i18n("Unrecognized prompt \"%1\"",
271 prompt ) );
272 handler->gplugReturnText( 0, 0 );
273 exp = -1;
274 return;
278 if (pExp >= 0 && pExp >= exp) {
279 revive();
280 has = -1;
283 if (has >= exp || nonBlocking)
284 returnData();
287 bool // virtual
288 KClassicGreeter::binaryPrompt( const char *, bool )
290 // this simply cannot happen ... :}
291 return true;
294 void // virtual
295 KClassicGreeter::start()
297 authTok = !(passwdEdit && passwdEdit->isEnabled());
298 exp = has = -1;
299 running = true;
302 void // virtual
303 KClassicGreeter::suspend()
307 void // virtual
308 KClassicGreeter::resume()
312 void // virtual
313 KClassicGreeter::next()
315 // assert( running );
316 if (loginEdit && loginEdit->hasFocus()) {
317 passwdEdit->setFocus(); // will cancel running login if necessary
318 has = 0;
319 } else if (passwdEdit && passwdEdit->hasFocus()) {
320 if (passwd1Edit)
321 passwd1Edit->setFocus();
322 has = 1;
323 } else if (passwd1Edit) {
324 if (passwd1Edit->hasFocus()) {
325 passwd2Edit->setFocus();
326 has = 1; // sic!
327 } else
328 has = 3;
329 } else
330 has = 1;
331 if (exp < 0)
332 handler->gplugStart();
333 else if (has >= exp)
334 returnData();
337 void // virtual
338 KClassicGreeter::abort()
340 running = false;
341 if (exp >= 0) {
342 exp = -1;
343 handler->gplugReturnText( 0, 0 );
347 void // virtual
348 KClassicGreeter::succeeded()
350 // assert( running || timed_login );
351 if (!authTok) {
352 setActive( false );
353 if (passwd1Edit) {
354 authTok = true;
355 return;
357 } else
358 setActive2( false );
359 exp = -1;
360 running = false;
363 void // virtual
364 KClassicGreeter::failed()
366 // assert( running || timed_login );
367 setActive( false );
368 setActive2( false );
369 exp = -1;
370 running = false;
373 void // virtual
374 KClassicGreeter::revive()
376 // assert( !running );
377 setActive2( true );
378 if (authTok) {
379 passwd1Edit->clear();
380 passwd2Edit->clear();
381 passwd1Edit->setFocus();
382 } else {
383 passwdEdit->clear();
384 if (loginEdit && loginEdit->isEnabled())
385 passwdEdit->setEnabled( true );
386 else {
387 setActive( true );
388 if (loginEdit && loginEdit->text().isEmpty())
389 loginEdit->setFocus();
390 else
391 passwdEdit->setFocus();
396 void // virtual
397 KClassicGreeter::clear()
399 // assert( !running && !passwd1Edit );
400 passwdEdit->clear();
401 if (loginEdit) {
402 loginEdit->clear();
403 loginEdit->setFocus();
404 curUser.clear();
405 } else
406 passwdEdit->setFocus();
410 // private
412 void
413 KClassicGreeter::setActive( bool enable )
415 if (loginEdit)
416 loginEdit->setEnabled( enable );
417 if (passwdEdit)
418 passwdEdit->setEnabled( enable );
421 void
422 KClassicGreeter::setActive2( bool enable )
424 if (passwd1Edit) {
425 passwd1Edit->setEnabled( enable );
426 passwd2Edit->setEnabled( enable );
430 void
431 KClassicGreeter::slotLoginLostFocus()
433 if (!running)
434 return;
435 loginEdit->setText( loginEdit->text().trimmed() );
436 if (exp > 0) {
437 if (curUser == loginEdit->text())
438 return;
439 exp = -1;
440 handler->gplugReturnText( 0, 0 );
442 curUser = loginEdit->text();
443 handler->gplugSetUser( curUser );
446 void
447 KClassicGreeter::slotChanged()
449 if (running)
450 handler->gplugChanged();
453 // factory
455 static bool init( const QString &,
456 QVariant (*getConf)( void *, const char *, const QVariant & ),
457 void *ctx )
459 echoMode = getConf( ctx, "EchoPasswd", QVariant( -1 ) ).toInt();
460 KGlobal::locale()->insertCatalog( "kgreet_classic" );
461 return true;
464 static void done( void )
466 KGlobal::locale()->removeCatalog( "kgreet_classic" );
469 static KGreeterPlugin *
470 create( KGreeterPluginHandler *handler,
471 QWidget *parent,
472 const QString &fixedEntity,
473 KGreeterPlugin::Function func,
474 KGreeterPlugin::Context ctx )
476 return new KClassicGreeter( handler, parent, fixedEntity, func, ctx );
479 KDE_EXPORT KGreeterPluginInfo kgreeterplugin_info = {
480 I18N_NOOP2("@item:inmenu authentication method", "Username + password (classic)"), "classic",
481 KGreeterPluginInfo::Local | KGreeterPluginInfo::Presettable,
482 init, done, create
485 #include "kgreet_classic.moc"