diff options
Diffstat (limited to 'src/pinentry/pinlineedit.cpp')
-rw-r--r-- | src/pinentry/pinlineedit.cpp | 204 |
1 files changed, 0 insertions, 204 deletions
diff --git a/src/pinentry/pinlineedit.cpp b/src/pinentry/pinlineedit.cpp deleted file mode 100644 index 9d172b56..00000000 --- a/src/pinentry/pinlineedit.cpp +++ /dev/null @@ -1,204 +0,0 @@ -/* pinlineedit.cpp - Modified QLineEdit widget. - * Copyright (C) 2018 Damien Goutte-Gattat - * Copyright (C) 2021 g10 Code GmbH - * - * Software engineering by Ingo Klöcker <[email protected]> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <https://www.gnu.org/licenses/>. - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include "pinlineedit.h" - -#include <QClipboard> -#include <QGuiApplication> -#include <QKeyEvent> - -static const int FormattedPassphraseGroupSize = 5; -static const QChar FormattedPassphraseSeparator = QChar::Nbsp; - -namespace { -struct Selection { - bool empty() const { return start < 0 || start >= end; } - int length() const { return empty() ? 0 : end - start; } - - int start; - int end; -}; -} // namespace - -class PinLineEdit::Private { - PinLineEdit *const q; - - public: - Private(PinLineEdit *q) : q{q} {} - - QString formatted(QString text) const { - const int dashCount = text.size() / FormattedPassphraseGroupSize; - text.reserve(text.size() + dashCount); - for (int i = FormattedPassphraseGroupSize; i < text.size(); - i += FormattedPassphraseGroupSize + 1) { - text.insert(i, FormattedPassphraseSeparator); - } - return text; - } - - Selection formattedSelection(Selection selection) const { - if (selection.empty()) { - return selection; - } - return {selection.start + selection.start / FormattedPassphraseGroupSize, - selection.end + (selection.end - 1) / FormattedPassphraseGroupSize}; - } - - QString unformatted(QString text) const { - for (int i = FormattedPassphraseGroupSize; i < text.size(); - i += FormattedPassphraseGroupSize) { - text.remove(i, 1); - } - return text; - } - - Selection unformattedSelection(Selection selection) const { - if (selection.empty()) { - return selection; - } - return { - selection.start - selection.start / (FormattedPassphraseGroupSize + 1), - selection.end - selection.end / (FormattedPassphraseGroupSize + 1)}; - } - - void copyToClipboard() { - if (q->echoMode() != QLineEdit::Normal) { - return; - } - - QString text = q->selectedText(); - if (mFormattedPassphrase) { - text.remove(FormattedPassphraseSeparator); - } - if (!text.isEmpty()) { - QGuiApplication::clipboard()->setText(text); - } - } - - int selectionEnd() { -#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) - return q->selectionEnd(); -#else - return q->selectionStart() + q->selectedText().size(); -#endif - } - - public: - bool mFormattedPassphrase = false; -}; - -PinLineEdit::PinLineEdit(QWidget *parent) - : QLineEdit(parent), d{new Private{this}} { - connect(this, SIGNAL(textEdited(QString)), this, SLOT(textEdited())); -} - -PinLineEdit::~PinLineEdit() = default; - -void PinLineEdit::setFormattedPassphrase(bool on) { - if (on == d->mFormattedPassphrase) { - return; - } - d->mFormattedPassphrase = on; - Selection selection{selectionStart(), d->selectionEnd()}; - if (d->mFormattedPassphrase) { - setText(d->formatted(text())); - selection = d->formattedSelection(selection); - } else { - setText(d->unformatted(text())); - selection = d->unformattedSelection(selection); - } - if (!selection.empty()) { - setSelection(selection.start, selection.length()); - } -} - -void PinLineEdit::copy() const { d->copyToClipboard(); } - -void PinLineEdit::cut() { - if (hasSelectedText()) { - copy(); - del(); - } -} - -void PinLineEdit::setPin(const QString &pin) { - setText(d->mFormattedPassphrase ? d->formatted(pin) : pin); -} - -QString PinLineEdit::pin() const { - if (d->mFormattedPassphrase) { - return d->unformatted(text()); - } else { - return text(); - } -} - -void PinLineEdit::keyPressEvent(QKeyEvent *e) { - if (e == QKeySequence::Copy) { - copy(); - return; - } else if (e == QKeySequence::Cut) { - if (!isReadOnly() && hasSelectedText()) { - copy(); - del(); - } - return; - } else if (e == QKeySequence::DeleteEndOfLine) { - if (!isReadOnly()) { - setSelection(cursorPosition(), text().size()); - copy(); - del(); - } - return; - } else if (e == QKeySequence::DeleteCompleteLine) { - if (!isReadOnly()) { - setSelection(0, text().size()); - copy(); - del(); - } - return; - } - - QLineEdit::keyPressEvent(e); - - if (e->key() == Qt::Key::Key_Backspace) { - emit backspacePressed(); - } -} - -void PinLineEdit::textEdited() { - if (!d->mFormattedPassphrase) { - return; - } - auto currentText = text(); - // first calculate the cursor position in the reformatted text; the cursor - // is put left of the separators, so that backspace works as expected - auto cursorPos = cursorPosition(); - cursorPos -= QStringView{currentText}.left(cursorPos).count( - FormattedPassphraseSeparator); - cursorPos += std::max(cursorPos - 1, 0) / FormattedPassphraseGroupSize; - // then reformat the text - currentText.remove(FormattedPassphraseSeparator); - currentText = d->formatted(currentText); - // finally, set reformatted text and updated cursor position - setText(currentText); - setCursorPosition(cursorPos); -} |