#include <QMessageBox>
#include <QPushButton>
+#include <QKeyEvent>
AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
QDialog(parent),
ui(new Ui::AskPassphraseDialog),
mode(mode),
- model(0)
+ model(0),
+ fCapsLock(false)
{
ui->setupUi(this);
ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE);
ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE);
ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE);
+
+ // Setup Caps Lock detection.
+ ui->passEdit1->installEventFilter(this);
+ ui->passEdit2->installEventFilter(this);
+ ui->passEdit3->installEventFilter(this);
+ ui->capsLabel->clear();
switch(mode)
{
ui->warningLabel->setText(tr("Enter the old and new passphrase to the wallet."));
break;
}
- resize(minimumSize()); // Get rid of extra space in dialog
textChanged();
connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
void AskPassphraseDialog::accept()
{
- std::string oldpass, newpass1, newpass2;
+ SecureString oldpass, newpass1, newpass2;
if(!model)
return;
- // TODO: mlock memory / munlock on return so they will not be swapped out, really need "mlockedstring" wrapper class to do this safely
oldpass.reserve(MAX_PASSPHRASE_SIZE);
newpass1.reserve(MAX_PASSPHRASE_SIZE);
newpass2.reserve(MAX_PASSPHRASE_SIZE);
- oldpass.assign(ui->passEdit1->text().toStdString());
- newpass1.assign(ui->passEdit2->text().toStdString());
- newpass2.assign(ui->passEdit3->text().toStdString());
+ // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
+ // Alternately, find a way to make this input mlock()'d to begin with.
+ oldpass.assign(ui->passEdit1->text().toStdString().c_str());
+ newpass1.assign(ui->passEdit2->text().toStdString().c_str());
+ newpass2.assign(ui->passEdit3->text().toStdString().c_str());
switch(mode)
{
if(model->setWalletEncrypted(true, newpass1))
{
QMessageBox::warning(this, tr("Wallet encrypted"),
- tr("Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer."));
+ tr("Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer."));
+ QApplication::quit();
}
else
{
}
ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(acceptable);
}
+
+bool AskPassphraseDialog::event(QEvent *event)
+{
+ // Detect Caps Lock key press.
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(event);
+ if (ke->key() == Qt::Key_CapsLock) {
+ fCapsLock = !fCapsLock;
+ }
+ if (fCapsLock) {
+ ui->capsLabel->setText(tr("Warning: The Caps Lock key is on."));
+ } else {
+ ui->capsLabel->clear();
+ }
+ }
+ return QWidget::event(event);
+}
+
+bool AskPassphraseDialog::eventFilter(QObject *, QEvent *event)
+{
+ /* Detect Caps Lock.
+ * There is no good OS-independent way to check a key state in Qt, but we
+ * can detect Caps Lock by checking for the following condition:
+ * Shift key is down and the result is a lower case character, or
+ * Shift key is not down and the result is an upper case character.
+ */
+ if (event->type() == QEvent::KeyPress) {
+ QKeyEvent *ke = static_cast<QKeyEvent *>(event);
+ QString str = ke->text();
+ if (str.length() != 0) {
+ const QChar *psz = str.unicode();
+ bool fShift = (ke->modifiers() & Qt::ShiftModifier) != 0;
+ if ((fShift && psz->isLower()) || (!fShift && psz->isUpper())) {
+ fCapsLock = true;
+ ui->capsLabel->setText(tr("Warning: The Caps Lock key is on."));
+ } else if (psz->isLetter()) {
+ fCapsLock = false;
+ ui->capsLabel->clear();
+ }
+ }
+ }
+ return false;
+}