QtPass
2.0.0
Developer documentation
Toggle main menu visibility
Loading...
Searching...
No Matches
secretlineedit.cpp
Go to the documentation of this file.
1
// SPDX-FileCopyrightText: 2026 Anne Jan Brouwer
2
// SPDX-License-Identifier: GPL-3.0-or-later
8
#include "
secretlineedit.h
"
9
#include "
clipboardmanager.h
"
10
#include <QAction>
11
#include <QApplication>
12
#include <QContextMenuEvent>
13
#include <QKeyEvent>
14
#include <QMenu>
15
#include <QMouseEvent>
16
17
SecretLineEdit::SecretLineEdit
(QWidget *parent) : QLineEdit(parent) {}
18
19
auto
SecretLineEdit::createSecretContextMenu
() -> QMenu * {
20
QMenu *menu = createStandardContextMenu();
21
for
(QAction *action : menu->actions()) {
22
// The standard actions call QLineEdit::copy() and cut(), which are not
23
// virtual.
24
if
(action->objectName() == QLatin1String(
"edit-copy"
)) {
25
disconnect(action, &QAction::triggered,
this
,
nullptr
);
26
connect(action, &QAction::triggered,
this
,
27
[
this
] {
copySelection
(QClipboard::Clipboard); });
28
}
else
if
(action->objectName() == QLatin1String(
"edit-cut"
)) {
29
disconnect(action, &QAction::triggered,
this
,
nullptr
);
30
connect(action, &QAction::triggered,
this
, [
this
] {
cutSelection
(); });
31
}
32
}
33
return
menu;
34
}
35
36
void
SecretLineEdit::keyPressEvent
(QKeyEvent *event) {
37
if
(event->matches(QKeySequence::Copy)) {
38
copySelection
(QClipboard::Clipboard);
39
event
->accept();
40
return
;
41
}
42
if
(event->matches(QKeySequence::Cut)) {
43
cutSelection
();
44
event
->accept();
45
return
;
46
}
47
// QLineEdit copies what these delete (Ctrl+K and Ctrl+U with the X11 key
48
// bindings), as a cut.
49
const
bool
toEnd =
event
->matches(QKeySequence::DeleteEndOfLine);
50
if
(toEnd || event->matches(QKeySequence::DeleteCompleteLine)) {
51
if
(!isReadOnly()) {
52
const
int
from = toEnd ? cursorPosition() : 0;
53
setSelection(from,
static_cast<
int
>
(text().size()) - from);
54
cutSelection
();
55
}
56
event
->accept();
57
return
;
58
}
59
withoutPlainSelectionCopy
([
this
, event] { QLineEdit::keyPressEvent(event); });
60
// Where QLineEdit would have copied: after a key it handled, not after a
61
// lone modifier or another key it ignores.
62
if
(event->isAccepted()) {
63
publishSelection
();
64
}
65
}
66
67
void
SecretLineEdit::mouseReleaseEvent
(QMouseEvent *event) {
68
withoutPlainSelectionCopy
(
69
[
this
, event] { QLineEdit::mouseReleaseEvent(event); });
70
if
(event->button() == Qt::LeftButton) {
71
publishSelection
();
72
}
73
}
74
75
void
SecretLineEdit::contextMenuEvent
(QContextMenuEvent *event) {
76
QMenu *menu =
createSecretContextMenu
();
77
menu->setAttribute(Qt::WA_DeleteOnClose);
78
menu->popup(event->globalPos());
79
}
80
81
void
SecretLineEdit::copySelection
(QClipboard::Mode mode) {
82
// As QLineEdit itself: nothing leaves a field that shows dots.
83
if
(echoMode() != QLineEdit::Normal || !hasSelectedText()) {
84
return
;
85
}
86
const
QString text = selectedText();
87
QApplication::clipboard()->setMimeData(
buildClipboardMimeData
(text), mode);
88
emit
copied
(text);
89
}
90
91
void
SecretLineEdit::cutSelection
() {
92
// As QLineEdit::cut(): a field that shows dots deletes without copying.
93
if
(isReadOnly() || !hasSelectedText()) {
94
return
;
95
}
96
copySelection
(QClipboard::Clipboard);
97
del();
98
}
99
100
void
SecretLineEdit::withoutPlainSelectionCopy
(
101
const
std::function<
void
()> &handler) {
102
// QLineEdit fills the primary selection with plain text itself, at the end
103
// of every key it handles and on a left-button release, but only in Normal
104
// echo mode (QWidgetLineControl::copy()). Replacing that afterwards still
105
// leaves a moment in which a clipboard manager could take the unmarked
106
// text, so the base handler runs in Password mode instead: same length,
107
// so cursor and selection stay where they are, and no copy.
108
// Editable, the field keeps Normal mode (see the class description) and
109
// publishSelection() replaces the plain copy.
110
if
(echoMode() != QLineEdit::Normal || !isReadOnly()) {
111
handler();
112
return
;
113
}
114
setEchoMode(QLineEdit::Password);
115
handler();
116
setEchoMode(QLineEdit::Normal);
117
}
118
119
void
SecretLineEdit::publishSelection
() {
120
if
(QApplication::clipboard()->supportsSelection()) {
121
copySelection
(QClipboard::Selection);
122
}
123
}
SecretLineEdit::mouseReleaseEvent
void mouseReleaseEvent(QMouseEvent *event) override
Fills the primary selection with the marked selection on a left-button release, instead of QLineEdit'...
Definition
secretlineedit.cpp:67
SecretLineEdit::copied
void copied(const QString &text)
Selected text was copied out of the line edit.
SecretLineEdit::cutSelection
void cutSelection()
Copies the selection through copySelection() and then deletes it. Does nothing when read-only or with...
Definition
secretlineedit.cpp:91
SecretLineEdit::withoutPlainSelectionCopy
void withoutPlainSelectionCopy(const std::function< void()> &handler)
Runs a base-class event handler so that it cannot fill the primary selection with plain text: in a re...
Definition
secretlineedit.cpp:100
SecretLineEdit::createSecretContextMenu
auto createSecretContextMenu() -> QMenu *
The standard context menu, with Copy and Cut going through the secret copy.
Definition
secretlineedit.cpp:19
SecretLineEdit::publishSelection
void publishSelection()
Fills the X11 primary selection with the marked selection, on platforms that have one; called after a...
Definition
secretlineedit.cpp:119
SecretLineEdit::SecretLineEdit
SecretLineEdit(QWidget *parent=nullptr)
Constructs the line edit.
Definition
secretlineedit.cpp:17
SecretLineEdit::contextMenuEvent
void contextMenuEvent(QContextMenuEvent *event) override
Shows createSecretContextMenu().
Definition
secretlineedit.cpp:75
SecretLineEdit::copySelection
void copySelection(QClipboard::Mode mode)
Puts the selection on the clipboard or in the primary selection as secret-marked MIME data and emits ...
Definition
secretlineedit.cpp:81
SecretLineEdit::keyPressEvent
void keyPressEvent(QKeyEvent *event) override
Ctrl+C copies with the hints, Ctrl+X as well before it deletes; after any other key the primary selec...
Definition
secretlineedit.cpp:36
buildClipboardMimeData
auto buildClipboardMimeData(const QString &text) -> QMimeData *
Build clipboard MIME data with platform-specific security hints.
Definition
clipboardmanager.cpp:190
clipboardmanager.h
ClipboardManager, which puts secrets on the clipboard and removes them again, and the MIME data that ...
secretlineedit.h
QLineEdit whose copies, cuts and primary-selection fills carry the secret clipboard hints and are rep...
src
secretlineedit.cpp
Generated by
1.18.0