[packages/pinentry] upstream patch to fix build against qt4; rel 2
atler
atler at pld-linux.org
Wed Jan 27 11:13:11 CET 2021
commit b99c9fc5194d1f62fa79da2ec53fd64b39c2a66f
Author: Jan Palus <atler at pld-linux.org>
Date: Wed Jan 27 11:11:53 2021 +0100
upstream patch to fix build against qt4; rel 2
see https://dev.gnupg.org/T5262
pinentry-qt4.patch | 922 +++++++++++++++++++++++++++++++++++++++++++++++++++++
pinentry.spec | 4 +-
2 files changed, 925 insertions(+), 1 deletion(-)
---
diff --git a/pinentry.spec b/pinentry.spec
index 53f030d..a28dfda 100644
--- a/pinentry.spec
+++ b/pinentry.spec
@@ -12,13 +12,14 @@ Summary: Simple PIN or passphrase entry dialogs
Summary(pl.UTF-8): Proste kontrolki dialogowe do wpisywania PIN-ów lub haseł
Name: pinentry
Version: 1.1.1
-Release: 1
+Release: 2
License: GPL v2+
Group: Applications
Source0: ftp://ftp.gnupg.org/gcrypt/pinentry/%{name}-%{version}.tar.bz2
# Source0-md5: d7f646d373b722317d985cddc1d107c1
Patch0: %{name}-info.patch
Patch1: %{name}-am.patch
+Patch2: %{name}-qt4.patch
URL: http://www.gnupg.org/
%{?with_qt5:BuildRequires: Qt5Core-devel >= 5}
%{?with_qt5:BuildRequires: Qt5Gui-devel >= 5}
@@ -159,6 +160,7 @@ Prosta kontrolka dialogowa do wpisywania PIN-ów lub haseł dla Qt5.
%setup -q
%patch0 -p1
%patch1 -p1
+%patch2 -p1
%if 0
cd qt4
diff --git a/pinentry-qt4.patch b/pinentry-qt4.patch
new file mode 100644
index 0000000..b3cb3ae
--- /dev/null
+++ b/pinentry-qt4.patch
@@ -0,0 +1,922 @@
+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 <steffen at klaralvdalens-datakonsult.se>.
+ * Modified by Marcus Brinkmann <marcus at g10code.de>.
+ * Modified by Marc Mutz <marc at kdab.com>
+ *
+ * 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+
+ */
+
+ #ifdef HAVE_CONFIG_H
+ #include "config.h"
+ #endif
+
+ #include "pinentryconfirm.h"
+ #include "pinentrydialog.h"
+ #include "pinentry.h"
+
+ #include <QApplication>
+ #include <QDebug>
+ #include <QIcon>
+ #include <QMessageBox>
+ #include <QPushButton>
+ #include <QString>
+ #include <QWidget>
++#if QT_VERSION >= 0x050000
+ #include <QWindow>
++#endif
+
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <errno.h>
+
+ #include <stdexcept>
+ #include <gpg-error.h>
+
+ #ifdef FALLBACK_CURSES
+ #include <pinentry-curses.h>
+ #endif
+
+ #if QT_VERSION >= 0x050000 && defined(QT_STATIC)
+ #include <QtPlugin>
+ #ifdef Q_OS_WIN
+ #include <windows.h>
+ #include <shlobj.h>
+ 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 <windows.h>
+ #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 <steffen at klaralvdalens-datakonsult.se>.
+ * Modified by Andre Heinecke <aheinecke at intevation.de>
+ *
+ * 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 <QGridLayout>
+
+ #include <QProgressBar>
+ #include <QApplication>
+ #include <QFontMetrics>
+ #include <QStyle>
+ #include <QPainter>
+ #include <QPushButton>
+ #include <QDialogButtonBox>
+ #include <QKeyEvent>
+ #include <QLabel>
+ #include <QPalette>
+ #include <QLineEdit>
+ #include <QAction>
+ #include <QCheckBox>
+ #include "pinlineedit.h"
+
+ #include <QDebug>
+
+ #ifdef Q_OS_WIN
+ #include <windows.h>
+ #if QT_VERSION >= 0x050700
+ #include <QtPlatformHeaders/QWindowsWindowFunctions>
+ #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"
================================================================
---- gitweb:
http://git.pld-linux.org/gitweb.cgi/packages/pinentry.git/commitdiff/b99c9fc5194d1f62fa79da2ec53fd64b39c2a66f
More information about the pld-cvs-commit
mailing list