kde-workspace/libs/kdm/kgreet_generic.cpp
2015-02-27 09:28:46 +00:00

355 lines
9 KiB
C++

/*
Conversation widget for kdm greeter
Copyright (C) 2008 Dirk Mueller <mueller@kde.org>
Copyright (C) 2008 Oswald Buddenhagen <ossi@kde.org>
based on classic kdm greeter:
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "kgreet_generic.h"
#include <kglobal.h>
#include <klocale.h>
#include <klineedit.h>
#include <kuser.h>
#include <QLayout>
#include <QLabel>
#include <QTextDocument>
extern KDE_EXPORT KGreeterPluginInfo kgreeterplugin_info; // defined at bottom
static int echoMode;
class KDMPasswordEdit : public KLineEdit {
public:
KDMPasswordEdit(QWidget *parent = 0) : KLineEdit(parent)
{
if (::echoMode == -1)
setPasswordMode(true);
else
setEchoMode(::echoMode ? Password : NoEcho);
setContextMenuPolicy(Qt::NoContextMenu);
}
};
KGenericGreeter::KGenericGreeter(KGreeterPluginHandler *_handler,
QWidget *parent,
const QString &_fixedEntity,
Function _func, Context _ctx) :
QObject(),
KGreeterPlugin(_handler),
m_lineEdit(0),
fixedUser(_fixedEntity),
func(_func),
ctx(_ctx),
exp(-1),
running(false)
{
m_parentWidget = new QWidget(parent);
m_parentWidget->setObjectName("talker");
// XXX set some minimal size
widgetList << m_parentWidget;
m_grid = new QGridLayout(m_parentWidget);
m_grid->setMargin(0);
if (ctx == ExUnlock || ctx == ExChangeTok)
fixedUser = KUser().loginName();
}
// virtual
KGenericGreeter::~KGenericGreeter()
{
abort();
delete m_parentWidget;
}
void // virtual
KGenericGreeter::loadUsers(const QStringList &users)
{
m_users = users;
}
void // virtual
KGenericGreeter::presetEntity(const QString &entity, int /* field */)
{
// assert(!running);
curUser = entity;
}
QString // virtual
KGenericGreeter::getEntity() const
{
return fixedUser.isEmpty() ? curUser : fixedUser;
}
void // virtual
KGenericGreeter::setUser(const QString &user)
{
// assert(running);
// assert(fixedUser.isEmpty());
if (!(kgreeterplugin_info.flags & KGreeterPluginInfo::Presettable))
return; // Not interested in PAM telling us who logged in
if (exp) {
abort();
start();
}
curUser = user;
if (m_lineEdit) { // could be null if plugin is misconfigured
m_lineEdit->setText(user);
m_lineEdit->selectAll();
m_lineEdit->setFocus();
}
}
void // virtual
KGenericGreeter::setEnabled(bool enable)
{
// assert(func == Authenticate && ctx == Shutdown);
// XXX this is likely to bear some bogosity
foreach (QWidget *w, m_children)
w->setEnabled(enable);
if (enable && m_lineEdit)
m_lineEdit->setFocus();
}
bool // virtual
KGenericGreeter::textMessage(const char *text, bool err)
{
if (err)
return false;
if (m_infoMsgs.isEmpty())
revive();
QString qtext = QString::fromUtf8(text);
m_infoMsgs.append(qtext);
QLabel *label = new QLabel(qtext, m_parentWidget);
m_grid->addWidget(label, m_line++, 0, 1, 2);
m_children.append(label);
return true;
}
void // virtual
KGenericGreeter::textPrompt(const char *prompt, bool echo, bool /* nonBlocking */)
{
exp =
exp >= 0 ||
func != Authenticate ||
!(kgreeterplugin_info.flags & KGreeterPluginInfo::Presettable);
if (!exp && !fixedUser.isEmpty()) {
handler->gplugReturnText(fixedUser.toLocal8Bit(),
KGreeterPluginHandler::IsUser);
return;
}
if (m_infoMsgs.isEmpty())
revive();
else
m_infoMsgs.clear();
QLabel *label = new QLabel(QString::fromUtf8(prompt).trimmed());
m_grid->addWidget(label, m_line, 0);
m_children.append(label);
m_echo = echo;
if (echo) {
m_lineEdit = new KLineEdit;
m_lineEdit->setContextMenuPolicy(Qt::NoContextMenu);
if (!exp) {
if (!m_users.isEmpty()) {
KCompletion *userNamesCompletion = new KCompletion;
userNamesCompletion->setItems(m_users);
m_lineEdit->setCompletionObject(userNamesCompletion);
m_lineEdit->setAutoDeleteCompletionObject(true);
m_lineEdit->setCompletionMode(KGlobalSettings::CompletionAuto);
}
if (!curUser.isEmpty()) {
m_lineEdit->setText(curUser);
m_lineEdit->selectAll();
connect(m_lineEdit, SIGNAL(selectionChanged()), SLOT(slotChanged()));
}
connect(m_lineEdit, SIGNAL(editingFinished()), SLOT(slotLoginLostFocus()));
}
connect(m_lineEdit, SIGNAL(editingFinished()), SLOT(slotChanged()));
connect(m_lineEdit, SIGNAL(textChanged(QString)), SLOT(slotChanged()));
} else {
m_lineEdit = new KDMPasswordEdit;
}
m_lineEdit->setMinimumWidth(
m_lineEdit->fontMetrics().width("This is a long password"));
m_grid->addWidget(m_lineEdit, m_line, 1);
m_children.append(m_lineEdit);
m_lineEdit->show();
m_lineEdit->setFocus();
}
bool // virtual
KGenericGreeter::binaryPrompt(const char *, bool)
{
// FIXME
return true;
}
void // virtual
KGenericGreeter::start()
{
exp = -1;
running = true;
handler->gplugStart();
}
void // virtual
KGenericGreeter::suspend()
{
}
void // virtual
KGenericGreeter::resume()
{
}
void // virtual
KGenericGreeter::next()
{
if (m_lineEdit) {
m_lineEdit->setEnabled(false);
QString text = m_lineEdit->text();
m_lineEdit = 0;
handler->gplugReturnText(text.toLocal8Bit(),
!m_echo ?
KGreeterPluginHandler::IsSecret :
!exp ?
KGreeterPluginHandler::IsUser : 0);
}
}
void // virtual
KGenericGreeter::abort()
{
running = false;
if (exp >= 0) {
exp = -1;
handler->gplugReturnText(0, 0);
}
}
void // virtual
KGenericGreeter::succeeded()
{
failed(); // redefining terms :-D
}
void // virtual
KGenericGreeter::failed()
{
// assert(running || timed_login);
if (!m_infoMsgs.isEmpty()) {
QString text = "<qt>";
foreach (const QString &msg, m_infoMsgs)
text += "<p>" + Qt::escape(msg) + "</p>";
text += "</qt>";
revive();
handler->gplugMsgBox(QMessageBox::Information, text);
} else {
foreach (QWidget *w, m_children)
w->setEnabled(false);
}
exp = -1;
running = false;
}
void // virtual
KGenericGreeter::revive()
{
// assert(!running);
foreach (QWidget *w, m_children)
w->deleteLater();
m_children.clear();
m_infoMsgs.clear();
m_lineEdit = 0;
m_line = 0;
}
void // virtual
KGenericGreeter::clear()
{
// assert(!running && !passwd1Edit);
revive();
curUser = QString::null;
}
// private
void
KGenericGreeter::slotLoginLostFocus()
{
m_lineEdit->setText(m_lineEdit->text().trimmed());
if (curUser != m_lineEdit->text()) {
curUser = m_lineEdit->text();
handler->gplugSetUser(curUser);
}
}
void
KGenericGreeter::slotChanged()
{
handler->gplugChanged();
}
// factory
static bool init(const QString &,
QVariant(*getConf)(void *, const char *, const QVariant &),
void *ctx)
{
echoMode = getConf(ctx, "EchoMode", QVariant(-1)).toInt();
// Fielded entities are not supported per se.
// This implies that the first field is the presettable entity, if any.
if (getConf(ctx, "generic.Presettable", QVariant(false)).toBool())
kgreeterplugin_info.flags |= KGreeterPluginInfo::Presettable;
KGlobal::locale()->insertCatalog("kgreet_generic");
return true;
}
static void done(void)
{
KGlobal::locale()->removeCatalog("kgreet_generic");
}
static KGreeterPlugin *
create(KGreeterPluginHandler *handler,
QWidget *parent,
const QString &fixedEntity,
KGreeterPlugin::Function func,
KGreeterPlugin::Context ctx)
{
return new KGenericGreeter(handler, parent, fixedEntity, func, ctx);
}
KDE_EXPORT KGreeterPluginInfo kgreeterplugin_info = {
I18N_NOOP2("@item:inmenu authentication method", "Generic"), "generic",
KGreeterPluginInfo::Local,
init, done, create
};
#include "moc_kgreet_generic.cpp"