X-Git-Url: https://git.lyx.org/gitweb/?a=blobdiff_plain;f=src%2Ffrontends%2Fqt%2FFancyLineEdit.cpp;h=b9874d2e89389a25e7b9ea2c6986544843b4bcbe;hb=89394bcd0f3b5079a066d8c3f6f7a5e606073db3;hp=b8d761bf49cd8ee47ea8b8115a707df6940b6b89;hpb=7d38a4d126e8e2dab08c6a47947b913921c3f083;p=features.git diff --git a/src/frontends/qt/FancyLineEdit.cpp b/src/frontends/qt/FancyLineEdit.cpp index b8d761bf49..b9874d2e89 100644 --- a/src/frontends/qt/FancyLineEdit.cpp +++ b/src/frontends/qt/FancyLineEdit.cpp @@ -15,6 +15,10 @@ #include "FancyLineEdit.h" +#if QT_VERSION < 0x050200 +#include "GuiApplication.h" +#endif + #if QT_VERSION >= 0x040600 #include @@ -29,6 +33,9 @@ #include #include #include +#if QT_VERSION >= 0x050000 +#include +#endif enum { margin = 6 }; @@ -39,165 +46,203 @@ enum { margin = 6 }; namespace lyx { namespace frontend { -// --------- FancyLineEditPrivate +//////////////////////////////////////////////////////////////////////// +// +// FancyLineEditPrivate +// +//////////////////////////////////////////////////////////////////////// + class FancyLineEditPrivate : public QObject { public: - explicit FancyLineEditPrivate(FancyLineEdit *parent); + explicit FancyLineEditPrivate(FancyLineEdit *parent); - bool eventFilter(QObject *obj, QEvent *event) override; + bool eventFilter(QObject *obj, QEvent *event) override; - FancyLineEdit *m_lineEdit; - QPixmap m_pixmap[2]; - QMenu *m_menu[2]; - bool m_menuTabFocusTrigger[2]; - IconButton *m_iconbutton[2]; - bool m_iconEnabled[2]; + FancyLineEdit *m_lineEdit; + QPixmap m_pixmap[2]; + QMenu *m_menu[2]; + bool m_menuTabFocusTrigger[2]; + IconButton *m_iconbutton[2]; + bool m_iconEnabled[2]; }; -FancyLineEditPrivate::FancyLineEditPrivate(FancyLineEdit *parent) : - QObject(parent), - m_lineEdit(parent) +FancyLineEditPrivate::FancyLineEditPrivate(FancyLineEdit *parent) + : QObject(parent), m_lineEdit(parent) { - for (int i = 0; i < 2; ++i) { - m_menu[i] = nullptr; - m_menuTabFocusTrigger[i] = false; - m_iconbutton[i] = new IconButton(parent); - m_iconbutton[i]->installEventFilter(this); - m_iconbutton[i]->hide(); - m_iconbutton[i]->setAutoHide(false); - m_iconEnabled[i] = false; - } + for (int i = 0; i < 2; ++i) { + m_menu[i] = nullptr; + m_menuTabFocusTrigger[i] = false; + m_iconbutton[i] = new IconButton(parent); + m_iconbutton[i]->installEventFilter(this); + m_iconbutton[i]->hide(); + m_iconbutton[i]->setAutoHide(false); + m_iconEnabled[i] = false; + } } + bool FancyLineEditPrivate::eventFilter(QObject *obj, QEvent *event) { - int buttonIndex = -1; - for (int i = 0; i < 2; ++i) { - if (obj == m_iconbutton[i]) { - buttonIndex = i; - break; - } - } - if (buttonIndex == -1) - return QObject::eventFilter(obj, event); - switch (event->type()) { - case QEvent::FocusIn: - if (m_menuTabFocusTrigger[buttonIndex] && m_menu[buttonIndex]) { - m_lineEdit->setFocus(); - m_menu[buttonIndex]->exec(m_iconbutton[buttonIndex]->mapToGlobal( - m_iconbutton[buttonIndex]->rect().center())); - return true; - } - default: - break; - } - return QObject::eventFilter(obj, event); + int buttonIndex = -1; + for (int i = 0; i < 2; ++i) { + if (obj == m_iconbutton[i]) { + buttonIndex = i; + break; + } + } + if (buttonIndex == -1) + return QObject::eventFilter(obj, event); + switch (event->type()) { + case QEvent::FocusIn: + if (m_menuTabFocusTrigger[buttonIndex] && m_menu[buttonIndex]) { + m_lineEdit->setFocus(); + m_menu[buttonIndex]->exec(m_iconbutton[buttonIndex]->mapToGlobal( + m_iconbutton[buttonIndex]->rect().center())); + return true; + } + default: + break; + } + return QObject::eventFilter(obj, event); } -// --------- FancyLineEdit +//////////////////////////////////////////////////////////////////////// +// +// FancyLineEdit +// +//////////////////////////////////////////////////////////////////////// + FancyLineEdit::FancyLineEdit(QWidget *parent) : QLineEdit(parent), m_d(new FancyLineEditPrivate(this)) { - ensurePolished(); - updateMargins(); - - connect(this, SIGNAL(textChanged(QString)), - this, SLOT(checkButtons(QString))); - connect(m_d->m_iconbutton[Left], SIGNAL(clicked()), - this, SLOT(iconClicked())); - connect(m_d->m_iconbutton[Right], SIGNAL(clicked()), - this, SLOT(iconClicked())); + ensurePolished(); + updateMargins(); + + connect(this, SIGNAL(textChanged(QString)), + this, SLOT(checkButtons(QString))); + connect(m_d->m_iconbutton[Left], SIGNAL(clicked()), + this, SLOT(iconClicked())); + connect(m_d->m_iconbutton[Right], SIGNAL(clicked()), + this, SLOT(iconClicked())); } + void FancyLineEdit::checkButtons(const QString &text) { - if (m_oldText.isEmpty() || text.isEmpty()) { - for (int i = 0; i < 2; ++i) { - if (m_d->m_iconbutton[i]->hasAutoHide()) - m_d->m_iconbutton[i]->animateShow(!text.isEmpty()); - } - m_oldText = text; - } + if (m_oldText.isEmpty() || text.isEmpty()) { + for (int i = 0; i < 2; ++i) { + if (m_d->m_iconbutton[i]->hasAutoHide()) + m_d->m_iconbutton[i]->animateShow(!text.isEmpty()); + } + m_oldText = text; + } } + +void FancyLineEdit::setClearButton(bool visible) +{ +// QLineEdit::setClearButtonEnabled() has been implemented in Qt 5.2. +// In earlier Qt versions, we roll our own button +#if QT_VERSION < 0x050200 + setButtonPixmap(FancyLineEdit::Right, getPixmap("images/", "editclear", "svgz,png")); + setButtonVisible(FancyLineEdit::Right, visible); + setAutoHideButton(FancyLineEdit::Right, true); +#else + setClearButtonEnabled(visible); +#endif +} + + void FancyLineEdit::setButtonVisible(Side side, bool visible) { - m_d->m_iconbutton[side]->setVisible(visible); - m_d->m_iconEnabled[side] = visible; - updateMargins(); + m_d->m_iconbutton[side]->setVisible(visible); + m_d->m_iconEnabled[side] = visible; + updateMargins(); } + bool FancyLineEdit::isButtonVisible(Side side) const { - return m_d->m_iconEnabled[side]; + return m_d->m_iconEnabled[side]; } + void FancyLineEdit::iconClicked() { - IconButton *button = qobject_cast(sender()); - int index = -1; - for (int i = 0; i < 2; ++i) - if (m_d->m_iconbutton[i] == button) - index = i; - if (index == -1) - return; - if (m_d->m_menu[index]) { - m_d->m_menu[index]->exec(QCursor::pos()); - } else { + IconButton *button = qobject_cast(sender()); + int index = -1; + for (int i = 0; i < 2; ++i) + if (m_d->m_iconbutton[i] == button) + index = i; + if (index == -1) + return; + if (m_d->m_menu[index]) { + m_d->m_menu[index]->exec(QCursor::pos()); + } else { buttonClicked((Side)index); - if (index == Left) + if (index == Left) leftButtonClicked(); - else if (index == Right) + else if (index == Right) rightButtonClicked(); - } + } } + void FancyLineEdit::updateMargins() { - bool leftToRight = (layoutDirection() == Qt::LeftToRight); - Side realLeft = (leftToRight ? Left : Right); - Side realRight = (leftToRight ? Right : Left); - - int leftMargin = m_d->m_iconbutton[realLeft]->pixmap().width() + 8; - int rightMargin = m_d->m_iconbutton[realRight]->pixmap().width() + 8; - // Note KDE does not reserve space for the highlight color - if (style()->inherits("OxygenStyle")) { - leftMargin = qMax(24, leftMargin); - rightMargin = qMax(24, rightMargin); - } - - QMargins margins((m_d->m_iconEnabled[realLeft] ? leftMargin : 0), 0, - (m_d->m_iconEnabled[realRight] ? rightMargin : 0), 0); - - setTextMargins(margins); + bool leftToRight = (layoutDirection() == Qt::LeftToRight); + Side realLeft = (leftToRight ? Left : Right); + Side realRight = (leftToRight ? Right : Left); + + qreal dpr = 1.0; +#if QT_VERSION >= 0x050000 + // Consider device/pixel ratio (HiDPI) + dpr = devicePixelRatio(); +#endif + int leftMargin = (m_d->m_iconbutton[realLeft]->pixmap().width() / dpr ) + 8; + int rightMargin = (m_d->m_iconbutton[realRight]->pixmap().width() / dpr) + 8; + // Note KDE does not reserve space for the highlight color + if (style()->inherits("OxygenStyle")) { + leftMargin = qMax(24, leftMargin); + rightMargin = qMax(24, rightMargin); + } + + QMargins margins((m_d->m_iconEnabled[realLeft] ? leftMargin : 0), 0, + (m_d->m_iconEnabled[realRight] ? rightMargin : 0), 0); + + setTextMargins(margins); } + void FancyLineEdit::updateButtonPositions() { - QRect contentRect = rect(); - for (int i = 0; i < 2; ++i) { - Side iconpos = (Side)i; - if (layoutDirection() == Qt::RightToLeft) - iconpos = (iconpos == Left ? Right : Left); - - if (iconpos == FancyLineEdit::Right) { - const int iconoffset = textMargins().right() + 4; - m_d->m_iconbutton[i]-> - setGeometry(contentRect.adjusted(width() - iconoffset, 0, 0, 0)); - } else { - const int iconoffset = textMargins().left() + 4; - m_d->m_iconbutton[i]-> - setGeometry(contentRect.adjusted(0, 0, -width() + iconoffset, 0)); - } - } + QRect contentRect = rect(); + for (int i = 0; i < 2; ++i) { + Side iconpos = (Side)i; + if (layoutDirection() == Qt::RightToLeft) + iconpos = (iconpos == Left ? Right : Left); + + if (iconpos == FancyLineEdit::Right) { + const int iconoffset = textMargins().right() + 4; + m_d->m_iconbutton[i]->setGeometry( + contentRect.adjusted(width() - iconoffset, + 0, 0, 0)); + } else { + const int iconoffset = textMargins().left() + 4; + m_d->m_iconbutton[i]->setGeometry( + contentRect.adjusted(0, 0, + -width() + iconoffset, 0)); + } + } } + void FancyLineEdit::resizeEvent(QResizeEvent *) { - updateButtonPositions(); + updateButtonPositions(); } @@ -212,102 +257,124 @@ void FancyLineEdit::keyPressEvent(QKeyEvent * e) void FancyLineEdit::setButtonPixmap(Side side, const QPixmap &buttonPixmap) { - m_d->m_iconbutton[side]->setPixmap(buttonPixmap); - updateMargins(); - updateButtonPositions(); - update(); + m_d->m_iconbutton[side]->setPixmap(buttonPixmap); + updateMargins(); + updateButtonPositions(); + update(); } + QPixmap FancyLineEdit::buttonPixmap(Side side) const { - return m_d->m_pixmap[side]; + return m_d->m_pixmap[side]; } + void FancyLineEdit::setButtonMenu(Side side, QMenu *buttonMenu) { - m_d->m_menu[side] = buttonMenu; - m_d->m_iconbutton[side]->setIconOpacity(1.0); - } + m_d->m_menu[side] = buttonMenu; + m_d->m_iconbutton[side]->setIconOpacity(1.0); +} QMenu *FancyLineEdit::buttonMenu(Side side) const { - return m_d->m_menu[side]; + return m_d->m_menu[side]; } + bool FancyLineEdit::hasMenuTabFocusTrigger(Side side) const { - return m_d->m_menuTabFocusTrigger[side]; + return m_d->m_menuTabFocusTrigger[side]; } + void FancyLineEdit::setMenuTabFocusTrigger(Side side, bool v) { - if (m_d->m_menuTabFocusTrigger[side] == v) - return; + if (m_d->m_menuTabFocusTrigger[side] == v) + return; - m_d->m_menuTabFocusTrigger[side] = v; - m_d->m_iconbutton[side]->setFocusPolicy(v ? Qt::TabFocus : Qt::NoFocus); + m_d->m_menuTabFocusTrigger[side] = v; + m_d->m_iconbutton[side]->setFocusPolicy(v ? Qt::TabFocus : Qt::NoFocus); } + bool FancyLineEdit::hasAutoHideButton(Side side) const { - return m_d->m_iconbutton[side]->hasAutoHide(); + return m_d->m_iconbutton[side]->hasAutoHide(); } + void FancyLineEdit::setAutoHideButton(Side side, bool h) { - m_d->m_iconbutton[side]->setAutoHide(h); - if (h) - m_d->m_iconbutton[side]->setIconOpacity(text().isEmpty() ? 0.0 : 1.0); - else - m_d->m_iconbutton[side]->setIconOpacity(1.0); + m_d->m_iconbutton[side]->setAutoHide(h); + if (h) + m_d->m_iconbutton[side]->setIconOpacity(text().isEmpty() ? 0.0 : 1.0); + else + m_d->m_iconbutton[side]->setIconOpacity(1.0); } + void FancyLineEdit::setButtonToolTip(Side side, const QString &tip) { - m_d->m_iconbutton[side]->setToolTip(tip); + m_d->m_iconbutton[side]->setToolTip(tip); } + void FancyLineEdit::setButtonFocusPolicy(Side side, Qt::FocusPolicy policy) { - m_d->m_iconbutton[side]->setFocusPolicy(policy); + m_d->m_iconbutton[side]->setFocusPolicy(policy); } + +//////////////////////////////////////////////////////////////////////// +// // IconButton - helper class to represent a clickable icon +// +//////////////////////////////////////////////////////////////////////// IconButton::IconButton(QWidget *parent) - : QAbstractButton(parent), m_iconOpacity(0.0), m_autoHide(false) + : QAbstractButton(parent), m_iconOpacity(0.0), m_autoHide(false) { - setCursor(Qt::ArrowCursor); - setFocusPolicy(Qt::NoFocus); + setCursor(Qt::ArrowCursor); + setFocusPolicy(Qt::NoFocus); } + void IconButton::paintEvent(QPaintEvent *) { - QPainter painter(this); - QRect pixmapRect = QRect(0, 0, m_pixmap.width(), m_pixmap.height()); - pixmapRect.moveCenter(rect().center()); - - if (m_autoHide) - painter.setOpacity(m_iconOpacity); - - painter.drawPixmap(pixmapRect, m_pixmap); + qreal dpr = 1.0; +#if QT_VERSION >= 0x050000 + // Consider device/pixel ratio (HiDPI) + QWindow * window = this->window()->windowHandle(); + dpr = window->devicePixelRatio(); +#endif + QRect pixmapRect(QPoint(), m_pixmap.size() / dpr); + pixmapRect.moveCenter(rect().center()); + QPixmap pm = m_pixmap; + + QPainter painter(this); + if (m_autoHide) + painter.setOpacity(m_iconOpacity); + + painter.drawPixmap(pixmapRect, pm); } + void IconButton::animateShow(bool visible) { - if (visible) { - QPropertyAnimation *animation = - new QPropertyAnimation(this, "iconOpacity"); - animation->setDuration(FADE_TIME); - animation->setEndValue(1.0); - animation->start(QAbstractAnimation::DeleteWhenStopped); - } else { - QPropertyAnimation *animation = - new QPropertyAnimation(this, "iconOpacity"); - animation->setDuration(FADE_TIME); - animation->setEndValue(0.0); - animation->start(QAbstractAnimation::DeleteWhenStopped); - } + if (visible) { + QPropertyAnimation *animation = + new QPropertyAnimation(this, "iconOpacity"); + animation->setDuration(FADE_TIME); + animation->setEndValue(1.0); + animation->start(QAbstractAnimation::DeleteWhenStopped); + } else { + QPropertyAnimation *animation = + new QPropertyAnimation(this, "iconOpacity"); + animation->setDuration(FADE_TIME); + animation->setEndValue(0.0); + animation->start(QAbstractAnimation::DeleteWhenStopped); + } } } // namespace frontend