~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to libs/kdm/kgreet_classic.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
Conversation widget for kdm greeter
 
4
 
 
5
Copyright (C) 1997, 1998, 2000 Steffen Hansen <hansen@kde.org>
 
6
Copyright (C) 2000-2003 Oswald Buddenhagen <ossi@kde.org>
 
7
 
 
8
 
 
9
This program is free software; you can redistribute it and/or modify
 
10
it under the terms of the GNU General Public License as published by
 
11
the Free Software Foundation; either version 2 of the License, or
 
12
(at your option) any later version.
 
13
 
 
14
This program is distributed in the hope that it will be useful,
 
15
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
GNU General Public License for more details.
 
18
 
 
19
You should have received a copy of the GNU General Public License
 
20
along with this program; if not, write to the Free Software
 
21
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 
22
 
 
23
*/
 
24
 
 
25
#include "kgreet_classic.h"
 
26
 
 
27
#include <kglobal.h>
 
28
#include <klocale.h>
 
29
#include <klineedit.h>
 
30
#include <kuser.h>
 
31
 
 
32
#include <QRegExp>
 
33
#include <QLayout>
 
34
#include <QLabel>
 
35
 
 
36
static int echoMode;
 
37
 
 
38
class KDMPasswordEdit : public KLineEdit {
 
39
public:
 
40
    KDMPasswordEdit(QWidget *parent) : KLineEdit(parent)
 
41
    {
 
42
        if (::echoMode == -1)
 
43
            setPasswordMode(true);
 
44
        else
 
45
            setEchoMode(::echoMode ? Password : NoEcho);
 
46
        setContextMenuPolicy(Qt::NoContextMenu);
 
47
    }
 
48
};
 
49
 
 
50
KClassicGreeter::KClassicGreeter(KGreeterPluginHandler *_handler,
 
51
                                 QWidget *parent,
 
52
                                 const QString &_fixedEntity,
 
53
                                 Function _func, Context _ctx) :
 
54
    QObject(),
 
55
    KGreeterPlugin(_handler),
 
56
    fixedUser(_fixedEntity),
 
57
    func(_func),
 
58
    ctx(_ctx),
 
59
    exp(-1),
 
60
    pExp(-1),
 
61
    running(false)
 
62
{
 
63
    QGridLayout *grid = 0;
 
64
    int line = 0;
 
65
 
 
66
    if (!_handler->gplugHasNode("user-entry") ||
 
67
        !_handler->gplugHasNode("pw-entry"))
 
68
    {
 
69
        parent = new QWidget(parent);
 
70
        parent->setObjectName("talker");
 
71
        widgetList << parent;
 
72
        grid = new QGridLayout(parent);
 
73
        grid->setMargin(0);
 
74
    }
 
75
 
 
76
    loginLabel = passwdLabel = passwd1Label = passwd2Label = 0;
 
77
    loginEdit = 0;
 
78
    passwdEdit = passwd1Edit = passwd2Edit = 0;
 
79
    if (ctx == ExUnlock || ctx == ExChangeTok)
 
80
        fixedUser = KUser().loginName();
 
81
    if (func != ChAuthTok) {
 
82
        if (fixedUser.isEmpty()) {
 
83
            loginEdit = new KLineEdit(parent);
 
84
            loginEdit->setContextMenuPolicy(Qt::NoContextMenu);
 
85
            connect(loginEdit, SIGNAL(editingFinished()), SLOT(slotLoginLostFocus()));
 
86
            connect(loginEdit, SIGNAL(editingFinished()), SLOT(slotChanged()));
 
87
            connect(loginEdit, SIGNAL(textChanged(const QString &)), SLOT(slotChanged()));
 
88
            connect(loginEdit, SIGNAL(selectionChanged()), SLOT(slotChanged()));
 
89
            if (!grid) {
 
90
                loginEdit->setObjectName("user-entry");
 
91
                widgetList << loginEdit;
 
92
            } else {
 
93
                loginLabel = new QLabel(i18n("&Username:"), parent);
 
94
                loginLabel->setBuddy(loginEdit);
 
95
                grid->addWidget(loginLabel, line, 0);
 
96
                grid->addWidget(loginEdit, line++, 1);
 
97
            }
 
98
        } else if (ctx != Login && ctx != Shutdown && grid) {
 
99
            loginLabel = new QLabel(i18n("Username:"), parent);
 
100
            grid->addWidget(loginLabel, line, 0);
 
101
            grid->addWidget(new QLabel(fixedUser, parent), line++, 1);
 
102
        }
 
103
        passwdEdit = new KDMPasswordEdit(parent);
 
104
        connect(passwdEdit, SIGNAL(textChanged(const QString &)),
 
105
                SLOT(slotChanged()));
 
106
        connect(passwdEdit, SIGNAL(editingFinished()), SLOT(slotChanged()));
 
107
        if (!grid) {
 
108
            passwdEdit->setObjectName("pw-entry");
 
109
            widgetList << passwdEdit;
 
110
        } else {
 
111
            passwdLabel = new QLabel(func == Authenticate ?
 
112
                                         i18n("&Password:") :
 
113
                                         i18n("Current &password:"),
 
114
                                     parent);
 
115
            passwdLabel->setBuddy(passwdEdit);
 
116
            grid->addWidget(passwdLabel, line, 0);
 
117
            grid->addWidget(passwdEdit, line++, 1);
 
118
        }
 
119
        if (loginEdit)
 
120
            loginEdit->setFocus();
 
121
        else
 
122
            passwdEdit->setFocus();
 
123
    }
 
124
    if (func != Authenticate) {
 
125
        passwd1Edit = new KDMPasswordEdit(parent);
 
126
        passwd1Label = new QLabel(i18n("&New password:"), parent);
 
127
        passwd1Label->setBuddy(passwd1Edit);
 
128
        passwd2Edit = new KDMPasswordEdit(parent);
 
129
        passwd2Label = new QLabel(i18n("Con&firm password:"), parent);
 
130
        passwd2Label->setBuddy(passwd2Edit);
 
131
        if (grid) {
 
132
            grid->addWidget(passwd1Label, line, 0);
 
133
            grid->addWidget(passwd1Edit, line++, 1);
 
134
            grid->addWidget(passwd2Label, line, 0);
 
135
            grid->addWidget(passwd2Edit, line, 1);
 
136
        }
 
137
        if (!passwdEdit)
 
138
            passwd1Edit->setFocus();
 
139
    }
 
140
}
 
