From 21e83f422667e431c1283b9ae3356fded3523e50 Mon Sep 17 00:00:00 2001 From: Daniel Kahn Gillmor Date: Wed, 13 May 2015 16:36:26 -0400 Subject: [PATCH] Avoid implicit declaration of function addnwstr. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit * pinentry/pinentry-curses.c [HAVE_NCURSESW]: Include . [! HAVE_NCURSESW]: Only include in this case. -- When built with libncursesw, we see this problem: pinentry-curses.c:440:8: warning: implicit declaration of function ‘addnwstr’ [-Wimplicit-function-declaration] ADDCH (start[i]); ^ --- pinentry/pinentry-curses.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pinentry/pinentry-curses.c b/pinentry/pinentry-curses.c index 60fd9da..65a5a67 100644 --- a/pinentry/pinentry-curses.c +++ b/pinentry/pinentry-curses.c @@ -22,7 +22,11 @@ #include #endif #include +#ifdef HAVE_NCURSESW +#include +#else #include +#endif #include #include #include -- 2.11.0 diff -ruN pinentry-1.1.0-orig/pinentry/pinentry-curses.c pinentry-1.1.0/pinentry/pinentry-curses.c --- pinentry-1.1.0-orig/pinentry/pinentry-curses.c 2017-12-03 10:13:05.000000000 -0600 +++ pinentry-1.1.0/pinentry/pinentry-curses.c 2020-10-09 05:27:21.000000000 -0500 @@ -55,6 +55,9 @@ # define GPG_ERR_MISSING_ENVVAR 303 #endif +/* Get rid of implict warning */ +int addnwstr(); + /* FIXME: We should allow configuration of these button labels and in any case use the default_ok, default_cancel values if available. diff --git a/qt/main.cpp b/qt/main.cpp index b0bcddd..bbcf226 100644 --- a/qt/main.cpp +++ b/qt/main.cpp @@ -1,397 +1,401 @@ /* main.cpp - A Qt dialog for PIN entry. * Copyright (C) 2002, 2008 Klarälvdalens Datakonsult AB (KDAB) * Copyright (C) 2003 g10 Code GmbH * Copyright 2007 Ingo Klöcker * * Written by Steffen Hansen . * Modified by Marcus Brinkmann . * Modified by Marc Mutz * * 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 . * SPDX-License-Identifier: GPL-2.0+ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pinentryconfirm.h" #include "pinentrydialog.h" #include "pinentry.h" #include #include #include #include #include #include #include +#if QT_VERSION >= 0x050000 #include +#endif #include #include #include #include #include #ifdef FALLBACK_CURSES #include #endif #if QT_VERSION >= 0x050000 && defined(QT_STATIC) #include #ifdef Q_OS_WIN #include #include Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin) #elif defined(Q_OS_MAC) Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin) #else Q_IMPORT_PLUGIN(QXcbIntegrationPlugin) #endif #endif #ifdef Q_OS_WIN #include #endif static QString escape_accel(const QString &s) { QString result; result.reserve(s.size()); bool afterUnderscore = false; for (unsigned int i = 0, end = s.size() ; i != end ; ++i) { const QChar ch = s[i]; if (ch == QLatin1Char('_')) { if (afterUnderscore) { // escaped _ result += QLatin1Char('_'); afterUnderscore = false; } else { // accel afterUnderscore = true; } } else { if (afterUnderscore || // accel ch == QLatin1Char('&')) { // escape & from being interpreted by Qt result += QLatin1Char('&'); } result += ch; afterUnderscore = false; } } if (afterUnderscore) // trailing single underscore: shouldn't happen, but deal with it robustly: { result += QLatin1Char('_'); } return result; } namespace { class InvalidUtf8 : public std::invalid_argument { public: InvalidUtf8() : std::invalid_argument("invalid utf8") {} ~InvalidUtf8() throw() {} }; } static const bool GPG_AGENT_IS_PORTED_TO_ONLY_SEND_UTF8 = false; static QString from_utf8(const char *s) { const QString result = QString::fromUtf8(s); if (result.contains(QChar::ReplacementCharacter)) { if (GPG_AGENT_IS_PORTED_TO_ONLY_SEND_UTF8) { throw InvalidUtf8(); } else { return QString::fromLocal8Bit(s); } } return result; } static void setup_foreground_window(QWidget *widget, WId parentWid) { +#if QT_VERSION >= 0x050000 /* For windows set the desktop window as the transient parent */ QWindow *parentWindow = nullptr; if (parentWid) { parentWindow = QWindow::fromWinId(parentWid); } #ifdef Q_OS_WIN if (!parentWindow) { HWND desktop = GetDesktopWindow(); if (desktop) { parentWindow = QWindow::fromWinId((WId) desktop); } } #endif if (parentWindow) { // Ensure that we have a native wid widget->winId(); QWindow *wndHandle = widget->windowHandle(); if (wndHandle) { wndHandle->setTransientParent(parentWindow); } } +#endif widget->setWindowFlags(Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint | Qt::WindowMinimizeButtonHint); } static int qt_cmd_handler(pinentry_t pe) { char *str; int want_pass = !!pe->pin; const QString ok = pe->ok ? escape_accel(from_utf8(pe->ok)) : pe->default_ok ? escape_accel(from_utf8(pe->default_ok)) : /* else */ QLatin1String("&OK") ; const QString cancel = pe->cancel ? escape_accel(from_utf8(pe->cancel)) : pe->default_cancel ? escape_accel(from_utf8(pe->default_cancel)) : /* else */ QLatin1String("&Cancel") ; str = pinentry_get_title (pe); const QString title = str ? from_utf8(str) : /* else */ QLatin1String("pinentry-qt") ; free (str); const QString repeatError = pe->repeat_error_string ? from_utf8(pe->repeat_error_string) : QLatin1String("Passphrases do not match"); const QString repeatString = pe->repeat_passphrase ? from_utf8(pe->repeat_passphrase) : QString(); const QString visibilityTT = pe->default_tt_visi ? from_utf8(pe->default_tt_visi) : QLatin1String("Show passphrase"); const QString hideTT = pe->default_tt_hide ? from_utf8(pe->default_tt_hide) : QLatin1String("Hide passphrase"); const QString generateLbl = pe->genpin_label ? from_utf8(pe->genpin_label) : QString(); const QString generateTT = pe->genpin_tt ? from_utf8(pe->genpin_tt) : QString(); if (want_pass) { char *str; PinEntryDialog pinentry(nullptr, 0, pe->timeout, true, !!pe->quality_bar, repeatString, visibilityTT, hideTT); setup_foreground_window(&pinentry, pe->parent_wid); pinentry.setPinentryInfo(pe); pinentry.setPrompt(escape_accel(from_utf8(pe->prompt))); pinentry.setDescription(from_utf8(pe->description)); pinentry.setRepeatErrorText(repeatError); pinentry.setGenpinLabel(generateLbl); pinentry.setGenpinTT(generateTT); str = pinentry_get_title (pe); if (str) { pinentry.setWindowTitle(from_utf8(str)); free (str); } /* If we reuse the same dialog window. */ pinentry.setPin(QString()); pinentry.setOkText(ok); pinentry.setCancelText(cancel); if (pe->error) { pinentry.setError(from_utf8(pe->error)); } if (pe->quality_bar) { pinentry.setQualityBar(from_utf8(pe->quality_bar)); } if (pe->quality_bar_tt) { pinentry.setQualityBarTT(from_utf8(pe->quality_bar_tt)); } bool ret = pinentry.exec(); if (!ret) { if (pinentry.timedOut()) pe->specific_err = gpg_error (GPG_ERR_TIMEOUT); return -1; } const QString pinStr = pinentry.pin(); QByteArray pin = pinStr.toUtf8(); if (!!pe->repeat_passphrase) { /* Should not have been possible to accept the dialog in that case but we do a safety check here */ pe->repeat_okay = (pinStr == pinentry.repeatedPin()); } int len = strlen(pin.constData()); if (len >= 0) { pinentry_setbufferlen(pe, len + 1); if (pe->pin) { strcpy(pe->pin, pin.constData()); return len; } } return -1; } else { const QString desc = pe->description ? from_utf8(pe->description) : QString(); const QString notok = pe->notok ? escape_accel(from_utf8(pe->notok)) : QString(); const QMessageBox::StandardButtons buttons = pe->one_button ? QMessageBox::Ok : pe->notok ? QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel : /* else */ QMessageBox::Ok | QMessageBox::Cancel ; PinentryConfirm box(QMessageBox::Information, pe->timeout, title, desc, buttons, nullptr); setup_foreground_window(&box, pe->parent_wid); const struct { QMessageBox::StandardButton button; QString label; } buttonLabels[] = { { QMessageBox::Ok, ok }, { QMessageBox::Yes, ok }, { QMessageBox::No, notok }, { QMessageBox::Cancel, cancel }, }; for (size_t i = 0 ; i < sizeof buttonLabels / sizeof * buttonLabels ; ++i) if ((buttons & buttonLabels[i].button) && !buttonLabels[i].label.isEmpty()) { box.button(buttonLabels[i].button)->setText(buttonLabels[i].label); #ifndef QT_NO_ACCESSIBILITY box.button(buttonLabels[i].button)->setAccessibleDescription(buttonLabels[i].label); #endif } box.setIconPixmap(icon()); if (!pe->one_button) { box.setDefaultButton(QMessageBox::Cancel); } box.show(); raiseWindow(&box); const int rc = box.exec(); if (rc == QMessageBox::Cancel) { pe->canceled = true; } if (box.timedOut()) { pe->specific_err = gpg_error (GPG_ERR_TIMEOUT); } return rc == QMessageBox::Ok || rc == QMessageBox::Yes ; } } static int qt_cmd_handler_ex(pinentry_t pe) { try { return qt_cmd_handler(pe); } catch (const InvalidUtf8 &) { pe->locale_err = true; return pe->pin ? -1 : false ; } catch (...) { pe->canceled = true; return pe->pin ? -1 : false ; } } pinentry_cmd_handler_t pinentry_cmd_handler = qt_cmd_handler_ex; int main(int argc, char *argv[]) { pinentry_init("pinentry-qt"); QApplication *app = NULL; int new_argc = 0; #ifdef FALLBACK_CURSES if (!pinentry_have_display(argc, argv)) { pinentry_cmd_handler = curses_cmd_handler; pinentry_set_flavor_flag ("curses"); } else #endif { /* Qt does only understand -display but not --display; thus we are fixing that here. The code is pretty simply and may get confused if an argument is called "--display". */ char **new_argv, *p; size_t n; int i, done; for (n = 0, i = 0; i < argc; i++) { n += strlen(argv[i]) + 1; } n++; new_argv = (char **)calloc(argc + 1, sizeof * new_argv); if (new_argv) { *new_argv = (char *)malloc(n); } if (!new_argv || !*new_argv) { fprintf(stderr, "pinentry-qt: can't fixup argument list: %s\n", strerror(errno)); exit(EXIT_FAILURE); } for (done = 0, p = *new_argv, i = 0; i < argc; i++) if (!done && !strcmp(argv[i], "--display")) { new_argv[i] = strcpy(p, argv[i] + 1); p += strlen(argv[i] + 1) + 1; done = 1; } else { new_argv[i] = strcpy(p, argv[i]); p += strlen(argv[i]) + 1; } /* Note: QApplication uses int &argc so argc has to be valid * for the full lifetime of the application. * * As Qt might modify argc / argv we use copies here so that * we do not loose options that are handled in both. e.g. display. */ new_argc = argc; Q_ASSERT (new_argc); app = new QApplication(new_argc, new_argv); app->setWindowIcon(QIcon(QLatin1String(":/document-encrypt.png"))); } pinentry_parse_opts(argc, argv); int rc = pinentry_loop(); delete app; return rc ? EXIT_FAILURE : EXIT_SUCCESS ; } diff --git a/qt/pinentrydialog.cpp b/qt/pinentrydialog.cpp index 684e465..1b2be36 100644 --- a/qt/pinentrydialog.cpp +++ b/qt/pinentrydialog.cpp @@ -1,499 +1,511 @@ /* 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 * * Written by Steffen Hansen . * Modified by Andre Heinecke * * 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 . * SPDX-License-Identifier: GPL-2.0+ */ #include "pinentrydialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "pinlineedit.h" #include #ifdef Q_OS_WIN #include #if QT_VERSION >= 0x050700 #include #endif #endif void raiseWindow(QWidget *w) { #ifdef Q_OS_WIN #if QT_VERSION >= 0x050700 QWindowsWindowFunctions::setWindowActivationBehavior( QWindowsWindowFunctions::AlwaysActivateWindow); #endif #endif w->setWindowState((w->windowState() & ~Qt::WindowMinimized) | Qt::WindowActive); w->activateWindow(); w->raise(); } QPixmap icon(QStyle::StandardPixmap which) { QPixmap pm = qApp->windowIcon().pixmap(48, 48); if (which != QStyle::SP_CustomBase) { const QIcon ic = qApp->style()->standardIcon(which); QPainter painter(&pm); const int emblemSize = 22; painter.drawPixmap(pm.width() - emblemSize, 0, ic.pixmap(emblemSize, emblemSize)); } 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), mRepeat(NULL), _grabbed(false), _disable_echo_allowed(true), mVisibilityTT(visibilityTT), mHideTT(hideTT), mVisiActionEdit(NULL), mGenerateActionEdit(NULL), mVisiCB(NULL) { _timed_out = false; if (modal) { setWindowModality(Qt::ApplicationModal); } _icon = new QLabel(this); _icon->setPixmap(icon()); _error = new QLabel(this); QPalette pal; pal.setColor(QPalette::WindowText, Qt::red); _error->setPalette(pal); _error->hide(); _desc = new QLabel(this); _desc->hide(); _prompt = new QLabel(this); _prompt->hide(); _edit = new PinLineEdit(this); _edit->setMaxLength(256); _edit->setMinimumWidth(_edit->fontMetrics().averageCharWidth()*20 + 48); _edit->setEchoMode(QLineEdit::Password); _prompt->setBuddy(_edit); if (enable_quality_bar) { _quality_bar_label = new QLabel(this); _quality_bar_label->setAlignment(Qt::AlignVCenter); _quality_bar = new QProgressBar(this); _quality_bar->setAlignment(Qt::AlignCenter); _have_quality_bar = true; } else { _have_quality_bar = false; } QDialogButtonBox *const buttons = new QDialogButtonBox(this); buttons->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); _ok = buttons->button(QDialogButtonBox::Ok); _cancel = buttons->button(QDialogButtonBox::Cancel); _ok->setDefault(true); if (style()->styleHint(QStyle::SH_DialogButtonBox_ButtonsHaveIcons)) { _ok->setIcon(style()->standardIcon(QStyle::SP_DialogOkButton)); _cancel->setIcon(style()->standardIcon(QStyle::SP_DialogCancelButton)); } if (timeout > 0) { _timer = new QTimer(this); connect(_timer, SIGNAL(timeout()), this, SLOT(slotTimeout())); _timer->start(timeout * 1000); } else { _timer = NULL; } connect(buttons, SIGNAL(accepted()), this, SLOT(accept())); connect(buttons, SIGNAL(rejected()), this, SLOT(reject())); connect(_edit, SIGNAL(textChanged(QString)), this, SLOT(updateQuality(QString))); connect(_edit, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString))); connect(_edit, SIGNAL(backspacePressed()), this, SLOT(onBackspace())); QGridLayout *const grid = new QGridLayout(this); int row = 1; grid->addWidget(_error, row++, 1, 1, 2); grid->addWidget(_desc, row++, 1, 1, 2); //grid->addItem( new QSpacerItem( 0, _edit->height() / 10, QSizePolicy::Minimum, QSizePolicy::Fixed ), 1, 1 ); grid->addWidget(_prompt, row, 1); grid->addWidget(_edit, row++, 2); if (!repeatString.isNull()) { mRepeat = new QLineEdit; mRepeat->setMaxLength(256); mRepeat->setEchoMode(QLineEdit::Password); connect(mRepeat, SIGNAL(textChanged(QString)), this, SLOT(textChanged(QString))); QLabel *repeatLabel = new QLabel(repeatString); repeatLabel->setBuddy(mRepeat); grid->addWidget(repeatLabel, row, 1); grid->addWidget(mRepeat, row++, 2); setTabOrder(_edit, mRepeat); setTabOrder(mRepeat, _ok); } if (enable_quality_bar) { grid->addWidget(_quality_bar_label, row, 1); grid->addWidget(_quality_bar, row++, 2); } /* Set up the show password action */ const QIcon visibilityIcon = QIcon::fromTheme(QLatin1String("visibility")); const QIcon hideIcon = QIcon::fromTheme(QLatin1String("hint")); const QIcon generateIcon = QIcon(); /* Disabled for now QIcon::fromTheme(QLatin1String("password-generate")); */ #if QT_VERSION >= 0x050200 if (!generateIcon.isNull()) { mGenerateActionEdit = _edit->addAction(generateIcon, QLineEdit::LeadingPosition); mGenerateActionEdit->setToolTip(mGenerateTT); connect(mGenerateActionEdit, SIGNAL(triggered()), this, SLOT(generatePin())); } if (!visibilityIcon.isNull() && !hideIcon.isNull()) { mVisiActionEdit = _edit->addAction(visibilityIcon, QLineEdit::TrailingPosition); mVisiActionEdit->setVisible(false); mVisiActionEdit->setToolTip(mVisibilityTT); connect(mVisiActionEdit, SIGNAL(triggered()), this, SLOT(toggleVisibility())); } else #endif { if (!mVisibilityTT.isNull()) { mVisiCB = new QCheckBox(mVisibilityTT); connect(mVisiCB, SIGNAL(toggled(bool)), this, SLOT(toggleVisibility())); grid->addWidget(mVisiCB, row++, 1, 1, 2, Qt::AlignLeft); } } grid->addWidget(buttons, ++row, 0, 1, 3); grid->addWidget(_icon, 0, 0, row - 1, 1, Qt::AlignVCenter | Qt::AlignLeft); grid->setSizeConstraint(QLayout::SetFixedSize); connect(qApp, SIGNAL(focusChanged(QWidget *, QWidget *)), this, SLOT(focusChanged(QWidget *, QWidget *))); +#if QT_VERSION >= 0x050000 + /* 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. + */ setWindowState(Qt::WindowMinimized); QTimer::singleShot(0, this, [this] () { raiseWindow (this); }); +#else + activateWindow(); + raise(); +#endif } void PinEntryDialog::showEvent(QShowEvent *event) { QDialog::showEvent(event); _edit->setFocus(); } void PinEntryDialog::setDescription(const QString &txt) { _desc->setVisible(!txt.isEmpty()); _desc->setText(txt); #ifndef QT_NO_ACCESSIBILITY _desc->setAccessibleDescription(txt); #endif _icon->setPixmap(icon()); setError(QString()); } QString PinEntryDialog::description() const { return _desc->text(); } void PinEntryDialog::setError(const QString &txt) { if (!txt.isNull()) { _icon->setPixmap(icon(QStyle::SP_MessageBoxCritical)); } _error->setText(txt); #ifndef QT_NO_ACCESSIBILITY _error->setAccessibleDescription(txt); #endif _error->setVisible(!txt.isEmpty()); } QString PinEntryDialog::error() const { return _error->text(); } void PinEntryDialog::setPin(const QString &txt) { _edit->setText(txt); } QString PinEntryDialog::pin() const { return _edit->text(); } 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); #ifndef QT_NO_ACCESSIBILITY _ok->setAccessibleDescription(txt); #endif _ok->setVisible(!txt.isEmpty()); } void PinEntryDialog::setCancelText(const QString &txt) { _cancel->setText(txt); #ifndef QT_NO_ACCESSIBILITY _cancel->setAccessibleDescription(txt); #endif _cancel->setVisible(!txt.isEmpty()); } void PinEntryDialog::setQualityBar(const QString &txt) { if (_have_quality_bar) { _quality_bar_label->setText(txt); #ifndef QT_NO_ACCESSIBILITY _quality_bar_label->setAccessibleDescription(txt); #endif } } void PinEntryDialog::setQualityBarTT(const QString &txt) { if (_have_quality_bar) { _quality_bar->setToolTip(txt); } } void PinEntryDialog::setGenpinLabel(const QString &txt) { if (!mGenerateActionEdit) { return; } if (txt.isEmpty()) { mGenerateActionEdit->setVisible(false); } else { mGenerateActionEdit->setText(txt); mGenerateActionEdit->setVisible(true); } } void PinEntryDialog::setGenpinTT(const QString &txt) { if (mGenerateActionEdit) { mGenerateActionEdit->setToolTip(txt); } } void PinEntryDialog::onBackspace() { if (_disable_echo_allowed) { _edit->setEchoMode(QLineEdit::NoEcho); if (mRepeat) { mRepeat->setEchoMode(QLineEdit::NoEcho); } } } void PinEntryDialog::updateQuality(const QString &txt) { int length; int percent; QPalette pal; if (_timer) { _timer->stop(); } _disable_echo_allowed = false; if (!_have_quality_bar || !_pinentry_info) { return; } const QByteArray utf8_pin = txt.toUtf8(); const char *pin = utf8_pin.constData(); length = strlen(pin); percent = length ? pinentry_inq_quality(_pinentry_info, pin, length) : 0; if (!length) { _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(pinentry_t peinfo) { _pinentry_info = 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) { if (_grabbed && old && (old == _edit || old == mRepeat)) { old->releaseKeyboard(); _grabbed = false; } if (!_grabbed && now && (now == _edit || now == mRepeat)) { now->grabKeyboard(); _grabbed = true; } } } void PinEntryDialog::textChanged(const QString &text) { Q_UNUSED(text); if (mRepeat && mRepeat->text() == _edit->text()) { _ok->setEnabled(true); _ok->setToolTip(QString()); } else if (mRepeat) { _ok->setEnabled(false); _ok->setToolTip(mRepeatError); } if (mVisiActionEdit && sender() == _edit) { mVisiActionEdit->setVisible(!_edit->text().isEmpty()); } if (mGenerateActionEdit) { mGenerateActionEdit->setVisible(_edit->text().isEmpty() && _pinentry_info->genpin_label); } } void PinEntryDialog::generatePin() { const char *pin = pinentry_inq_genpin(_pinentry_info); if (pin) { if (_edit->echoMode() == QLineEdit::Password) { toggleVisibility(); } const auto pinStr = QString::fromUtf8(pin); _edit->setText(pinStr); mRepeat->setText(pinStr); } } void PinEntryDialog::toggleVisibility() { if (sender() != mVisiCB) { if (_edit->echoMode() == QLineEdit::Password) { mVisiActionEdit->setIcon(QIcon::fromTheme(QLatin1String("hint"))); mVisiActionEdit->setToolTip(mHideTT); _edit->setEchoMode(QLineEdit::Normal); if (mRepeat) { mRepeat->setEchoMode(QLineEdit::Normal); } } else { mVisiActionEdit->setIcon(QIcon::fromTheme(QLatin1String("visibility"))); mVisiActionEdit->setToolTip(mVisibilityTT); _edit->setEchoMode(QLineEdit::Password); if (mRepeat) { mRepeat->setEchoMode(QLineEdit::Password); } } } else { if (mVisiCB->isChecked()) { if (mRepeat) { mRepeat->setEchoMode(QLineEdit::Normal); } _edit->setEchoMode(QLineEdit::Normal); } else { if (mRepeat) { mRepeat->setEchoMode(QLineEdit::Password); } _edit->setEchoMode(QLineEdit::Password); } } } QString PinEntryDialog::repeatedPin() const { if (mRepeat) { return mRepeat->text(); } return QString(); } bool PinEntryDialog::timedOut() const { return _timed_out; } void PinEntryDialog::setRepeatErrorText(const QString &err) { mRepeatError = err; } #include "pinentrydialog.moc"