/* Conversation widget for kdm greeter Copyright (C) 2008 Dirk Mueller Copyright (C) 2008 Oswald Buddenhagen based on classic kdm greeter: Copyright (C) 1997, 1998, 2000 Steffen Hansen Copyright (C) 2000-2003 Oswald Buddenhagen 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 #include #include #include #include #include #include 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 = ""; foreach (const QString &msg, m_infoMsgs) text += "

" + Qt::escape(msg) + "

"; text += "
"; 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(); } // 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"