141
 
 
142
// virtual
 
143
KClassicGreeter::~KClassicGreeter()
 
144
{
 
145
    abort();
 
146
    qDeleteAll(widgetList);
 
147
}
 
148
 
 
149
void // virtual
 
150
KClassicGreeter::loadUsers(const QStringList &users)
 
151
{
 
152
    KCompletion *userNamesCompletion = new KCompletion;
 
153
    userNamesCompletion->setItems(users);
 
154
    loginEdit->setCompletionObject(userNamesCompletion);
 
155
    loginEdit->setAutoDeleteCompletionObject(true);
 
156
    loginEdit->setCompletionMode(KGlobalSettings::CompletionAuto);
 
157
}
 
158
 
 
159
void // virtual
 
160
KClassicGreeter::presetEntity(const QString &entity, int field)
 
161
{
 
162
    loginEdit->setText(entity);
 
163
    if (field == 1) {
 
164
        passwdEdit->setFocus();
 
165
    } else {
 
166
        loginEdit->setFocus();
 
167
        loginEdit->selectAll();
 
168
        if (field == -1) {
 
169
            passwdEdit->setText("     ");
 
170
            passwdEdit->setEnabled(false);
 
171
            authTok = false;
 
172
        }
 
173
    }
 
174
    curUser = entity;
 
175
}
 
176
 
 
177
QString // virtual
 
178
KClassicGreeter::getEntity() const
 
179
{
 
180
    return fixedUser.isEmpty() ? loginEdit->text() : fixedUser;
 
181
}
 
182
 
 
183
void // virtual
 
184
KClassicGreeter::setUser(const QString &user)
 
185
{
 
186
    // assert(fixedUser.isEmpty());
 
187
    curUser = user;
 
188
    loginEdit->setText(user);
 
189
    passwdEdit->setFocus();
 
190
    passwdEdit->selectAll();
 
191
}
 
192
 
 
193
void // virtual
 
194
KClassicGreeter::setEnabled(bool enable)
 
195
{
 
196
    // assert(!passwd1Label);
 
197
    // assert(func == Authenticate && ctx == Shutdown);
 
198
//    if (loginLabel)
 
199
//        loginLabel->setEnabled(enable);
 
200
    passwdLabel->setEnabled(enable);
 
201
    setActive(enable);
 
202
    if (enable)
 
203
        passwdEdit->setFocus();
 
204
}
 
205
 
 
206
void // private
 
207
KClassicGreeter::returnData()
 
