1 /* apply_lineedit.cpp
2 *
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include <ui/qt/widgets/apply_line_edit.h>
11
12 #include <epan/prefs.h>
13
14 #include <ui/qt/utils/color_utils.h>
15
16 #include <QRegExp>
17 #include <QRegExpValidator>
18 #include <QStyle>
19
ApplyLineEdit(QString linePlaceholderText,QWidget * parent)20 ApplyLineEdit::ApplyLineEdit(QString linePlaceholderText, QWidget * parent)
21 : QLineEdit(parent),
22 apply_button_(0)
23 {
24 emptyAllowed_ = false;
25 regex_ = QString();
26
27 apply_button_ = new StockIconToolButton(parent, "x-filter-apply");
28 apply_button_->setCursor(Qt::ArrowCursor);
29 apply_button_->setEnabled(false);
30 apply_button_->setToolTip(tr("Apply changes"));
31 apply_button_->setIconSize(QSize(24, 14));
32 apply_button_->setMaximumWidth(30);
33 apply_button_->setStyleSheet(
34 "QToolButton {"
35 " border: none;"
36 " background: transparent;" // Disables platform style on Windows.
37 " padding: 0 0 0 0;"
38 "}"
39 );
40
41 #ifdef Q_OS_MAC
42 setAttribute(Qt::WA_MacSmallSize, true);
43 apply_button_->setAttribute(Qt::WA_MacSmallSize, true);
44 #endif
45
46 setPlaceholderText(linePlaceholderText);
47
48 connect(this, &ApplyLineEdit::textEdited, this, &ApplyLineEdit::onTextEdited);
49 connect(this, &ApplyLineEdit::textChanged, this, &ApplyLineEdit::onTextChanged);
50
51 connect(this, &ApplyLineEdit::returnPressed, this, &ApplyLineEdit::onSubmitContent);
52 connect(apply_button_, &StockIconToolButton::clicked, this, &ApplyLineEdit::onSubmitContent);
53
54 handleValidation(QString(linePlaceholderText));
55
56 setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
57 }
58
~ApplyLineEdit()59 ApplyLineEdit::~ApplyLineEdit() {}
60
setRegEx(QString regex)61 void ApplyLineEdit::setRegEx(QString regex)
62 {
63 regex_ = regex;
64 }
65
regex()66 QString ApplyLineEdit::regex()
67 {
68 return regex_;
69 }
70
setEmptyAllowed(bool emptyAllowed)71 void ApplyLineEdit::setEmptyAllowed(bool emptyAllowed)
72 {
73 emptyAllowed_ = emptyAllowed;
74 }
75
emptyAllowed()76 bool ApplyLineEdit::emptyAllowed()
77 {
78 return emptyAllowed_;
79 }
80
isValidText(QString & text,bool ignoreEmptyCheck)81 bool ApplyLineEdit::isValidText(QString & text, bool ignoreEmptyCheck)
82 {
83 if (text.length() == 0)
84 {
85 if (! ignoreEmptyCheck && ! emptyAllowed_)
86 return false;
87 else if (ignoreEmptyCheck)
88 return true;
89 }
90
91 if (regex_.length() > 0)
92 {
93 QRegExp rx (regex_);
94 QRegExpValidator v(rx, 0);
95
96 int pos = 0;
97 if (! rx.isValid() || v.validate(text, pos) != QValidator::Acceptable)
98 return false;
99 }
100
101 return true;
102 }
103
onTextEdited(const QString & text)104 void ApplyLineEdit::onTextEdited(const QString & text)
105 {
106 QString newText = QString(text);
107 apply_button_->setEnabled(isValidText(newText));
108 handleValidation(newText);
109 }
110
onTextChanged(const QString & text)111 void ApplyLineEdit::onTextChanged(const QString & text)
112 {
113 handleValidation(QString(text));
114 }
115
handleValidation(QString newText)116 void ApplyLineEdit::handleValidation(QString newText)
117 {
118 int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
119
120 QString style_sheet = QString(
121 "ApplyLineEdit {"
122 " padding-left: %1px;"
123 " padding-right: %2px;"
124 " background-color: %3;"
125 "}"
126 )
127 .arg(frameWidth + 1)
128 .arg(apply_button_->sizeHint().width() + frameWidth)
129 .arg(isValidText(newText, true) ? QString("") : ColorUtils::fromColorT(prefs.gui_text_invalid).name());
130
131 setStyleSheet(style_sheet);
132 }
133
resizeEvent(QResizeEvent *)134 void ApplyLineEdit::resizeEvent(QResizeEvent *)
135 {
136 int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
137 QSize apsz = apply_button_->sizeHint();
138
139 apply_button_->move((contentsRect().right() + pos().x()) - (frameWidth + apsz.width()) - 2,
140 contentsRect().top() + pos().y());
141
142 apply_button_->setMinimumHeight(height());
143 apply_button_->setMaximumHeight(height());
144 }
145
onSubmitContent()146 void ApplyLineEdit::onSubmitContent()
147 {
148 QString data = text();
149 if (! isValidText(data))
150 return;
151
152 /* Freeze apply button to signal the text has been sent. Will be unfreezed, if the text in the textbox changes again */
153 apply_button_->setEnabled(false);
154
155 emit textApplied();
156 }
157