]> git.sur5r.net Git - minitube/blob - src/searchlineedit.cpp
Merge tag 'upstream/2.3'
[minitube] / src / searchlineedit.cpp
1 #include "searchlineedit.h"
2
3 #include <QPainter>
4 #include <QMouseEvent>
5 #include <QMenu>
6 #include <QStyle>
7 #include <QStyleOptionFrameV2>
8
9 #include "autocomplete.h"
10 #include "iconutils.h"
11
12 ClearButton::ClearButton(QWidget *parent) : QAbstractButton(parent), hovered(false), mousePressed(false) {
13     setCursor(Qt::ArrowCursor);
14     setToolTip(tr("Clear"));
15     setVisible(false);
16     setFocusPolicy(Qt::NoFocus);
17 }
18
19 void ClearButton::paintEvent(QPaintEvent *e) {
20     Q_UNUSED(e);
21     QPainter painter(this);
22     const int h = height();
23     int iconSize = 16;
24     if (h > 30) iconSize = 22;
25     QIcon::Mode iconMode = QIcon::Normal;
26     if (mousePressed) iconMode = QIcon::Active;
27     QPixmap p = IconUtils::icon("edit-clear").pixmap(iconSize, iconSize, iconMode);
28     // QPixmap p = IconUtils::tintedIcon("edit-clear", Qt::black, QSize(iconSize, iconSize)).pixmap(iconSize, iconSize, iconMode);
29     int x = (width() - p.width()) / 2;
30     int y = (h - p.height()) / 2;
31     painter.drawPixmap(x, y, p);
32 }
33
34 void ClearButton::textChanged(const QString &text) {
35     setVisible(!text.isEmpty());
36 }
37
38 void ClearButton::enterEvent(QEvent *e) {
39     Q_UNUSED(e);
40     hovered = true;
41 }
42
43 void ClearButton::leaveEvent(QEvent *e) {
44     Q_UNUSED(e);
45     hovered = false;
46 }
47
48 void ClearButton::mousePressEvent(QEvent *e) {
49     Q_UNUSED(e);
50     mousePressed = true;
51 }
52
53 void ClearButton::mouseReleaseEvent(QEvent *e) {
54     Q_UNUSED(e);
55     mousePressed = false;
56 }
57
58 /*
59     Search icon on the left hand side of the search widget
60     When a menu is set a down arrow appears
61  */
62 class SearchButton : public QAbstractButton {
63 public:
64     SearchButton(QWidget *parent = 0);
65     void paintEvent(QPaintEvent *event);
66     QMenu *m_menu;
67
68 protected:
69     void mousePressEvent(QMouseEvent *event);
70 };
71
72 SearchButton::SearchButton(QWidget *parent)
73     : QAbstractButton(parent),
74     m_menu(0) {
75     setObjectName(QLatin1String("SearchButton"));
76     setCursor(Qt::ArrowCursor);
77     setFocusPolicy(Qt::NoFocus);
78 }
79
80 void SearchButton::mousePressEvent(QMouseEvent *event) {
81     if (m_menu && event->button() == Qt::LeftButton) {
82         QWidget *p = parentWidget();
83         if (p) {
84             QPoint r = p->mapToGlobal(QPoint(0, p->height()));
85             m_menu->exec(QPoint(r.x() + height() / 2, r.y()));
86         }
87         event->accept();
88     }
89     QAbstractButton::mousePressEvent(event);
90 }
91
92 void SearchButton::paintEvent(QPaintEvent *event) {
93     Q_UNUSED(event);
94     QPainter painter(this);
95     const int h = height();
96     int iconSize = 16;
97     if (h > 30) iconSize = 22;
98     QPixmap p = IconUtils::icon("edit-find").pixmap(iconSize, iconSize);
99     int x = (width() - p.width()) / 2;
100     int y = (h - p.height()) / 2;
101     painter.drawPixmap(x, y, p);
102 }
103
104 /*
105     SearchLineEdit is an enhanced QLineEdit
106     - A Search icon on the left with optional menu
107     - When there is no text and doesn't have focus an "inactive text" is displayed
108     - When there is text a clear button is displayed on the right hand side
109  */
110 SearchLineEdit::SearchLineEdit(QWidget *parent) : ExLineEdit(parent),
111 searchButton(new SearchButton(this)) {
112     connect(lineEdit(), SIGNAL(textChanged(const QString &)), SIGNAL(textChanged(const QString &)));
113     connect(lineEdit(), SIGNAL(textEdited(const QString &)), SIGNAL(textEdited(const QString &)));
114     connect(lineEdit(), SIGNAL(returnPressed()), SLOT(returnPressed()));
115
116     setLeftWidget(searchButton);
117     inactiveText = tr("Search");
118
119     QSizePolicy policy = sizePolicy();
120     setSizePolicy(QSizePolicy::Preferred, policy.verticalPolicy());
121
122     // completion
123     autoComplete = new AutoComplete(this, m_lineEdit);
124     connect(autoComplete, SIGNAL(suggestionAccepted(Suggestion*)), SIGNAL(suggestionAccepted(Suggestion*)));
125 }
126
127 void SearchLineEdit::paintEvent(QPaintEvent *event) {
128     if (lineEdit()->text().isEmpty() && !hasFocus() && !inactiveText.isEmpty()) {
129         ExLineEdit::paintEvent(event);
130         QStyleOptionFrameV2 panel;
131         initStyleOption(&panel);
132         QRect r = style()->subElementRect(QStyle::SE_LineEditContents, &panel, this);
133         QFontMetrics fm = fontMetrics();
134         int horizontalMargin = lineEdit()->x();
135         QRect lineRect(horizontalMargin + r.x(), r.y() + (r.height() - fm.height() + 1) / 2,
136                        r.width() - 2 * horizontalMargin, fm.height());
137         QPainter painter(this);
138         painter.setPen(palette().brush(QPalette::Disabled, QPalette::Text).color());
139         painter.drawText(lineRect, Qt::AlignLeft|Qt::AlignVCenter, inactiveText);
140     } else {
141         ExLineEdit::paintEvent(event);
142     }
143 }
144
145 void SearchLineEdit::resizeEvent(QResizeEvent *event) {
146     updateGeometries();
147     ExLineEdit::resizeEvent(event);
148 }
149
150 void SearchLineEdit::updateGeometries() {
151     int menuHeight = height();
152     int menuWidth = menuHeight + 1;
153     if (!searchButton->m_menu)
154         menuWidth = (menuHeight / 5) * 4;
155     searchButton->resize(QSize(menuWidth, menuHeight));
156 }
157
158 void SearchLineEdit::setInactiveText(const QString &text) {
159     inactiveText = text;
160 }
161
162 void SearchLineEdit::setMenu(QMenu *menu) {
163     if (searchButton->m_menu)
164         searchButton->m_menu->deleteLater();
165     searchButton->m_menu = menu;
166     updateGeometries();
167 }
168
169 QMenu *SearchLineEdit::menu() const {
170     if (!searchButton->m_menu) {
171         searchButton->m_menu = new QMenu(searchButton);
172         if (isVisible())
173             (const_cast<SearchLineEdit*>(this))->updateGeometries();
174     }
175     return searchButton->m_menu;
176 }
177
178 void SearchLineEdit::returnPressed() {
179     if (!lineEdit()->text().isEmpty()) {
180         autoComplete->preventSuggest();
181         emit search(lineEdit()->text());
182     }
183 }
184
185 void SearchLineEdit::enableSuggest() {
186     autoComplete->enableSuggest();
187 }
188
189 void SearchLineEdit::preventSuggest() {
190     autoComplete->preventSuggest();
191 }
192
193 void SearchLineEdit::focusInEvent(QFocusEvent *event) {
194     ExLineEdit::focusInEvent(event);
195     enableSuggest();
196 }