2 * \file fancylineedit.cpp
3 * This file is part of LyX, the document processor.
4 * Licence details can be found in the file COPYING.
6 * \author Nokia Corporation (qt-info@nokia.com)
8 * Full author contact details are available in file CREDITS.
12 // Code taken from the Qt Creator project and customized a little
16 #include "FancyLineEdit.h"
18 #if QT_VERSION >= 0x040600
23 #include <QPropertyAnimation>
24 #include <QApplication>
26 #include <QMouseEvent>
28 #include <QAbstractButton>
31 #include <QPaintEvent>
35 #define ICONBUTTON_HEIGHT 18
42 ////////////////////////////////////////////////////////////////////////
44 // FancyLineEditPrivate
46 ////////////////////////////////////////////////////////////////////////
48 class FancyLineEditPrivate : public QObject {
50 explicit FancyLineEditPrivate(FancyLineEdit *parent);
52 bool eventFilter(QObject *obj, QEvent *event) override;
54 FancyLineEdit *m_lineEdit;
57 bool m_menuTabFocusTrigger[2];
58 IconButton *m_iconbutton[2];
59 bool m_iconEnabled[2];
63 FancyLineEditPrivate::FancyLineEditPrivate(FancyLineEdit *parent)
64 : QObject(parent), m_lineEdit(parent)
66 for (int i = 0; i < 2; ++i) {
68 m_menuTabFocusTrigger[i] = false;
69 m_iconbutton[i] = new IconButton(parent);
70 m_iconbutton[i]->installEventFilter(this);
71 m_iconbutton[i]->hide();
72 m_iconbutton[i]->setAutoHide(false);
73 m_iconEnabled[i] = false;
78 bool FancyLineEditPrivate::eventFilter(QObject *obj, QEvent *event)
81 for (int i = 0; i < 2; ++i) {
82 if (obj == m_iconbutton[i]) {
87 if (buttonIndex == -1)
88 return QObject::eventFilter(obj, event);
89 switch (event->type()) {
91 if (m_menuTabFocusTrigger[buttonIndex] && m_menu[buttonIndex]) {
92 m_lineEdit->setFocus();
93 m_menu[buttonIndex]->exec(m_iconbutton[buttonIndex]->mapToGlobal(
94 m_iconbutton[buttonIndex]->rect().center()));
100 return QObject::eventFilter(obj, event);
104 ////////////////////////////////////////////////////////////////////////
108 ////////////////////////////////////////////////////////////////////////
110 FancyLineEdit::FancyLineEdit(QWidget *parent) :
112 m_d(new FancyLineEditPrivate(this))
117 connect(this, SIGNAL(textChanged(QString)),
118 this, SLOT(checkButtons(QString)));
119 connect(m_d->m_iconbutton[Left], SIGNAL(clicked()),
120 this, SLOT(iconClicked()));
121 connect(m_d->m_iconbutton[Right], SIGNAL(clicked()),
122 this, SLOT(iconClicked()));
126 void FancyLineEdit::checkButtons(const QString &text)
128 if (m_oldText.isEmpty() || text.isEmpty()) {
129 for (int i = 0; i < 2; ++i) {
130 if (m_d->m_iconbutton[i]->hasAutoHide())
131 m_d->m_iconbutton[i]->animateShow(!text.isEmpty());
138 void FancyLineEdit::setButtonVisible(Side side, bool visible)
140 m_d->m_iconbutton[side]->setVisible(visible);
141 m_d->m_iconEnabled[side] = visible;
146 bool FancyLineEdit::isButtonVisible(Side side) const
148 return m_d->m_iconEnabled[side];
152 void FancyLineEdit::iconClicked()
154 IconButton *button = qobject_cast<IconButton *>(sender());
156 for (int i = 0; i < 2; ++i)
157 if (m_d->m_iconbutton[i] == button)
161 if (m_d->m_menu[index]) {
162 m_d->m_menu[index]->exec(QCursor::pos());
164 buttonClicked((Side)index);
167 else if (index == Right)
168 rightButtonClicked();
173 void FancyLineEdit::updateMargins()
175 bool leftToRight = (layoutDirection() == Qt::LeftToRight);
176 Side realLeft = (leftToRight ? Left : Right);
177 Side realRight = (leftToRight ? Right : Left);
179 int leftMargin = m_d->m_iconbutton[realLeft]->pixmap().width() + 8;
180 int rightMargin = m_d->m_iconbutton[realRight]->pixmap().width() + 8;
181 // Note KDE does not reserve space for the highlight color
182 if (style()->inherits("OxygenStyle")) {
183 leftMargin = qMax(24, leftMargin);
184 rightMargin = qMax(24, rightMargin);
187 QMargins margins((m_d->m_iconEnabled[realLeft] ? leftMargin : 0), 0,
188 (m_d->m_iconEnabled[realRight] ? rightMargin : 0), 0);
190 setTextMargins(margins);
194 void FancyLineEdit::updateButtonPositions()
196 QRect contentRect = rect();
197 for (int i = 0; i < 2; ++i) {
198 Side iconpos = (Side)i;
199 if (layoutDirection() == Qt::RightToLeft)
200 iconpos = (iconpos == Left ? Right : Left);
202 if (iconpos == FancyLineEdit::Right) {
203 const int iconoffset = textMargins().right() + 4;
204 m_d->m_iconbutton[i]->setGeometry(
205 contentRect.adjusted(width() - iconoffset,
208 const int iconoffset = textMargins().left() + 4;
209 m_d->m_iconbutton[i]->setGeometry(
210 contentRect.adjusted(0, 0,
211 -width() + iconoffset, 0));
217 void FancyLineEdit::resizeEvent(QResizeEvent *)
219 updateButtonPositions();
223 void FancyLineEdit::keyPressEvent(QKeyEvent * e)
225 if (e->type() == QEvent::KeyPress && e->key() == Qt::Key_Down)
226 Q_EMIT downPressed();
228 QLineEdit::keyPressEvent(e);
232 void FancyLineEdit::setButtonPixmap(Side side, const QPixmap &buttonPixmap)
234 m_d->m_iconbutton[side]->setPixmap(buttonPixmap);
236 updateButtonPositions();
241 QPixmap FancyLineEdit::buttonPixmap(Side side) const
243 return m_d->m_pixmap[side];
247 void FancyLineEdit::setButtonMenu(Side side, QMenu *buttonMenu)
249 m_d->m_menu[side] = buttonMenu;
250 m_d->m_iconbutton[side]->setIconOpacity(1.0);
253 QMenu *FancyLineEdit::buttonMenu(Side side) const
255 return m_d->m_menu[side];
259 bool FancyLineEdit::hasMenuTabFocusTrigger(Side side) const
261 return m_d->m_menuTabFocusTrigger[side];
265 void FancyLineEdit::setMenuTabFocusTrigger(Side side, bool v)
267 if (m_d->m_menuTabFocusTrigger[side] == v)
270 m_d->m_menuTabFocusTrigger[side] = v;
271 m_d->m_iconbutton[side]->setFocusPolicy(v ? Qt::TabFocus : Qt::NoFocus);
275 bool FancyLineEdit::hasAutoHideButton(Side side) const
277 return m_d->m_iconbutton[side]->hasAutoHide();
281 void FancyLineEdit::setAutoHideButton(Side side, bool h)
283 m_d->m_iconbutton[side]->setAutoHide(h);
285 m_d->m_iconbutton[side]->setIconOpacity(text().isEmpty() ? 0.0 : 1.0);
287 m_d->m_iconbutton[side]->setIconOpacity(1.0);
291 void FancyLineEdit::setButtonToolTip(Side side, const QString &tip)
293 m_d->m_iconbutton[side]->setToolTip(tip);
297 void FancyLineEdit::setButtonFocusPolicy(Side side, Qt::FocusPolicy policy)
299 m_d->m_iconbutton[side]->setFocusPolicy(policy);
303 ////////////////////////////////////////////////////////////////////////
305 // IconButton - helper class to represent a clickable icon
307 ////////////////////////////////////////////////////////////////////////
309 IconButton::IconButton(QWidget *parent)
310 : QAbstractButton(parent), m_iconOpacity(0.0), m_autoHide(false)
312 setCursor(Qt::ArrowCursor);
313 setFocusPolicy(Qt::NoFocus);
317 void IconButton::paintEvent(QPaintEvent *)
319 QPainter painter(this);
320 QRect pixmapRect = QRect(0, 0, m_pixmap.width(), m_pixmap.height());
321 pixmapRect.moveCenter(rect().center());
324 painter.setOpacity(m_iconOpacity);
326 painter.drawPixmap(pixmapRect, m_pixmap);
330 void IconButton::animateShow(bool visible)
333 QPropertyAnimation *animation =
334 new QPropertyAnimation(this, "iconOpacity");
335 animation->setDuration(FADE_TIME);
336 animation->setEndValue(1.0);
337 animation->start(QAbstractAnimation::DeleteWhenStopped);
339 QPropertyAnimation *animation =
340 new QPropertyAnimation(this, "iconOpacity");
341 animation->setDuration(FADE_TIME);
342 animation->setEndValue(0.0);
343 animation->start(QAbstractAnimation::DeleteWhenStopped);
347 } // namespace frontend
351 #endif // QT_VERSION >= 0x040600
353 #include "moc_FancyLineEdit.cpp"