208
{
 
209
    switch (exp) {
 
210
    case 0:
 
211
        handler->gplugReturnText((loginEdit ? loginEdit->text() :
 
212
                                              fixedUser).toLocal8Bit(),
 
213
                                 KGreeterPluginHandler::IsUser);
 
214
        break;
 
215
    case 1:
 
216
        Q_ASSERT(passwdEdit);
 
217
        handler->gplugReturnText(passwdEdit->text().toLocal8Bit() ,
 
218
                                 KGreeterPluginHandler::IsPassword |
 
219
                                 KGreeterPluginHandler::IsSecret);
 
220
        break;
 
221
    case 2:
 
222
        Q_ASSERT(passwd1Edit);
 
223
        handler->gplugReturnText(passwd1Edit->text().toLocal8Bit(),
 
224
                                 KGreeterPluginHandler::IsSecret);
 
225
        break;
 
226
    default: // case 3:
 
227
        Q_ASSERT(passwd2Edit);
 
228
        handler->gplugReturnText(passwd2Edit->text().toLocal8Bit(),
 
229
                                 KGreeterPluginHandler::IsNewPassword |
 
230
                                 KGreeterPluginHandler::IsSecret);
 
231
        break;
 
232
    }
 
233
}
 
234
 
 
235
bool // virtual
 
236
KClassicGreeter::textMessage(const char *text, bool err)
 
237
{
 
238
    if (!err &&
 
239
        QString(text).indexOf(QRegExp("^Changing password for [^ ]+$")) >= 0)
 
240
        return true;
 
241
    return false;
 
242
}
 
243
 
 
244
void // virtual
 
245
KClassicGreeter::textPrompt(const char *prompt, bool echo, bool nonBlocking)
 
246
{
 
247
    pExp = exp;
 
248
    if (echo) {
 
249
        exp = 0;
 
250
    } else if (!authTok) {
 
251
        exp = 1;
 
252
    } else {
 
253
        QString pr(prompt);
 
254
        if (pr.indexOf(QRegExp("\\bpassword\\b", Qt::CaseInsensitive)) >= 0) {
 
255
            if (pr.indexOf(QRegExp("\\b(re-?(enter|type)|again|confirm|repeat)\\b",
 
256
                                   Qt::CaseInsensitive)) >= 0) {
 
257
                exp = 3;
 
258
            } else if (pr.indexOf(QRegExp("\\bnew\\b", Qt::CaseInsensitive)) >= 0) {
 
259
                exp = 2;
 
260
            } else { // QRegExp("\\b(old|current)\\b", Qt::CaseInsensitive) is too strict
 
261
                handler->gplugReturnText("", KGreeterPluginHandler::IsOldPassword |
 
262
                                             KGreeterPluginHandler::IsSecret);
 
263
                return;
 
264
            }
 
265
        } else {
 
266
            handler->gplugMsgBox(QMessageBox::Critical,
 
267
                                 i18n("Unrecognized prompt \"%1\"", prompt));
 
268
            handler->gplugReturnText(0, 0);
 
269
            exp = -1;
 
270
            return;
 
271
        }
 
272
    }
 
273
 
 
274
    if (pExp >= 0 && pExp >= exp) {
 
275
        revive();
 
276
        has = -1;
 
277
    }
 
278
 
 
279
    if (has >= exp || nonBlocking)
 
280
        returnData();
 
281
}
 
282
 
 
283
bool // virtual
 
284
KClassicGreeter::binaryPrompt(const char *, bool)
 
285
{
 
286
    // this simply cannot happen ... :}
 
287
    return true;
 
288
}
 
289
 
 
290
void // virtual
 
291
KClassicGreeter::start()
 
292
{
 
293
    authTok = !(passwdEdit && passwdEdit->isEnabled());
 
294
    exp = has = -1;
 
295
    running = true;
 
296
}
 
297
 
 
298
void // virtual
 
299
KClassicGreeter::suspend()
 
300
{
 
301
}
 
302
 
 
303
void // virtual
 
304
KClassicGreeter::resume()
 
305
{
 
306
}
 
307
 
 
308
void // virtual
 
309
KClassicGreeter::next()
 
310
{
 
311
    // assert(running);
 
312
    int pHas = has;
 
313
    if (loginEdit && loginEdit->hasFocus()) {
 
314
        passwdEdit->setFocus(); // will cancel running login if necessary
 
315
        has = 0;
 
316
    } else if (passwdEdit && passwdEdit->hasFocus()) {
 
317
        if (passwd1Edit)
 
318
            passwd1Edit->setFocus();
 
319
        has = 1;
 
320
    } else if (passwd1Edit) {
 
321
        if (passwd1Edit->hasFocus()) {
 
322
            passwd2Edit->setFocus();
 
323
            has = 1; // sic!
 
324
        } else {
 
325
            has = 3;
 
326
        }
 
327
    } else {
 
328
        has = 1;
 
329
    }
 
330
    if (exp < 0)
 
331
        handler->gplugStart();
 
332
    else if (has >= exp && has > pHas)
 
333
        returnData();
 
334
}
 
