diff options
Diffstat (limited to 'src/widgets')
-rw-r--r-- | src/widgets/accessible/qaccessiblemenu.cpp | 14 | ||||
-rw-r--r-- | src/widgets/accessible/qaccessiblemenu_p.h | 2 | ||||
-rw-r--r-- | src/widgets/accessible/qaccessiblewidget.cpp | 10 | ||||
-rw-r--r-- | src/widgets/dialogs/qcolordialog.cpp | 35 | ||||
-rw-r--r-- | src/widgets/dialogs/qfilesystemmodel.cpp | 21 | ||||
-rw-r--r-- | src/widgets/doc/qtwidgets.qdocconf | 2 | ||||
-rw-r--r-- | src/widgets/doc/src/widgets-and-layouts/widgets.qdoc | 6 | ||||
-rw-r--r-- | src/widgets/itemviews/qtableview.cpp | 23 | ||||
-rw-r--r-- | src/widgets/kernel/qapplication.cpp | 8 | ||||
-rw-r--r-- | src/widgets/kernel/qgesturemanager.cpp | 2 | ||||
-rw-r--r-- | src/widgets/kernel/qwidget.cpp | 99 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow.cpp | 27 | ||||
-rw-r--r-- | src/widgets/kernel/qwidgetwindow_p.h | 2 | ||||
-rw-r--r-- | src/widgets/util/qundostack.cpp | 2 | ||||
-rw-r--r-- | src/widgets/widgets/qlineedit.cpp | 1 | ||||
-rw-r--r-- | src/widgets/widgets/qlineedit_p.cpp | 59 | ||||
-rw-r--r-- | src/widgets/widgets/qlineedit_p.h | 15 | ||||
-rw-r--r-- | src/widgets/widgets/qmenubar.cpp | 55 | ||||
-rw-r--r-- | src/widgets/widgets/qmenubar_p.h | 3 |
19 files changed, 220 insertions, 166 deletions
diff --git a/src/widgets/accessible/qaccessiblemenu.cpp b/src/widgets/accessible/qaccessiblemenu.cpp index 5b10c6d6c6..4a684e01f9 100644 --- a/src/widgets/accessible/qaccessiblemenu.cpp +++ b/src/widgets/accessible/qaccessiblemenu.cpp @@ -231,6 +231,20 @@ QObject *QAccessibleMenuItem::object() const return m_action; } +/*! \reimp */ +QWindow *QAccessibleMenuItem::window() const +{ + QWindow *result = Q_NULLPTR; + if (!m_owner.isNull()) { + result = m_owner->windowHandle(); + if (!result) { + if (const QWidget *nativeParent = m_owner->nativeParentWidget()) + result = nativeParent->windowHandle(); + } + } + return result; +} + QRect QAccessibleMenuItem::rect() const { QRect rect; diff --git a/src/widgets/accessible/qaccessiblemenu_p.h b/src/widgets/accessible/qaccessiblemenu_p.h index e9dc851ab3..5a5a4a3222 100644 --- a/src/widgets/accessible/qaccessiblemenu_p.h +++ b/src/widgets/accessible/qaccessiblemenu_p.h @@ -114,6 +114,8 @@ public: QAccessibleInterface *parent() const Q_DECL_OVERRIDE; QAccessibleInterface *child(int index) const Q_DECL_OVERRIDE; QObject * object() const Q_DECL_OVERRIDE; + QWindow *window() const Q_DECL_OVERRIDE; + QRect rect() const Q_DECL_OVERRIDE; QAccessible::Role role() const Q_DECL_OVERRIDE; void setText(QAccessible::Text t, const QString & text) Q_DECL_OVERRIDE; diff --git a/src/widgets/accessible/qaccessiblewidget.cpp b/src/widgets/accessible/qaccessiblewidget.cpp index 901fd7e201..5096c1ff37 100644 --- a/src/widgets/accessible/qaccessiblewidget.cpp +++ b/src/widgets/accessible/qaccessiblewidget.cpp @@ -210,8 +210,14 @@ bool QAccessibleWidget::isValid() const /*! \reimp */ QWindow *QAccessibleWidget::window() const { - Q_ASSERT(widget()); - return widget()->windowHandle(); + const QWidget *w = widget(); + Q_ASSERT(w); + QWindow *result = w->windowHandle(); + if (!result) { + if (const QWidget *nativeParent = w->nativeParentWidget()) + result = nativeParent->windowHandle(); + } + return result; } /*! diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp index 5494036827..f3652c09da 100644 --- a/src/widgets/dialogs/qcolordialog.cpp +++ b/src/widgets/dialogs/qcolordialog.cpp @@ -174,8 +174,6 @@ private: namespace { -struct QWellArrayData; - class QWellArray : public QWidget { Q_OBJECT @@ -195,8 +193,6 @@ public: QSize sizeHint() const Q_DECL_OVERRIDE; - virtual void setCellBrush(int row, int col, const QBrush &); - inline int cellWidth() const { return cellw; } @@ -263,7 +259,6 @@ private: int curCol; int selRow; int selCol; - QWellArrayData *d; }; void QWellArray::paintEvent(QPaintEvent *e) @@ -313,15 +308,10 @@ void QWellArray::paintEvent(QPaintEvent *e) } } -struct QWellArrayData { - QBrush *brush; -}; - QWellArray::QWellArray(int rows, int cols, QWidget *parent) : QWidget(parent) ,nrows(rows), ncols(cols) { - d = 0; setFocusPolicy(Qt::StrongFocus); cellw = 28; cellh = 24; @@ -370,14 +360,12 @@ void QWellArray::paintCell(QPainter* p, int row, int col, const QRect &rect) */ void QWellArray::paintCellContents(QPainter *p, int row, int col, const QRect &r) { - if (d) { - p->fillRect(r, d->brush[row*numCols()+col]); - } else { - p->fillRect(r, Qt::white); - p->setPen(Qt::black); - p->drawLine(r.topLeft(), r.bottomRight()); - p->drawLine(r.topRight(), r.bottomLeft()); - } + Q_UNUSED(row); + Q_UNUSED(col); + p->fillRect(r, Qt::white); + p->setPen(Qt::black); + p->drawLine(r.topLeft(), r.bottomRight()); + p->drawLine(r.topRight(), r.bottomLeft()); } void QWellArray::mousePressEvent(QMouseEvent *e) @@ -453,17 +441,6 @@ void QWellArray::focusInEvent(QFocusEvent*) emit currentChanged(curRow, curCol); } -void QWellArray::setCellBrush(int row, int col, const QBrush &b) -{ - if (!d) { - d = new QWellArrayData; - int i = numRows()*numCols(); - d->brush = new QBrush[i]; - } - if (row >= 0 && row < numRows() && col >= 0 && col < numCols()) - d->brush[row*numCols()+col] = b; -} - /*!\reimp */ diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp index 1d07c31476..5424a4126a 100644 --- a/src/widgets/dialogs/qfilesystemmodel.cpp +++ b/src/widgets/dialogs/qfilesystemmodel.cpp @@ -372,6 +372,9 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS ) return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); QModelIndex index = QModelIndex(); // start with "My Computer" + QString elementPath; + QChar separator = QLatin1Char('/'); + QString trailingSeparator; #if defined(Q_OS_WIN) if (absolutePath.startsWith(QLatin1String("//"))) { // UNC path QString host = QLatin1String("\\\\") + pathElements.constFirst(); @@ -379,6 +382,8 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS absolutePath.append(QLatin1Char('/')); if (longPath.endsWith(QLatin1Char('/')) && !absolutePath.endsWith(QLatin1Char('/'))) absolutePath.append(QLatin1Char('/')); + if (absolutePath.endsWith(QLatin1Char('/'))) + trailingSeparator = QLatin1String("\\"); int r = 0; QFileSystemModelPrivate::QFileSystemNode *rootNode = const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); if (!root.children.contains(host.toLower())) { @@ -395,11 +400,10 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS r = translateVisibleLocation(rootNode, r); index = q->index(r, 0, QModelIndex()); pathElements.pop_front(); - } else -#endif - -#if defined(Q_OS_WIN) - { + separator = QLatin1Char('\\'); + elementPath = host; + elementPath.append(separator); + } else { if (!pathElements.at(0).contains(QLatin1Char(':'))) { QString rootPath = QDir(longPath).rootPath(); pathElements.prepend(rootPath); @@ -417,6 +421,11 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS for (int i = 0; i < pathElements.count(); ++i) { QString element = pathElements.at(i); + if (i != 0) + elementPath.append(separator); + elementPath.append(element); + if (i == pathElements.count() - 1) + elementPath.append(trailingSeparator); #ifdef Q_OS_WIN // On Windows, "filename " and "filename" are equivalent and // "filename . " and "filename" are equivalent @@ -448,7 +457,7 @@ QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QS if (!alreadyExisted) { // Someone might call ::index("file://cookie/monster/doesn't/like/veggies"), // a path that doesn't exists, I.E. don't blindly create directories. - QFileInfo info(absolutePath); + QFileInfo info(elementPath); if (!info.exists()) return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); QFileSystemModelPrivate *p = const_cast<QFileSystemModelPrivate*>(this); diff --git a/src/widgets/doc/qtwidgets.qdocconf b/src/widgets/doc/qtwidgets.qdocconf index 75bbb99579..d0cf9671b1 100644 --- a/src/widgets/doc/qtwidgets.qdocconf +++ b/src/widgets/doc/qtwidgets.qdocconf @@ -4,7 +4,7 @@ project = QtWidgets description = Qt Widgets Reference Documentation version = $QT_VERSION -examplesinstallpath = qtbase/widgets +examplesinstallpath = widgets qhp.projects = QtWidgets diff --git a/src/widgets/doc/src/widgets-and-layouts/widgets.qdoc b/src/widgets/doc/src/widgets-and-layouts/widgets.qdoc index abd6ddd5fb..1e99030e7a 100644 --- a/src/widgets/doc/src/widgets-and-layouts/widgets.qdoc +++ b/src/widgets/doc/src/widgets-and-layouts/widgets.qdoc @@ -43,11 +43,11 @@ \table \row - \li \image gtk-label.png + \li \image fusion-label.png \li \image windowsvista-pushbutton.png \li \image macintosh-progressbar.png \row - \li \image gtk-combobox.png + \li \image fusion-combobox.png \li \image windowsvista-radiobutton.png \li \image macintosh-lineedit.png \endtable @@ -69,7 +69,7 @@ \table \row \li \image windowsxp-treeview.png - \li \image gtk-calendarwidget.png + \li \image fusion-calendarwidget.png \li \image qundoview.png \endtable diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp index ff3832e499..c7cc1d155e 100644 --- a/src/widgets/itemviews/qtableview.cpp +++ b/src/widgets/itemviews/qtableview.cpp @@ -3247,13 +3247,12 @@ void QTableViewPrivate::selectRow(int row, bool anchor) command |= QItemSelectionModel::Current; } - QModelIndex tl = model->index(qMin(rowSectionAnchor, row), logicalColumn(0), root); - QModelIndex br = model->index(qMax(rowSectionAnchor, row), logicalColumn(model->columnCount(root) - 1), root); - if ((verticalHeader->sectionsMoved() && tl.row() != br.row()) - || horizontalHeader->sectionsMoved()) { - q->setSelection(q->visualRect(tl)|q->visualRect(br), command); + QModelIndex upper = model->index(qMin(rowSectionAnchor, row), column, root); + QModelIndex lower = model->index(qMax(rowSectionAnchor, row), column, root); + if ((verticalHeader->sectionsMoved() && upper.row() != lower.row())) { + q->setSelection(q->visualRect(upper) | q->visualRect(lower), command | QItemSelectionModel::Rows); } else { - selectionModel->select(QItemSelection(tl, br), command); + selectionModel->select(QItemSelection(upper, lower), command | QItemSelectionModel::Rows); } } } @@ -3287,14 +3286,12 @@ void QTableViewPrivate::selectColumn(int column, bool anchor) command |= QItemSelectionModel::Current; } - QModelIndex tl = model->index(logicalRow(0), qMin(columnSectionAnchor, column), root); - QModelIndex br = model->index(logicalRow(model->rowCount(root) - 1), - qMax(columnSectionAnchor, column), root); - if ((horizontalHeader->sectionsMoved() && tl.column() != br.column()) - || verticalHeader->sectionsMoved()) { - q->setSelection(q->visualRect(tl)|q->visualRect(br), command); + QModelIndex left = model->index(row, qMin(columnSectionAnchor, column), root); + QModelIndex right = model->index(row, qMax(columnSectionAnchor, column), root); + if ((horizontalHeader->sectionsMoved() && left.column() != right.column())) { + q->setSelection(q->visualRect(left) | q->visualRect(right), command | QItemSelectionModel::Columns); } else { - selectionModel->select(QItemSelection(tl, br), command); + selectionModel->select(QItemSelection(left, right), command | QItemSelectionModel::Columns); } } } diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp index 4ff466e04b..5007969c96 100644 --- a/src/widgets/kernel/qapplication.cpp +++ b/src/widgets/kernel/qapplication.cpp @@ -2213,10 +2213,10 @@ void QApplicationPrivate::notifyActiveWindowChange(QWindow *previous) QApplication::setActiveWindow(tlw); // QTBUG-37126, Active X controls may set the focus on native child widgets. if (wnd && tlw && wnd != tlw->windowHandle()) { - if (QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(wnd)) { - if (widgetWindow->widget()->inherits("QAxHostWidget")) - widgetWindow->widget()->setFocus(Qt::ActiveWindowFocusReason); - } + if (QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(wnd)) + if (QWidget *widget = widgetWindow->widget()) + if (widget->inherits("QAxHostWidget")) + widget->setFocus(Qt::ActiveWindowFocusReason); } } diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp index 777be8525e..c901285d1a 100644 --- a/src/widgets/kernel/qgesturemanager.cpp +++ b/src/widgets/kernel/qgesturemanager.cpp @@ -552,7 +552,7 @@ bool QGestureManager::filterEvent(QObject *receiver, QEvent *event) // filter method. QWidgetWindow *widgetWindow = qobject_cast<QWidgetWindow *>(receiver); - if (widgetWindow) + if (widgetWindow && widgetWindow->widget()) return filterEvent(widgetWindow->widget(), event); QGesture *state = qobject_cast<QGesture *>(receiver); diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index 495af34c60..6fa74b7cc6 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -12374,6 +12374,53 @@ static inline bool canMapPosition(QWindow *window) return window->handle() && !qt_window_private(window)->resizeEventPending; } +#ifndef QT_NO_GRAPHICSVIEW +static inline QGraphicsProxyWidget *graphicsProxyWidget(const QWidget *w) +{ + QGraphicsProxyWidget *result = Q_NULLPTR; + const QWidgetPrivate *d = qt_widget_private(const_cast<QWidget *>(w)); + if (d->extra) + result = d->extra->proxyWidget; + return result; +} +#endif // !QT_NO_GRAPHICSVIEW + +struct MapToGlobalTransformResult { + QTransform transform; + QWindow *window; +}; + +static MapToGlobalTransformResult mapToGlobalTransform(const QWidget *w) +{ + MapToGlobalTransformResult result; + result.window = Q_NULLPTR; + for ( ; w ; w = w->parentWidget()) { +#ifndef QT_NO_GRAPHICSVIEW + if (QGraphicsProxyWidget *qgpw = graphicsProxyWidget(w)) { + if (const QGraphicsScene *scene = qgpw->scene()) { + const QList <QGraphicsView *> views = scene->views(); + if (!views.isEmpty()) { + result.transform *= qgpw->sceneTransform(); + result.transform *= views.first()->viewportTransform(); + w = views.first()->viewport(); + } + } + } +#endif // !QT_NO_GRAPHICSVIEW + QWindow *window = w->windowHandle(); + if (window && canMapPosition(window)) { + result.window = window; + break; + } + + const QPoint topLeft = w->geometry().topLeft(); + result.transform.translate(topLeft.x(), topLeft.y()); + if (w->isWindow()) + break; + } + return result; +} + /*! \fn QPoint QWidget::mapToGlobal(const QPoint &pos) const @@ -12385,29 +12432,9 @@ static inline bool canMapPosition(QWindow *window) */ QPoint QWidget::mapToGlobal(const QPoint &pos) const { -#ifndef QT_NO_GRAPHICSVIEW - Q_D(const QWidget); - if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) { - const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views(); - if (!views.isEmpty()) { - const QPointF scenePos = d->extra->proxyWidget->mapToScene(pos); - const QPoint viewPortPos = views.first()->mapFromScene(scenePos); - return views.first()->viewport()->mapToGlobal(viewPortPos); - } - } -#endif // !QT_NO_GRAPHICSVIEW - int x = pos.x(), y = pos.y(); - const QWidget *w = this; - while (w) { - QWindow *window = w->windowHandle(); - if (window && canMapPosition(window)) - return window->mapToGlobal(QPoint(x, y)); - - x += w->data->crect.x(); - y += w->data->crect.y(); - w = w->isWindow() ? 0 : w->parentWidget(); - } - return QPoint(x, y); + const MapToGlobalTransformResult t = mapToGlobalTransform(this); + const QPoint g = t.transform.map(pos); + return t.window ? t.window->mapToGlobal(g) : g; } /*! @@ -12420,29 +12447,9 @@ QPoint QWidget::mapToGlobal(const QPoint &pos) const */ QPoint QWidget::mapFromGlobal(const QPoint &pos) const { -#ifndef QT_NO_GRAPHICSVIEW - Q_D(const QWidget); - if (d->extra && d->extra->proxyWidget && d->extra->proxyWidget->scene()) { - const QList <QGraphicsView *> views = d->extra->proxyWidget->scene()->views(); - if (!views.isEmpty()) { - const QPoint viewPortPos = views.first()->viewport()->mapFromGlobal(pos); - const QPointF scenePos = views.first()->mapToScene(viewPortPos); - return d->extra->proxyWidget->mapFromScene(scenePos).toPoint(); - } - } -#endif // !QT_NO_GRAPHICSVIEW - int x = pos.x(), y = pos.y(); - const QWidget *w = this; - while (w) { - QWindow *window = w->windowHandle(); - if (window && canMapPosition(window)) - return window->mapFromGlobal(QPoint(x, y)); - - x -= w->data->crect.x(); - y -= w->data->crect.y(); - w = w->isWindow() ? 0 : w->parentWidget(); - } - return QPoint(x, y); + const MapToGlobalTransformResult t = mapToGlobalTransform(this); + const QPoint windowLocal = t.window ? t.window->mapFromGlobal(pos) : pos; + return t.transform.inverted().map(windowLocal); } QWidget *qt_pressGrab = 0; diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 843b89b6e4..675d54f6b4 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -93,7 +93,7 @@ QRectF QWidgetWindowPrivate::closestAcceptableGeometry(const QRectF &rect) const { Q_Q(const QWidgetWindow); const QWidget *widget = q->widget(); - if (!widget->isWindow() || !widget->hasHeightForWidth()) + if (!widget || !widget->isWindow() || !widget->hasHeightForWidth()) return QRect(); const QSize oldSize = rect.size().toSize(); const QSize newSize = QLayout::closestAcceptableSize(widget, oldSize); @@ -129,7 +129,7 @@ QWidgetWindow::QWidgetWindow(QWidget *widget) && !QApplication::testAttribute(Qt::AA_ForceRasterWidgets)) { setSurfaceType(QSurface::RasterGLSurface); } - connect(m_widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName); + connect(widget, &QObject::objectNameChanged, this, &QWidgetWindow::updateObjectName); connect(this, SIGNAL(screenChanged(QScreen*)), this, SLOT(handleScreenChange())); } @@ -148,16 +148,18 @@ QAccessibleInterface *QWidgetWindow::accessibleRoot() const QObject *QWidgetWindow::focusObject() const { - QWidget *widget = m_widget->focusWidget(); + QWidget *windowWidget = m_widget; + if (!windowWidget) + return Q_NULLPTR; + + QWidget *widget = windowWidget->focusWidget(); if (!widget) - widget = m_widget; + widget = windowWidget; - if (widget) { - QObject *focusObj = QWidgetPrivate::get(widget)->focusObject(); - if (focusObj) - return focusObj; - } + QObject *focusObj = QWidgetPrivate::get(widget)->focusObject(); + if (focusObj) + return focusObj; return widget; } @@ -180,6 +182,9 @@ static inline bool shouldBePropagatedToWidget(QEvent *event) bool QWidgetWindow::event(QEvent *event) { + if (!m_widget) + return QWindow::event(event); + if (m_widget->testAttribute(Qt::WA_DontShowOnScreen)) { // \a event is uninteresting for QWidgetWindow, the event was probably // generated before WA_DontShowOnScreen was set @@ -207,7 +212,7 @@ bool QWidgetWindow::event(QEvent *event) #ifndef QT_NO_ACCESSIBILITY QAccessible::State state; state.active = true; - QAccessibleStateChangeEvent ev(widget(), state); + QAccessibleStateChangeEvent ev(m_widget, state); QAccessible::updateAccessibility(&ev); #endif return false; } @@ -381,7 +386,7 @@ void QWidgetWindow::handleEnterLeaveEvent(QEvent *event) } else { const QEnterEvent *ee = static_cast<QEnterEvent *>(event); QWidget *child = m_widget->childAt(ee->pos()); - QWidget *receiver = child ? child : m_widget; + QWidget *receiver = child ? child : m_widget.data(); QApplicationPrivate::dispatchEnterLeave(receiver, 0, ee->screenPos()); qt_last_mouse_receiver = receiver; } diff --git a/src/widgets/kernel/qwidgetwindow_p.h b/src/widgets/kernel/qwidgetwindow_p.h index d20e7cb15e..a0d79b2b72 100644 --- a/src/widgets/kernel/qwidgetwindow_p.h +++ b/src/widgets/kernel/qwidgetwindow_p.h @@ -125,7 +125,7 @@ private: }; QWidget *getFocusWidget(FocusWidgets fw); - QWidget *m_widget; + QPointer<QWidget> m_widget; QPointer<QWidget> m_implicit_mouse_grabber; #ifndef QT_NO_DRAGANDDROP QPointer<QWidget> m_dragTarget; diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp index 1863ab9145..18f85ca505 100644 --- a/src/widgets/util/qundostack.cpp +++ b/src/widgets/util/qundostack.cpp @@ -627,6 +627,8 @@ void QUndoStack::push(QUndoCommand *cmd) Marks the stack as clean and emits cleanChanged() if the stack was not already clean. + This is typically called when a document is saved, for example. + Whenever the stack returns to this state through the use of undo/redo commands, it emits the signal cleanChanged(). This signal is also emitted when the stack leaves the clean state. diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 3c9cab4e17..2bc715724d 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -2192,7 +2192,6 @@ void QLineEdit::changeEvent(QEvent *ev) d->control->setPasswordCharacter(style()->styleHint(QStyle::SH_LineEdit_PasswordCharacter, &opt, this)); d->control->setPasswordMaskDelay(style()->styleHint(QStyle::SH_LineEdit_PasswordMaskDelay, &opt, this)); } - d->m_iconSize = QSize(); update(); break; case QEvent::LayoutDirectionChange: diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index 3d8a854753..7da1d911ee 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -320,6 +320,12 @@ QLineEditIconButton::QLineEditIconButton(QWidget *parent) setFocusPolicy(Qt::NoFocus); } +QLineEditPrivate *QLineEditIconButton::lineEditPrivate() const +{ + QLineEdit *le = qobject_cast<QLineEdit *>(parentWidget()); + return le ? static_cast<QLineEditPrivate *>(qt_widget_private(le)) : Q_NULLPTR; +} + void QLineEditIconButton::paintEvent(QPaintEvent *) { QPainter painter(this); @@ -331,7 +337,9 @@ void QLineEditIconButton::paintEvent(QPaintEvent *) QIcon::Mode state = QIcon::Disabled; if (isEnabled()) state = isDown() ? QIcon::Selected : QIcon::Normal; - const QSize iconSize(IconButtonSize, IconButtonSize); + const QLineEditPrivate *lep = lineEditPrivate(); + const int iconWidth = lep ? lep->sideWidgetParameters().iconSize : 16; + const QSize iconSize(iconWidth, iconWidth); const QPixmap iconPixmap = icon().pixmap(window, iconSize, state, QIcon::Off); QRect pixmapRect = QRect(QPoint(0, 0), iconSize); pixmapRect.moveCenter(rect().center()); @@ -346,8 +354,8 @@ void QLineEditIconButton::actionEvent(QActionEvent *e) const QAction *action = e->action(); if (isVisibleTo(parentWidget()) != action->isVisible()) { setVisible(action->isVisible()); - if (QLineEdit *le = qobject_cast<QLineEdit *>(parentWidget())) - static_cast<QLineEditPrivate *>(qt_widget_private(le))->positionSideWidgets(); + if (QLineEditPrivate *lep = lineEditPrivate()) + lep->positionSideWidgets(); } } break; @@ -413,11 +421,15 @@ void QLineEditPrivate::_q_clearButtonClicked() } } -QSize QLineEditPrivate::iconSize() const +QLineEditPrivate::SideWidgetParameters QLineEditPrivate::sideWidgetParameters() const { - if (!m_iconSize.isValid()) // This might require style-specific handling (pixel metric). - m_iconSize = QSize(QLineEditIconButton::IconButtonSize + 6, QLineEditIconButton::IconButtonSize + 2); - return m_iconSize; + Q_Q(const QLineEdit); + SideWidgetParameters result; + result.iconSize = q->height() < 34 ? 16 : 32; + result.margin = result.iconSize / 4; + result.widgetWidth = result.iconSize + 6; + result.widgetHeight = result.iconSize + 2; + return result; } QIcon QLineEditPrivate::clearButtonIcon() const @@ -443,15 +455,16 @@ void QLineEditPrivate::positionSideWidgets() Q_Q(QLineEdit); if (hasSideWidgets()) { const QRect contentRect = q->rect(); - const QSize iconSize = QLineEditPrivate::iconSize(); - const int delta = QLineEditIconButton::IconMargin + iconSize.width(); - QRect widgetGeometry(QPoint(QLineEditIconButton::IconMargin, (contentRect.height() - iconSize.height()) / 2), iconSize); + const SideWidgetParameters p = sideWidgetParameters(); + const int delta = p.margin + p.widgetWidth; + QRect widgetGeometry(QPoint(p.margin, (contentRect.height() - p.widgetHeight) / 2), + QSize(p.widgetWidth, p.widgetHeight)); for (const SideWidgetEntry &e : leftSideWidgetList()) { e.widget->setGeometry(widgetGeometry); if (e.action->isVisible()) widgetGeometry.moveLeft(widgetGeometry.left() + delta); } - widgetGeometry.moveLeft(contentRect.width() - iconSize.width() - QLineEditIconButton::IconMargin); + widgetGeometry.moveLeft(contentRect.width() - p.widgetWidth - p.margin); for (const SideWidgetEntry &e : rightSideWidgetList()) { e.widget->setGeometry(widgetGeometry); if (e.action->isVisible()) @@ -539,18 +552,26 @@ static bool isSideWidgetVisible(const QLineEditPrivate::SideWidgetEntry &e) int QLineEditPrivate::effectiveLeftTextMargin() const { - const auto &list = leftSideWidgetList(); - return leftTextMargin + (QLineEditIconButton::IconMargin + iconSize().width()) - * int(std::count_if(list.begin(), list.end(), - isSideWidgetVisible)); + int result = leftTextMargin; + if (!leftSideWidgetList().empty()) { + const SideWidgetParameters p = sideWidgetParameters(); + result += (p.margin + p.widgetWidth) + * int(std::count_if(leftSideWidgetList().begin(), leftSideWidgetList().end(), + isSideWidgetVisible)); + } + return result; } int QLineEditPrivate::effectiveRightTextMargin() const { - const auto &list = rightSideWidgetList(); - return rightTextMargin + (QLineEditIconButton::IconMargin + iconSize().width()) - * int(std::count_if(list.begin(), list.end(), - isSideWidgetVisible)); + int result = rightTextMargin; + if (!rightSideWidgetList().empty()) { + const SideWidgetParameters p = sideWidgetParameters(); + result += (p.margin + p.widgetWidth) + * int(std::count_if(rightSideWidgetList().begin(), rightSideWidgetList().end(), + isSideWidgetVisible)); + } + return result; } diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index 12a4299204..a14cd66398 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -71,6 +71,8 @@ QT_BEGIN_NAMESPACE +class QLineEditPrivate; + // QLineEditIconButton: This is a simple helper class that represents clickable icons that fade in with text class Q_AUTOTEST_EXPORT QLineEditIconButton : public QToolButton @@ -78,8 +80,6 @@ class Q_AUTOTEST_EXPORT QLineEditIconButton : public QToolButton Q_OBJECT Q_PROPERTY(qreal opacity READ opacity WRITE setOpacity) public: - enum { IconMargin = 4, IconButtonSize = 16 }; - explicit QLineEditIconButton(QWidget *parent = 0); qreal opacity() const { return m_opacity; } @@ -99,6 +99,7 @@ private: #ifndef QT_NO_ANIMATION void startOpacityAnimation(qreal endValue); #endif + QLineEditPrivate *lineEditPrivate() const; qreal m_opacity; }; @@ -122,6 +123,13 @@ public: }; typedef std::vector<SideWidgetEntry> SideWidgetEntryList; + struct SideWidgetParameters { + int iconSize; + int widgetWidth; + int widgetHeight; + int margin; + }; + QLineEditPrivate() : control(0), frame(1), contextMenuEnabled(1), cursorVisible(0), dragEnabled(0), clickCausedFocus(0), hscroll(0), vscroll(0), @@ -212,7 +220,7 @@ public: QWidget *addAction(QAction *newAction, QAction *before, QLineEdit::ActionPosition, int flags = 0); void removeAction(QAction *action); - QSize iconSize() const; + SideWidgetParameters sideWidgetParameters() const; QIcon clearButtonIcon() const; void setClearButtonEnabled(bool enabled); void positionSideWidgets(); @@ -233,7 +241,6 @@ private: SideWidgetEntryList leadingSideWidgets; SideWidgetEntryList trailingSideWidgets; int lastTextSize; - mutable QSize m_iconSize; }; Q_DECLARE_TYPEINFO(QLineEditPrivate::SideWidgetEntry, Q_PRIMITIVE_TYPE); diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 59cf9c9aee..3a90e14655 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -698,7 +698,6 @@ void QMenuBarPrivate::init() if (platformMenuBar) q->hide(); q->setBackgroundRole(QPalette::Button); - oldWindow = oldParent = 0; handleReparent(); q->setMouseTracking(q->style()->styleHint(QStyle::SH_MenuBar_MouseTracking, 0, q)); @@ -1320,30 +1319,41 @@ void QMenuBarPrivate::handleReparent() { Q_Q(QMenuBar); QWidget *newParent = q->parentWidget(); - //Note: if parent is reparented, then window may change even if parent doesn't - // we need to install an event filter on parent, and remove the old one - - if (oldParent != newParent) { - if (oldParent) - oldParent->removeEventFilter(q); - if (newParent) - newParent->installEventFilter(q); + //Note: if parent is reparented, then window may change even if parent doesn't. + // We need to install an avent filter on each parent up to the parent that is + // also a window (for shortcuts) + QWidget *newWindow = newParent ? newParent->window() : Q_NULLPTR; + + QVector<QPointer<QWidget> > newParents; + // Remove event filters on ex-parents, keep them on still-parents + // The parents are always ordered in the vector + foreach (const QPointer<QWidget> &w, oldParents) { + if (w) { + if (newParent == w) { + newParents.append(w); + if (newParent != newWindow) //stop at the window + newParent = newParent->parentWidget(); + } else { + w->removeEventFilter(q); + } + } } - //we also need event filter on top-level (for shortcuts) - QWidget *newWindow = newParent ? newParent->window() : 0; - - if (oldWindow != newWindow) { - if (oldParent && oldParent != oldWindow) - oldWindow->removeEventFilter(q); - - if (newParent && newParent != newWindow) - newWindow->installEventFilter(q); + // At this point, newParent is the next one to be added to newParents + while (newParent && newParent != newWindow) { + //install event filters all the way up to (excluding) the window + newParents.append(newParent); + newParent->installEventFilter(q); + newParent = newParent->parentWidget(); } - oldParent = newParent; - oldWindow = newWindow; + if (newParent && newWindow) { + // Install the event filter on the window + newParents.append(newParent); + newParent->installEventFilter(q); + } + oldParents = newParents; if (platformMenuBar) { if (newWindow) { @@ -1450,10 +1460,9 @@ bool QMenuBar::event(QEvent *e) bool QMenuBar::eventFilter(QObject *object, QEvent *event) { Q_D(QMenuBar); - if (object == parent() && object) { - if (event->type() == QEvent::ParentChange) //GrandparentChange + if (object && (event->type() == QEvent::ParentChange)) //GrandparentChange d->handleReparent(); - } + if (object == d->leftWidget || object == d->rightWidget) { switch (event->type()) { case QEvent::ShowToParent: diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h index 8a01cb3233..0db986bac5 100644 --- a/src/widgets/widgets/qmenubar_p.h +++ b/src/widgets/widgets/qmenubar_p.h @@ -124,8 +124,7 @@ public: // reparenting void handleReparent(); - QWidget *oldParent; - QWidget *oldWindow; + QVector<QPointer<QWidget> > oldParents; QList<QAction*> hiddenActions; //default action |