diff --git a/qt/main.cpp b/qt/main.cpp index 3c653ee..a051240 100644 --- a/qt/main.cpp +++ b/qt/main.cpp @@ -1,346 +1,352 @@ /* 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include "pinentryconfirm.h" #include "pinentrydialog.h" #include "pinentry.h" #include #include #include #include #include #include #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 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; } /* Hack for creating a QWidget with a "foreign" window ID */ class ForeignWidget : public QWidget { public: explicit ForeignWidget(WId wid) : QWidget(0) { QWidget::destroy(); create(wid, false, false); } ~ForeignWidget() { destroy(false, false); } }; 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 int qt_cmd_handler(pinentry_t pe) { QWidget *parent = 0; /* FIXME: Add parent window ID to pinentry and GTK. */ if (pe->parent_wid) { parent = new ForeignWidget((WId) pe->parent_wid); } 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") ; const QString title = pe->title ? from_utf8(pe->title) : /* else */ QLatin1String("pinentry-qt") ; 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"); + if (want_pass) { PinEntryDialog pinentry(parent, 0, pe->timeout, true, !!pe->quality_bar, - repeatString); + repeatString, visibilityTT, hideTT); pinentry.setPinentryInfo(pe); pinentry.setPrompt(escape_accel(from_utf8(pe->prompt))); pinentry.setDescription(from_utf8(pe->description)); pinentry.setRepeatErrorText(repeatError); if (pe->title) { pinentry.setWindowTitle(from_utf8(pe->title)); } /* 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) { 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, parent); 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; } 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"); std::auto_ptr app; #ifdef FALLBACK_CURSES if (!pinentry_have_display(argc, argv)) { pinentry_cmd_handler = curses_cmd_handler; } 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; } /* We use a modal dialog window, so we don't need the application window anymore. */ i = argc; app.reset(new QApplication(i, new_argv)); const QIcon fallback = QIcon(QLatin1String(":/document-encrypt.png")); const QIcon icon = QIcon::fromTheme(QLatin1String("document-encrypt"), fallback); app->setWindowIcon(icon); } pinentry_parse_opts(argc, argv); return pinentry_loop() ? EXIT_FAILURE : EXIT_SUCCESS ; } diff --git a/qt/pinentrydialog.cpp b/qt/pinentrydialog.cpp index aca3a52..44a3a9f 100644 --- a/qt/pinentrydialog.cpp +++ b/qt/pinentrydialog.cpp @@ -1,393 +1,475 @@ /* 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "pinentrydialog.h" #include #include #include #include #include #include #include #include #include #include #include +#include +#include #ifdef Q_OS_WIN #include #endif /* I [wk] have no idea for what this code was supposed to do. Foregrounding a window is heavily restricted by modern Windows versions. This is the reason why gpg-agent employs its AllowSetForegroundWindow callback machinery to ask the supposed to be be calling process to allow a pinentry to go into the foreground. [ah] This is a Hack to workaround the fact that Foregrounding a Window is so restricted that it AllowSetForegroundWindow does not always work (e.g. when the ForegroundWindow timeout has not expired. */ #ifdef Q_OS_WIN WINBOOL SetForegroundWindowEx(HWND hWnd) { //Attach foreground window thread to our thread const DWORD ForeGroundID = GetWindowThreadProcessId(::GetForegroundWindow(), NULL); const DWORD CurrentID = GetCurrentThreadId(); WINBOOL retval; AttachThreadInput(ForeGroundID, CurrentID, TRUE); //Do our stuff here HWND hLastActivePopupWnd = GetLastActivePopup(hWnd); retval = SetForegroundWindow(hLastActivePopupWnd); //Detach the attached thread AttachThreadInput(ForeGroundID, CurrentID, FALSE); return retval; }// End SetForegroundWindowEx #endif void raiseWindow(QWidget *w) { /* Maybe Qt will become agressive enough one day that * this is enough on windows too*/ w->raise(); #ifdef Q_OS_WIN /* In the meantime we do our own attention grabbing */ if (!SetForegroundWindow((HWND)w->winId()) && !SetForegroundWindowEx((HWND)w->winId())) { OutputDebugString("SetForegroundWindow (ex) failed"); /* Yet another fallback which will not work on some * versions and is not recommended by msdn */ if (!ShowWindow((HWND)w->winId(), SW_SHOWNORMAL)) { OutputDebugString("ShowWindow failed."); } } #endif } 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() { reject(); } PinEntryDialog::PinEntryDialog(QWidget *parent, const char *name, int timeout, bool modal, bool enable_quality_bar, - const QString &repeatString) - : QDialog(parent, Qt::WindowStaysOnTopHint), mRepeat(NULL), _grabbed(false) + const QString &repeatString, + const QString &visibilityTT, + const QString &hideTT) + : QDialog(parent, Qt::WindowStaysOnTopHint), + mRepeat(NULL), + _grabbed(false), + mVisibilityTT(visibilityTT), + mHideTT(hideTT), + mVisiActionEdit(NULL), + mVisiActionRepeat(NULL), + mVisiCB(NULL) { setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); if (modal) { setWindowModality(Qt::ApplicationModal); } _icon = new QLabel(this); _icon->setPixmap(icon()); _error = new QLabel(this); _error->setWordWrap(true); QPalette pal; pal.setColor(QPalette::WindowText, Qt::red); _error->setPalette(pal); _error->hide(); _desc = new QLabel(this); _desc->setWordWrap(true); _desc->hide(); _prompt = new QLabel(this); _prompt->hide(); _edit = new QLineEdit(this); _edit->setMaxLength(256); _edit->setEchoMode(QLineEdit::Password); _prompt->setBuddy(_edit); if (enable_quality_bar) { _quality_bar_label = new QLabel(this); _quality_bar_label->setAlignment(Qt::AlignRight | 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))); _edit->setFocus(); 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 ); if (enable_quality_bar) { grid->addWidget(_quality_bar_label, row, 1); grid->addWidget(_quality_bar, row++, 2); } 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(checkRepeat(QString))); - connect(_edit, SIGNAL(textChanged(QString)), - this, SLOT(checkRepeat(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); } - row += 2; - grid->addWidget(buttons, row, 0, 1, 3); + /* Set up the show password action */ + const QIcon visibilityIcon = QIcon::fromTheme(QLatin1String("visibility")); + const QIcon hideIcon = QIcon::fromTheme(QLatin1String("hint")); +#if QT_VERSION >= 0x050200 + if (!visibilityIcon.isNull() && !hideIcon.isNull()) { + mVisiActionEdit = _edit->addAction(visibilityIcon, QLineEdit::TrailingPosition); + mVisiActionEdit->setVisible(false); + mVisiActionEdit->setToolTip(mVisibilityTT); + if (mRepeat) { + mVisiActionRepeat = mRepeat->addAction(visibilityIcon, QLineEdit::TrailingPosition); + mVisiActionRepeat->setVisible(false); + mVisiActionRepeat->setToolTip(mVisibilityTT); + connect(mVisiActionRepeat, SIGNAL(triggered()), this, SLOT(toggleVisibility())); + } + 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 *))); } void PinEntryDialog::showEvent(QShowEvent *event) { QDialog::showEvent(event); raiseWindow(this); } 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::null); } 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()); } 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::updateQuality(const QString &txt) { int length; int percent; QPalette pal; if (_timer) { _timer->stop(); } 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::checkRepeat(const QString &repPin) +void PinEntryDialog::textChanged(const QString &text) { - if (mRepeat->text() == _edit->text()) { + Q_UNUSED(text); + if (mRepeat && mRepeat->text() == _edit->text()) { _ok->setEnabled(true); _ok->setToolTip(QString()); - } else { + } else if (mRepeat) { _ok->setEnabled(false); _ok->setToolTip(mRepeatError); } + + if (mVisiActionEdit && sender() == _edit) { + mVisiActionEdit->setVisible(!_edit->text().isEmpty()); + } + if (mVisiActionRepeat && sender() == mRepeat) { + mVisiActionRepeat->setVisible(!mRepeat->text().isEmpty()); + } +} + +void PinEntryDialog::toggleVisibility() +{ + if (sender() == mVisiActionEdit) { + if (_edit->echoMode() == QLineEdit::Password) { + mVisiActionEdit->setIcon(QIcon::fromTheme(QLatin1String("hint"))); + mVisiActionEdit->setToolTip(mHideTT); + _edit->setEchoMode(QLineEdit::Normal); + } else { + mVisiActionEdit->setIcon(QIcon::fromTheme(QLatin1String("visibility"))); + mVisiActionEdit->setToolTip(mVisibilityTT); + _edit->setEchoMode(QLineEdit::Password); + } + } + if (sender() == mVisiActionRepeat) { + if (mRepeat->echoMode() == QLineEdit::Password) { + mVisiActionRepeat->setIcon(QIcon::fromTheme(QLatin1String("hint"))); + mVisiActionRepeat->setToolTip(mHideTT); + mRepeat->setEchoMode(QLineEdit::Normal); + } else { + mVisiActionRepeat->setIcon(QIcon::fromTheme(QLatin1String("visibility"))); + mVisiActionRepeat->setToolTip(mVisibilityTT); + mRepeat->setEchoMode(QLineEdit::Password); + } + } + if (sender() == mVisiCB) { + 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(); } void PinEntryDialog::setRepeatErrorText(const QString &err) { mRepeatError = err; } #include "pinentrydialog.moc" diff --git a/qt/pinentrydialog.h b/qt/pinentrydialog.h index 1713412..4c1241c 100644 --- a/qt/pinentrydialog.h +++ b/qt/pinentrydialog.h @@ -1,108 +1,118 @@ /* pinentrydialog.h - 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, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __PINENTRYDIALOG_H__ #define __PINENTRYDIALOG_H__ #include #include #include #include "pinentry.h" class QLabel; class QPushButton; class QLineEdit; class QString; class QProgressBar; +class QCheckBox; +class QAction; QPixmap icon(QStyle::StandardPixmap which = QStyle::SP_CustomBase); void raiseWindow(QWidget *w); class PinEntryDialog : public QDialog { Q_OBJECT Q_PROPERTY(QString description READ description WRITE setDescription) Q_PROPERTY(QString error READ error WRITE setError) Q_PROPERTY(QString pin READ pin WRITE setPin) Q_PROPERTY(QString prompt READ prompt WRITE setPrompt) public: explicit PinEntryDialog(QWidget *parent = 0, const char *name = 0, int timeout = 0, bool modal = false, bool enable_quality_bar = false, - const QString &repeatString = QString()); + const QString &repeatString = QString(), + const QString &visibiltyTT = QString(), + const QString &hideTT = QString()); void setDescription(const QString &); QString description() const; void setError(const QString &); QString error() const; void setPin(const QString &); QString pin() const; QString repeatedPin() const; void setRepeatErrorText(const QString &); void setPrompt(const QString &); QString prompt() const; void setOkText(const QString &); void setCancelText(const QString &); void setQualityBar(const QString &); void setQualityBarTT(const QString &); void setPinentryInfo(pinentry_t); protected slots: void updateQuality(const QString &); void slotTimeout(); - void checkRepeat(const QString &); + void textChanged(const QString &); void focusChanged(QWidget *old, QWidget *now); + void toggleVisibility(); protected: /* reimp */ void showEvent(QShowEvent *event); private: QLabel *_icon; QLabel *_desc; QLabel *_error; QLabel *_prompt; QLabel *_quality_bar_label; QProgressBar *_quality_bar; QLineEdit *_edit; QLineEdit *mRepeat; QPushButton *_ok; QPushButton *_cancel; bool _grabbed; bool _have_quality_bar; pinentry_t _pinentry_info; QTimer *_timer; - QString mRepeatError; + QString mRepeatError, + mVisibilityTT, + mHideTT; + QAction *mVisiActionEdit, + *mVisiActionRepeat; + QCheckBox *mVisiCB; }; #endif // __PINENTRYDIALOG_H__