#include "ui_askpassphrasedialog.h"
#include "guiconstants.h"
+#include "dialogwindowflags.h"
#include "walletmodel.h"
#include <QMessageBox>
#include <QPushButton>
+#include <QKeyEvent>
+
+extern bool fWalletUnlockMintOnly;
AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
- QDialog(parent),
+ QDialog(parent, DIALOGWINDOWHINTS),
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);
+
switch(mode)
{
case Encrypt: // Ask passphrase x2
setWindowTitle(tr("Encrypt wallet"));
break;
case Unlock: // Ask passphrase
+ case UnlockMining:
ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet."));
ui->passLabel2->hide();
ui->passEdit2->hide();
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)
{
break;
}
QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm wallet encryption"),
- tr("WARNING: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR BITCOINS</b>!\nAre you sure you wish to encrypt your wallet?"),
+ tr("Warning: If you encrypt your wallet and lose your passphrase, you will <b>LOSE ALL OF YOUR COINS</b>!") + "<br><br>" + tr("Are you sure you wish to encrypt your wallet?"),
QMessageBox::Yes|QMessageBox::Cancel,
QMessageBox::Cancel);
if(retval == QMessageBox::Yes)
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."));
+ "<qt>" +
+ tr("NovaCoin will close now to finish the encryption process. "
+ "Remember that encrypting your wallet cannot fully protect "
+ "your coins from being stolen by malware infecting your computer.") +
+ "<br><br><b>" +
+ tr("IMPORTANT: Any previous backups you have made of your wallet file "
+ "should be replaced with the newly generated, encrypted wallet file. "
+ "For security reasons, previous backups of the unencrypted wallet file "
+ "will become useless as soon as you start using the new, encrypted wallet.") +
+ "</b></qt>");
+ QApplication::quit();
}
else
{
QDialog::accept(); // Success
}
break;
+ case UnlockMining:
+ if(!model->setWalletLocked(false, oldpass))
+ {
+ QMessageBox::critical(this, tr("Wallet unlock failed"),
+ tr("The passphrase entered for the wallet decryption was incorrect."));
+ }
+ else
+ {
+ QDialog::accept(); // Success
+ fWalletUnlockMintOnly = true;
+ }
+ break;
case Decrypt:
if(!model->setWalletEncrypted(false, oldpass))
{
}
else
{
- QDialog::accept(); // Success
+ QMessageBox::warning(this, tr("Wallet decrypted"),
+ "<qt>" +
+ tr("NovaCoin will close now to finish the decryption process. ") +
+ "</b></qt>");
+ QApplication::quit();
}
break;
case ChangePass:
if(model->changePassphrase(oldpass, newpass1))
{
QMessageBox::information(this, tr("Wallet encrypted"),
- tr("Wallet passphrase was succesfully changed."));
+ tr("Wallet passphrase was successfully changed."));
QDialog::accept(); // Success
}
else
void AskPassphraseDialog::textChanged()
{
- // Validate input, set Ok button to enabled when accepable
+ // Validate input, set Ok button to enabled when acceptable
bool acceptable = false;
switch(mode)
{
acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
break;
case Unlock: // Old passphrase x1
+ case UnlockMining:
case Decrypt:
acceptable = !ui->passEdit1->text().isEmpty();
break;
}
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 *object, 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 QDialog::eventFilter(object, event);
+}