diff --git a/doomsday/libshell/include/de/shell/lineeditwidget.h b/doomsday/libshell/include/de/shell/lineeditwidget.h index 87fbc8a160..35a808d996 100644 --- a/doomsday/libshell/include/de/shell/lineeditwidget.h +++ b/doomsday/libshell/include/de/shell/lineeditwidget.h @@ -67,6 +67,18 @@ class LIBSHELL_PUBLIC LineEditWidget : public TextWidget */ void setLexicon(Lexicon const &lexicon); + enum EchoMode + { + NormalEchoMode, + PasswordEchoMode + }; + + /** + * Determines how the entered text is drawn on screen. + * @param mode Echo mode. + */ + void setEchoMode(EchoMode mode); + /** * Enables or disables the signal emitted when the edit widget receives an * Enter key. By default, a signal is emitted. diff --git a/doomsday/libshell/include/de/shell/protocol.h b/doomsday/libshell/include/de/shell/protocol.h index 6c620f3419..a617162df0 100644 --- a/doomsday/libshell/include/de/shell/protocol.h +++ b/doomsday/libshell/include/de/shell/protocol.h @@ -163,6 +163,8 @@ class LIBSHELL_PUBLIC Protocol : public de::Protocol */ static PacketType recognize(Packet const *packet); + static Block passwordResponse(String const &plainPassword); + /** * Constructs a console command packet. * diff --git a/doomsday/libshell/src/lineeditwidget.cpp b/doomsday/libshell/src/lineeditwidget.cpp index 85319167bf..ea3cfbdf83 100644 --- a/doomsday/libshell/src/lineeditwidget.cpp +++ b/doomsday/libshell/src/lineeditwidget.cpp @@ -36,6 +36,7 @@ DENG2_PIMPL(LineEditWidget) String text; int cursor; ///< Index in range [0...text.size()] Lexicon lexicon; + EchoMode echoMode; struct Completion { int pos; @@ -58,7 +59,8 @@ DENG2_PIMPL(LineEditWidget) Instance(Public &i) : Base(i), signalOnEnter(true), - cursor(0) + cursor(0), + echoMode(NormalEchoMode) { // Initial height of the command line (1 row). height = new ConstantRule(1); @@ -344,7 +346,14 @@ void LineEditWidget::draw() { buf.setRichFormatRange(TextCanvas::Char::Underline, d->completion.range()); } - buf.drawWrappedText(Vector2i(d->prompt.size(), 0), d->text, d->wraps, attr); + + // Echo mode determines what we actually draw. + String text = d->text; + if(d->echoMode == PasswordEchoMode) + { + text = String(d->text.size(), '*'); + } + buf.drawWrappedText(Vector2i(d->prompt.size(), 0), text, d->wraps, attr); targetCanvas().draw(buf, pos.topLeft); } @@ -480,6 +489,11 @@ void LineEditWidget::setLexicon(Lexicon const &lexicon) d->lexicon = lexicon; } +void LineEditWidget::setEchoMode(EchoMode mode) +{ + d->echoMode = mode; +} + void LineEditWidget::setSignalOnEnter(int enterSignal) { d->signalOnEnter = enterSignal; diff --git a/doomsday/libshell/src/protocol.cpp b/doomsday/libshell/src/protocol.cpp index bb845a9ff3..37c41c97ed 100644 --- a/doomsday/libshell/src/protocol.cpp +++ b/doomsday/libshell/src/protocol.cpp @@ -22,6 +22,7 @@ #include #include #include +#include #include namespace de { @@ -234,6 +235,15 @@ Protocol::PacketType Protocol::recognize(Packet const *packet) return Unknown; } +Block Protocol::passwordResponse(String const &plainPassword) +{ + Block response; + response.append("Shell"); + response += QCryptographicHash::hash(plainPassword.toUtf8(), + QCryptographicHash::Sha1); + return response; +} + RecordPacket *Protocol::newCommand(String const &command) { RecordPacket *cmd = new RecordPacket(PT_COMMAND);