aboutsummaryrefslogtreecommitdiffstats
path: root/src/m_pinentry/pinentrydialog.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/m_pinentry/pinentrydialog.cpp')
-rw-r--r--src/m_pinentry/pinentrydialog.cpp635
1 files changed, 635 insertions, 0 deletions
diff --git a/src/m_pinentry/pinentrydialog.cpp b/src/m_pinentry/pinentrydialog.cpp
new file mode 100644
index 0000000..dcfdd50
--- /dev/null
+++ b/src/m_pinentry/pinentrydialog.cpp
@@ -0,0 +1,635 @@
+/* pinentrydialog.cpp - A (not yet) secure Qt 4 dialog for PIN entry.
+ * Copyright (C) 2002, 2008 Klarälvdalens Datakonsult AB (KDAB)
+ * Copyright 2007 Ingo Klöcker
+ * Copyright 2016 Intevation GmbH
+ * Copyright (C) 2021, 2022 g10 Code GmbH
+ *
+ * Written by Steffen Hansen <[email protected]>.
+ * Modified by Andre Heinecke <[email protected]>
+ * Software engineering by Ingo Klöcker <[email protected]>
+ *
+ * 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, see <https://www.gnu.org/licenses/>.
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "pinentrydialog.h"
+
+#include <qnamespace.h>
+
+#include <QAccessible>
+#include <QAction>
+#include <QApplication>
+#include <QCheckBox>
+#include <QDebug>
+#include <QDialogButtonBox>
+#include <QFontMetrics>
+#include <QGridLayout>
+#include <QHBoxLayout>
+#include <QKeyEvent>
+#include <QLabel>
+#include <QLineEdit>
+#include <QMessageBox>
+#include <QPainter>
+#include <QPalette>
+#include <QProgressBar>
+#include <QPushButton>
+#include <QRegularExpression>
+#include <QStyle>
+#include <QVBoxLayout>
+
+#include "GFModuleCommonUtils.hpp"
+#include "accessibility.h"
+#include "capslock/capslock.h"
+#include "pinentry.h"
+#include "pinlineedit.h"
+
+void raiseWindow(QWidget *w) {
+ w->setWindowState((w->windowState() & ~Qt::WindowMinimized) |
+ Qt::WindowActive);
+ w->activateWindow();
+ w->raise();
+}
+
+auto applicationIconPixmap(const QIcon &overlayIcon) -> QPixmap {
+ QPixmap pm = qApp->windowIcon().pixmap(48, 48);
+
+ if (!overlayIcon.isNull()) {
+ QPainter painter(&pm);
+ const int emblem_size = 22;
+ painter.drawPixmap(pm.width() - emblem_size, 0,
+ overlayIcon.pixmap(emblem_size, emblem_size));
+ }
+
+ return pm;
+}
+
+void PinEntryDialog::slotTimeout() {
+ _timed_out = true;
+ reject();
+}
+
+PinEntryDialog::PinEntryDialog(QWidget *parent, const char *name, int timeout,
+ bool modal, bool enable_quality_bar,
+ const QString &repeatString,
+ const QString &visibilityTT,
+ const QString &hideTT)
+ : QDialog{parent},
+ _have_quality_bar{enable_quality_bar},
+ mVisibilityTT{visibilityTT},
+ mHideTT{hideTT} {
+ Q_UNUSED(name)
+
+ if (modal) {
+ setWindowModality(Qt::ApplicationModal);
+ setModal(true);
+ }
+
+ QPalette red_text_palette;
+ red_text_palette.setColor(QPalette::WindowText, Qt::red);
+
+ auto *const main_layout = new QVBoxLayout{this};
+
+ auto *const hbox = new QHBoxLayout;
+
+ _icon = new QLabel(this);
+ _icon->setPixmap(applicationIconPixmap());
+ hbox->addWidget(_icon, 0, Qt::AlignVCenter | Qt::AlignLeft);
+
+ auto *const grid = new QGridLayout;
+ int row = 1;
+
+ _error = new QLabel{this};
+ _error->setTextFormat(Qt::PlainText);
+ _error->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ _error->setPalette(red_text_palette);
+ _error->hide();
+ grid->addWidget(_error, row, 1, 1, 2);
+
+ row++;
+ _desc = new QLabel{this};
+ _desc->setTextFormat(Qt::PlainText);
+ _desc->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ _desc->hide();
+ grid->addWidget(_desc, row, 1, 1, 2);
+
+ row++;
+ mCapsLockHint = new QLabel{this};
+ mCapsLockHint->setTextFormat(Qt::PlainText);
+ mCapsLockHint->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ mCapsLockHint->setPalette(red_text_palette);
+ mCapsLockHint->setAlignment(Qt::AlignCenter);
+ mCapsLockHint->setVisible(false);
+ grid->addWidget(mCapsLockHint, row, 1, 1, 2);
+
+ row++;
+ {
+ _prompt = new QLabel(this);
+ _prompt->setTextFormat(Qt::PlainText);
+ _prompt->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ _prompt->hide();
+ grid->addWidget(_prompt, row, 1);
+
+ auto *const l = new QHBoxLayout;
+ _edit = new PinLineEdit(this);
+ _edit->setMaxLength(256);
+ _edit->setMinimumWidth(_edit->fontMetrics().averageCharWidth() * 20 + 48);
+ _edit->setEchoMode(QLineEdit::Password);
+ _prompt->setBuddy(_edit);
+ l->addWidget(_edit, 1);
+
+ if (!repeatString.isNull()) {
+ mGenerateButton = new QPushButton{this};
+ mGenerateButton->setIcon(
+ QIcon(QLatin1String(":/icons/password-generate.svg")));
+ mGenerateButton->setVisible(false);
+ l->addWidget(mGenerateButton);
+ }
+ grid->addLayout(l, row, 2);
+ }
+
+ /* Set up the show password action */
+ const QIcon visibility_icon = QIcon(QLatin1String(":/icons/visibility.svg"));
+ const QIcon hide_icon = QIcon(QLatin1String(":/icons/hint.svg"));
+#if QT_VERSION >= 0x050200
+ if (!visibility_icon.isNull() && !hide_icon.isNull()) {
+ mVisiActionEdit =
+ _edit->addAction(visibility_icon, QLineEdit::TrailingPosition);
+ mVisiActionEdit->setVisible(false);
+ mVisiActionEdit->setToolTip(mVisibilityTT);
+ } else
+#endif
+ {
+ if (!mVisibilityTT.isNull()) {
+ row++;
+ mVisiCB = new QCheckBox{mVisibilityTT, this};
+ grid->addWidget(mVisiCB, row, 1, 1, 2, Qt::AlignLeft);
+ }
+ }
+
+ row++;
+ mConstraintsHint = new QLabel{this};
+ mConstraintsHint->setTextFormat(Qt::PlainText);
+ mConstraintsHint->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ mConstraintsHint->setVisible(false);
+ grid->addWidget(mConstraintsHint, row, 2);
+
+ row++;
+ mFormattedPassphraseHintSpacer = new QLabel{this};
+ mFormattedPassphraseHintSpacer->setVisible(false);
+ mFormattedPassphraseHint = new QLabel{this};
+ mFormattedPassphraseHint->setTextFormat(Qt::PlainText);
+ mFormattedPassphraseHint->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ mFormattedPassphraseHint->setVisible(false);
+ grid->addWidget(mFormattedPassphraseHintSpacer, row, 1);
+ grid->addWidget(mFormattedPassphraseHint, row, 2);
+
+ if (!repeatString.isNull()) {
+ row++;
+ auto *repeat_label = new QLabel{this};
+ repeat_label->setTextFormat(Qt::PlainText);
+ repeat_label->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ repeat_label->setText(repeatString);
+ grid->addWidget(repeat_label, row, 1);
+
+ mRepeat = new PinLineEdit(this);
+ mRepeat->setMaxLength(256);
+ mRepeat->setEchoMode(QLineEdit::Password);
+ repeat_label->setBuddy(mRepeat);
+ grid->addWidget(mRepeat, row, 2);
+
+ row++;
+ mRepeatError = new QLabel{this};
+ mRepeatError->setTextFormat(Qt::PlainText);
+ mRepeatError->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ mRepeatError->setPalette(red_text_palette);
+ mRepeatError->hide();
+ grid->addWidget(mRepeatError, row, 2);
+ }
+
+ if (enable_quality_bar) {
+ row++;
+ _quality_bar_label = new QLabel(this);
+ _quality_bar_label->setTextFormat(Qt::PlainText);
+ _quality_bar_label->setTextInteractionFlags(Qt::TextSelectableByMouse);
+ _quality_bar_label->setAlignment(Qt::AlignVCenter);
+ grid->addWidget(_quality_bar_label, row, 1);
+
+ _quality_bar = new QProgressBar(this);
+ _quality_bar->setAlignment(Qt::AlignCenter);
+ _quality_bar_label->setBuddy(_quality_bar);
+ grid->addWidget(_quality_bar, row, 2);
+ }
+
+ hbox->addLayout(grid, 1);
+ main_layout->addLayout(hbox);
+
+ auto *const buttons = new QDialogButtonBox(this);
+ buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
+ _ok = buttons->button(QDialogButtonBox::Ok);
+ _cancel = buttons->button(QDialogButtonBox::Cancel);
+
+ if (style()->styleHint(QStyle::SH_DialogButtonBox_ButtonsHaveIcons)) {
+ _ok->setIcon(style()->standardIcon(QStyle::SP_DialogOkButton));
+ _cancel->setIcon(style()->standardIcon(QStyle::SP_DialogCancelButton));
+ }
+
+ main_layout->addStretch(1);
+ main_layout->addWidget(buttons);
+ main_layout->setSizeConstraint(QLayout::SetFixedSize);
+
+ if (timeout > 0) {
+ _timer = new QTimer(this);
+ connect(_timer, &QTimer::timeout, this, &PinEntryDialog::slotTimeout);
+ _timer->start(timeout * 1000);
+ }
+
+ connect(buttons, &QDialogButtonBox::accepted, this,
+ &PinEntryDialog::onAccept);
+ connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
+ connect(_edit, &QLineEdit::textChanged, this, &PinEntryDialog::updateQuality);
+ connect(_edit, &QLineEdit::textChanged, this, &PinEntryDialog::textChanged);
+ connect(_edit, &PinLineEdit::backspacePressed, this,
+ &PinEntryDialog::onBackspace);
+ if (mGenerateButton != nullptr) {
+ connect(mGenerateButton, &QPushButton::clicked, this,
+ &PinEntryDialog::generatePin);
+ }
+ if (mVisiActionEdit != nullptr) {
+ connect(mVisiActionEdit, &QAction::triggered, this,
+ &PinEntryDialog::toggleVisibility);
+ }
+ if (mVisiCB != nullptr) {
+ connect(mVisiCB, &QCheckBox::toggled, this,
+ &PinEntryDialog::toggleVisibility);
+ }
+ if (mRepeat != nullptr) {
+ connect(mRepeat, &QLineEdit::textChanged, this,
+ &PinEntryDialog::textChanged);
+ }
+
+ auto *caps_lock_watcher = new CapsLockWatcher{this};
+ connect(caps_lock_watcher, &CapsLockWatcher::stateChanged, this,
+ [this](bool locked) { mCapsLockHint->setVisible(locked); });
+
+ connect(qApp, &QApplication::focusChanged, this,
+ &PinEntryDialog::focusChanged);
+ connect(qApp, &QApplication::applicationStateChanged, this,
+ &PinEntryDialog::checkCapsLock);
+ checkCapsLock();
+
+ setAttribute(Qt::WA_DeleteOnClose);
+ setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint);
+
+ /* This is mostly an issue on Windows where this results
+ in the pinentry popping up nicely with an animation and
+ comes to front. It is not ifdefed for Windows only since
+ window managers on Linux like KWin can also have this
+ result in an animation when the pinentry is shown and
+ not just popping it up.
+ */
+ if (qApp->platformName() != QLatin1String("wayland")) {
+ setWindowState(Qt::WindowMinimized);
+ QTimer::singleShot(0, this, [this]() { raiseWindow(this); });
+ } else {
+ raiseWindow(this);
+ }
+}
+
+void PinEntryDialog::keyPressEvent(QKeyEvent *e) {
+ const auto return_pressed =
+ (!e->modifiers() &&
+ (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return)) ||
+ (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter);
+ if (return_pressed && _edit->hasFocus() && (mRepeat != nullptr)) {
+ // if the user pressed Return in the first input field, then move the
+ // focus to the repeat input field and prevent further event processing
+ // by QDialog (which would trigger the default button)
+ mRepeat->setFocus();
+ e->ignore();
+ return;
+ }
+
+ QDialog::keyPressEvent(e);
+}
+
+void PinEntryDialog::keyReleaseEvent(QKeyEvent *event) {
+ QDialog::keyReleaseEvent(event);
+ checkCapsLock();
+}
+
+void PinEntryDialog::showEvent(QShowEvent *event) {
+ QDialog::showEvent(event);
+ _edit->setFocus();
+}
+
+void PinEntryDialog::setDescription(const QString &txt) {
+ _desc->setVisible(!txt.isEmpty());
+ _desc->setText(txt);
+ _icon->setPixmap(applicationIconPixmap());
+ setError(QString());
+}
+
+QString PinEntryDialog::description() const { return _desc->text(); }
+
+void PinEntryDialog::setError(const QString &txt) {
+ if (!txt.isNull()) {
+ _icon->setPixmap(
+ applicationIconPixmap(QIcon{QStringLiteral(":/icons/data-error.svg")}));
+ }
+ _error->setText(txt);
+ _error->setVisible(!txt.isEmpty());
+}
+
+QString PinEntryDialog::error() const { return _error->text(); }
+
+void PinEntryDialog::setPin(const QString &txt) { _edit->setPin(txt); }
+
+QString PinEntryDialog::pin() const { return _edit->pin(); }
+
+void PinEntryDialog::setPrompt(const QString &txt) {
+ _prompt->setText(txt);
+ _prompt->setVisible(!txt.isEmpty());
+ if (txt.contains("PIN")) _disable_echo_allowed = false;
+}
+
+QString PinEntryDialog::prompt() const { return _prompt->text(); }
+
+void PinEntryDialog::setOkText(const QString &txt) {
+ _ok->setText(txt);
+ _ok->setVisible(!txt.isEmpty());
+}
+
+void PinEntryDialog::setCancelText(const QString &txt) {
+ _cancel->setText(txt);
+ _cancel->setVisible(!txt.isEmpty());
+}
+
+void PinEntryDialog::setQualityBar(const QString &txt) {
+ if (_have_quality_bar) {
+ _quality_bar_label->setText(txt);
+ }
+}
+
+void PinEntryDialog::setQualityBarTT(const QString &txt) {
+ if (_have_quality_bar) {
+ _quality_bar->setToolTip(txt);
+ }
+}
+
+void PinEntryDialog::setGenpinLabel(const QString &txt) {
+ if (mGenerateButton == nullptr) {
+ return;
+ }
+ mGenerateButton->setVisible(!txt.isEmpty());
+ if (!txt.isEmpty()) {
+ Accessibility::setName(mGenerateButton, txt);
+ }
+}
+
+void PinEntryDialog::setGenpinTT(const QString &txt) {
+ if (mGenerateButton != nullptr) {
+ mGenerateButton->setToolTip(txt);
+ }
+}
+
+void PinEntryDialog::setCapsLockHint(const QString &txt) {
+ mCapsLockHint->setText(txt);
+}
+
+void PinEntryDialog::setFormattedPassphrase(
+ const PinEntryDialog::FormattedPassphraseOptions &options) {
+ mFormatPassphrase = options.formatPassphrase;
+ mFormattedPassphraseHint->setTextFormat(Qt::RichText);
+ mFormattedPassphraseHint->setText(QLatin1String("<html>") +
+ options.hint.toHtmlEscaped() +
+ QLatin1String("</html>"));
+ Accessibility::setName(mFormattedPassphraseHint, options.hint);
+ // toggleFormattedPassphrase();
+}
+
+void PinEntryDialog::setConstraintsOptions(const ConstraintsOptions &options) {
+ mEnforceConstraints = options.enforce;
+ mConstraintsHint->setText(options.shortHint);
+ if (!options.longHint.isEmpty()) {
+ mConstraintsHint->setToolTip(
+ QLatin1String("<html>") +
+ options.longHint.toHtmlEscaped().replace(QLatin1String("\n\n"),
+ QLatin1String("<br>")) +
+ QLatin1String("</html>"));
+ Accessibility::setDescription(mConstraintsHint, options.longHint);
+ }
+ mConstraintsErrorTitle = options.errorTitle;
+
+ mConstraintsHint->setVisible(mEnforceConstraints &&
+ !options.shortHint.isEmpty());
+}
+
+void PinEntryDialog::toggleFormattedPassphrase() {
+ const bool enable_formatting =
+ mFormatPassphrase && _edit->echoMode() == QLineEdit::Normal;
+ _edit->setFormattedPassphrase(enable_formatting);
+ if (mRepeat != nullptr) {
+ mRepeat->setFormattedPassphrase(enable_formatting);
+ const bool hint_about_to_be_hidden =
+ mFormattedPassphraseHint->isVisible() && !enable_formatting;
+ if (hint_about_to_be_hidden) {
+ // set hint spacer to current height of hint label before hiding the hint
+ mFormattedPassphraseHintSpacer->setMinimumHeight(
+ mFormattedPassphraseHint->height());
+ mFormattedPassphraseHintSpacer->setVisible(true);
+ } else if (enable_formatting) {
+ mFormattedPassphraseHintSpacer->setVisible(false);
+ }
+ mFormattedPassphraseHint->setVisible(enable_formatting);
+ }
+}
+
+void PinEntryDialog::onBackspace() {
+ cancelTimeout();
+
+ if (_disable_echo_allowed) {
+ _edit->setEchoMode(QLineEdit::NoEcho);
+ if (mRepeat != nullptr) {
+ mRepeat->setEchoMode(QLineEdit::NoEcho);
+ }
+ }
+}
+
+void PinEntryDialog::updateQuality(const QString &txt) {
+ int length;
+ int percent;
+ QPalette pal;
+
+ _disable_echo_allowed = false;
+
+ if (!_have_quality_bar) {
+ return;
+ }
+
+ length = txt.length();
+ percent = length != 0 ? pinentry_inq_quality(txt) : 0;
+ if (length == 0) {
+ _quality_bar->reset();
+ } else {
+ pal = _quality_bar->palette();
+ if (percent < 0) {
+ pal.setColor(QPalette::Highlight, QColor("red"));
+ percent = -percent;
+ } else {
+ pal.setColor(QPalette::Highlight, QColor("green"));
+ }
+ _quality_bar->setPalette(pal);
+ _quality_bar->setValue(percent);
+ }
+}
+
+void PinEntryDialog::setPinentryInfo(struct pinentry peinfo) {
+ _pinentry_info = SecureCreateQSharedObject<struct pinentry>(peinfo);
+}
+
+void PinEntryDialog::focusChanged(QWidget *old, QWidget *now) {
+ // Grab keyboard. It might be a little weird to do it here, but it works!
+ // Previously this code was in showEvent, but that did not work in Qt4.
+ if (!_pinentry_info || (_pinentry_info->grab != 0)) {
+ if (_grabbed && (old != nullptr) && (old == _edit || old == mRepeat)) {
+ old->releaseKeyboard();
+ _grabbed = false;
+ }
+ if (!_grabbed && (now != nullptr) && (now == _edit || now == mRepeat)) {
+ now->grabKeyboard();
+ _grabbed = true;
+ }
+ }
+}
+
+void PinEntryDialog::textChanged(const QString &text) {
+ Q_UNUSED(text);
+
+ cancelTimeout();
+
+ if ((mVisiActionEdit != nullptr) && sender() == _edit) {
+ mVisiActionEdit->setVisible(!_edit->pin().isEmpty());
+ }
+ if (mGenerateButton != nullptr) {
+ mGenerateButton->setVisible(_edit->pin().isEmpty()
+#ifndef QT_NO_ACCESSIBILITY
+ && !mGenerateButton->accessibleName().isEmpty()
+#endif
+ );
+ }
+}
+
+void PinEntryDialog::generatePin() {
+ // std::unique_ptr<char> pin{pinentry_inq_genpin(_pinentry_info.get())};
+ // if (pin) {
+ // if (_edit->echoMode() == QLineEdit::Password) {
+ // if (mVisiActionEdit != nullptr) {
+ // mVisiActionEdit->trigger();
+ // }
+ // if (mVisiCB != nullptr) {
+ // mVisiCB->setChecked(true);
+ // }
+ // }
+ // const auto pin_str = QString::fromUtf8(pin.get());
+ // _edit->setPin(pin_str);
+ // mRepeat->setPin(pin_str);
+ // // explicitly focus the first input field and select the generated
+ // password _edit->setFocus(); _edit->selectAll();
+ // }
+}
+
+void PinEntryDialog::toggleVisibility() {
+ if (sender() != mVisiCB) {
+ if (_edit->echoMode() == QLineEdit::Password) {
+ if (mVisiActionEdit != nullptr) {
+ mVisiActionEdit->setIcon(QIcon(QLatin1String(":/icons/hint.svg")));
+ mVisiActionEdit->setToolTip(mHideTT);
+ }
+ _edit->setEchoMode(QLineEdit::Normal);
+ if (mRepeat != nullptr) {
+ mRepeat->setEchoMode(QLineEdit::Normal);
+ }
+ } else {
+ if (mVisiActionEdit != nullptr) {
+ mVisiActionEdit->setIcon(
+ QIcon(QLatin1String(":/icons/visibility.svg")));
+ mVisiActionEdit->setToolTip(mVisibilityTT);
+ }
+ _edit->setEchoMode(QLineEdit::Password);
+ if (mRepeat != nullptr) {
+ mRepeat->setEchoMode(QLineEdit::Password);
+ }
+ }
+ } else {
+ if (mVisiCB->isChecked()) {
+ if (mRepeat != nullptr) {
+ mRepeat->setEchoMode(QLineEdit::Normal);
+ }
+ _edit->setEchoMode(QLineEdit::Normal);
+ } else {
+ if (mRepeat != nullptr) {
+ mRepeat->setEchoMode(QLineEdit::Password);
+ }
+ _edit->setEchoMode(QLineEdit::Password);
+ }
+ }
+ toggleFormattedPassphrase();
+}
+
+QString PinEntryDialog::repeatedPin() const {
+ if (mRepeat != nullptr) {
+ return mRepeat->pin();
+ }
+ return QString();
+}
+
+bool PinEntryDialog::timedOut() const { return _timed_out; }
+
+void PinEntryDialog::setRepeatErrorText(const QString &err) {
+ if (mRepeatError != nullptr) {
+ mRepeatError->setText(err);
+ }
+}
+
+void PinEntryDialog::cancelTimeout() {
+ if (_timer != nullptr) {
+ _timer->stop();
+ }
+}
+
+void PinEntryDialog::checkCapsLock() {
+ const auto state = capsLockState();
+ if (state != LockState::Unknown) {
+ mCapsLockHint->setVisible(state == LockState::On);
+ }
+}
+
+void PinEntryDialog::onAccept() {
+ cancelTimeout();
+
+ if ((mRepeat != nullptr) && mRepeat->pin() != _edit->pin()) {
+#ifndef QT_NO_ACCESSIBILITY
+ if (QAccessible::isActive()) {
+ QMessageBox::information(this, mRepeatError->text(),
+ mRepeatError->text());
+ } else
+#endif
+ {
+ mRepeatError->setVisible(true);
+ }
+ return;
+ }
+
+ accept();
+}