[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