1 /* interface_toolbar_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 "config.h"
11 
12 #include <ui/qt/widgets/interface_toolbar_lineedit.h>
13 #include <ui/qt/widgets/stock_icon_tool_button.h>
14 #include "epan/prefs.h"
15 #include <ui/qt/utils/color_utils.h>
16 
17 #include <QStyle>
18 
19 // To do:
20 // - Make a narrower apply button
21 
InterfaceToolbarLineEdit(QWidget * parent,QString validation_regex,bool is_required)22 InterfaceToolbarLineEdit::InterfaceToolbarLineEdit(QWidget *parent, QString validation_regex, bool is_required) :
23     QLineEdit(parent),
24     regex_expr_(validation_regex),
25     is_required_(is_required),
26     text_edited_(false)
27 {
28     apply_button_ = new StockIconToolButton(this, "x-filter-apply");
29     apply_button_->setCursor(Qt::ArrowCursor);
30     apply_button_->setEnabled(false);
31     apply_button_->setToolTip(tr("Apply changes"));
32     apply_button_->setIconSize(QSize(24, 14));
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     updateStyleSheet(isValid());
42 
43     connect(this, &InterfaceToolbarLineEdit::textChanged, this, &InterfaceToolbarLineEdit::validateText);
44     connect(this, &InterfaceToolbarLineEdit::textEdited, this, &InterfaceToolbarLineEdit::validateEditedText);
45     connect(this, &InterfaceToolbarLineEdit::returnPressed, this, &InterfaceToolbarLineEdit::applyEditedText);
46     connect(apply_button_, &StockIconToolButton::clicked, this, &InterfaceToolbarLineEdit::applyEditedText);
47 }
48 
validateText()49 void InterfaceToolbarLineEdit::validateText()
50 {
51     bool valid = isValid();
52 
53     apply_button_->setEnabled(valid);
54     updateStyleSheet(valid);
55 }
56 
validateEditedText()57 void InterfaceToolbarLineEdit::validateEditedText()
58 {
59     text_edited_ = true;
60 }
61 
applyEditedText()62 void InterfaceToolbarLineEdit::applyEditedText()
63 {
64     if (text_edited_ && isValid())
65     {
66         emit editedTextApplied();
67         disableApplyButton();
68     }
69 }
70 
disableApplyButton()71 void InterfaceToolbarLineEdit::disableApplyButton()
72 {
73     apply_button_->setEnabled(false);
74     text_edited_ = false;
75 }
76 
isValid()77 bool InterfaceToolbarLineEdit::isValid()
78 {
79     bool valid = true;
80 
81     if (is_required_ && text().length() == 0)
82     {
83         valid = false;
84     }
85 
86     if (!regex_expr_.isEmpty() && text().length() > 0)
87     {
88         if (!regex_expr_.isValid() || regex_expr_.indexIn(text(), 0) == -1)
89         {
90             valid = false;
91         }
92     }
93 
94     return valid;
95 }
96 
updateStyleSheet(bool is_valid)97 void InterfaceToolbarLineEdit::updateStyleSheet(bool is_valid)
98 {
99     int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
100     QSize apsz = apply_button_->sizeHint();
101 
102     QString style_sheet = QString(
103             "InterfaceToolbarLineEdit {"
104             "  padding-right: %1px;"
105             "  background-color: %2;"
106             "}"
107             )
108             .arg(apsz.width() + frameWidth)
109             .arg(is_valid || !isEnabled() ? QString("") : ColorUtils::fromColorT(prefs.gui_text_invalid).name());
110 
111     setStyleSheet(style_sheet);
112 }
113 
resizeEvent(QResizeEvent *)114 void InterfaceToolbarLineEdit::resizeEvent(QResizeEvent *)
115 {
116     int frameWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth);
117     QSize apsz = apply_button_->sizeHint();
118 
119     apply_button_->move(contentsRect().right() - frameWidth - apsz.width() + 2,
120                         contentsRect().top());
121     apply_button_->setMinimumHeight(contentsRect().height());
122     apply_button_->setMaximumHeight(contentsRect().height());
123 }
124