335
 
 
336
void // virtual
 
337
KClassicGreeter::abort()
 
338
{
 
339
    running = false;
 
340
    if (exp >= 0) {
 
341
        exp = -1;
 
342
        handler->gplugReturnText(0, 0);
 
343
    }
 
344
}
 
345
 
 
346
void // virtual
 
347
KClassicGreeter::succeeded()
 
348
{
 
349
    // assert(running || timed_login);
 
350
    if (!authTok) {
 
351
        setActive(false);
 
352
        if (passwd1Edit) {
 
353
            authTok = true;
 
354
            return;
 
355
        }
 
356
    } else {
 
357
        setActive2(false);
 
358
    }
 
359
    exp = -1;
 
360
    running = false;
 
361
}
 
362
 
 
363
void // virtual
 
364
KClassicGreeter::failed()
 
365
{
 
366
    // assert(running || timed_login);
 
367
    setActive(false);
 
368
    setActive2(false);
 
369
    exp = -1;
 
370
    running = false;
 
371
}
 
372
 
 
373
void // virtual
 
374
KClassicGreeter::revive()
 
375
{
 
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();
 
392
        }
 
393
    }
 
394
}
 
395
 
 
396
void // virtual
 
397
KClassicGreeter::clear()
 
398
{
 
399
    // assert(!running && !passwd1Edit);
 
400
    passwdEdit->clear();
 
401
    if (loginEdit) {
 
402
        loginEdit->clear();
 
403
        loginEdit->setFocus();
 
404
        curUser.clear();
 
405
    } else {
 
406
        passwdEdit->setFocus();
 
407
    }
 
408
}
 
409
 
 
410
 
 
411
// private
 
412
 
 
413
void
 
414
KClassicGreeter::setActive(bool enable)
 
415
{
 
416
    if (loginEdit)
 
417
        loginEdit->setEnabled(enable);
 
418
    if (passwdEdit)
 
419
        passwdEdit->setEnabled(enable);
 
420
}
 
421
 
 
422
void
 
423
KClassicGreeter::setActive2(bool enable)
 
424
{
 
425
    if (passwd1Edit) {
 
426
        passwd1Edit->setEnabled(enable);
 
427
        passwd2Edit->setEnabled(enable);
 
428
    }
 
429
}
 
430
 
 
431
void
 
432
KClassicGreeter::slotLoginLostFocus()
 
433
{
 
434
    if (!running)
 
435
        return;
 
436
    loginEdit->setText(loginEdit->text().trimmed());
 
437
    if (exp > 0) {
 
438
        if (curUser == loginEdit->text())
 
439
            return;
 
440
        exp = -1;
 
441
        handler->gplugReturnText(0, 0);
 
442
    }
 
443
    curUser = loginEdit->text();
 
444
    handler->gplugSetUser(curUser);
 
445
}
 
446
 
 
447
void
 
448
KClassicGreeter::slotChanged()
 
449
{
 
450
    if (running)
 
451
        handler->gplugChanged();
 
452
}
 
453
 
 
454
// factory
 
455
 
 
456
static bool init(const QString &,
 
457
                 QVariant(*getConf)(void *, const char *, const QVariant &),
 
458
                 void *ctx)
 
459
{
 
460
    echoMode = getConf(ctx, "EchoPasswd", QVariant(-1)).toInt();
 
461
    KGlobal::locale()->insertCatalog("kgreet_classic");
 
462
    return true;
 
463
}
 
464
 
 
465
static void done(void)
 
466
{
 
467
    KGlobal::locale()->removeCatalog("kgreet_classic");
 
468
}
 
469
 
 
470
static KGreeterPlugin *
 
471
create(KGreeterPluginHandler *handler,
 
472
       QWidget *parent,
 
473
       const QString &fixedEntity,
 
474
       KGreeterPlugin::Function func,
 
475
       KGreeterPlugin::Context ctx)
 
476
{
 
477
    return new KClassicGreeter(handler, parent, fixedEntity, func, ctx);
 
478
}
 
479
 
 
480
KDE_EXPORT KGreeterPluginInfo kgreeterplugin_info = {
 
481
    I18N_NOOP2("@item:inmenu authentication method", "Username + password (classic)"), "classic",
 
482
    KGreeterPluginInfo::Local | KGreeterPluginInfo::Presettable,
 
483
    init, done, create
 
484
};
 
485
 
 
486
#include "kgreet_classic.moc"