1 #include "exlineedit.h"
2 #include "iconutils.h"
3
ClearButton(QWidget * parent)4 ClearButton::ClearButton(QWidget *parent)
5 : QAbstractButton(parent), hovered(false), mousePressed(false) {
6 setCursor(Qt::ArrowCursor);
7 setToolTip(tr("Clear"));
8 setVisible(false);
9 setFocusPolicy(Qt::NoFocus);
10 }
11
paintEvent(QPaintEvent * e)12 void ClearButton::paintEvent(QPaintEvent *e) {
13 Q_UNUSED(e);
14 QPainter painter(this);
15 const int h = height();
16 int iconSize = 16;
17 if (h > 32) iconSize = 22;
18 QIcon::Mode iconMode = QIcon::Normal;
19 if (mousePressed) iconMode = QIcon::Active;
20 QPixmap p = IconUtils::icon("edit-clear").pixmap(iconSize, iconSize, iconMode);
21 int x = (width() - p.width()) / 2;
22 int y = (h - p.height()) / 2;
23 painter.drawPixmap(x, y, p);
24 }
25
textChanged(const QString & text)26 void ClearButton::textChanged(const QString &text) {
27 setVisible(!text.isEmpty());
28 }
29
enterEvent(QEvent * e)30 void ClearButton::enterEvent(QEvent *e) {
31 hovered = true;
32 QAbstractButton::enterEvent(e);
33 }
34
leaveEvent(QEvent * e)35 void ClearButton::leaveEvent(QEvent *e) {
36 hovered = false;
37 QAbstractButton::leaveEvent(e);
38 }
39
mousePressEvent(QMouseEvent * e)40 void ClearButton::mousePressEvent(QMouseEvent *e) {
41 mousePressed = true;
42 QAbstractButton::mousePressEvent(e);
43 }
44
mouseReleaseEvent(QMouseEvent * e)45 void ClearButton::mouseReleaseEvent(QMouseEvent *e) {
46 mousePressed = false;
47 QAbstractButton::mouseReleaseEvent(e);
48 }
49
ExLineEdit(QWidget * parent)50 ExLineEdit::ExLineEdit(QWidget *parent)
51 : QWidget(parent), m_leftWidget(nullptr), m_lineEdit(new QLineEdit(this)),
52 m_clearButton(new ClearButton(this)) {
53 setFocusPolicy(m_lineEdit->focusPolicy());
54 setAttribute(Qt::WA_InputMethodEnabled);
55 setSizePolicy(m_lineEdit->sizePolicy());
56 setBackgroundRole(m_lineEdit->backgroundRole());
57 setMouseTracking(true);
58 setAcceptDrops(true);
59 setAttribute(Qt::WA_MacShowFocusRect, true);
60 QPalette p = m_lineEdit->palette();
61 setPalette(p);
62
63 // line edit
64 m_lineEdit->setFrame(false);
65 m_lineEdit->setFocusProxy(this);
66 m_lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
67 m_lineEdit->setStyleSheet("background:transparent");
68 QPalette clearPalette = m_lineEdit->palette();
69 clearPalette.setBrush(QPalette::Base, QBrush(Qt::transparent));
70 m_lineEdit->setPalette(clearPalette);
71
72 // clearButton
73 connect(m_clearButton, SIGNAL(clicked()), m_lineEdit, SLOT(clear()));
74 connect(m_lineEdit, SIGNAL(textChanged(const QString &)), m_clearButton,
75 SLOT(textChanged(const QString &)));
76 }
77
setFont(const QFont & font)78 void ExLineEdit::setFont(const QFont &font) {
79 m_lineEdit->setFont(font);
80 updateGeometries();
81 }
82
setLeftWidget(QWidget * widget)83 void ExLineEdit::setLeftWidget(QWidget *widget) {
84 m_leftWidget = widget;
85 }
86
leftWidget() const87 QWidget *ExLineEdit::leftWidget() const {
88 return m_leftWidget;
89 }
90
clear()91 void ExLineEdit::clear() {
92 m_lineEdit->clear();
93 }
94
text()95 QString ExLineEdit::text() {
96 return m_lineEdit->text();
97 }
98
resizeEvent(QResizeEvent * e)99 void ExLineEdit::resizeEvent(QResizeEvent *e) {
100 Q_ASSERT(m_leftWidget);
101 updateGeometries();
102 QWidget::resizeEvent(e);
103 }
104
updateGeometries()105 void ExLineEdit::updateGeometries() {
106 QStyleOptionFrame panel;
107 initStyleOption(&panel);
108 QRect rect = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
109
110 int padding = 3;
111 // int height = rect.height() + padding*2;
112 int width = rect.width();
113
114 // int m_leftWidgetHeight = m_leftWidget->height();
115 m_leftWidget->setGeometry(rect.x() + 2, 0, m_leftWidget->width(), m_leftWidget->height());
116
117 int clearButtonWidth = this->height();
118 m_lineEdit->setGeometry(m_leftWidget->x() + m_leftWidget->width(), padding,
119 width - clearButtonWidth - m_leftWidget->width(),
120 this->height() - padding * 2);
121
122 m_clearButton->setGeometry(this->width() - clearButtonWidth, 0, clearButtonWidth,
123 this->height());
124 }
125
initStyleOption(QStyleOptionFrame * option) const126 void ExLineEdit::initStyleOption(QStyleOptionFrame *option) const {
127 option->initFrom(this);
128 option->rect = contentsRect();
129 option->lineWidth = style()->pixelMetric(QStyle::PM_DefaultFrameWidth, option, this);
130 option->midLineWidth = 0;
131 option->state |= QStyle::State_Sunken;
132 if (m_lineEdit->isReadOnly()) option->state |= QStyle::State_ReadOnly;
133 #ifdef QT_KEYPAD_NAVIGATION
134 if (hasEditFocus()) option->state |= QStyle::State_HasEditFocus;
135 #endif
136 option->features = QStyleOptionFrame::None;
137 }
138
sizeHint() const139 QSize ExLineEdit::sizeHint() const {
140 m_lineEdit->setFrame(true);
141 QSize size = m_lineEdit->sizeHint();
142 m_lineEdit->setFrame(false);
143 size = size + QSize(3, 3);
144 return size;
145 }
146
focusInEvent(QFocusEvent * e)147 void ExLineEdit::focusInEvent(QFocusEvent *e) {
148 m_lineEdit->event(e);
149 QWidget::focusInEvent(e);
150 }
151
focusOutEvent(QFocusEvent * e)152 void ExLineEdit::focusOutEvent(QFocusEvent *e) {
153 m_lineEdit->event(e);
154
155 if (m_lineEdit->completer()) {
156 connect(m_lineEdit->completer(), SIGNAL(activated(QString)), m_lineEdit,
157 SLOT(setText(QString)));
158 connect(m_lineEdit->completer(), SIGNAL(highlighted(QString)), m_lineEdit,
159 SLOT(_q_completionHighlighted(QString)));
160 }
161 QWidget::focusOutEvent(e);
162 }
163
keyPressEvent(QKeyEvent * e)164 void ExLineEdit::keyPressEvent(QKeyEvent *e) {
165 if (e->key() == Qt::Key_Escape && !m_lineEdit->text().isEmpty()) {
166 m_lineEdit->clear();
167 }
168 m_lineEdit->event(e);
169 QWidget::keyPressEvent(e);
170 }
171
event(QEvent * e)172 bool ExLineEdit::event(QEvent *e) {
173 if (e->type() == QEvent::ShortcutOverride || e->type() == QEvent::InputMethod)
174 m_lineEdit->event(e);
175 return QWidget::event(e);
176 }
177
paintEvent(QPaintEvent * e)178 void ExLineEdit::paintEvent(QPaintEvent *e) {
179 Q_UNUSED(e);
180 if (hasFocus()) {
181 QPainter p(this);
182 QStyleOptionFrame panel;
183 initStyleOption(&panel);
184 style()->drawPrimitive(QStyle::PE_PanelLineEdit, &panel, &p, this);
185 }
186 }
187