diff options
Diffstat (limited to 'src/widgets/widgets/qlineedit_p.cpp')
-rw-r--r-- | src/widgets/widgets/qlineedit_p.cpp | 191 |
1 files changed, 101 insertions, 90 deletions
diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 4143b848b5..fdd6a3aa4f 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -1,41 +1,5 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWidgets module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qlineedit.h" #include "qlineedit_p.h" @@ -51,7 +15,7 @@ # include "qwidgetaction.h" #endif #include "qclipboard.h" -#ifndef QT_NO_ACCESSIBILITY +#if QT_CONFIG(accessibility) #include "qaccessible.h" #endif #ifndef QT_NO_IM @@ -86,6 +50,18 @@ int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const return control->xToPos(x, betweenOrOn); } +QString QLineEditPrivate::textBeforeCursor(int curPos) const +{ + const QString &text = control->text(); + return text.mid(0, curPos); +} + +QString QLineEditPrivate::textAfterCursor(int curPos) const +{ + const QString &text = control->text(); + return text.mid(curPos); +} + bool QLineEditPrivate::inSelection(int x) const { x -= adjustedContentsRect().x() - hscroll + horizontalMargin; @@ -98,8 +74,25 @@ QRect QLineEditPrivate::cursorRect() const } #if QT_CONFIG(completer) +void QLineEditPrivate::connectCompleter() +{ + Q_Q(const QLineEdit); + QObject::connect(control->completer(), qOverload<const QString &>(&QCompleter::activated), + q, &QLineEdit::setText); + QObjectPrivate::connect(control->completer(), qOverload<const QString &>(&QCompleter::highlighted), + this, &QLineEditPrivate::completionHighlighted); +} -void QLineEditPrivate::_q_completionHighlighted(const QString &newText) +void QLineEditPrivate::disconnectCompleter() +{ + Q_Q(const QLineEdit); + QObject::disconnect(control->completer(), qOverload<const QString &>(&QCompleter::activated), + q, &QLineEdit::setText); + QObjectPrivate::disconnect(control->completer(), qOverload<const QString &>(&QCompleter::highlighted), + this, &QLineEditPrivate::completionHighlighted); +} + +void QLineEditPrivate::completionHighlighted(const QString &newText) { Q_Q(QLineEdit); if (control->completer()->completionMode() != QCompleter::InlineCompletion) { @@ -120,14 +113,14 @@ void QLineEditPrivate::_q_completionHighlighted(const QString &newText) #endif // QT_CONFIG(completer) -void QLineEditPrivate::_q_handleWindowActivate() +void QLineEditPrivate::handleWindowActivate() { Q_Q(QLineEdit); if (!q->hasFocus() && control->hasSelectedText()) control->deselect(); } -void QLineEditPrivate::_q_textEdited(const QString &text) +void QLineEditPrivate::textEdited(const QString &text) { Q_Q(QLineEdit); edited = true; @@ -139,7 +132,7 @@ void QLineEditPrivate::_q_textEdited(const QString &text) #endif } -void QLineEditPrivate::_q_cursorPositionChanged(int from, int to) +void QLineEditPrivate::cursorPositionChanged(int from, int to) { Q_Q(QLineEdit); q->update(); @@ -147,14 +140,14 @@ void QLineEditPrivate::_q_cursorPositionChanged(int from, int to) } #ifdef QT_KEYPAD_NAVIGATION -void QLineEditPrivate::_q_editFocusChange(bool e) +void QLineEditPrivate::editFocusChange(bool e) { Q_Q(QLineEdit); q->setEditFocus(e); } #endif -void QLineEditPrivate::_q_selectionChanged() +void QLineEditPrivate::selectionChanged() { Q_Q(QLineEdit); if (control->preeditAreaText().isEmpty()) { @@ -167,14 +160,14 @@ void QLineEditPrivate::_q_selectionChanged() } emit q->selectionChanged(); -#ifndef QT_NO_ACCESSIBILITY +#if QT_CONFIG(accessibility) QAccessibleTextSelectionEvent ev(q, control->selectionStart(), control->selectionEnd()); ev.setCursorPosition(control->cursorPosition()); QAccessible::updateAccessibility(&ev); #endif } -void QLineEditPrivate::_q_updateNeeded(const QRect &rect) +void QLineEditPrivate::updateNeeded(const QRect &rect) { q_func()->update(adjustedControlRect(rect)); } @@ -182,45 +175,51 @@ void QLineEditPrivate::_q_updateNeeded(const QRect &rect) void QLineEditPrivate::init(const QString& txt) { Q_Q(QLineEdit); + + const auto qUpdateMicroFocus = [q]() + { + q->updateMicroFocus(); + }; control = new QWidgetLineControl(txt); control->setParent(q); control->setFont(q->font()); - QObject::connect(control, SIGNAL(textChanged(QString)), - q, SIGNAL(textChanged(QString))); - QObject::connect(control, SIGNAL(textEdited(QString)), - q, SLOT(_q_textEdited(QString))); - QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)), - q, SLOT(_q_cursorPositionChanged(int,int))); - QObject::connect(control, SIGNAL(selectionChanged()), - q, SLOT(_q_selectionChanged())); - QObject::connect(control, SIGNAL(editingFinished()), - q, SLOT(_q_controlEditingFinished())); + QObject::connect(control, &QWidgetLineControl::textChanged, + q, &QLineEdit::textChanged); + QObjectPrivate::connect(control, &QWidgetLineControl::textEdited, + this, &QLineEditPrivate::textEdited); + QObjectPrivate::connect(control, &QWidgetLineControl::cursorPositionChanged, + this, &QLineEditPrivate::cursorPositionChanged); + QObjectPrivate::connect(control, &QWidgetLineControl::selectionChanged, + this, &QLineEditPrivate::selectionChanged); + QObjectPrivate::connect(control, &QWidgetLineControl::editingFinished, + this, &QLineEditPrivate::controlEditingFinished); #ifdef QT_KEYPAD_NAVIGATION - QObject::connect(control, SIGNAL(editFocusChange(bool)), - q, SLOT(_q_editFocusChange(bool))); + QObject::connect(control, &QWidgetLineControl::editFocusChange, + this, &QLineEditPrivate::editFocusChange); #endif - QObject::connect(control, SIGNAL(cursorPositionChanged(int,int)), - q, SLOT(updateMicroFocus())); + QObject::connect(control, &QWidgetLineControl::cursorPositionChanged, + q, qUpdateMicroFocus); - QObject::connect(control, SIGNAL(textChanged(QString)), - q, SLOT(updateMicroFocus())); + QObject::connect(control, &QWidgetLineControl::textChanged, + q, qUpdateMicroFocus); - QObject::connect(control, SIGNAL(updateMicroFocus()), - q, SLOT(updateMicroFocus())); + QObject::connect(control, &QWidgetLineControl::updateMicroFocus, + q, qUpdateMicroFocus); // for now, going completely overboard with updates. - QObject::connect(control, SIGNAL(selectionChanged()), - q, SLOT(update())); + QObject::connect(control, &QWidgetLineControl::selectionChanged, + q, qOverload<>(&QLineEdit::update)); - QObject::connect(control, SIGNAL(selectionChanged()), - q, SLOT(updateMicroFocus())); + QObject::connect(control, &QWidgetLineControl::selectionChanged, + q, qUpdateMicroFocus); - QObject::connect(control, SIGNAL(displayTextChanged(QString)), - q, SLOT(update())); + QObject::connect(control, &QWidgetLineControl::displayTextChanged, + q, qOverload<>(&QLineEdit::update)); - QObject::connect(control, SIGNAL(updateNeeded(QRect)), - q, SLOT(_q_updateNeeded(QRect))); - QObject::connect(control, SIGNAL(inputRejected()), q, SIGNAL(inputRejected())); + QObjectPrivate::connect(control, &QWidgetLineControl::updateNeeded, + this, &QLineEditPrivate::updateNeeded); + QObject::connect(control, &QWidgetLineControl::inputRejected, + q, &QLineEdit::inputRejected); QStyleOptionFrame opt; q->initStyleOption(&opt); @@ -303,7 +302,7 @@ bool QLineEditPrivate::sendMouseEventToInputContext( QMouseEvent *e ) if ( control->composeMode() ) { int tmp_cursor = xToPos(e->position().toPoint().x()); int mousePos = tmp_cursor - control->cursor(); - if ( mousePos < 0 || mousePos > control->preeditAreaText().length() ) + if ( mousePos < 0 || mousePos > control->preeditAreaText().size() ) mousePos = -1; if (mousePos >= 0) { @@ -406,8 +405,9 @@ void QLineEditIconButton::setHideWithText(bool hide) void QLineEditIconButton::onAnimationFinished() { - if (shouldHideWithText() && isVisible() && !m_wasHidden) { + if (shouldHideWithText() && isVisible() && m_fadingOut) { hide(); + m_fadingOut = false; // Invalidate previous geometry to take into account new size of side widgets if (auto le = lineEditPrivate()) @@ -417,7 +417,7 @@ void QLineEditIconButton::onAnimationFinished() void QLineEditIconButton::animateShow(bool visible) { - m_wasHidden = visible; + m_fadingOut = !visible; if (shouldHideWithText() && !isVisible()) { show(); @@ -432,7 +432,7 @@ void QLineEditIconButton::animateShow(bool visible) void QLineEditIconButton::startOpacityAnimation(qreal endValue) { - QPropertyAnimation *animation = new QPropertyAnimation(this, QByteArrayLiteral("opacity")); + QPropertyAnimation *animation = new QPropertyAnimation(this, QByteArrayLiteral("opacity"), this); connect(animation, &QPropertyAnimation::finished, this, &QLineEditIconButton::onAnimationFinished); animation->setDuration(160); @@ -459,7 +459,7 @@ static void displayWidgets(const QLineEditPrivate::SideWidgetEntryList &widgets, } #endif -void QLineEditPrivate::_q_textChanged(const QString &text) +void QLineEditPrivate::textChanged(const QString &text) { if (hasSideWidgets()) { const int newTextSize = text.size(); @@ -474,16 +474,16 @@ void QLineEditPrivate::_q_textChanged(const QString &text) } } -void QLineEditPrivate::_q_clearButtonClicked() +void QLineEditPrivate::clearButtonClicked() { Q_Q(QLineEdit); if (!q->text().isEmpty()) { q->clear(); - _q_textEdited(QString()); + textEdited(QString()); } } -void QLineEditPrivate::_q_controlEditingFinished() +void QLineEditPrivate::controlEditingFinished() { Q_Q(QLineEdit); edited = false; @@ -495,8 +495,8 @@ QLineEditPrivate::SideWidgetParameters QLineEditPrivate::sideWidgetParameters() { Q_Q(const QLineEdit); SideWidgetParameters result; - result.iconSize = q->style()->pixelMetric(QStyle::PM_SmallIconSize, nullptr, q); - result.margin = result.iconSize / 4; + result.iconSize = q->style()->pixelMetric(QStyle::PM_LineEditIconSize, nullptr, q); + result.margin = q->style()->pixelMetric(QStyle::PM_LineEditIconMargin, nullptr, q); result.widgetWidth = result.iconSize + 6; result.widgetHeight = result.iconSize + 2; return result; @@ -577,7 +577,8 @@ QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineE if (!newAction) return nullptr; if (!hasSideWidgets()) { // initial setup. - QObject::connect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString))); + QObjectPrivate::connect(q, &QLineEdit::textChanged, + this, &QLineEditPrivate::textChanged); lastTextSize = q->text().size(); } QWidget *w = nullptr; @@ -593,7 +594,8 @@ QWidget *QLineEditPrivate::addAction(QAction *newAction, QAction *before, QLineE toolButton->setIcon(newAction->icon()); toolButton->setOpacity(lastTextSize > 0 || !(flags & SideWidgetFadeInWithText) ? 1 : 0); if (flags & SideWidgetClearButton) { - QObject::connect(toolButton, SIGNAL(clicked()), q, SLOT(_q_clearButtonClicked())); + QObjectPrivate::connect(toolButton, &QToolButton::clicked, + this, &QLineEditPrivate::clearButtonClicked); #if QT_CONFIG(animation) // The clear button is handled only by this widget. The button should be really @@ -656,7 +658,8 @@ void QLineEditPrivate::removeAction(QAction *action) delete entry.widget; positionSideWidgets(); if (!hasSideWidgets()) // Last widget, remove connection - QObject::disconnect(q, SIGNAL(textChanged(QString)), q, SLOT(_q_textChanged(QString))); + QObjectPrivate::connect(q, &QLineEdit::textChanged, + this, &QLineEditPrivate::textChanged); q->update(); } #endif // QT_CONFIG(action) @@ -667,10 +670,18 @@ static int effectiveTextMargin(int defaultMargin, const QLineEditPrivate::SideWi if (widgets.empty()) return defaultMargin; - return defaultMargin + (parameters.margin + parameters.widgetWidth) * - int(std::count_if(widgets.begin(), widgets.end(), + const auto visibleSideWidgetCount = std::count_if(widgets.begin(), widgets.end(), [](const QLineEditPrivate::SideWidgetEntry &e) { - return e.widget->isVisibleTo(e.widget->parentWidget()); })); +#if QT_CONFIG(toolbutton) && QT_CONFIG(animation) + // a button that's fading out doesn't get any space + if (auto* iconButton = qobject_cast<QLineEditIconButton*>(e.widget)) + return iconButton->needsSpace(); + +#endif + return e.widget->isVisibleTo(e.widget->parentWidget()); + }); + + return defaultMargin + (parameters.margin + parameters.widgetWidth) * visibleSideWidgetCount; } QMargins QLineEditPrivate::effectiveTextMargins() const |