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
14 #include "FancyLineEdit.h"
16 #if QT_VERSION >= 0x040600
18 #include <QtCore/QEvent>
19 #include <QtCore/QDebug>
20 #include <QtCore/QString>
21 #include <QtCore/QPropertyAnimation>
22 #include <QtGui/QApplication>
23 #include <QtGui/QMenu>
24 #include <QtGui/QMouseEvent>
25 #include <QtGui/QLabel>
26 #include <QtGui/QAbstractButton>
27 #include <QtGui/QPainter>
28 #include <QtGui/QStyle>
29 #include <QtGui/QPaintEvent>
33 #define ICONBUTTON_HEIGHT 18
40 // --------- FancyLineEditPrivate
41 class FancyLineEditPrivate : public QObject {
43 explicit FancyLineEditPrivate(FancyLineEdit *parent);
45 virtual bool eventFilter(QObject *obj, QEvent *event);
47 FancyLineEdit *m_lineEdit;
50 bool m_menuTabFocusTrigger[2];
51 IconButton *m_iconbutton[2];
52 bool m_iconEnabled[2];
56 FancyLineEditPrivate::FancyLineEditPrivate(FancyLineEdit *parent) :
60 for (int i = 0; i < 2; ++i) {
62 m_menuTabFocusTrigger[i] = false;
63 m_iconbutton[i] = new IconButton(parent);
64 m_iconbutton[i]->installEventFilter(this);
65 m_iconbutton[i]->hide();
66 m_iconbutton[i]->setAutoHide(false);
67 m_iconEnabled[i] = false;
71 bool FancyLineEditPrivate::eventFilter(QObject *obj, QEvent *event)
74 for (int i = 0; i < 2; ++i) {
75 if (obj == m_iconbutton[i]) {
80 if (buttonIndex == -1)
81 return QObject::eventFilter(obj, event);
82 switch (event->type()) {
84 if (m_menuTabFocusTrigger[buttonIndex] && m_menu[buttonIndex]) {
85 m_lineEdit->setFocus();
86 m_menu[buttonIndex]->exec(m_iconbutton[buttonIndex]->mapToGlobal(
87 m_iconbutton[buttonIndex]->rect().center()));
93 return QObject::eventFilter(obj, event);
97 // --------- FancyLineEdit
98 FancyLineEdit::FancyLineEdit(QWidget *parent) :
100 m_d(new FancyLineEditPrivate(this))
105 connect(this, SIGNAL(textChanged(QString)), this, SLOT(checkButtons(QString)));
106 connect(m_d->m_iconbutton[Left], SIGNAL(clicked()), this, SLOT(iconClicked()));
107 connect(m_d->m_iconbutton[Right], SIGNAL(clicked()), this, SLOT(iconClicked()));
110 void FancyLineEdit::checkButtons(const QString &text)
112 if (m_oldText.isEmpty() || text.isEmpty()) {
113 for (int i = 0; i < 2; ++i) {
114 if (m_d->m_iconbutton[i]->hasAutoHide())
115 m_d->m_iconbutton[i]->animateShow(!text.isEmpty());
121 FancyLineEdit::~FancyLineEdit()
125 void FancyLineEdit::setButtonVisible(Side side, bool visible)
127 m_d->m_iconbutton[side]->setVisible(visible);
128 m_d->m_iconEnabled[side] = visible;
132 bool FancyLineEdit::isButtonVisible(Side side) const
134 return m_d->m_iconEnabled[side];
137 void FancyLineEdit::iconClicked()
139 IconButton *button = qobject_cast<IconButton *>(sender());
141 for (int i = 0; i < 2; ++i)
142 if (m_d->m_iconbutton[i] == button)
146 if (m_d->m_menu[index]) {
147 m_d->m_menu[index]->exec(QCursor::pos());
149 buttonClicked((Side)index);
152 else if (index == Right)
153 rightButtonClicked();
157 void FancyLineEdit::updateMargins()
159 bool leftToRight = (layoutDirection() == Qt::LeftToRight);
160 Side realLeft = (leftToRight ? Left : Right);
161 Side realRight = (leftToRight ? Right : Left);
163 int leftMargin = m_d->m_iconbutton[realLeft]->pixmap().width() + 8;
164 int rightMargin = m_d->m_iconbutton[realRight]->pixmap().width() + 8;
165 // Note KDE does not reserve space for the highlight color
166 if (style()->inherits("OxygenStyle")) {
167 leftMargin = qMax(24, leftMargin);
168 rightMargin = qMax(24, rightMargin);
171 QMargins margins((m_d->m_iconEnabled[realLeft] ? leftMargin : 0), 0,
172 (m_d->m_iconEnabled[realRight] ? rightMargin : 0), 0);
174 setTextMargins(margins);
177 void FancyLineEdit::updateButtonPositions()
179 QRect contentRect = rect();
180 for (int i = 0; i < 2; ++i) {
181 Side iconpos = (Side)i;
182 if (layoutDirection() == Qt::RightToLeft)
183 iconpos = (iconpos == Left ? Right : Left);
185 if (iconpos == FancyLineEdit::Right) {
186 const int iconoffset = textMargins().right() + 4;
187 m_d->m_iconbutton[i]->setGeometry(contentRect.adjusted(width() - iconoffset, 0, 0, 0));
189 const int iconoffset = textMargins().left() + 4;
190 m_d->m_iconbutton[i]->setGeometry(contentRect.adjusted(0, 0, -width() + iconoffset, 0));
195 void FancyLineEdit::resizeEvent(QResizeEvent *)
197 updateButtonPositions();
200 void FancyLineEdit::setButtonPixmap(Side side, const QPixmap &buttonPixmap)
202 m_d->m_iconbutton[side]->setPixmap(buttonPixmap);
204 updateButtonPositions();
208 QPixmap FancyLineEdit::buttonPixmap(Side side) const
210 return m_d->m_pixmap[side];
213 void FancyLineEdit::setButtonMenu(Side side, QMenu *buttonMenu)
215 m_d->m_menu[side] = buttonMenu;
216 m_d->m_iconbutton[side]->setIconOpacity(1.0);
219 QMenu *FancyLineEdit::buttonMenu(Side side) const
221 return m_d->m_menu[side];
224 bool FancyLineEdit::hasMenuTabFocusTrigger(Side side) const
226 return m_d->m_menuTabFocusTrigger[side];
229 void FancyLineEdit::setMenuTabFocusTrigger(Side side, bool v)
231 if (m_d->m_menuTabFocusTrigger[side] == v)
234 m_d->m_menuTabFocusTrigger[side] = v;
235 m_d->m_iconbutton[side]->setFocusPolicy(v ? Qt::TabFocus : Qt::NoFocus);
238 bool FancyLineEdit::hasAutoHideButton(Side side) const
240 return m_d->m_iconbutton[side]->hasAutoHide();
243 void FancyLineEdit::setAutoHideButton(Side side, bool h)
245 m_d->m_iconbutton[side]->setAutoHide(h);
247 m_d->m_iconbutton[side]->setIconOpacity(text().isEmpty() ? 0.0 : 1.0);
249 m_d->m_iconbutton[side]->setIconOpacity(1.0);
252 void FancyLineEdit::setButtonToolTip(Side side, const QString &tip)
254 m_d->m_iconbutton[side]->setToolTip(tip);
257 void FancyLineEdit::setButtonFocusPolicy(Side side, Qt::FocusPolicy policy)
259 m_d->m_iconbutton[side]->setFocusPolicy(policy);
262 // IconButton - helper class to represent a clickable icon
264 IconButton::IconButton(QWidget *parent)
265 : QAbstractButton(parent), m_autoHide(false)
267 setCursor(Qt::ArrowCursor);
268 setFocusPolicy(Qt::NoFocus);
271 void IconButton::paintEvent(QPaintEvent *)
273 QPainter painter(this);
274 QRect pixmapRect = QRect(0, 0, m_pixmap.width(), m_pixmap.height());
275 pixmapRect.moveCenter(rect().center());
278 painter.setOpacity(m_iconOpacity);
280 painter.drawPixmap(pixmapRect, m_pixmap);
283 void IconButton::animateShow(bool visible)
286 QPropertyAnimation *animation = new QPropertyAnimation(this, "iconOpacity");
287 animation->setDuration(FADE_TIME);
288 animation->setEndValue(1.0);
289 animation->start(QAbstractAnimation::DeleteWhenStopped);
291 QPropertyAnimation *animation = new QPropertyAnimation(this, "iconOpacity");
292 animation->setDuration(FADE_TIME);
293 animation->setEndValue(0.0);
294 animation->start(QAbstractAnimation::DeleteWhenStopped);
302 #endif // QT_VERSION >= 0x040600
304 #include "moc_FancyLineEdit.cpp"