diff options
Diffstat (limited to 'src/widgets/widgets')
95 files changed, 1707 insertions, 501 deletions
diff --git a/src/widgets/widgets/qabstractbutton.cpp b/src/widgets/widgets/qabstractbutton.cpp index e413b3b87a..a1707b9cab 100644 --- a/src/widgets/widgets/qabstractbutton.cpp +++ b/src/widgets/widgets/qabstractbutton.cpp @@ -221,13 +221,12 @@ void QButtonGroup::addButton(QAbstractButton *button, int id) button->d_func()->group = this; d->buttonList.append(button); if (id == -1) { - QList<int> ids = d->mapping.values(); - if (ids.isEmpty()) - d->mapping[button] = -2; - else { - std::sort(ids.begin(), ids.end()); - d->mapping[button] = ids.first()-1; - } + const QHash<QAbstractButton*, int>::const_iterator it + = std::min_element(d->mapping.cbegin(), d->mapping.cend()); + if (it == d->mapping.cend()) + d->mapping[button] = -2; + else + d->mapping[button] = *it - 1; } else { d->mapping[button] = id; } @@ -1222,16 +1221,14 @@ void QAbstractButton::keyPressEvent(QKeyEvent *e) } break; } - case Qt::Key_Escape: - if (d->down) { + default: + if (e->matches(QKeySequence::Cancel) && d->down) { setDown(false); repaint(); //flush paint event before invoking potentially expensive operation QApplication::flush(); d->emitReleased(); - break; + return; } - // fall through - default: e->ignore(); } } diff --git a/src/widgets/widgets/qabstractbutton.h b/src/widgets/widgets/qabstractbutton.h index 4b397e2396..5f3e82a2e6 100644 --- a/src/widgets/widgets/qabstractbutton.h +++ b/src/widgets/widgets/qabstractbutton.h @@ -63,7 +63,7 @@ class Q_WIDGETS_EXPORT QAbstractButton : public QWidget Q_PROPERTY(bool down READ isDown WRITE setDown DESIGNABLE false) public: - explicit QAbstractButton(QWidget* parent=0); + explicit QAbstractButton(QWidget *parent = Q_NULLPTR); ~QAbstractButton(); void setText(const QString &text); @@ -135,7 +135,7 @@ protected: protected: - QAbstractButton(QAbstractButtonPrivate &dd, QWidget* parent = 0); + QAbstractButton(QAbstractButtonPrivate &dd, QWidget* parent = Q_NULLPTR); private: Q_DECLARE_PRIVATE(QAbstractButton) diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp index 2e1caedde7..65d06eafc5 100644 --- a/src/widgets/widgets/qabstractscrollarea.cpp +++ b/src/widgets/widgets/qabstractscrollarea.cpp @@ -168,6 +168,10 @@ QAbstractScrollAreaPrivate::QAbstractScrollAreaPrivate() { } +QAbstractScrollAreaPrivate::~QAbstractScrollAreaPrivate() +{ +} + QAbstractScrollAreaScrollBarContainer::QAbstractScrollAreaScrollBarContainer(Qt::Orientation orientation, QWidget *parent) :QWidget(parent), scrollBar(new QScrollBar(orientation, this)), layout(new QBoxLayout(orientation == Qt::Horizontal ? QBoxLayout::LeftToRight : QBoxLayout::TopToBottom)), @@ -206,10 +210,12 @@ QWidgetList QAbstractScrollAreaScrollBarContainer::widgets(LogicalPosition posit QWidgetList list; const int scrollBarIndex = scrollBarLayoutIndex(); if (position == LogicalLeft) { + list.reserve(scrollBarIndex); for (int i = 0; i < scrollBarIndex; ++i) list.append(layout->itemAt(i)->widget()); } else if (position == LogicalRight) { const int layoutItemCount = layout->count(); + list.reserve(layoutItemCount - (scrollBarIndex + 1)); for (int i = scrollBarIndex + 1; i < layoutItemCount; ++i) list.append(layout->itemAt(i)->widget()); } diff --git a/src/widgets/widgets/qabstractscrollarea.h b/src/widgets/widgets/qabstractscrollarea.h index 13dafd547b..8bc32b1c78 100644 --- a/src/widgets/widgets/qabstractscrollarea.h +++ b/src/widgets/widgets/qabstractscrollarea.h @@ -54,7 +54,7 @@ class Q_WIDGETS_EXPORT QAbstractScrollArea : public QFrame Q_PROPERTY(SizeAdjustPolicy sizeAdjustPolicy READ sizeAdjustPolicy WRITE setSizeAdjustPolicy) public: - explicit QAbstractScrollArea(QWidget* parent=0); + explicit QAbstractScrollArea(QWidget *parent = Q_NULLPTR); ~QAbstractScrollArea(); enum SizeAdjustPolicy { @@ -94,7 +94,7 @@ public: void setSizeAdjustPolicy(SizeAdjustPolicy policy); protected: - QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent = 0); + QAbstractScrollArea(QAbstractScrollAreaPrivate &dd, QWidget *parent = Q_NULLPTR); void setViewportMargins(int left, int top, int right, int bottom); void setViewportMargins(const QMargins &margins); QMargins viewportMargins() const; diff --git a/src/widgets/widgets/qabstractscrollarea_p.h b/src/widgets/widgets/qabstractscrollarea_p.h index f770bb69f8..33222573f4 100644 --- a/src/widgets/widgets/qabstractscrollarea_p.h +++ b/src/widgets/widgets/qabstractscrollarea_p.h @@ -54,12 +54,15 @@ QT_BEGIN_NAMESPACE class QScrollBar; class QAbstractScrollAreaScrollBarContainer; + +// ### Qt 6: is the export still needed? If not, unexport QFramePrivate, too. class Q_WIDGETS_EXPORT QAbstractScrollAreaPrivate: public QFramePrivate { Q_DECLARE_PUBLIC(QAbstractScrollArea) public: QAbstractScrollAreaPrivate(); + ~QAbstractScrollAreaPrivate(); void replaceScrollBar(QScrollBar *scrollBar, Qt::Orientation orientation); diff --git a/src/widgets/widgets/qabstractslider.h b/src/widgets/widgets/qabstractslider.h index 2f649e3d3d..6faca5ea3c 100644 --- a/src/widgets/widgets/qabstractslider.h +++ b/src/widgets/widgets/qabstractslider.h @@ -58,7 +58,7 @@ class Q_WIDGETS_EXPORT QAbstractSlider : public QWidget Q_PROPERTY(bool sliderDown READ isSliderDown WRITE setSliderDown DESIGNABLE false) public: - explicit QAbstractSlider(QWidget *parent=0); + explicit QAbstractSlider(QWidget *parent = Q_NULLPTR); ~QAbstractSlider(); Qt::Orientation orientation() const; @@ -144,7 +144,7 @@ protected: protected: - QAbstractSlider(QAbstractSliderPrivate &dd, QWidget *parent=0); + QAbstractSlider(QAbstractSliderPrivate &dd, QWidget *parent = Q_NULLPTR); private: Q_DISABLE_COPY(QAbstractSlider) diff --git a/src/widgets/widgets/qabstractspinbox.cpp b/src/widgets/widgets/qabstractspinbox.cpp index c96c779d6a..ba4bbe40a8 100644 --- a/src/widgets/widgets/qabstractspinbox.cpp +++ b/src/widgets/widgets/qabstractspinbox.cpp @@ -720,7 +720,16 @@ void QAbstractSpinBox::interpretText() QVariant QAbstractSpinBox::inputMethodQuery(Qt::InputMethodQuery query) const { Q_D(const QAbstractSpinBox); - return d->edit->inputMethodQuery(query); + const QVariant lineEditValue = d->edit->inputMethodQuery(query); + switch (query) { + case Qt::ImHints: + if (const int hints = inputMethodHints()) + return QVariant(hints | lineEditValue.toInt()); + break; + default: + break; + } + return lineEditValue; } /*! diff --git a/src/widgets/widgets/qabstractspinbox.h b/src/widgets/widgets/qabstractspinbox.h index a80a89c894..046036b9a8 100644 --- a/src/widgets/widgets/qabstractspinbox.h +++ b/src/widgets/widgets/qabstractspinbox.h @@ -64,7 +64,7 @@ class Q_WIDGETS_EXPORT QAbstractSpinBox : public QWidget Q_PROPERTY(bool keyboardTracking READ keyboardTracking WRITE setKeyboardTracking) Q_PROPERTY(bool showGroupSeparator READ isGroupSeparatorShown WRITE setGroupSeparatorShown) public: - explicit QAbstractSpinBox(QWidget *parent = 0); + explicit QAbstractSpinBox(QWidget *parent = Q_NULLPTR); ~QAbstractSpinBox(); enum StepEnabledFlag { StepNone = 0x00, StepUpEnabled = 0x01, @@ -154,7 +154,7 @@ protected: Q_SIGNALS: void editingFinished(); protected: - QAbstractSpinBox(QAbstractSpinBoxPrivate &dd, QWidget *parent = 0); + QAbstractSpinBox(QAbstractSpinBoxPrivate &dd, QWidget *parent = Q_NULLPTR); private: Q_PRIVATE_SLOT(d_func(), void _q_editorTextChanged(const QString &)) diff --git a/src/widgets/widgets/qbuttongroup.h b/src/widgets/widgets/qbuttongroup.h index 01de03ac84..ba4f8e26c1 100644 --- a/src/widgets/widgets/qbuttongroup.h +++ b/src/widgets/widgets/qbuttongroup.h @@ -51,7 +51,7 @@ class Q_WIDGETS_EXPORT QButtonGroup : public QObject Q_PROPERTY(bool exclusive READ exclusive WRITE setExclusive) public: - explicit QButtonGroup(QObject *parent = 0); + explicit QButtonGroup(QObject *parent = Q_NULLPTR); ~QButtonGroup(); void setExclusive(bool); diff --git a/src/widgets/widgets/qcalendarwidget.cpp b/src/widgets/widgets/qcalendarwidget.cpp index 2150fc7a50..48b224fe13 100644 --- a/src/widgets/widgets/qcalendarwidget.cpp +++ b/src/widgets/widgets/qcalendarwidget.cpp @@ -776,7 +776,7 @@ bool QCalendarTextNavigator::eventFilter(QObject *o, QEvent *e) applyDate(); emit editingFinished(); removeDateLabel(); - } else if (ke->key() == Qt::Key_Escape) { + } else if (ke->matches(QKeySequence::Cancel)) { removeDateLabel(); } else if (e->type() == QEvent::KeyPress) { createDateLabel(); @@ -3078,8 +3078,7 @@ void QCalendarWidget::resizeEvent(QResizeEvent * event) void QCalendarWidget::keyPressEvent(QKeyEvent * event) { Q_D(QCalendarWidget); - if(d->yearEdit->isVisible()&& event->key() == Qt::Key_Escape) - { + if (d->yearEdit->isVisible()&& event->matches(QKeySequence::Cancel)) { d->yearEdit->setValue(yearShown()); d->_q_yearEditingFinished(); return; diff --git a/src/widgets/widgets/qcalendarwidget.h b/src/widgets/widgets/qcalendarwidget.h index c456cc2161..df54985351 100644 --- a/src/widgets/widgets/qcalendarwidget.h +++ b/src/widgets/widgets/qcalendarwidget.h @@ -83,7 +83,7 @@ public: }; Q_ENUM(SelectionMode) - explicit QCalendarWidget(QWidget *parent = 0); + explicit QCalendarWidget(QWidget *parent = Q_NULLPTR); ~QCalendarWidget(); virtual QSize sizeHint() const Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qcheckbox.h b/src/widgets/widgets/qcheckbox.h index b614659f02..61d03eb8e6 100644 --- a/src/widgets/widgets/qcheckbox.h +++ b/src/widgets/widgets/qcheckbox.h @@ -49,8 +49,8 @@ class Q_WIDGETS_EXPORT QCheckBox : public QAbstractButton Q_PROPERTY(bool tristate READ isTristate WRITE setTristate) public: - explicit QCheckBox(QWidget *parent=0); - explicit QCheckBox(const QString &text, QWidget *parent=0); + explicit QCheckBox(QWidget *parent = Q_NULLPTR); + explicit QCheckBox(const QString &text, QWidget *parent = Q_NULLPTR); ~QCheckBox(); QSize sizeHint() const Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index b04aa7053a..35c54f102f 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -546,7 +546,8 @@ void QComboBoxPrivateContainer::setItemView(QAbstractItemView *itemView) disconnect(view, SIGNAL(destroyed()), this, SLOT(viewDestroyed())); - delete view; + if (isAncestorOf(view)) + delete view; view = 0; } @@ -653,8 +654,9 @@ void QComboBoxPrivateContainer::changeEvent(QEvent *e) bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e) { switch (e->type()) { - case QEvent::ShortcutOverride: - switch (static_cast<QKeyEvent*>(e)->key()) { + case QEvent::ShortcutOverride: { + QKeyEvent *keyEvent = static_cast<QKeyEvent*>(e); + switch (keyEvent->key()) { case Qt::Key_Enter: case Qt::Key_Return: #ifdef QT_KEYPAD_NAVIGATION @@ -666,17 +668,21 @@ bool QComboBoxPrivateContainer::eventFilter(QObject *o, QEvent *e) } return true; case Qt::Key_Down: - if (!(static_cast<QKeyEvent*>(e)->modifiers() & Qt::AltModifier)) + if (!(keyEvent->modifiers() & Qt::AltModifier)) break; // fall through case Qt::Key_F4: - case Qt::Key_Escape: combo->hidePopup(); return true; default: + if (keyEvent->matches(QKeySequence::Cancel)) { + combo->hidePopup(); + return true; + } break; } - break; + break; + } case QEvent::MouseMove: if (isVisible()) { QMouseEvent *m = static_cast<QMouseEvent *>(e); @@ -2268,6 +2274,7 @@ void QComboBox::insertItems(int index, const QStringList &list) // construct a QStandardItem, reducing the number of expensive signals from the model if (QStandardItemModel *m = qobject_cast<QStandardItemModel*>(d->model)) { QList<QStandardItem *> items; + items.reserve(insertCount); QStandardItem *hiddenRoot = m->invisibleRootItem(); for (int i = 0; i < insertCount; ++i) items.append(new QStandardItem(list.at(i))); @@ -3032,9 +3039,6 @@ void QComboBox::mousePressEvent(QMouseEvent *e) d->showPopupFromMouseEvent(e); } -/*! - \reimp -*/ void QComboBoxPrivate::showPopupFromMouseEvent(QMouseEvent *e) { Q_Q(QComboBox); diff --git a/src/widgets/widgets/qcombobox.h b/src/widgets/widgets/qcombobox.h index ae35f7a89a..3182a0a3aa 100644 --- a/src/widgets/widgets/qcombobox.h +++ b/src/widgets/widgets/qcombobox.h @@ -74,7 +74,7 @@ class Q_WIDGETS_EXPORT QComboBox : public QWidget Q_PROPERTY(int modelColumn READ modelColumn WRITE setModelColumn) public: - explicit QComboBox(QWidget *parent = 0); + explicit QComboBox(QWidget *parent = Q_NULLPTR); ~QComboBox(); int maxVisibleItems() const; diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h index 3fdfdcc22f..b69b94f3b9 100644 --- a/src/widgets/widgets/qcombobox_p.h +++ b/src/widgets/widgets/qcombobox_p.h @@ -57,7 +57,6 @@ #include "QtGui/qpainter.h" #include "QtWidgets/qstyle.h" #include "QtWidgets/qstyleoption.h" -#include "QtCore/qhash.h" #include "QtCore/qpair.h" #include "QtCore/qtimer.h" #include "private/qwidget_p.h" diff --git a/src/widgets/widgets/qcommandlinkbutton.h b/src/widgets/widgets/qcommandlinkbutton.h index 486c48af5d..9ddb14270d 100644 --- a/src/widgets/widgets/qcommandlinkbutton.h +++ b/src/widgets/widgets/qcommandlinkbutton.h @@ -49,9 +49,9 @@ class Q_WIDGETS_EXPORT QCommandLinkButton: public QPushButton Q_PROPERTY(bool flat READ isFlat WRITE setFlat DESIGNABLE false) public: - explicit QCommandLinkButton(QWidget *parent=0); - explicit QCommandLinkButton(const QString &text, QWidget *parent=0); - explicit QCommandLinkButton(const QString &text, const QString &description, QWidget *parent=0); + explicit QCommandLinkButton(QWidget *parent = Q_NULLPTR); + explicit QCommandLinkButton(const QString &text, QWidget *parent = Q_NULLPTR); + explicit QCommandLinkButton(const QString &text, const QString &description, QWidget *parent = Q_NULLPTR); ~QCommandLinkButton(); QString description() const; diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index a8da78a025..abee788a46 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -1687,6 +1687,10 @@ QDateTimeEditPrivate::QDateTimeEditPrivate() #endif } +QDateTimeEditPrivate::~QDateTimeEditPrivate() +{ +} + void QDateTimeEditPrivate::updateTimeSpec() { minimum = minimum.toDateTime().toTimeSpec(spec); @@ -2655,7 +2659,7 @@ bool QCalendarPopup::event(QEvent *event) { if (event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event); - if (keyEvent->key()== Qt::Key_Escape) + if (keyEvent->matches(QKeySequence::Cancel)) dateChanged = false; } return QWidget::event(event); diff --git a/src/widgets/widgets/qdatetimeedit.h b/src/widgets/widgets/qdatetimeedit.h index 4e77713fd0..829ce205be 100644 --- a/src/widgets/widgets/qdatetimeedit.h +++ b/src/widgets/widgets/qdatetimeedit.h @@ -86,10 +86,10 @@ public: Q_DECLARE_FLAGS(Sections, Section) - explicit QDateTimeEdit(QWidget *parent = 0); - explicit QDateTimeEdit(const QDateTime &dt, QWidget *parent = 0); - explicit QDateTimeEdit(const QDate &d, QWidget *parent = 0); - explicit QDateTimeEdit(const QTime &t, QWidget *parent = 0); + explicit QDateTimeEdit(QWidget *parent = Q_NULLPTR); + explicit QDateTimeEdit(const QDateTime &dt, QWidget *parent = Q_NULLPTR); + explicit QDateTimeEdit(const QDate &d, QWidget *parent = Q_NULLPTR); + explicit QDateTimeEdit(const QTime &t, QWidget *parent = Q_NULLPTR); ~QDateTimeEdit(); QDateTime dateTime() const; @@ -185,7 +185,7 @@ protected: virtual void paintEvent(QPaintEvent *event); void initStyleOption(QStyleOptionSpinBox *option) const; - QDateTimeEdit(const QVariant &val, QVariant::Type parserType, QWidget *parent = 0); + QDateTimeEdit(const QVariant &val, QVariant::Type parserType, QWidget *parent = Q_NULLPTR); private: Q_DECLARE_PRIVATE(QDateTimeEdit) Q_DISABLE_COPY(QDateTimeEdit) @@ -198,8 +198,8 @@ class Q_WIDGETS_EXPORT QTimeEdit : public QDateTimeEdit Q_OBJECT Q_PROPERTY(QTime time READ time WRITE setTime NOTIFY userTimeChanged USER true) public: - explicit QTimeEdit(QWidget *parent = 0); - explicit QTimeEdit(const QTime &time, QWidget *parent = 0); + explicit QTimeEdit(QWidget *parent = Q_NULLPTR); + explicit QTimeEdit(const QTime &time, QWidget *parent = Q_NULLPTR); ~QTimeEdit(); Q_SIGNALS: @@ -211,8 +211,8 @@ class Q_WIDGETS_EXPORT QDateEdit : public QDateTimeEdit Q_OBJECT Q_PROPERTY(QDate date READ date WRITE setDate NOTIFY userDateChanged USER true) public: - explicit QDateEdit(QWidget *parent = 0); - explicit QDateEdit(const QDate &date, QWidget *parent = 0); + explicit QDateEdit(QWidget *parent = Q_NULLPTR); + explicit QDateEdit(const QDate &date, QWidget *parent = Q_NULLPTR); ~QDateEdit(); Q_SIGNALS: diff --git a/src/widgets/widgets/qdatetimeedit_p.h b/src/widgets/widgets/qdatetimeedit_p.h index 50e2cde8cc..4a6014000b 100644 --- a/src/widgets/widgets/qdatetimeedit_p.h +++ b/src/widgets/widgets/qdatetimeedit_p.h @@ -62,11 +62,12 @@ QT_BEGIN_NAMESPACE class QCalendarPopup; -class QDateTimeEditPrivate : public QAbstractSpinBoxPrivate, public QDateTimeParser +class Q_AUTOTEST_EXPORT QDateTimeEditPrivate : public QAbstractSpinBoxPrivate, public QDateTimeParser { Q_DECLARE_PUBLIC(QDateTimeEdit) public: QDateTimeEditPrivate(); + ~QDateTimeEditPrivate(); void init(const QVariant &var); void readLocaleSettings(); diff --git a/src/widgets/widgets/qdial.h b/src/widgets/widgets/qdial.h index 7e01aefce3..cb69e02301 100644 --- a/src/widgets/widgets/qdial.h +++ b/src/widgets/widgets/qdial.h @@ -54,7 +54,7 @@ class Q_WIDGETS_EXPORT QDial: public QAbstractSlider Q_PROPERTY(qreal notchTarget READ notchTarget WRITE setNotchTarget) Q_PROPERTY(bool notchesVisible READ notchesVisible WRITE setNotchesVisible) public: - explicit QDial(QWidget *parent = 0); + explicit QDial(QWidget *parent = Q_NULLPTR); ~QDial(); diff --git a/src/widgets/widgets/qdialogbuttonbox.cpp b/src/widgets/widgets/qdialogbuttonbox.cpp index 5b6bfb3b3c..4d2c32d43e 100644 --- a/src/widgets/widgets/qdialogbuttonbox.cpp +++ b/src/widgets/widgets/qdialogbuttonbox.cpp @@ -261,7 +261,7 @@ void QDialogButtonBoxPrivate::layoutButtons() if (center) buttonLayout->addStretch(); - QList<QAbstractButton *> acceptRoleList = buttonLists[QPlatformDialogHelper::AcceptRole]; + const QList<QAbstractButton *> &acceptRoleList = buttonLists[QPlatformDialogHelper::AcceptRole]; while (*currentLayout != QPlatformDialogHelper::EOL) { int role = (*currentLayout & ~QPlatformDialogHelper::Reverse); diff --git a/src/widgets/widgets/qdialogbuttonbox.h b/src/widgets/widgets/qdialogbuttonbox.h index 02960b5b79..83c1fd66fd 100644 --- a/src/widgets/widgets/qdialogbuttonbox.h +++ b/src/widgets/widgets/qdialogbuttonbox.h @@ -106,11 +106,11 @@ public: GnomeLayout }; - QDialogButtonBox(QWidget *parent = 0); - QDialogButtonBox(Qt::Orientation orientation, QWidget *parent = 0); - explicit QDialogButtonBox(StandardButtons buttons, QWidget *parent = 0); + QDialogButtonBox(QWidget *parent = Q_NULLPTR); + QDialogButtonBox(Qt::Orientation orientation, QWidget *parent = Q_NULLPTR); + explicit QDialogButtonBox(StandardButtons buttons, QWidget *parent = Q_NULLPTR); QDialogButtonBox(StandardButtons buttons, Qt::Orientation orientation, - QWidget *parent = 0); + QWidget *parent = Q_NULLPTR); ~QDialogButtonBox(); void setOrientation(Qt::Orientation orientation); diff --git a/src/widgets/widgets/qdockarealayout.cpp b/src/widgets/widgets/qdockarealayout.cpp index e71b9616fc..8c79425e44 100644 --- a/src/widgets/widgets/qdockarealayout.cpp +++ b/src/widgets/widgets/qdockarealayout.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com> ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtWidgets module of the Qt Toolkit. @@ -1017,7 +1018,7 @@ QLayoutItem *QDockAreaLayoutInfo::plug(const QList<int> &path) index = -index - 1; if (path.count() > 1) { - const QDockAreaLayoutItem &item = item_list.at(index); + QDockAreaLayoutItem &item = item_list[index]; Q_ASSERT(item.subinfo != 0); return item.subinfo->plug(path.mid(1)); } @@ -1063,7 +1064,7 @@ QLayoutItem *QDockAreaLayoutInfo::unplug(const QList<int> &path) const int index = path.first(); if (path.count() > 1) { - const QDockAreaLayoutItem &item = item_list.at(index); + QDockAreaLayoutItem &item = item_list[index]; Q_ASSERT(item.subinfo != 0); return item.subinfo->unplug(path.mid(1)); } @@ -1815,7 +1816,8 @@ void QDockAreaLayoutInfo::saveState(QDataStream &stream) const stream << flags; if (w->isWindow()) { - stream << w->x() << w->y() << w->width() << w->height(); + const QRect geometry = w->geometry(); + stream << geometry.x() << geometry.y() << geometry.width() << geometry.height(); } else { stream << item.pos << item.size << pick(o, item.minimumSize()) << pick(o, item.maximumSize()); @@ -1854,20 +1856,6 @@ static Qt::DockWidgetArea toDockWidgetArea(QInternal::DockPosition pos) return Qt::NoDockWidgetArea; } -static QRect constrainedRect(QRect rect, const QRect &desktop) -{ - if (desktop.isValid()) { - rect.setWidth(qMin(rect.width(), desktop.width())); - rect.setHeight(qMin(rect.height(), desktop.height())); - rect.moveLeft(qMax(rect.left(), desktop.left())); - rect.moveTop(qMax(rect.top(), desktop.top())); - rect.moveRight(qMin(rect.right(), desktop.right())); - rect.moveBottom(qMin(rect.bottom(), desktop.bottom())); - } - - return rect; -} - bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> &widgets, bool testing) { uchar marker; @@ -1958,11 +1946,7 @@ bool QDockAreaLayoutInfo::restoreState(QDataStream &stream, QList<QDockWidget*> #endif if (!testing) { QRect r(x, y, w, h); - QDesktopWidget *desktop = QApplication::desktop(); - if (desktop->isVirtualDesktop()) - r = constrainedRect(r, desktop->screenGeometry(desktop->screenNumber(r.topLeft()))); - else - r = constrainedRect(r, desktop->screenGeometry(widget)); + r = QDockAreaLayout::constrainedRect(r, widget); widget->move(r.topLeft()); widget->resize(r.size()); } @@ -2075,6 +2059,36 @@ void QDockAreaLayoutInfo::updateSeparatorWidgets() const #endif //QT_NO_TABBAR #ifndef QT_NO_TABBAR +/*! \internal + reparent all the widgets contained in this layout portion to the + specified parent. This is used to reparent dock widgets and tabbars + to the floating window or the main window + */ +void QDockAreaLayoutInfo::reparentWidgets(QWidget *parent) +{ + if (tabBar) + tabBar->setParent(parent); + + for (int i = 0; i < item_list.count(); ++i) { + const QDockAreaLayoutItem &item = item_list.at(i); + if (item.flags & QDockAreaLayoutItem::GapItem) + continue; + if (item.skip()) + continue; + if (item.subinfo) + item.subinfo->reparentWidgets(parent); + if (item.widgetItem) { + QWidget *w = item.widgetItem->widget(); + if (w->parent() != parent) { + bool hidden = w->isHidden(); + w->setParent(parent); + if (!hidden) + w->show(); + } + } + } +} + //returns whether the tabbar is visible or not bool QDockAreaLayoutInfo::updateTabBar() const { @@ -2092,6 +2106,8 @@ bool QDockAreaLayoutInfo::updateTabBar() const const QSignalBlocker blocker(tabBar); bool gap = false; + const quintptr oldCurrentId = currentTabId(); + int tab_idx = 0; for (int i = 0; i < item_list.count(); ++i) { const QDockAreaLayoutItem &item = item_list.at(i); @@ -2140,6 +2156,9 @@ bool QDockAreaLayoutInfo::updateTabBar() const tabBar->removeTab(tab_idx); } + if (oldCurrentId > 0 && currentTabId() != oldCurrentId) + that->setCurrentTabId(oldCurrentId); + //returns if the tabbar is visible or not return ( (gap ? 1 : 0) + tabBar->count()) > 1; } @@ -2198,8 +2217,10 @@ QSet<QTabBar*> QDockAreaLayoutInfo::usedTabBars() const QSet<QWidget*> QDockAreaLayoutInfo::usedSeparatorWidgets() const { QSet<QWidget*> result; + const int numSeparatorWidgets = separatorWidgets.count(); + result.reserve(numSeparatorWidgets); - for (int i = 0; i < separatorWidgets.count(); ++i) + for (int i = 0; i < numSeparatorWidgets; ++i) result << separatorWidgets.at(i); for (int i = 0; i < item_list.count(); ++i) { @@ -2244,6 +2265,22 @@ QRect QDockAreaLayoutInfo::tabContentRect() const return result; } + +int QDockAreaLayoutInfo::tabIndexToListIndex(int tabIndex) const +{ + Q_ASSERT(tabbed && tabBar); + quintptr data = qvariant_cast<quintptr>(tabBar->tabData(tabIndex)); + for (int i = 0; i < item_list.count(); ++i) { + if (tabId(item_list.at(i)) == data) + return i; + } + return -1; +} + +void QDockAreaLayoutInfo::moveTab(int from, int to) +{ + item_list.move(tabIndexToListIndex(from), tabIndexToListIndex(to)); +} #endif // QT_NO_TABBAR /****************************************************************************** @@ -2965,6 +3002,33 @@ QSize QDockAreaLayout::minimumSize() const return QSize(qMax(row1, row2, row3), qMax(col1, col2, col3)); } +/*! \internal + Try to fit the given rectangle \a rect on the screen which contains + the window \a widget. + Used to compute the geometry of a dragged a dock widget that should + be shown with \a rect, but needs to be visible on the screen + */ +QRect QDockAreaLayout::constrainedRect(QRect rect, QWidget* widget) +{ + QRect desktop; + QDesktopWidget *desktopW = QApplication::desktop(); + if (desktopW->isVirtualDesktop()) + desktop = desktopW->screenGeometry(rect.topLeft()); + else + desktop = desktopW->screenGeometry(widget); + + if (desktop.isValid()) { + rect.setWidth(qMin(rect.width(), desktop.width())); + rect.setHeight(qMin(rect.height(), desktop.height())); + rect.moveLeft(qMax(rect.left(), desktop.left())); + rect.moveTop(qMax(rect.top(), desktop.top())); + rect.moveRight(qMin(rect.right(), desktop.right())); + rect.moveBottom(qMin(rect.bottom(), desktop.bottom())); + } + + return rect; +} + bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget) { QList<int> index = indexOfPlaceHolder(dockWidget->objectName()); @@ -2978,9 +3042,7 @@ bool QDockAreaLayout::restoreDockWidget(QDockWidget *dockWidget) item.widgetItem = new QDockWidgetItem(dockWidget); if (placeHolder->window) { - const QRect screenGeometry = - QApplication::desktop()->screenGeometry(placeHolder->topLevelRect.center()); - const QRect r = constrainedRect(placeHolder->topLevelRect, screenGeometry); + const QRect r = constrainedRect(placeHolder->topLevelRect, dockWidget); dockWidget->d_func()->setWindowState(true, true, r); } dockWidget->setVisible(!placeHolder->hidden); @@ -3045,6 +3107,53 @@ void QDockAreaLayout::tabifyDockWidget(QDockWidget *first, QDockWidget *second) remove(index); } +void QDockAreaLayout::resizeDocks(const QList<QDockWidget *> &docks, + const QList<int> &sizes, Qt::Orientation o) +{ + if (docks.count() != sizes.count()) { + qWarning("QMainWidget::resizeDocks: size of the lists are not the same"); + return; + } + int count = docks.count(); + fallbackToSizeHints = false; + for (int i = 0; i < count; ++i) { + QList<int> path = indexOf(docks[i]); + if (path.isEmpty()) { + qWarning("QMainWidget::resizeDocks: one QDockWidget is not part of the layout"); + continue; + } + int size = sizes[i]; + if (size <= 0) { + qWarning("QMainWidget::resizeDocks: all sizes need to be larger than 0"); + size = 1; + } + + while (path.size() > 1) { + QDockAreaLayoutInfo *info = this->info(path); + if (!info->tabbed && info->o == o) { + info->item_list[path.last()].size = size; + int totalSize = 0; + foreach (const QDockAreaLayoutItem &item, info->item_list) { + if (!item.skip()) { + if (totalSize != 0) + totalSize += sep; + totalSize += item.size == -1 ? pick(o, item.sizeHint()) : item.size; + } + } + size = totalSize; + } + path.removeLast(); + } + + const int dockNum = path.first(); + Q_ASSERT(dockNum < QInternal::DockCount); + QRect &r = this->docks[dockNum].rect; + QSize s = r.size(); + rpick(o, s) = size; + r.setSize(s); + } +} + void QDockAreaLayout::splitDockWidget(QDockWidget *after, QDockWidget *dockWidget, Qt::Orientation orientation) diff --git a/src/widgets/widgets/qdockarealayout_p.h b/src/widgets/widgets/qdockarealayout_p.h index 7c67466c7b..5d352f0124 100644 --- a/src/widgets/widgets/qdockarealayout_p.h +++ b/src/widgets/widgets/qdockarealayout_p.h @@ -202,12 +202,16 @@ public: QTabBar *tabBar; int tabBarShape; + void reparentWidgets(QWidget *p); bool updateTabBar() const; void setTabBarShape(int shape); QSize tabBarMinimumSize() const; QSize tabBarSizeHint() const; QSet<QTabBar*> usedTabBars() const; + + int tabIndexToListIndex(int) const; + void moveTab(int from, int to); #endif // QT_NO_TABBAR }; @@ -229,7 +233,8 @@ public: bool isValid() const; - enum { DockWidgetStateMarker = 0xfd }; + enum { DockWidgetStateMarker = 0xfd, FloatingDockWidgetTabMarker = 0xf9 }; + static QRect constrainedRect(QRect rect, QWidget *widget); void saveState(QDataStream &stream) const; bool restoreState(QDataStream &stream, const QList<QDockWidget*> &widgets, bool testing = false); @@ -263,6 +268,7 @@ public: void splitDockWidget(QDockWidget *after, QDockWidget *dockWidget, Qt::Orientation orientation); void tabifyDockWidget(QDockWidget *first, QDockWidget *second); + void resizeDocks(const QList<QDockWidget *> &docks, const QList<int> &sizes, Qt::Orientation o); void apply(bool animate); diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp index 21b0904cc0..67eb466ba8 100644 --- a/src/widgets/widgets/qdockwidget.cpp +++ b/src/widgets/widgets/qdockwidget.cpp @@ -65,6 +65,18 @@ extern QString qt_setWindowTitle_helperHelper(const QString&, const QWidget*); / // qmainwindow.cpp extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window); +static inline QMainWindowLayout *qt_mainwindow_layout_from_dock(const QDockWidget *dock) +{ + const QWidget *p = dock->parentWidget(); + while (p) { + const QMainWindow *window = qobject_cast<const QMainWindow*>(p); + if (window) + return qt_mainwindow_layout(window); + p = p->parentWidget(); + } + return Q_NULLPTR; +} + static inline bool hasFeature(const QDockWidgetPrivate *priv, QDockWidget::DockWidgetFeature feature) { return (priv->features & feature) == feature; } @@ -194,31 +206,46 @@ QDockWidgetLayout::~QDockWidgetLayout() qDeleteAll(item_list); } +/*! \internal + Returns true if the dock widget managed by this layout should have a native + window decoration or if Qt needs to draw it. + */ bool QDockWidgetLayout::nativeWindowDeco() const { - return nativeWindowDeco(parentWidget()->isWindow()); + bool floating = parentWidget()->isWindow(); + if (!floating && qobject_cast<QDockWidgetGroupWindow*>(parentWidget()->parentWidget())) + return wmSupportsNativeWindowDeco(); + return nativeWindowDeco(floating); } -static bool isXcb() +/*! \internal + Returns true if the window manager can draw natively the windows decoration + of a dock widget + */ +bool QDockWidgetLayout::wmSupportsNativeWindowDeco() { +#if defined(Q_OS_WINCE) || defined(Q_OS_ANDROID) + return false; +#else static const bool xcb = !QGuiApplication::platformName().compare(QLatin1String("xcb"), Qt::CaseInsensitive); - return xcb; + return !xcb; +#endif } +/*! \internal + Returns true if the dock widget managed by this layout should have a native + window decoration or if Qt needs to draw it. The \a floating parameter + overrides the floating current state of the dock widget. + */ bool QDockWidgetLayout::nativeWindowDeco(bool floating) const { -#if defined(Q_OS_WINCE) || defined(Q_OS_ANDROID) - Q_UNUSED(floating) - return false; -#else - return !isXcb() && (floating && item_list[QDockWidgetLayout::TitleBar] == 0); -#endif + return wmSupportsNativeWindowDeco() && floating && item_list.at(QDockWidgetLayout::TitleBar) == 0; } void QDockWidgetLayout::addItem(QLayoutItem*) { - qWarning() << "QDockWidgetLayout::addItem(): please use QDockWidgetLayout::setWidget()"; + qWarning("QDockWidgetLayout::addItem(): please use QDockWidgetLayout::setWidget()"); return; } @@ -480,7 +507,7 @@ void QDockWidgetLayout::setGeometry(const QRect &geometry) if (QLayoutItem *item = item_list[TitleBar]) { item->setGeometry(_titleArea); } else { - QStyleOptionDockWidgetV2 opt; + QStyleOptionDockWidget opt; q->initStyleOption(&opt); if (QLayoutItem *item = item_list[CloseButton]) { @@ -587,6 +614,7 @@ void QDockWidgetPrivate::init() #ifndef QT_NO_ACTION toggleViewAction = new QAction(q); toggleViewAction->setCheckable(true); + toggleViewAction->setMenuRole(QAction::NoRole); fixedWindowTitle = qt_setWindowTitle_helperHelper(q->windowTitle(), q); toggleViewAction->setText(fixedWindowTitle); QObject::connect(toggleViewAction, SIGNAL(triggered(bool)), @@ -611,7 +639,10 @@ void QDockWidget::initStyleOption(QStyleOptionDockWidget *option) const return; QDockWidgetLayout *dwlayout = qobject_cast<QDockWidgetLayout*>(layout()); - option->initFrom(this); + QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent()); + // If we are in a floating tab, init from the parent because the attributes and the geometry + // of the title bar should be taken from the floating window. + option->initFrom(floatingTab && !isFloating() ? parentWidget() : this); option->rect = dwlayout->titleArea(); option->title = d->fixedWindowTitle; option->closable = hasFeature(this, QDockWidget::DockWidgetClosable); @@ -619,10 +650,7 @@ void QDockWidget::initStyleOption(QStyleOptionDockWidget *option) const option->floatable = hasFeature(this, QDockWidget::DockWidgetFloatable); QDockWidgetLayout *l = qobject_cast<QDockWidgetLayout*>(layout()); - QStyleOptionDockWidgetV2 *v2 - = qstyleoption_cast<QStyleOptionDockWidgetV2*>(option); - if (v2 != 0) - v2->verticalTitleBar = l->verticalTitleBar; + option->verticalTitleBar = l->verticalTitleBar; } void QDockWidgetPrivate::_q_toggleView(bool b) @@ -681,14 +709,20 @@ void QDockWidgetPrivate::_q_toggleTopLevel() q->setFloating(!q->isFloating()); } +/*! \internal + Initialize the drag state structure and remember the position of the click. + This is called when the mouse is pressed, but the dock is not yet dragged out. + + \a nca specify that the event comes from NonClientAreaMouseButtonPress + */ void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca) { + Q_Q(QDockWidget); + if (state != 0) return; - QMainWindow *win = qobject_cast<QMainWindow*>(parent); - Q_ASSERT(win != 0); - QMainWindowLayout *layout = qt_mainwindow_layout(win); + QMainWindowLayout *layout = qt_mainwindow_layout_from_dock(q); Q_ASSERT(layout != 0); if (layout->pluggingWidget != 0) // the main window is animating a docking operation return; @@ -702,23 +736,33 @@ void QDockWidgetPrivate::initDrag(const QPoint &pos, bool nca) state->ctrlDrag = false; } -void QDockWidgetPrivate::startDrag() +/*! \internal + Actually start the drag and detach the dockwidget. + The \a group parameter is true when we should potentially drag a group of + tabbed widgets, and false if the dock widget should always be dragged + alone. + */ +void QDockWidgetPrivate::startDrag(bool group) { Q_Q(QDockWidget); if (state == 0 || state->dragging) return; - QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); + QMainWindowLayout *layout = qt_mainwindow_layout_from_dock(q); Q_ASSERT(layout != 0); - state->widgetItem = layout->unplug(q); + state->widgetItem = layout->unplug(q, group); if (state->widgetItem == 0) { /* I have a QMainWindow parent, but I was never inserted with QMainWindow::addDockWidget, so the QMainWindowLayout has no widget item for me. :( I have to create it myself, and then delete it if I don't get dropped into a dock area. */ - state->widgetItem = new QDockWidgetItem(q); + QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent); + if (floatingTab && !q->isFloating()) + state->widgetItem = new QDockWidgetGroupWindowItem(floatingTab); + else + state->widgetItem = new QDockWidgetItem(q); state->ownWidgetItem = true; } @@ -728,6 +772,11 @@ void QDockWidgetPrivate::startDrag() state->dragging = true; } +/*! \internal + Ends the drag end drop operation of the QDockWidget. + The \a abort parameter specifies that it ends because of programmatic state + reset rather than mouse release event. + */ void QDockWidgetPrivate::endDrag(bool abort) { Q_Q(QDockWidget); @@ -736,29 +785,31 @@ void QDockWidgetPrivate::endDrag(bool abort) q->releaseMouse(); if (state->dragging) { - QMainWindowLayout *mwLayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); + QMainWindowLayout *mwLayout = qt_mainwindow_layout_from_dock(q); Q_ASSERT(mwLayout != 0); if (abort || !mwLayout->plug(state->widgetItem)) { if (hasFeature(this, QDockWidget::DockWidgetFloatable)) { + // This QDockWidget will now stay in the floating state. if (state->ownWidgetItem) delete state->widgetItem; mwLayout->restore(); - if (isXcb()) { + QDockWidgetLayout *dwLayout = qobject_cast<QDockWidgetLayout*>(layout); + if (!dwLayout->nativeWindowDeco()) { // get rid of the X11BypassWindowManager window flag and activate the resizer Qt::WindowFlags flags = q->windowFlags(); flags &= ~Qt::X11BypassWindowManagerHint; q->setWindowFlags(flags); - setResizerActive(true); + setResizerActive(q->isFloating()); q->show(); } else { - QDockWidgetLayout *myLayout - = qobject_cast<QDockWidgetLayout*>(layout); - setResizerActive(myLayout->widgetForRole(QDockWidgetLayout::TitleBar) != 0); + setResizerActive(false); } undockedGeometry = q->geometry(); q->activateWindow(); } else { + // The tab was not plugged back in the QMainWindow but the QDockWidget cannot + // stay floating, revert to the previous state. mwLayout->revert(state->widgetItem); } } @@ -782,11 +833,7 @@ bool QDockWidgetPrivate::isAnimating() const { Q_Q(const QDockWidget); - QMainWindow *mainWin = qobject_cast<QMainWindow*>(parent); - if (mainWin == 0) - return false; - - QMainWindowLayout *mainWinLayout = qt_mainwindow_layout(mainWin); + QMainWindowLayout *mainWinLayout = qt_mainwindow_layout_from_dock(q); if (mainWinLayout == 0) return false; @@ -804,12 +851,14 @@ bool QDockWidgetPrivate::mousePressEvent(QMouseEvent *event) if (!dwLayout->nativeWindowDeco()) { QRect titleArea = dwLayout->titleArea(); + QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent); + if (event->button() != Qt::LeftButton || !titleArea.contains(event->pos()) || // check if the tool window is movable... do nothing if it // is not (but allow moving if the window is floating) (!hasFeature(this, QDockWidget::DockWidgetMovable) && !q->isFloating()) || - qobject_cast<QMainWindow*>(parent) == 0 || + (qobject_cast<QMainWindow*>(parent) == 0 && !floatingTab) || isAnimating() || state != 0) { return false; } @@ -853,7 +902,7 @@ bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event) QDockWidgetLayout *dwlayout = qobject_cast<QDockWidgetLayout *>(layout); - QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); + QMainWindowLayout *mwlayout = qt_mainwindow_layout_from_dock(q); if (!dwlayout->nativeWindowDeco()) { if (!state->dragging && mwlayout->pluggingWidget == 0 @@ -871,7 +920,12 @@ bool QDockWidgetPrivate::mouseMoveEvent(QMouseEvent *event) if (state->dragging && !state->nca) { QPoint pos = event->globalPos() - state->pressPos; - q->move(pos); + + QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow*>(parent); + if (floatingTab && !q->isFloating()) + floatingTab->move(pos); + else + q->move(pos); if (state && !state->ctrlDrag) mwlayout->hover(state->widgetItem, event->globalPos()); @@ -902,8 +956,9 @@ void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event) int fw = q->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, q); - QRect geo = q->geometry(); - QRect titleRect = q->frameGeometry(); + QWidget *tl = q->topLevelWidget(); + QRect geo = tl->geometry(); + QRect titleRect = tl->frameGeometry(); #ifdef Q_DEAD_CODE_FROM_QT4_MAC if ((features & QDockWidget::DockWidgetVerticalTitleBar)) { titleRect.setTop(geo.top()); @@ -924,7 +979,7 @@ void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event) break; if (state != 0) break; - if (qobject_cast<QMainWindow*>(parent) == 0) + if (qobject_cast<QMainWindow*>(parent) == 0 && qobject_cast<QDockWidgetGroupWindow*>(parent) == 0) break; if (isAnimating()) break; @@ -958,11 +1013,17 @@ void QDockWidgetPrivate::nonClientAreaMouseEvent(QMouseEvent *event) } } +/*! \internal + Called when the QDockWidget or the QDockWidgetGroupWindow is moved + */ void QDockWidgetPrivate::moveEvent(QMoveEvent *event) { Q_Q(QDockWidget); - if (state == 0 || !state->dragging || !state->nca || !q->isWindow()) + if (state == 0 || !state->dragging || !state->nca) + return; + + if (!q->isWindow() && qobject_cast<QDockWidgetGroupWindow*>(parent) == 0) return; // When the native window frame is being dragged, all we get is these mouse @@ -971,7 +1032,7 @@ void QDockWidgetPrivate::moveEvent(QMoveEvent *event) if (state->ctrlDrag) return; - QMainWindowLayout *layout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); + QMainWindowLayout *layout = qt_mainwindow_layout_from_dock(q); Q_ASSERT(layout != 0); QPoint globalMousePos = event->pos() + state->pressPos; @@ -999,8 +1060,9 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect Q_Q(QDockWidget); if (!floating && parent) { - QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); - if (mwlayout && mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea) + QMainWindowLayout *mwlayout = qt_mainwindow_layout_from_dock(q); + if (mwlayout && mwlayout->dockWidgetArea(q) == Qt::NoDockWidgetArea + && !qobject_cast<QDockWidgetGroupWindow *>(parent)) return; // this dockwidget can't be redocked } @@ -1031,14 +1093,8 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect q->setWindowFlags(flags); - if (!rect.isNull()) { - if (floating) { - q->resize(rect.size()); - q->move(rect.topLeft()); - } else { + if (!rect.isNull()) q->setGeometry(rect); - } - } updateButtons(); @@ -1048,7 +1104,7 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect if (floating != wasFloating) { emit q->topLevelChanged(floating); if (!floating && parent) { - QMainWindowLayout *mwlayout = qt_mainwindow_layout(qobject_cast<QMainWindow *>(q->parentWidget())); + QMainWindowLayout *mwlayout = qt_mainwindow_layout_from_dock(q); if (mwlayout) emit q->dockLocationChanged(mwlayout->dockWidgetArea(q)); } @@ -1230,8 +1286,11 @@ void QDockWidget::setFeatures(QDockWidget::DockWidgetFeatures features) emit featuresChanged(d->features); update(); if (closableChanged && layout->nativeWindowDeco()) { - //this ensures the native decoration is drawn - d->setWindowState(true /*floating*/, true /*unplug*/); + QDockWidgetGroupWindow *floatingTab = qobject_cast<QDockWidgetGroupWindow *>(parent()); + if (floatingTab && !isFloating()) + floatingTab->adjustFlags(); + else + d->setWindowState(true /*floating*/, true /*unplug*/); //this ensures the native decoration is drawn } } @@ -1323,11 +1382,12 @@ void QDockWidget::changeEvent(QEvent *event) #endif #ifndef QT_NO_TABBAR { - QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget()); - if (QMainWindowLayout *winLayout = qt_mainwindow_layout(win)) { + if (QMainWindowLayout *winLayout = qt_mainwindow_layout_from_dock(this)) { if (QDockAreaLayoutInfo *info = winLayout->layoutState.dockAreaLayout.info(this)) info->updateTabBar(); } + if (QDockWidgetGroupWindow *p = qobject_cast<QDockWidgetGroupWindow *>(parent())) + p->adjustFlags(); } #endif // QT_NO_TABBAR break; @@ -1368,7 +1428,7 @@ void QDockWidget::paintEvent(QPaintEvent *event) // Title must be painted after the frame, since the areas overlap, and // the title may wish to extend out to all sides (eg. XP style) - QStyleOptionDockWidgetV2 titleOpt; + QStyleOptionDockWidget titleOpt; initStyleOption(&titleOpt); p.drawControl(QStyle::CE_DockWidgetTitle, titleOpt); } @@ -1380,7 +1440,7 @@ bool QDockWidget::event(QEvent *event) Q_D(QDockWidget); QMainWindow *win = qobject_cast<QMainWindow*>(parentWidget()); - QMainWindowLayout *layout = qt_mainwindow_layout(win); + QMainWindowLayout *layout = qt_mainwindow_layout_from_dock(this); switch (event->type()) { #ifndef QT_NO_ACTION @@ -1417,6 +1477,9 @@ bool QDockWidget::event(QEvent *event) } if (!isFloating() && layout != 0 && onTop) layout->raise(this); + if (QDockWidgetGroupWindow *p = qobject_cast<QDockWidgetGroupWindow *>(parent())) + p->adjustFlags(); + break; } case QEvent::WindowActivate: diff --git a/src/widgets/widgets/qdockwidget.h b/src/widgets/widgets/qdockwidget.h index af4a5521bf..25e4d4d0a4 100644 --- a/src/widgets/widgets/qdockwidget.h +++ b/src/widgets/widgets/qdockwidget.h @@ -58,8 +58,9 @@ class Q_WIDGETS_EXPORT QDockWidget : public QWidget Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle DESIGNABLE true) public: - explicit QDockWidget(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0); - explicit QDockWidget(QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit QDockWidget(const QString &title, QWidget *parent = Q_NULLPTR, + Qt::WindowFlags flags = Qt::WindowFlags()); + explicit QDockWidget(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); ~QDockWidget(); QWidget *widget() const; diff --git a/src/widgets/widgets/qdockwidget_p.h b/src/widgets/widgets/qdockwidget_p.h index 752d6519e5..9c68bc5fb1 100644 --- a/src/widgets/widgets/qdockwidget_p.h +++ b/src/widgets/widgets/qdockwidget_p.h @@ -108,7 +108,7 @@ public: void setWindowState(bool floating, bool unplug = false, const QRect &rect = QRect()); void nonClientAreaMouseEvent(QMouseEvent *event); void initDrag(const QPoint &pos, bool nca); - void startDrag(); + void startDrag(bool group = true); void endDrag(bool abort = false); void moveEvent(QMoveEvent *event); @@ -151,6 +151,7 @@ public: int minimumTitleWidth() const; int titleHeight() const; void updateMaxSize(); + static bool wmSupportsNativeWindowDeco(); bool nativeWindowDeco() const; bool nativeWindowDeco(bool floating) const; diff --git a/src/widgets/widgets/qeffects.cpp b/src/widgets/widgets/qeffects.cpp index 708e90cc32..b256861d08 100644 --- a/src/widgets/widgets/qeffects.cpp +++ b/src/widgets/widgets/qeffects.cpp @@ -197,7 +197,7 @@ bool QAlphaWidget::eventFilter(QObject *o, QEvent *e) break; case QEvent::KeyPress: { QKeyEvent *ke = (QKeyEvent*)e; - if (ke->key() == Qt::Key_Escape) { + if (ke->matches(QKeySequence::Cancel)) { showWidget = false; } else { duration = 0; diff --git a/src/widgets/widgets/qfocusframe.cpp b/src/widgets/widgets/qfocusframe.cpp index 5a403fa669..bf8cb30ef7 100644 --- a/src/widgets/widgets/qfocusframe.cpp +++ b/src/widgets/widgets/qfocusframe.cpp @@ -250,6 +250,10 @@ void QFocusFrame::paintEvent(QPaintEvent *) { Q_D(QFocusFrame); + + if (!d->widget) + return; + QStylePainter p(this); QStyleOption option; initStyleOption(&option); diff --git a/src/widgets/widgets/qfocusframe.h b/src/widgets/widgets/qfocusframe.h index f976ba9827..bbd639c2f9 100644 --- a/src/widgets/widgets/qfocusframe.h +++ b/src/widgets/widgets/qfocusframe.h @@ -46,7 +46,7 @@ class Q_WIDGETS_EXPORT QFocusFrame : public QWidget { Q_OBJECT public: - QFocusFrame(QWidget *parent=0); + QFocusFrame(QWidget *parent = Q_NULLPTR); ~QFocusFrame(); void setWidget(QWidget *widget); diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp index faa2f41a51..957d148c74 100644 --- a/src/widgets/widgets/qfontcombobox.cpp +++ b/src/widgets/widgets/qfontcombobox.cpp @@ -401,14 +401,6 @@ void QFontComboBoxPrivate::_q_currentChanged(const QString &text) */ /*! - \fn void QFontComboBox::setWritingSystem(QFontDatabase::WritingSystem script) -*/ - -/*! - \fn void QFontComboBox::setCurrentFont(const QFont &font); -*/ - -/*! Constructs a font combobox with the given \a parent. */ QFontComboBox::QFontComboBox(QWidget *parent) diff --git a/src/widgets/widgets/qfontcombobox.h b/src/widgets/widgets/qfontcombobox.h index 0c8cf5d58d..412acd041e 100644 --- a/src/widgets/widgets/qfontcombobox.h +++ b/src/widgets/widgets/qfontcombobox.h @@ -53,7 +53,7 @@ class Q_WIDGETS_EXPORT QFontComboBox : public QComboBox Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChanged) public: - explicit QFontComboBox(QWidget *parent = 0); + explicit QFontComboBox(QWidget *parent = Q_NULLPTR); ~QFontComboBox(); void setWritingSystem(QFontDatabase::WritingSystem); diff --git a/src/widgets/widgets/qframe.cpp b/src/widgets/widgets/qframe.cpp index 0861ea70b5..755b03a4ca 100644 --- a/src/widgets/widgets/qframe.cpp +++ b/src/widgets/widgets/qframe.cpp @@ -45,7 +45,7 @@ QT_BEGIN_NAMESPACE QFramePrivate::QFramePrivate() - : frect(QRect(0, 0, 0, 0)), + : frect(0, 0, 0, 0), frameStyle(QFrame::NoFrame | QFrame::Plain), lineWidth(1), midLineWidth(0), @@ -55,6 +55,10 @@ QFramePrivate::QFramePrivate() { } +QFramePrivate::~QFramePrivate() +{ +} + inline void QFramePrivate::init() { setLayoutItemMargins(QStyle::SE_FrameLayoutItem); diff --git a/src/widgets/widgets/qframe.h b/src/widgets/widgets/qframe.h index c32e38f311..eb4d74c72a 100644 --- a/src/widgets/widgets/qframe.h +++ b/src/widgets/widgets/qframe.h @@ -54,7 +54,7 @@ class Q_WIDGETS_EXPORT QFrame : public QWidget Q_PROPERTY(QRect frameRect READ frameRect WRITE setFrameRect DESIGNABLE false) public: - explicit QFrame(QWidget* parent = 0, Qt::WindowFlags f = 0); + explicit QFrame(QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); ~QFrame(); int frameStyle() const; @@ -108,7 +108,7 @@ protected: protected: - QFrame(QFramePrivate &dd, QWidget* parent = 0, Qt::WindowFlags f = 0); + QFrame(QFramePrivate &dd, QWidget* parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); void initStyleOption(QStyleOptionFrame *option) const; private: diff --git a/src/widgets/widgets/qframe_p.h b/src/widgets/widgets/qframe_p.h index 2b80e9abbe..eb04bbed4a 100644 --- a/src/widgets/widgets/qframe_p.h +++ b/src/widgets/widgets/qframe_p.h @@ -50,11 +50,13 @@ QT_BEGIN_NAMESPACE -class QFramePrivate : public QWidgetPrivate +// ### unexport this class when and if QAbstractScrollAreaPrivate is unexported +class Q_WIDGETS_EXPORT QFramePrivate : public QWidgetPrivate { Q_DECLARE_PUBLIC(QFrame) public: QFramePrivate(); + ~QFramePrivate(); void updateFrameWidth(); void updateStyledFrameWidths(); diff --git a/src/widgets/widgets/qgroupbox.h b/src/widgets/widgets/qgroupbox.h index 8100fadff4..57ebdce8dd 100644 --- a/src/widgets/widgets/qgroupbox.h +++ b/src/widgets/widgets/qgroupbox.h @@ -53,8 +53,8 @@ class Q_WIDGETS_EXPORT QGroupBox : public QWidget Q_PROPERTY(bool checkable READ isCheckable WRITE setCheckable) Q_PROPERTY(bool checked READ isChecked WRITE setChecked DESIGNABLE isCheckable NOTIFY toggled USER true) public: - explicit QGroupBox(QWidget* parent=0); - explicit QGroupBox(const QString &title, QWidget* parent=0); + explicit QGroupBox(QWidget *parent = Q_NULLPTR); + explicit QGroupBox(const QString &title, QWidget *parent = Q_NULLPTR); ~QGroupBox(); QString title() const; diff --git a/src/widgets/widgets/qkeysequenceedit.h b/src/widgets/widgets/qkeysequenceedit.h index 1887a40bfc..ad60bcc513 100644 --- a/src/widgets/widgets/qkeysequenceedit.h +++ b/src/widgets/widgets/qkeysequenceedit.h @@ -48,8 +48,8 @@ class Q_WIDGETS_EXPORT QKeySequenceEdit : public QWidget Q_PROPERTY(QKeySequence keySequence READ keySequence WRITE setKeySequence NOTIFY keySequenceChanged USER true) public: - explicit QKeySequenceEdit(QWidget *parent = 0); - explicit QKeySequenceEdit(const QKeySequence &keySequence, QWidget *parent = 0); + explicit QKeySequenceEdit(QWidget *parent = Q_NULLPTR); + explicit QKeySequenceEdit(const QKeySequence &keySequence, QWidget *parent = Q_NULLPTR); ~QKeySequenceEdit(); QKeySequence keySequence() const; diff --git a/src/widgets/widgets/qlabel.cpp b/src/widgets/widgets/qlabel.cpp index 83e94c4128..55e277026c 100644 --- a/src/widgets/widgets/qlabel.cpp +++ b/src/widgets/widgets/qlabel.cpp @@ -53,6 +53,54 @@ QT_BEGIN_NAMESPACE +QLabelPrivate::QLabelPrivate() + : QFramePrivate(), + sh(), + msh(), + text(), + pixmap(Q_NULLPTR), + scaledpixmap(Q_NULLPTR), + cachedimage(Q_NULLPTR), +#ifndef QT_NO_PICTURE + picture(Q_NULLPTR), +#endif +#ifndef QT_NO_MOVIE + movie(), +#endif + control(Q_NULLPTR), + shortcutCursor(), +#ifndef QT_NO_CURSOR + cursor(), +#endif +#ifndef QT_NO_SHORTCUT + buddy(), + shortcutId(0), +#endif + textformat(Qt::AutoText), + textInteractionFlags(Qt::LinksAccessibleByMouse), + sizePolicy(), + margin(0), + align(Qt::AlignLeft | Qt::AlignVCenter | Qt::TextExpandTabs), + indent(-1), + valid_hints(false), + scaledcontents(false), + textLayoutDirty(false), + textDirty(false), + isRichText(false), + isTextLabel(false), + hasShortcut(/*???*/), +#ifndef QT_NO_CURSOR + validCursor(false), + onAnchor(false), +#endif + openExternalLinks(false) +{ +} + +QLabelPrivate::~QLabelPrivate() +{ +} + /*! \class QLabel \brief The QLabel widget provides a text or image display. @@ -202,41 +250,8 @@ void QLabelPrivate::init() { Q_Q(QLabel); - valid_hints = false; - margin = 0; -#ifndef QT_NO_MOVIE - movie = 0; -#endif -#ifndef QT_NO_SHORTCUT - shortcutId = 0; -#endif - pixmap = 0; - scaledpixmap = 0; - cachedimage = 0; -#ifndef QT_NO_PICTURE - picture = 0; -#endif - align = Qt::AlignLeft | Qt::AlignVCenter | Qt::TextExpandTabs; - indent = -1; - scaledcontents = false; - textLayoutDirty = false; - textDirty = false; - textformat = Qt::AutoText; - control = 0; - textInteractionFlags = Qt::LinksAccessibleByMouse; - isRichText = false; - isTextLabel = false; - q->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred, QSizePolicy::Label)); - -#ifndef QT_NO_CURSOR - validCursor = false; - onAnchor = false; -#endif - - openExternalLinks = false; - setLayoutItemMargins(QStyle::SE_LabelLayoutItem); } @@ -1081,7 +1096,7 @@ void QLabel::paintEvent(QPaintEvent *) d->cachedimage = new QImage(d->pixmap->toImage()); delete d->scaledpixmap; QImage scaledImage = - d->cachedimage->scaled(cr.size() * devicePixelRatio(), + d->cachedimage->scaled(cr.size() * devicePixelRatioF(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation); d->scaledpixmap = new QPixmap(QPixmap::fromImage(scaledImage)); } diff --git a/src/widgets/widgets/qlabel.h b/src/widgets/widgets/qlabel.h index 330626a9c5..1a3a68db60 100644 --- a/src/widgets/widgets/qlabel.h +++ b/src/widgets/widgets/qlabel.h @@ -58,8 +58,8 @@ class Q_WIDGETS_EXPORT QLabel : public QFrame Q_PROPERTY(QString selectedText READ selectedText) public: - explicit QLabel(QWidget *parent=0, Qt::WindowFlags f=0); - explicit QLabel(const QString &text, QWidget *parent=0, Qt::WindowFlags f=0); + explicit QLabel(QWidget *parent=Q_NULLPTR, Qt::WindowFlags f=Qt::WindowFlags()); + explicit QLabel(const QString &text, QWidget *parent=Q_NULLPTR, Qt::WindowFlags f=Qt::WindowFlags()); ~QLabel(); QString text() const; diff --git a/src/widgets/widgets/qlabel_p.h b/src/widgets/widgets/qlabel_p.h index 3778cb9d47..b4da56c290 100644 --- a/src/widgets/widgets/qlabel_p.h +++ b/src/widgets/widgets/qlabel_p.h @@ -60,54 +60,25 @@ QT_BEGIN_NAMESPACE -class QLabelPrivate : public QFramePrivate +class Q_AUTOTEST_EXPORT QLabelPrivate : public QFramePrivate { Q_DECLARE_PUBLIC(QLabel) public: - QLabelPrivate() {} + QLabelPrivate(); + ~QLabelPrivate(); void init(); void clearContents(); void updateLabel(); QSize sizeForWidth(int w) const; - mutable QSize sh; - mutable QSize msh; - mutable bool valid_hints; - mutable QSizePolicy sizePolicy; - int margin; - QString text; - QPixmap *pixmap; - QPixmap *scaledpixmap; - QImage *cachedimage; -#ifndef QT_NO_PICTURE - QPicture *picture; -#endif #ifndef QT_NO_MOVIE - QPointer<QMovie> movie; void _q_movieUpdated(const QRect&); void _q_movieResized(const QSize&); #endif #ifndef QT_NO_SHORTCUT void updateShortcut(); #endif -#ifndef QT_NO_SHORTCUT - QPointer<QWidget> buddy; - int shortcutId; -#endif - ushort align; - short indent; - uint scaledcontents :1; - mutable uint textLayoutDirty : 1; - mutable uint textDirty : 1; - mutable uint isRichText : 1; - mutable uint isTextLabel : 1; - mutable uint hasShortcut : 1; - Qt::TextFormat textformat; - mutable QWidgetTextControl *control; - mutable QTextCursor shortcutCursor; - Qt::TextInteractionFlags textInteractionFlags; - inline bool needTextControl() const { return isTextLabel && (isRichText @@ -129,13 +100,46 @@ public: QMenu *createStandardContextMenu(const QPoint &pos); #endif - bool openExternalLinks; - + mutable QSize sh; + mutable QSize msh; + QString text; + QPixmap *pixmap; + QPixmap *scaledpixmap; + QImage *cachedimage; +#ifndef QT_NO_PICTURE + QPicture *picture; +#endif +#ifndef QT_NO_MOVIE + QPointer<QMovie> movie; +#endif + mutable QWidgetTextControl *control; + mutable QTextCursor shortcutCursor; +#ifndef QT_NO_CURSOR + QCursor cursor; +#endif +#ifndef QT_NO_SHORTCUT + QPointer<QWidget> buddy; + int shortcutId; +#endif + Qt::TextFormat textformat; + Qt::TextInteractionFlags textInteractionFlags; + mutable QSizePolicy sizePolicy; + int margin; + ushort align; + short indent; + mutable uint valid_hints : 1; + uint scaledcontents : 1; + mutable uint textLayoutDirty : 1; + mutable uint textDirty : 1; + mutable uint isRichText : 1; + mutable uint isTextLabel : 1; + mutable uint hasShortcut : 1; #ifndef QT_NO_CURSOR uint validCursor : 1; uint onAnchor : 1; - QCursor cursor; #endif + uint openExternalLinks : 1; + // <-- space for more bit field values here friend class QMessageBoxPrivate; }; diff --git a/src/widgets/widgets/qlcdnumber.h b/src/widgets/widgets/qlcdnumber.h index d93edc75ca..9a7904a8bb 100644 --- a/src/widgets/widgets/qlcdnumber.h +++ b/src/widgets/widgets/qlcdnumber.h @@ -53,8 +53,8 @@ class Q_WIDGETS_EXPORT QLCDNumber : public QFrame // LCD number widget Q_PROPERTY(int intValue READ intValue WRITE display) public: - explicit QLCDNumber(QWidget* parent = 0); - explicit QLCDNumber(uint numDigits, QWidget* parent = 0); + explicit QLCDNumber(QWidget* parent = Q_NULLPTR); + explicit QLCDNumber(uint numDigits, QWidget* parent = Q_NULLPTR); ~QLCDNumber(); enum Mode { diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp index 0500907b3d..6b32665065 100644 --- a/src/widgets/widgets/qlineedit.cpp +++ b/src/widgets/widgets/qlineedit.cpp @@ -1488,7 +1488,7 @@ void QLineEdit::mousePressEvent(QMouseEvent* e) int cursor = d->xToPos(e->pos().x()); #ifndef QT_NO_DRAGANDDROP if (!mark && d->dragEnabled && d->control->echoMode() == Normal && - e->button() == Qt::LeftButton && d->control->inSelection(e->pos().x())) { + e->button() == Qt::LeftButton && d->inSelection(e->pos().x())) { if (!d->dndTimer.isActive()) d->dndTimer.start(QApplication::startDragTime(), this); } else @@ -1897,18 +1897,14 @@ void QLineEdit::paintEvent(QPaintEvent *) } QRect lineRect(r.x() + d->horizontalMargin, d->vscroll, r.width() - 2*d->horizontalMargin, fm.height()); - int minLB = qMax(0, -fm.minLeftBearing()); - int minRB = qMax(0, -fm.minRightBearing()); - if (d->shouldShowPlaceholderText()) { if (!d->placeholderText.isEmpty()) { QColor col = pal.text().color(); col.setAlpha(128); QPen oldpen = p.pen(); p.setPen(col); - QRect ph = lineRect.adjusted(minLB, 0, 0, 0); - QString elidedText = fm.elidedText(d->placeholderText, Qt::ElideRight, ph.width()); - p.drawText(ph, va, elidedText); + QString elidedText = fm.elidedText(d->placeholderText, Qt::ElideRight, lineRect.width()); + p.drawText(lineRect, va, elidedText); p.setPen(oldpen); } } @@ -1918,11 +1914,10 @@ void QLineEdit::paintEvent(QPaintEvent *) // horizontal scrolling. d->hscroll is the left indent from the beginning // of the text line to the left edge of lineRect. we update this value // depending on the delta from the last paint event; in effect this means - // the below code handles all scrolling based on the textline (widthUsed, - // minLB, minRB), the line edit rect (lineRect) and the cursor position - // (cix). - int widthUsed = qRound(d->control->naturalTextWidth()) + 1 + minRB; - if ((minLB + widthUsed) <= lineRect.width()) { + // the below code handles all scrolling based on the textline (widthUsed), + // the line edit rect (lineRect) and the cursor position (cix). + int widthUsed = qRound(d->control->naturalTextWidth()) + 1; + if (widthUsed <= lineRect.width()) { // text fits in lineRect; use hscroll for alignment switch (va & ~(Qt::AlignAbsolute|Qt::AlignVertical_Mask)) { case Qt::AlignRight: @@ -1936,7 +1931,6 @@ void QLineEdit::paintEvent(QPaintEvent *) d->hscroll = 0; break; } - d->hscroll -= minLB; } else if (cix - d->hscroll >= lineRect.width()) { // text doesn't fit, cursor is to the right of lineRect (scroll right) d->hscroll = cix - lineRect.width() + 1; diff --git a/src/widgets/widgets/qlineedit.h b/src/widgets/widgets/qlineedit.h index e006f1c0d8..ac192f0da8 100644 --- a/src/widgets/widgets/qlineedit.h +++ b/src/widgets/widgets/qlineedit.h @@ -84,8 +84,8 @@ public: }; Q_ENUM(ActionPosition) - explicit QLineEdit(QWidget* parent=0); - explicit QLineEdit(const QString &, QWidget* parent=0); + explicit QLineEdit(QWidget *parent = Q_NULLPTR); + explicit QLineEdit(const QString &, QWidget *parent = Q_NULLPTR); ~QLineEdit(); QString text() const; diff --git a/src/widgets/widgets/qlineedit_p.cpp b/src/widgets/widgets/qlineedit_p.cpp index e24cc8a03a..599ebce0ab 100644 --- a/src/widgets/widgets/qlineedit_p.cpp +++ b/src/widgets/widgets/qlineedit_p.cpp @@ -70,6 +70,12 @@ int QLineEditPrivate::xToPos(int x, QTextLine::CursorPosition betweenOrOn) const return control->xToPos(x, betweenOrOn); } +bool QLineEditPrivate::inSelection(int x) const +{ + x -= adjustedContentsRect().x() - hscroll + horizontalMargin; + return control->inSelection(x); +} + QRect QLineEditPrivate::cursorRect() const { return adjustedControlRect(control->cursorRect()); @@ -364,7 +370,7 @@ void QLineEditIconButton::startOpacityAnimation(qreal endValue) void QLineEditIconButton::updateCursor() { #ifndef QT_NO_CURSOR - setCursor(qFuzzyCompare(m_opacity, 1.0) || !parentWidget() ? QCursor(Qt::ArrowCursor) : parentWidget()->cursor()); + setCursor(qFuzzyCompare(m_opacity, qreal(1.0)) || !parentWidget() ? QCursor(Qt::ArrowCursor) : parentWidget()->cursor()); #endif } diff --git a/src/widgets/widgets/qlineedit_p.h b/src/widgets/widgets/qlineedit_p.h index 5a22285149..60372ab393 100644 --- a/src/widgets/widgets/qlineedit_p.h +++ b/src/widgets/widgets/qlineedit_p.h @@ -114,7 +114,7 @@ public: QAction *action; int flags; }; - typedef QList<SideWidgetEntry> SideWidgetEntryList; + typedef QVector<SideWidgetEntry> SideWidgetEntryList; QLineEditPrivate() : control(0), frame(1), contextMenuEnabled(1), cursorVisible(0), @@ -139,6 +139,7 @@ public: QRect adjustedControlRect(const QRect &) const; int xToPos(int x, QTextLine::CursorPosition = QTextLine::CursorBetweenCharacters) const; + bool inSelection(int x) const; QRect cursorRect() const; void setCursorVisible(bool visible); @@ -228,6 +229,7 @@ private: int lastTextSize; mutable QSize m_iconSize; }; +Q_DECLARE_TYPEINFO(QLineEditPrivate::SideWidgetEntry, Q_PRIMITIVE_TYPE); static bool isSideWidgetVisible(const QLineEditPrivate::SideWidgetEntry &e) { diff --git a/src/widgets/widgets/qmaccocoaviewcontainer_mac.h b/src/widgets/widgets/qmaccocoaviewcontainer_mac.h index 5920c1f8bf..a27d8f8690 100644 --- a/src/widgets/widgets/qmaccocoaviewcontainer_mac.h +++ b/src/widgets/widgets/qmaccocoaviewcontainer_mac.h @@ -45,7 +45,7 @@ class Q_WIDGETS_EXPORT QMacCocoaViewContainer : public QWidget { Q_OBJECT public: - QMacCocoaViewContainer(NSView *cocoaViewToWrap, QWidget *parent = 0); + QMacCocoaViewContainer(NSView *cocoaViewToWrap, QWidget *parent = Q_NULLPTR); virtual ~QMacCocoaViewContainer(); void setCocoaView(NSView *view); diff --git a/src/widgets/widgets/qmacnativewidget_mac.h b/src/widgets/widgets/qmacnativewidget_mac.h index 761e55656b..5e82872faa 100644 --- a/src/widgets/widgets/qmacnativewidget_mac.h +++ b/src/widgets/widgets/qmacnativewidget_mac.h @@ -45,7 +45,7 @@ class Q_WIDGETS_EXPORT QMacNativeWidget : public QWidget { Q_OBJECT public: - QMacNativeWidget(NSView *parentView = 0); + QMacNativeWidget(NSView *parentView = Q_NULLPTR); ~QMacNativeWidget(); QSize sizeHint() const; diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp index 4d5d3e5ec1..ff4bb3cc98 100644 --- a/src/widgets/widgets/qmainwindow.cpp +++ b/src/widgets/widgets/qmainwindow.cpp @@ -263,7 +263,14 @@ void QMainWindowPrivate::init() An example of how to create menus follows: - \snippet mainwindows/application/mainwindow.cpp 26 + \code + void MainWindow::createMenus() + { + fileMenu = menuBar()->addMenu(tr("&File")); + fileMenu->addAction(newAct); + fileMenu->addAction(openAct); + fileMenu->addAction(saveAct); + \endcode The \c createPopupMenu() function creates popup menus when the main window receives context menu events. The default @@ -290,7 +297,12 @@ void QMainWindowPrivate::init() An example of toolbar creation follows: - \snippet mainwindows/application/mainwindow.cpp 29 + \code + void MainWindow::createToolBars() + { + fileToolBar = addToolBar(tr("File")); + fileToolBar->addAction(newAct); + \endcode \section2 Creating Dock Widgets @@ -420,6 +432,13 @@ QMainWindow::~QMainWindow() at the bottom. Implies AllowTabbedDocks. See also \l setTabPosition(). + \value GroupedDragging When dragging the titlebar of a dock, all the tabs + that are tabbed with it are going to be dragged. + Implies AllowTabbedDocks. Does not work well if + some QDockWidgets have restrictions in which area + they are allowed. (This enum value was added in Qt + 5.6.) + These options only control how dock widgets may be dropped in a QMainWindow. They do not re-arrange the dock widgets to conform with the specified options. For this reason they should be set before any dock widgets @@ -1080,7 +1099,7 @@ void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget addDockWidget(area, dockwidget, orientation); #ifdef Q_DEAD_CODE_FROM_QT4_MAC //drawer support - QMacCocoaAutoReleasePool pool; + QMacAutoReleasePool pool; extern bool qt_mac_is_macdrawer(const QWidget *); //qwidget_mac.cpp if (qt_mac_is_macdrawer(dockwidget)) { extern bool qt_mac_set_drawer_preferred_edge(QWidget *, Qt::DockWidgetArea); //qwidget_mac.cpp @@ -1218,6 +1237,35 @@ void QMainWindow::removeDockWidget(QDockWidget *dockwidget) Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const { return d_func()->layout->dockWidgetArea(dockwidget); } + +/*! + \since 5.6 + Resizes the dock widgets in the list \a docks to the corresponding size in + pixels from the list \a sizes. If \a orientation is Qt::Horizontal, adjusts + the width, otherwise adjusts the height of the dock widgets. + The sizes will be adjusted such that the maximum and the minimum sizes are + respected and the QMainWindow itself will not be resized. + Any additional/missing space is distributed amongst the widgets according + to the relative weight of the sizes. + + Example: + \code + resizeDocks({blueWidget, yellowWidget}, {20 , 40}, Qt::Horizontal); + \endcode + If the blue and the yellow widget are nested on the same level they will be + resized such that the yellowWidget is twice as big as the blueWidget + + If some widgets are grouped in tabs, only one widget per group should be + specified. Widgets not in the list might be changed to repect the constraints. +*/ +void QMainWindow::resizeDocks(const QList<QDockWidget *> &docks, + const QList<int> &sizes, Qt::Orientation orientation) +{ + d_func()->layout->layoutState.dockAreaLayout.resizeDocks(docks, sizes, orientation); + d_func()->layout->invalidate(); +} + + #endif // QT_NO_DOCKWIDGET /*! diff --git a/src/widgets/widgets/qmainwindow.h b/src/widgets/widgets/qmainwindow.h index cbbea74b9b..70d78a7904 100644 --- a/src/widgets/widgets/qmainwindow.h +++ b/src/widgets/widgets/qmainwindow.h @@ -77,12 +77,13 @@ public: AllowNestedDocks = 0x02, AllowTabbedDocks = 0x04, ForceTabbedDocks = 0x08, // implies AllowTabbedDocks, !AllowNestedDocks - VerticalTabs = 0x10 // implies AllowTabbedDocks + VerticalTabs = 0x10, // implies AllowTabbedDocks + GroupedDragging = 0x20 // implies AllowTabbedDocks }; Q_ENUM(DockOption) Q_DECLARE_FLAGS(DockOptions, DockOption) - explicit QMainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); + explicit QMainWindow(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); ~QMainWindow(); QSize iconSize() const; @@ -164,6 +165,9 @@ public: bool restoreDockWidget(QDockWidget *dockwidget); Qt::DockWidgetArea dockWidgetArea(QDockWidget *dockwidget) const; + + void resizeDocks(const QList<QDockWidget *> &docks, + const QList<int> &sizes, Qt::Orientation orientation); #endif // QT_NO_DOCKWIDGET QByteArray saveState(int version = 0) const; diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp index 046666f571..1bb8496505 100644 --- a/src/widgets/widgets/qmainwindowlayout.cpp +++ b/src/widgets/widgets/qmainwindowlayout.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2015 The Qt Company Ltd. +** Copyright (C) 2015 Olivier Goffart <ogoffart@woboq.com> ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the QtWidgets module of the Qt Toolkit. @@ -49,6 +50,7 @@ #include <qstatusbar.h> #include <qstring.h> #include <qstyle.h> +#include <qstylepainter.h> #include <qvarlengtharray.h> #include <qstack.h> #include <qmap.h> @@ -61,6 +63,7 @@ #include <private/qapplication_p.h> #include <private/qlayoutengine_p.h> +#include <private/qwidgetresizehandler_p.h> #ifdef Q_DEAD_CODE_FROM_QT4_MAC # include <private/qcore_mac_p.h> # include <private/qt_cocoa_helpers_mac_p.h> @@ -68,9 +71,7 @@ QT_BEGIN_NAMESPACE -#ifdef QT_NO_DOCKWIDGET extern QMainWindowLayout *qt_mainwindow_layout(const QMainWindow *window); -#endif /****************************************************************************** ** debug @@ -165,6 +166,228 @@ QDebug operator<<(QDebug debug, const QMainWindowLayout *layout) #endif // !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_DEBUG) /****************************************************************************** + ** QDockWidgetGroupWindow + */ +// QDockWidgetGroupWindow is the floating window containing the tabbed dockwidgets in case several +// dockwidgets are dragged together (QMainWindow::GroupedDragging feature). +// QDockWidgetGroupLayout is the layout of that window and use a QDockAreaLayoutInfo to layout +// the tabs inside it. +#ifndef QT_NO_DOCKWIDGET +class QDockWidgetGroupLayout : public QLayout { + QDockAreaLayoutInfo info; + QWidgetResizeHandler *resizer; +public: + QDockWidgetGroupLayout(QWidget* parent) : QLayout(parent) { + setSizeConstraint(QLayout::SetMinAndMaxSize); + resizer = new QWidgetResizeHandler(parent); + resizer->setMovingEnabled(false); + } + ~QDockWidgetGroupLayout() { + info.deleteAllLayoutItems(); + } + + void addItem(QLayoutItem*) Q_DECL_OVERRIDE { Q_UNREACHABLE(); } + int count() const Q_DECL_OVERRIDE { return 0; } + QLayoutItem* itemAt(int index) const Q_DECL_OVERRIDE + { + int x = 0; + return info.itemAt(&x, index); + } + QLayoutItem* takeAt(int index) Q_DECL_OVERRIDE + { + int x = 0; + return info.takeAt(&x, index); + } + QSize sizeHint() const Q_DECL_OVERRIDE + { + int fw = frameWidth(); + return info.sizeHint() + QSize(fw, fw); + } + QSize minimumSize() const Q_DECL_OVERRIDE + { + int fw = frameWidth(); + return info.minimumSize() + QSize(fw, fw); + } + QSize maximumSize() const Q_DECL_OVERRIDE + { + int fw = frameWidth(); + return info.maximumSize() + QSize(fw, fw); + } + void setGeometry(const QRect&r) Q_DECL_OVERRIDE + { + QDockAreaLayoutInfo *li = layoutInfo(); + if (li->isEmpty()) { + static_cast<QDockWidgetGroupWindow *>(parent())->destroyIfEmpty(); + return; + } + int fw = frameWidth(); + li->reparentWidgets(parentWidget()); + li->rect = r.adjusted(fw, fw, -fw, -fw); + li->fitItems(); + li->apply(false); + resizer->setActive(QWidgetResizeHandler::Resize, !nativeWindowDeco()); + } + + QDockAreaLayoutInfo *layoutInfo() { + return &info; + } + + bool nativeWindowDeco() const + { + return QDockWidgetLayout::wmSupportsNativeWindowDeco(); + } + + int frameWidth() const + { + return nativeWindowDeco() ? 0 : + parentWidget()->style()->pixelMetric(QStyle::PM_DockWidgetFrameWidth, 0, parentWidget()); + } +}; + +bool QDockWidgetGroupWindow::event(QEvent *e) +{ + switch (e->type()) { + case QEvent::Close: + // Forward the close to the QDockWidget just as if its close button was pressed + if (QDockWidget *dw = topDockWidget()) { + e->ignore(); + dw->close(); + adjustFlags(); + } + return true; + case QEvent::Move: + // Let QDockWidgetPrivate::moseEvent handle the dragging + if (QDockWidget *dw = topDockWidget()) + static_cast<QDockWidgetPrivate *>(QObjectPrivate::get(dw))->moveEvent(static_cast<QMoveEvent*>(e)); + return true; + case QEvent::NonClientAreaMouseMove: + case QEvent::NonClientAreaMouseButtonPress: + case QEvent::NonClientAreaMouseButtonRelease: + case QEvent::NonClientAreaMouseButtonDblClick: + // Let the QDockWidgetPrivate of the currently visible dock widget handle the drag and drop + if (QDockWidget *dw = topDockWidget()) + static_cast<QDockWidgetPrivate *>(QObjectPrivate::get(dw))->nonClientAreaMouseEvent(static_cast<QMouseEvent*>(e)); + return true; + case QEvent::ChildAdded: + if (qobject_cast<QDockWidget *>(static_cast<QChildEvent*>(e)->child())) + adjustFlags(); + break; + default: + break; + } + return QWidget::event(e); +} + +void QDockWidgetGroupWindow::paintEvent(QPaintEvent *) +{ + QDockWidgetGroupLayout *lay = static_cast<QDockWidgetGroupLayout *>(layout()); + bool nativeDeco = lay->nativeWindowDeco(); + + if (!nativeDeco) { + QStyleOptionFrame framOpt; + framOpt.init(this); + QStylePainter p(this); + p.drawPrimitive(QStyle::PE_FrameDockWidget, framOpt); + } +} + +QDockAreaLayoutInfo *QDockWidgetGroupWindow::layoutInfo() const +{ + return static_cast<QDockWidgetGroupLayout*>(layout())->layoutInfo(); +} + +/*! \internal + Returns the currently active QDockWidget. + */ +QDockWidget *QDockWidgetGroupWindow::topDockWidget() const +{ + QDockAreaLayoutInfo *info = layoutInfo(); + QDockWidget *dw = 0; + if (info->tabBar && info->tabBar->currentIndex() >= 0) { + int i = info->tabIndexToListIndex(info->tabBar->currentIndex()); + if (i >= 0) { + const QDockAreaLayoutItem &item = info->item_list.at(i); + if (item.widgetItem) + dw = qobject_cast<QDockWidget *>(item.widgetItem->widget()); + } + } + if (!dw) { + for (int i = 0; !dw && i < info->item_list.count(); ++i) { + const QDockAreaLayoutItem &item = info->item_list.at(i); + if (item.skip()) + continue; + if (!item.widgetItem) + continue; + dw = qobject_cast<QDockWidget *>(item.widgetItem->widget()); + } + } + return dw; +} + +/*! \internal + Destroy this window if there is no more QDockWidget in it. + */ +void QDockWidgetGroupWindow::destroyIfEmpty() +{ + if (layoutInfo()->isEmpty()) { + // Make sure to reparent the possibly floating or hidden QDockWidgets to the parent + foreach (QDockWidget *dw, + findChildren<QDockWidget *>(QString(), Qt::FindDirectChildrenOnly)) { + bool wasFloating = dw->isFloating(); + bool wasHidden = dw->isHidden(); + dw->setParent(parentWidget()); + if (wasFloating) { + dw->setFloating(true); + } else { + // maybe it was hidden, we still have to put it back in the main layout. + QMainWindowLayout *ml = qt_mainwindow_layout(static_cast<QMainWindow*>(parentWidget())); + Qt::DockWidgetArea area = ml->dockWidgetArea(this); + if (area == Qt::NoDockWidgetArea) + area = Qt::LeftDockWidgetArea; + static_cast<QMainWindow*>(parentWidget())->addDockWidget(area, dw); + } + if (!wasHidden) + dw->show(); + } + foreach (QTabBar *tb, findChildren<QTabBar *>(QString(), Qt::FindDirectChildrenOnly)) + tb->setParent(parentWidget()); + deleteLater(); + } +} + +/*! \internal + Sets the flags of this window in accordence to the capabilities of the dock widgets + */ +void QDockWidgetGroupWindow::adjustFlags() +{ + QDockWidget *top = topDockWidget(); + if (!top) + return; + const bool nativeDeco = static_cast<QDockWidgetGroupLayout *>(layout())->nativeWindowDeco(); + + Qt::WindowFlags oldFlags = windowFlags(); + Qt::WindowFlags flags = oldFlags; + if (nativeDeco) { + flags |= Qt::CustomizeWindowHint | Qt::WindowTitleHint; + if (top->features() & QDockWidget::DockWidgetClosable) + flags |= Qt::WindowCloseButtonHint; + else + flags &= ~Qt::WindowCloseButtonHint; + flags &= ~Qt::FramelessWindowHint; + } else { + flags |= Qt::FramelessWindowHint; + } + if (oldFlags != flags) { + setWindowFlags(flags); + show(); // setWindowFlags hides the window + } + + setWindowTitle(top->windowTitle()); + setWindowIcon(top->windowIcon()); +} +#endif + +/****************************************************************************** ** QMainWindowLayoutState */ @@ -335,8 +558,8 @@ QList<int> QMainWindowLayoutState::indexOf(QWidget *widget) const #ifndef QT_NO_DOCKWIDGET // is it a dock widget? - if (QDockWidget *dockWidget = qobject_cast<QDockWidget *>(widget)) { - result = dockAreaLayout.indexOf(dockWidget); + if (qobject_cast<QDockWidget *>(widget) || qobject_cast<QDockWidgetGroupWindow *>(widget)) { + result = dockAreaLayout.indexOf(widget); if (!result.isEmpty()) result.prepend(1); return result; @@ -413,7 +636,8 @@ QList<int> QMainWindowLayoutState::gapIndex(QWidget *widget, #ifndef QT_NO_DOCKWIDGET // is it a dock widget? - if (qobject_cast<QDockWidget *>(widget) != 0) { + if (qobject_cast<QDockWidget *>(widget) != 0 + || qobject_cast<QDockWidgetGroupWindow *>(widget)) { result = dockAreaLayout.gapIndex(pos); if (!result.isEmpty()) result.prepend(1); @@ -440,7 +664,7 @@ bool QMainWindowLayoutState::insertGap(const QList<int> &path, QLayoutItem *item #ifndef QT_NO_DOCKWIDGET if (i == 1) { - Q_ASSERT(qobject_cast<QDockWidget*>(item->widget()) != 0); + Q_ASSERT(qobject_cast<QDockWidget*>(item->widget()) || qobject_cast<QDockWidgetGroupWindow*>(item->widget())); return dockAreaLayout.insertGap(path.mid(1), item); } #endif //QT_NO_DOCKWIDGET @@ -593,6 +817,17 @@ void QMainWindowLayoutState::saveState(QDataStream &stream) const { #ifndef QT_NO_DOCKWIDGET dockAreaLayout.saveState(stream); +#ifndef QT_NO_TABBAR + QList<QDockWidgetGroupWindow *> floatingTabs = + mainWindow->findChildren<QDockWidgetGroupWindow *>(QString(), Qt::FindDirectChildrenOnly); + + foreach (QDockWidgetGroupWindow *floating, floatingTabs) { + if (floating->layoutInfo()->isEmpty()) + continue; + stream << uchar(QDockAreaLayout::FloatingDockWidgetTabMarker) << floating->geometry(); + floating->layoutInfo()->saveState(stream); + } +#endif #endif #ifndef QT_NO_TOOLBAR toolBarAreaLayout.saveState(stream); @@ -638,12 +873,28 @@ bool QMainWindowLayoutState::checkFormat(QDataStream &stream) case QDockAreaLayout::DockWidgetStateMarker: { QList<QDockWidget *> dockWidgets = findChildrenHelper<QDockWidget*>(mainWindow); + foreach (QDockWidgetGroupWindow *floating, findChildrenHelper<QDockWidgetGroupWindow*>(mainWindow)) + dockWidgets += findChildrenHelper<QDockWidget*>(floating); if (!dockAreaLayout.restoreState(stream, dockWidgets, true /*testing*/)) { return false; } } break; -#endif +#ifndef QT_NO_TABBAR + case QDockAreaLayout::FloatingDockWidgetTabMarker: + { + QRect geom; + stream >> geom; + QDockAreaLayoutInfo info; + QList<QDockWidget *> dockWidgets = findChildrenHelper<QDockWidget*>(mainWindow); + foreach (QDockWidgetGroupWindow *floating, findChildrenHelper<QDockWidgetGroupWindow*>(mainWindow)) + dockWidgets += findChildrenHelper<QDockWidget*>(floating); + if (!info.restoreState(stream, dockWidgets, true /* testing*/)) + return false; + } + break; +#endif // QT_NO_TABBAR +#endif // QT_NO_DOCKWIDGET default: //there was an error during the parsing return false; @@ -682,6 +933,8 @@ bool QMainWindowLayoutState::restoreState(QDataStream &_stream, case QDockAreaLayout::DockWidgetStateMarker: { QList<QDockWidget *> dockWidgets = findChildrenHelper<QDockWidget*>(mainWindow); + foreach (QDockWidgetGroupWindow *floating, findChildrenHelper<QDockWidgetGroupWindow*>(mainWindow)) + dockWidgets += findChildrenHelper<QDockWidget*>(floating); if (!dockAreaLayout.restoreState(stream, dockWidgets)) return false; @@ -702,6 +955,26 @@ bool QMainWindowLayoutState::restoreState(QDataStream &_stream, } } break; +#ifndef QT_NO_TABBAR + case QDockAreaLayout::FloatingDockWidgetTabMarker: + { + QList<QDockWidget *> dockWidgets = findChildrenHelper<QDockWidget*>(mainWindow); + foreach (QDockWidgetGroupWindow *floating, findChildrenHelper<QDockWidgetGroupWindow*>(mainWindow)) + dockWidgets += findChildrenHelper<QDockWidget*>(floating); + QDockWidgetGroupWindow* floatingTab = qt_mainwindow_layout(mainWindow)->createTabbedDockWindow(); + *floatingTab->layoutInfo() = QDockAreaLayoutInfo(&dockAreaLayout.sep, QInternal::LeftDock, + Qt::Horizontal, QTabBar::RoundedSouth, mainWindow); + QRect geometry; + stream >> geometry; + if (!floatingTab->layoutInfo()->restoreState(stream, dockWidgets, false)) + return false; + geometry = QDockAreaLayout::constrainedRect(geometry, floatingTab); + floatingTab->move(geometry.topLeft()); + floatingTab->resize(geometry.size()); + floatingTab->show(); + } + break; +#endif // QT_NO_TABBAR #endif // QT_NO_DOCKWIDGET #ifndef QT_NO_TOOLBAR @@ -1223,7 +1496,7 @@ void QMainWindowLayout::splitDockWidget(QDockWidget *after, invalidate(); } -Qt::DockWidgetArea QMainWindowLayout::dockWidgetArea(QDockWidget *widget) const +Qt::DockWidgetArea QMainWindowLayout::dockWidgetArea(QWidget *widget) const { QList<int> pathToWidget = layoutState.dockAreaLayout.indexOf(widget); if (pathToWidget.isEmpty()) @@ -1238,20 +1511,88 @@ void QMainWindowLayout::keepSize(QDockWidget *w) #ifndef QT_NO_TABBAR +// Handle custom tooltip, and allow to drag tabs away. class QMainWindowTabBar : public QTabBar { + QMainWindow *mainWindow; + QDockWidget *draggingDock; // Currently dragging (detached) dock widget public: - QMainWindowTabBar(QWidget *parent); + QMainWindowTabBar(QMainWindow *parent); protected: bool event(QEvent *e) Q_DECL_OVERRIDE; + void mouseReleaseEvent(QMouseEvent*) Q_DECL_OVERRIDE; + void mouseMoveEvent(QMouseEvent*) Q_DECL_OVERRIDE; + }; -QMainWindowTabBar::QMainWindowTabBar(QWidget *parent) - : QTabBar(parent) +QMainWindowTabBar::QMainWindowTabBar(QMainWindow *parent) + : QTabBar(parent), mainWindow(parent), draggingDock(0) { setExpanding(false); } +void QMainWindowTabBar::mouseMoveEvent(QMouseEvent *e) +{ + // The QTabBar handles the moving (reordering) of tabs. + // When QTabBarPrivate::dragInProgress is true, and that the mouse is outside of a region + // around the QTabBar, we will consider the user wants to drag that QDockWidget away from this + // tab area. + + QTabBarPrivate *d = static_cast<QTabBarPrivate*>(d_ptr.data()); + if (!draggingDock && (mainWindow->dockOptions() & QMainWindow::GroupedDragging)) { + int offset = QApplication::startDragDistance() + 1; + offset *= 3; + QRect r = rect().adjusted(-offset, -offset, offset, offset); + if (d->dragInProgress && !r.contains(e->pos()) && d->validIndex(d->pressedIndex)) { + QMainWindowLayout* mlayout = qt_mainwindow_layout(mainWindow); + QDockAreaLayoutInfo *info = mlayout->dockInfo(this); + Q_ASSERT(info); + int idx = info->tabIndexToListIndex(d->pressedIndex); + const QDockAreaLayoutItem &item = info->item_list.at(idx); + if (item.widgetItem + && (draggingDock = qobject_cast<QDockWidget *>(item.widgetItem->widget()))) { + // We should drag this QDockWidget away by unpluging it. + // First cancel the QTabBar's internal move + d->moveTabFinished(d->pressedIndex); + d->pressedIndex = -1; + if (d->movingTab) + d->movingTab->setVisible(false); + d->dragStartPosition = QPoint(); + + // Then starts the drag using QDockWidgetPrivate's API + QDockWidgetPrivate *dockPriv = static_cast<QDockWidgetPrivate *>(QObjectPrivate::get(draggingDock)); + QDockWidgetLayout *dwlayout = static_cast<QDockWidgetLayout *>(draggingDock->layout()); + dockPriv->initDrag(dwlayout->titleArea().center(), true); + dockPriv->startDrag(false); + if (dockPriv->state) + dockPriv->state->ctrlDrag = e->modifiers() & Qt::ControlModifier; + } + } + } + + if (draggingDock) { + QDockWidgetPrivate *dockPriv = static_cast<QDockWidgetPrivate *>(QObjectPrivate::get(draggingDock)); + if (dockPriv->state && dockPriv->state->dragging) { + QPoint pos = e->globalPos() - dockPriv->state->pressPos; + draggingDock->move(pos); + // move will call QMainWindowLayout::hover + } + } + QTabBar::mouseMoveEvent(e); +} + +void QMainWindowTabBar::mouseReleaseEvent(QMouseEvent *e) +{ + if (draggingDock && e->button() == Qt::LeftButton) { + QDockWidgetPrivate *dockPriv = static_cast<QDockWidgetPrivate *>(QObjectPrivate::get(draggingDock)); + if (dockPriv->state && dockPriv->state->dragging) { + dockPriv->endDrag(); + } + draggingDock = 0; + } + QTabBar::mouseReleaseEvent(e); +} + bool QMainWindowTabBar::event(QEvent *e) { // show the tooltip if tab is too small to fit label @@ -1276,11 +1617,13 @@ QTabBar *QMainWindowLayout::getTabBar() if (!unusedTabBars.isEmpty()) { result = unusedTabBars.takeLast(); } else { - result = new QMainWindowTabBar(parentWidget()); + result = new QMainWindowTabBar(static_cast<QMainWindow *>(parentWidget())); result->setDrawBase(true); result->setElideMode(Qt::ElideRight); result->setDocumentMode(_documentMode); + result->setMovable(true); connect(result, SIGNAL(currentChanged(int)), this, SLOT(tabChanged())); + connect(result, &QTabBar::tabMoved, this, &QMainWindowLayout::tabMoved); } usedTabBars.insert(result); @@ -1303,12 +1646,30 @@ QWidget *QMainWindowLayout::getSeparatorWidget() return result; } +/*! \internal + Returns a pointer QDockAreaLayoutInfo which contains this \a widget directly + (in its internal list) + */ +QDockAreaLayoutInfo *QMainWindowLayout::dockInfo(QWidget *widget) +{ + QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget); + if (info) + return info; + foreach (QDockWidgetGroupWindow *dwgw, + parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) { + info = dwgw->layoutInfo()->info(widget); + if (info) + return info; + } + return 0; +} + void QMainWindowLayout::tabChanged() { QTabBar *tb = qobject_cast<QTabBar*>(sender()); if (tb == 0) return; - QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(tb); + QDockAreaLayoutInfo *info = dockInfo(tb); if (info == 0) return; info->apply(false); @@ -1316,6 +1677,16 @@ void QMainWindowLayout::tabChanged() if (QWidget *w = centralWidget()) w->raise(); } + +void QMainWindowLayout::tabMoved(int from, int to) +{ + QTabBar *tb = qobject_cast<QTabBar*>(sender()); + Q_ASSERT(tb); + QDockAreaLayoutInfo *info = dockInfo(tb); + Q_ASSERT(info); + + info->moveTab(from, to); +} #endif // QT_NO_TABBAR bool QMainWindowLayout::startSeparatorMove(const QPoint &pos) @@ -1353,7 +1724,7 @@ bool QMainWindowLayout::endSeparatorMove(const QPoint&) void QMainWindowLayout::raise(QDockWidget *widget) { - QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget); + QDockAreaLayoutInfo *info = dockInfo(widget); if (info == 0) return; #ifndef QT_NO_TABBAR @@ -1537,6 +1908,8 @@ void QMainWindowLayout::revert(QLayoutItem *widgetItem) QWidget *widget = widgetItem->widget(); layoutState = savedState; currentGapPos = layoutState.indexOf(widget); + if (currentGapPos.isEmpty()) + return; fixToolBarOrientation(widgetItem, currentGapPos.at(1)); layoutState.unplug(currentGapPos); layoutState.fitLayout(); @@ -1547,6 +1920,54 @@ void QMainWindowLayout::revert(QLayoutItem *widgetItem) bool QMainWindowLayout::plug(QLayoutItem *widgetItem) { +#ifndef QT_NO_DOCKWIDGET + if (currentHoveredFloat) { + QWidget *widget = widgetItem->widget(); + QList<int> previousPath = layoutState.indexOf(widget); + if (!previousPath.isEmpty()) + layoutState.remove(previousPath); + // Let's remove the widget from any possible group window + foreach (QDockWidgetGroupWindow *dwgw, + parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) { + QList<int> path = dwgw->layoutInfo()->indexOf(widget); + if (!path.isEmpty()) + dwgw->layoutInfo()->remove(path); + } + currentGapRect = QRect(); + + if (QDockWidget *dropTo = qobject_cast<QDockWidget*>(currentHoveredFloat)) { + //dropping to a normal widget, we mutate it in a QDockWidgetGroupWindow with two tabs + QDockWidgetGroupWindow *floatingTabs = createTabbedDockWindow(); + floatingTabs->setGeometry(dropTo->geometry()); + QDockAreaLayoutInfo *info = floatingTabs->layoutInfo(); + *info = QDockAreaLayoutInfo(&layoutState.dockAreaLayout.sep, QInternal::LeftDock, + Qt::Horizontal, QTabBar::RoundedSouth, + static_cast<QMainWindow*>(parentWidget())); + info->tabbed = true; + QLayout *parentLayout = currentHoveredFloat->parentWidget()->layout(); + info->item_list.append(parentLayout->takeAt(parentLayout->indexOf(currentHoveredFloat))); + + dropTo->setParent(floatingTabs); + dropTo->show(); + dropTo->d_func()->plug(QRect()); + currentHoveredFloat = floatingTabs; + } + + QDockWidgetGroupWindow *dwgw = qobject_cast<QDockWidgetGroupWindow *>(currentHoveredFloat); + Q_ASSERT(dwgw); + Q_ASSERT(dwgw->layoutInfo()->tabbed); // because floating group should always be tabbed + previousPath = dwgw->layoutInfo()->indexOf(widget); + if (!previousPath.isEmpty()) + dwgw->layoutInfo()->remove(previousPath); + dwgw->layoutInfo()->tab(0, widgetItem); + QRect globalRect = dwgw->layoutInfo()->tabContentRect(); + globalRect.moveTopLeft(dwgw->mapToGlobal(globalRect.topLeft())); + pluggingWidget = widget; + widgetAnimator.animate(widget, globalRect, dockOptions & QMainWindow::AnimatedDocks); + return true; + } +#endif + if (!parentWidget()->isVisible() || parentWidget()->isMinimized() || currentGapPos.isEmpty()) return false; @@ -1554,6 +1975,16 @@ bool QMainWindowLayout::plug(QLayoutItem *widgetItem) QWidget *widget = widgetItem->widget(); +#ifndef QT_NO_DOCKWIDGET + // Let's remove the widget from any possible group window + foreach (QDockWidgetGroupWindow *dwgw, + parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) { + QList<int> path = dwgw->layoutInfo()->indexOf(widget); + if (!path.isEmpty()) + dwgw->layoutInfo()->remove(path); + } +#endif + QList<int> previousPath = layoutState.indexOf(widget); const QLayoutItem *it = layoutState.plug(currentGapPos); @@ -1601,8 +2032,59 @@ void QMainWindowLayout::animationFinished(QWidget *widget) if (widget == pluggingWidget) { #ifndef QT_NO_DOCKWIDGET - if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) + if (QDockWidgetGroupWindow *dwgw = qobject_cast<QDockWidgetGroupWindow *>(widget)) { + // When the animated widget was a QDockWidgetGroupWindow, it means each of the + // embedded QDockWidget needs to be plugged back into the QMainWindow layout. + savedState.clear(); + QDockAreaLayoutInfo* info = dwgw->layoutInfo(); + QDockAreaLayoutInfo* parentInfo; + QList<int> path; + + if (QDockWidgetGroupWindow *dropTo = qobject_cast<QDockWidgetGroupWindow *>(currentHoveredFloat)) { + parentInfo = dropTo->layoutInfo(); + Q_ASSERT(parentInfo->tabbed); + path = parentInfo->indexOf(widget); + Q_ASSERT(path.size() == 1); + } else { + path = layoutState.dockAreaLayout.indexOf(widget); + Q_ASSERT(path.size() >= 2); + parentInfo = layoutState.dockAreaLayout.info(path); + Q_ASSERT(parentInfo); + } + + if (parentInfo->tabbed) { + // merge the two tab widgets + int idx = path.last(); + Q_ASSERT(parentInfo->item_list[idx].widgetItem->widget() == dwgw); + delete parentInfo->item_list[idx].widgetItem; + parentInfo->item_list.removeAt(idx); + std::copy(info->item_list.cbegin(), info->item_list.cend(), + std::inserter(parentInfo->item_list, parentInfo->item_list.begin() + idx)); + quintptr currentId = info->currentTabId(); + *info = QDockAreaLayoutInfo(); + parentInfo->reparentWidgets(currentHoveredFloat ? currentHoveredFloat.data() : parentWidget()); + parentInfo->updateTabBar(); + parentInfo->setCurrentTabId(currentId); + } else { + QDockAreaLayoutItem &item = layoutState.dockAreaLayout.item(path); + Q_ASSERT(item.widgetItem->widget() == dwgw); + delete item.widgetItem; + item.widgetItem = 0; + item.subinfo = new QDockAreaLayoutInfo(qMove(*info)); + *info = QDockAreaLayoutInfo(); + item.subinfo->reparentWidgets(parentWidget()); + item.subinfo->setTabBarShape(parentInfo->tabBarShape); + } + dwgw->destroyIfEmpty(); + } + + if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) { + if (currentHoveredFloat) { + dw->setParent(currentHoveredFloat); + dw->show(); + } dw->d_func()->plug(currentGapRect); + } #endif #ifndef QT_NO_TOOLBAR if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) @@ -1612,6 +2094,7 @@ void QMainWindowLayout::animationFinished(QWidget *widget) savedState.clear(); currentGapPos.clear(); pluggingWidget = 0; + currentHoveredFloat = Q_NULLPTR; //applying the state will make sure that the currentGap is updated correctly //and all the geometries (especially the one from the central widget) is correct layoutState.apply(false); @@ -1621,7 +2104,7 @@ void QMainWindowLayout::animationFinished(QWidget *widget) if (qobject_cast<QDockWidget*>(widget) != 0) { // info() might return null if the widget is destroyed while // animating but before the animationFinished signal is received. - if (QDockAreaLayoutInfo *info = layoutState.dockAreaLayout.info(widget)) + if (QDockAreaLayoutInfo *info = dockInfo(widget)) info->setCurrentTab(widget); } #endif @@ -1673,9 +2156,6 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow, QLayout *parentLay #endif // QT_NO_DOCKWIDGET , widgetAnimator(this) , pluggingWidget(0) -#ifndef QT_NO_RUBBERBAND - , gapIndicator(new QRubberBand(QRubberBand::Rectangle, mainwindow)) -#endif //QT_NO_RUBBERBAND #ifdef Q_DEAD_CODE_FROM_QT4_MAC , blockVisiblityCheck(false) #endif @@ -1693,12 +2173,6 @@ QMainWindowLayout::QMainWindowLayout(QMainWindow *mainwindow, QLayout *parentLay tabPositions[i] = QTabWidget::South; #endif #endif // QT_NO_DOCKWIDGET - -#ifndef QT_NO_RUBBERBAND - // For accessibility to identify this special widget. - gapIndicator->setObjectName(QLatin1String("qt_rubberband")); - gapIndicator->hide(); -#endif pluggingWidget = 0; setObjectName(mainwindow->objectName() + QLatin1String("_layout")); @@ -1765,8 +2239,34 @@ void QMainWindowLayout::setCentralWidget(QWidget *widget) invalidate(); } -QLayoutItem *QMainWindowLayout::unplug(QWidget *widget) +/*! \internal + Unplug \a widget (QDockWidget or QToolBar) from it's parent container. + + If \a group is true we might actually unplug the group of tabs this + widget is part if QMainWindow::GroupedDragging is set. When \a group + is false, the widget itself is always unplugged alone + + Returns the QLayoutItem of the dragged element. + The layout item is kept in the layout but set as a gap item. + */ +QLayoutItem *QMainWindowLayout::unplug(QWidget *widget, bool group) { +#if !defined(QT_NO_DOCKWIDGET) && !defined(QT_NO_TABBAR) + if (!widget->isWindow() && qobject_cast<const QDockWidgetGroupWindow *>(widget->parentWidget())) { + if (group) { + // We are just dragging a floating window as it, not need to do anything, we just have to + // look up the corresponding QWidgetItem* if it exists + QList<int> tabbedWindowPath = layoutState.indexOf(widget->parentWidget()); + return tabbedWindowPath.isEmpty() ? 0 : layoutState.item(tabbedWindowPath); + } else { + // We are unplugging a dock widget from a floating window. + if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) { + dw->d_func()->unplug(widget->geometry()); + return 0; + } + } + } +#endif QList<int> path = layoutState.indexOf(widget); if (path.isEmpty()) return 0; @@ -1780,9 +2280,35 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget) #ifndef QT_NO_DOCKWIDGET if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) { - dw->d_func()->unplug(r); + Q_ASSERT(path.first() == 1); + bool actualGroup = false; +#ifndef QT_NO_TABBAR + if (group && (dockOptions & QMainWindow::GroupedDragging) && path.size() > 3) { + QDockAreaLayoutItem &parentItem = layoutState.dockAreaLayout.item(path.mid(1, path.size() - 2)); + if (parentItem.subinfo && parentItem.subinfo->tabbed) { + // The QDockWidget is part of a group of tab and we need to unplug them all. + actualGroup = true; + path.removeLast(); + + QDockWidgetGroupWindow* floatingTabs = createTabbedDockWindow(); + QDockAreaLayoutInfo* info = floatingTabs->layoutInfo(); + *info = qMove(*parentItem.subinfo); + delete parentItem.subinfo; + parentItem.subinfo = 0; + floatingTabs->setGeometry(info->rect.translated(parentWidget()->pos())); + floatingTabs->show(); + floatingTabs->raise(); + item = new QDockWidgetGroupWindowItem(floatingTabs); + parentItem.widgetItem = item; + savedState = layoutState; + } + } +#endif // QT_NO_TABBAR + if (!actualGroup) { + dw->d_func()->unplug(r); + } } -#endif +#endif // QT_NO_DOCKWIDGET #ifndef QT_NO_TOOLBAR if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) { tb->d_func()->unplug(r); @@ -1804,18 +2330,75 @@ QLayoutItem *QMainWindowLayout::unplug(QWidget *widget) void QMainWindowLayout::updateGapIndicator() { #ifndef QT_NO_RUBBERBAND - gapIndicator->setVisible(!widgetAnimator.animating() && !currentGapPos.isEmpty()); - gapIndicator->setGeometry(currentGapRect); -#endif + if ((!widgetAnimator.animating() && !currentGapPos.isEmpty()) || currentHoveredFloat) { + QWidget *expectedParent = currentHoveredFloat ? currentHoveredFloat.data() : parentWidget(); + if (!gapIndicator) { + gapIndicator = new QRubberBand(QRubberBand::Rectangle, expectedParent); + // For accessibility to identify this special widget. + gapIndicator->setObjectName(QLatin1String("qt_rubberband")); + } else if (gapIndicator->parent() != expectedParent) { + gapIndicator->setParent(expectedParent); + } + gapIndicator->setGeometry(currentHoveredFloat ? currentHoveredFloat->rect() : currentGapRect); + gapIndicator->show(); + gapIndicator->raise(); + } else if (gapIndicator) { + gapIndicator->hide(); + } +#endif //QT_NO_RUBBERBAND } -QList<int> QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos) +void QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mousePos) { if (!parentWidget()->isVisible() || parentWidget()->isMinimized() || pluggingWidget != 0 || widgetItem == 0) - return QList<int>(); + return; QWidget *widget = widgetItem->widget(); + +#ifndef QT_NO_DOCKWIDGET + if ((dockOptions & QMainWindow::GroupedDragging) && (qobject_cast<QDockWidget*>(widget) + || qobject_cast<QDockWidgetGroupWindow *>(widget))) { + + // Check if we are over another floating dock widget + QVarLengthArray<QWidget *, 10> candidates; + foreach (QObject *c, parentWidget()->children()) { + QWidget *w = qobject_cast<QWidget*>(c); + if (!w) + continue; + if (w == widget) + continue; + if (!w->isTopLevel() || !w->isVisible() || w->isMinimized()) + continue; + if (!qobject_cast<QDockWidget*>(w) && !qobject_cast<QDockWidgetGroupWindow *>(w)) + continue; + candidates << w; + if (QDockWidgetGroupWindow *group = qobject_cast<QDockWidgetGroupWindow *>(w)) { + // Sometimes, there are floating QDockWidget that have a QDockWidgetGroupWindow as a parent. + foreach (QObject *c, group->children()) { + if (QDockWidget *dw = qobject_cast<QDockWidget*>(c)) { + if (dw != widget && dw->isFloating() && dw->isVisible() && !dw->isMinimized()) + candidates << dw; + } + } + } + } + foreach (QWidget *w, candidates) { + QWindow *handle1 = widget->windowHandle(); + QWindow *handle2 = w->windowHandle(); + if (handle1 && handle2 && handle1->screen() != handle2->screen()) + continue; + if (!w->geometry().contains(mousePos)) + continue; + + currentHoveredFloat = w; + restore(true); + return; + } + } + currentHoveredFloat = Q_NULLPTR; +#endif //QT_NO_DOCKWIDGET + QPoint pos = parentWidget()->mapFromGlobal(mousePos); if (!savedState.isValid()) @@ -1829,6 +2412,9 @@ QList<int> QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mouse #ifndef QT_NO_DOCKWIDGET if (QDockWidget *dw = qobject_cast<QDockWidget*>(widget)) allowed = dw->isAreaAllowed(toDockWidgetArea(path.at(1))); + + if (qobject_cast<QDockWidgetGroupWindow *>(widget)) + allowed = true; #endif #ifndef QT_NO_TOOLBAR if (QToolBar *tb = qobject_cast<QToolBar*>(widget)) @@ -1840,13 +2426,13 @@ QList<int> QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mouse } if (path == currentGapPos) - return currentGapPos; // the gap is already there + return; // the gap is already there currentGapPos = path; if (path.isEmpty()) { fixToolBarOrientation(widgetItem, 2); // 2 = top dock, ie. horizontal restore(true); - return QList<int>(); + return; } fixToolBarOrientation(widgetItem, currentGapPos.at(1)); @@ -1855,7 +2441,7 @@ QList<int> QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mouse if (!newState.insertGap(path, widgetItem)) { restore(true); // not enough space - return QList<int>(); + return; } QSize min = newState.minimumSize(); @@ -1863,7 +2449,7 @@ QList<int> QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mouse if (min.width() > size.width() || min.height() > size.height()) { restore(true); - return QList<int>(); + return; } newState.fitLayout(); @@ -1877,8 +2463,13 @@ QList<int> QMainWindowLayout::hover(QLayoutItem *widgetItem, const QPoint &mouse applyState(layoutState); updateGapIndicator(); +} - return path; +QDockWidgetGroupWindow *QMainWindowLayout::createTabbedDockWindow() +{ + QDockWidgetGroupWindow* f = new QDockWidgetGroupWindow(parentWidget(), Qt::Tool); + new QDockWidgetGroupLayout(f); + return f; } void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animate) @@ -1886,6 +2477,11 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR QSet<QTabBar*> used = newState.dockAreaLayout.usedTabBars(); + foreach (QDockWidgetGroupWindow *dwgw, + parent()->findChildren<QDockWidgetGroupWindow*>(QString(), Qt::FindDirectChildrenOnly)) { + used += dwgw->layoutInfo()->usedTabBars(); + } + QSet<QTabBar*> retired = usedTabBars - used; usedTabBars = used; foreach (QTabBar *tab_bar, retired) { @@ -1904,6 +2500,8 @@ void QMainWindowLayout::applyState(QMainWindowLayoutState &newState, bool animat } } + for (int i = 0; i < QInternal::DockCount; ++i) + newState.dockAreaLayout.docks[i].reparentWidgets(parentWidget()); #endif // QT_NO_TABBAR #endif // QT_NO_DOCKWIDGET diff --git a/src/widgets/widgets/qmainwindowlayout_p.h b/src/widgets/widgets/qmainwindowlayout_p.h index 9f84ee95db..9a13e5f5ce 100644 --- a/src/widgets/widgets/qmainwindowlayout_p.h +++ b/src/widgets/widgets/qmainwindowlayout_p.h @@ -77,6 +77,37 @@ QT_BEGIN_NAMESPACE class QToolBar; class QRubberBand; +#ifndef QT_NO_DOCKWIDGET +class QDockWidgetGroupWindow : public QWidget +{ + Q_OBJECT +public: + explicit QDockWidgetGroupWindow(QWidget* parent = 0, Qt::WindowFlags f = 0) + : QWidget(parent, f) {} + QDockAreaLayoutInfo *layoutInfo() const; + QDockWidget *topDockWidget() const; + void destroyIfEmpty(); + void adjustFlags(); +protected: + bool event(QEvent *) Q_DECL_OVERRIDE; + void paintEvent(QPaintEvent*) Q_DECL_OVERRIDE; +}; + +// This item will be used in the layout for the gap item. We cannot use QWidgetItem directly +// because QWidgetItem functions return an empty size for widgets that are are floating. +class QDockWidgetGroupWindowItem : public QWidgetItem +{ +public: + explicit QDockWidgetGroupWindowItem(QDockWidgetGroupWindow *parent) : QWidgetItem(parent) {} + QSize minimumSize() const Q_DECL_OVERRIDE { return lay()->minimumSize(); } + QSize maximumSize() const Q_DECL_OVERRIDE { return lay()->maximumSize(); } + QSize sizeHint() const Q_DECL_OVERRIDE { return lay()->sizeHint(); } + +private: + QLayout *lay() const { return const_cast<QDockWidgetGroupWindowItem *>(this)->widget()->layout(); } +}; +#endif + /* This data structure represents the state of all the tool-bars and dock-widgets. It's value based so it can be easilly copied into a temporary variable. All operations are performed without moving any widgets. Only when we are sure we have the desired state, we call apply(), which moves the @@ -196,10 +227,11 @@ public: QDockWidget *dockwidget, Qt::Orientation orientation); void tabifyDockWidget(QDockWidget *first, QDockWidget *second); - Qt::DockWidgetArea dockWidgetArea(QDockWidget *dockwidget) const; + Qt::DockWidgetArea dockWidgetArea(QWidget* widget) const; void raise(QDockWidget *widget); void setVerticalTabsEnabled(bool enabled); bool restoreDockWidget(QDockWidget *dockwidget); + QDockAreaLayoutInfo *dockInfo(QWidget *w); #ifndef QT_NO_TABBAR bool _documentMode; @@ -224,6 +256,8 @@ public: void setTabShape(QTabWidget::TabShape tabShape); QTabWidget::TabPosition tabPosition(Qt::DockWidgetArea area) const; void setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition); + + QDockWidgetGroupWindow *createTabbedDockWindow(); #endif // QT_NO_TABWIDGET #endif // QT_NO_TABBAR @@ -268,12 +302,15 @@ public: QRect currentGapRect; QWidget *pluggingWidget; #ifndef QT_NO_RUBBERBAND - QRubberBand *gapIndicator; + QPointer<QRubberBand> gapIndicator; +#endif +#ifndef QT_NO_DOCKWIDGET + QPointer<QWidget> currentHoveredFloat; // set when dragging over a floating dock widget #endif - QList<int> hover(QLayoutItem *widgetItem, const QPoint &mousePos); + void hover(QLayoutItem *widgetItem, const QPoint &mousePos); bool plug(QLayoutItem *widgetItem); - QLayoutItem *unplug(QWidget *widget); + QLayoutItem *unplug(QWidget *widget, bool group = false); void revert(QLayoutItem *widgetItem); void updateGapIndicator(); void paintDropIndicator(QPainter *p, QWidget *widget, const QRegion &clip); @@ -286,6 +323,7 @@ private Q_SLOTS: #ifndef QT_NO_DOCKWIDGET #ifndef QT_NO_TABBAR void tabChanged(); + void tabMoved(int from, int to); #endif #endif private: diff --git a/src/widgets/widgets/qmdiarea.h b/src/widgets/widgets/qmdiarea.h index 461282f8a8..e05535b2af 100644 --- a/src/widgets/widgets/qmdiarea.h +++ b/src/widgets/widgets/qmdiarea.h @@ -79,7 +79,7 @@ public: }; Q_ENUM(ViewMode) - QMdiArea(QWidget *parent = 0); + QMdiArea(QWidget *parent = Q_NULLPTR); ~QMdiArea(); QSize sizeHint() const Q_DECL_OVERRIDE; @@ -89,7 +89,7 @@ public: QMdiSubWindow *activeSubWindow() const; QList<QMdiSubWindow *> subWindowList(WindowOrder order = CreationOrder) const; - QMdiSubWindow *addSubWindow(QWidget *widget, Qt::WindowFlags flags = 0); + QMdiSubWindow *addSubWindow(QWidget *widget, Qt::WindowFlags flags = Qt::WindowFlags()); void removeSubWindow(QWidget *widget); QBrush background() const; diff --git a/src/widgets/widgets/qmdiarea_p.h b/src/widgets/widgets/qmdiarea_p.h index 7f28879f8d..f6bdf61492 100644 --- a/src/widgets/widgets/qmdiarea_p.h +++ b/src/widgets/widgets/qmdiarea_p.h @@ -142,8 +142,8 @@ public: #endif QMdiAreaTabBar *tabBar; QList<QMdi::Rearranger *> pendingRearrangements; - QList< QPointer<QMdiSubWindow> > pendingPlacements; - QList< QPointer<QMdiSubWindow> > childWindows; + QVector< QPointer<QMdiSubWindow> > pendingPlacements; + QVector< QPointer<QMdiSubWindow> > childWindows; QList<int> indicesToActivatedChildren; QPointer<QMdiSubWindow> active; QPointer<QMdiSubWindow> aboutToBecomeActive; diff --git a/src/widgets/widgets/qmdisubwindow.cpp b/src/widgets/widgets/qmdisubwindow.cpp index 1808030639..14aeb73baf 100644 --- a/src/widgets/widgets/qmdisubwindow.cpp +++ b/src/widgets/widgets/qmdisubwindow.cpp @@ -1091,8 +1091,8 @@ void QMdiSubWindowPrivate::updateDirtyRegions() if (!parent) return; - foreach (Operation operation, operationMap.keys()) - operationMap.find(operation).value().region = getRegion(operation); + for (OperationInfoMap::iterator it = operationMap.begin(), end = operationMap.end(); it != end; ++it) + it.value().region = getRegion(it.key()); } /*! @@ -2689,7 +2689,10 @@ bool QMdiSubWindow::eventFilter(QObject *object, QEvent *event) // System menu events. if (d->systemMenu && d->systemMenu == object) { if (event->type() == QEvent::MouseButtonDblClick) { - close(); + const QMouseEvent *mouseEvent = static_cast<const QMouseEvent *>(event); + const QAction *action = d->systemMenu->actionAt(mouseEvent->pos()); + if (!action || action->isEnabled()) + close(); } else if (event->type() == QEvent::MouseMove) { QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event); d->hoveredSubControl = d->getSubControl(mapFromGlobal(mouseEvent->globalPos())); diff --git a/src/widgets/widgets/qmdisubwindow.h b/src/widgets/widgets/qmdisubwindow.h index 693477c894..e7d0ca4e44 100644 --- a/src/widgets/widgets/qmdisubwindow.h +++ b/src/widgets/widgets/qmdisubwindow.h @@ -60,7 +60,7 @@ public: }; Q_DECLARE_FLAGS(SubWindowOptions, SubWindowOption) - QMdiSubWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0); + QMdiSubWindow(QWidget *parent = Q_NULLPTR, Qt::WindowFlags flags = Qt::WindowFlags()); ~QMdiSubWindow(); QSize sizeHint() const Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index e81359feac..ea3e4c4488 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -102,9 +102,9 @@ class QTornOffMenu : public QMenu causedPopup.action = ((QTornOffMenu*)p)->d_func()->causedPopup.action; causedStack = ((QTornOffMenu*)p)->d_func()->calcCausedStack(); } - QList<QPointer<QWidget> > calcCausedStack() const Q_DECL_OVERRIDE { return causedStack; } + QVector<QPointer<QWidget> > calcCausedStack() const Q_DECL_OVERRIDE { return causedStack; } QPointer<QMenu> causedMenu; - QList<QPointer<QWidget> > causedStack; + QVector<QPointer<QWidget> > causedStack; }; public: QTornOffMenu(QMenu *p) : QMenu(*(new QTornOffMenuPrivate(p))) @@ -192,11 +192,10 @@ void QMenuPrivate::syncPlatformMenu() return; QPlatformMenuItem *beforeItem = Q_NULLPTR; - QListIterator<QAction*> it(q->actions()); - it.toBack(); - while (it.hasPrevious()) { + const QList<QAction*> actions = q->actions(); + for (QList<QAction*>::const_reverse_iterator it = actions.rbegin(), end = actions.rend(); it != end; ++it) { QPlatformMenuItem *menuItem = platformMenu->createMenuItem(); - QAction *action = it.previous(); + QAction *action = *it; menuItem->setTag(reinterpret_cast<quintptr>(action)); QObject::connect(menuItem, SIGNAL(activated()), action, SLOT(trigger()), Qt::QueuedConnection); QObject::connect(menuItem, SIGNAL(hovered()), action, SIGNAL(hovered()), Qt::QueuedConnection); @@ -236,9 +235,9 @@ QRect QMenuPrivate::popupGeometry(int screen) const } } -QList<QPointer<QWidget> > QMenuPrivate::calcCausedStack() const +QVector<QPointer<QWidget> > QMenuPrivate::calcCausedStack() const { - QList<QPointer<QWidget> > ret; + QVector<QPointer<QWidget> > ret; for(QWidget *widget = causedPopup.widget; widget; ) { ret.append(widget); if (QTornOffMenu *qtmenu = qobject_cast<QTornOffMenu*>(widget)) @@ -503,8 +502,8 @@ void QMenuPrivate::hideMenu(QMenu *menu) if (activeMenu == menu) activeMenu = 0; menu->d_func()->causedPopup.action = 0; - menu->d_func()->causedPopup.widget = 0; menu->close(); + menu->d_func()->causedPopup.widget = 0; if (previousMouseMenu.data() == menu) handleEnterLeaveEvents(&previousMouseMenu, Q_NULLPTR); } @@ -1110,8 +1109,7 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) handleEnterLeaveEvents(&previousMouseMenu,qobject_cast<QMenu *>(caused)); if(e->type() != QEvent::MouseButtonRelease || mouseDown == caused) { QMouseEvent new_e(e->type(), cpos, caused->mapTo(caused->topLevelWidget(), cpos), e->screenPos(), - e->button(), e->buttons(), e->modifiers()); - QGuiApplicationPrivate::setMouseEventSource(&new_e, e->source()); + e->button(), e->buttons(), e->modifiers(), e->source()); QApplication::sendEvent(caused, &new_e); return true; } @@ -1123,7 +1121,7 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) return false; } -void QMenuPrivate::activateCausedStack(const QList<QPointer<QWidget> > &causedStack, QAction *action, QAction::ActionEvent action_e, bool self) +void QMenuPrivate::activateCausedStack(const QVector<QPointer<QWidget> > &causedStack, QAction *action, QAction::ActionEvent action_e, bool self) { QBoolBlocker guard(activationRecursionGuard); if(self) @@ -1171,7 +1169,7 @@ void QMenuPrivate::activateAction(QAction *action, QAction::ActionEvent action_e /* I have to save the caused stack here because it will be undone after popup execution (ie in the hide). Then I iterate over the list to actually send the events. --Sam */ - const QList<QPointer<QWidget> > causedStack = calcCausedStack(); + const QVector<QPointer<QWidget> > causedStack = calcCausedStack(); if (action_e == QAction::Trigger) { #ifndef QT_NO_WHATSTHIS if (!inWhatsThisMode) @@ -1233,7 +1231,7 @@ void QMenuPrivate::_q_actionTriggered() if (!activationRecursionGuard && actionGuard) { //in case the action has not been activated by the mouse //we check the parent hierarchy - QList< QPointer<QWidget> > list; + QVector< QPointer<QWidget> > list; for(QWidget *widget = q->parentWidget(); widget; ) { if (qobject_cast<QMenu*>(widget) #ifndef QT_NO_MENUBAR @@ -1266,7 +1264,7 @@ void QMenuPrivate::_q_platformMenuAboutToShow() #ifdef Q_OS_OSX if (platformMenu) Q_FOREACH (QAction *action, q->actions()) - if (QWidget *widget = widgetItems.value(const_cast<QAction *>(action))) + if (QWidget *widget = widgetItems.value(action)) if (widget->parent() == q) { QPlatformMenuItem *menuItem = platformMenu->menuItemForTag(reinterpret_cast<quintptr>(action)); moveWidgetToPlatformItem(widget, menuItem); @@ -1444,7 +1442,7 @@ void QMenu::initStyleOption(QStyleOptionMenuItem *option, const QAction *action) addSeparator(), and addMenu(). \sa QMenuBar, {fowler}{GUI Design Handbook: Menu, Drop-Down and Pop-Up}, - {Application Example}, {Menus Example}, {Recent Files Example} + {Application Example}, {Menus Example} */ @@ -1572,6 +1570,100 @@ QAction *QMenu::addAction(const QString &text, const QObject *receiver, const ch return action; } +/*!\fn QAction *QMenu::addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0) + + \since 5.6 + + \overload + + This convenience function creates a new action with the text \a + text and an optional shortcut \a shortcut. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a method of the \a receiver. The function adds the newly created + action to the menu's list of actions and returns it. + + QMenu takes ownership of the returned QAction. +*/ + +/*!\fn QAction *QMenu::addAction(const QString &text, Functor functor, const QKeySequence &shortcut = 0) + + \since 5.6 + + \overload + + This convenience function creates a new action with the text \a + text and an optional shortcut \a shortcut. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. The function adds the newly created + action to the menu's list of actions and returns it. + + QMenu takes ownership of the returned QAction. +*/ + +/*!\fn QAction *QMenu::addAction(const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut = 0) + + \since 5.6 + + \overload + + This convenience function creates a new action with the text \a + text and an optional shortcut \a shortcut. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. The function adds the newly created + action to the menu's list of actions and returns it. + + If \a context is destroyed, the functor will not be called. + + QMenu takes ownership of the returned QAction. +*/ + +/*!\fn QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0) + + \since 5.6 + + \overload + + This convenience function creates a new action with an \a icon + and some \a text and an optional shortcut \a shortcut. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a method of the \a receiver. The function adds the newly created + action to the menu's list of actions and returns it. + + QMenu takes ownership of the returned QAction. +*/ + +/*!\fn QAction *QMenu::addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut = 0) + + \since 5.6 + + \overload + + This convenience function creates a new action with an \a icon + and some \a text and an optional shortcut \a shortcut. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. The function adds the newly created + action to the menu's list of actions and returns it. + + QMenu takes ownership of the returned QAction. +*/ + +/*!\fn QAction *QMenu::addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut = 0) + + \since 5.6 + + \overload + + This convenience function creates a new action with an \a icon + and some \a text and an optional shortcut \a shortcut. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. The function adds the newly created + action to the menu's list of actions and returns it. + + If \a context is destroyed, the functor will not be called. + + QMenu takes ownership of the returned QAction. +*/ + /*! \overload @@ -2494,7 +2586,11 @@ void QMenu::mousePressEvent(QMouseEvent *e) Q_D(QMenu); if (d->aboutToHide || d->mouseEventTaken(e)) return; - if (!rect().contains(e->pos())) { + // Workaround for XCB on multiple screens which doesn't have offset. If the menu is open on one screen + // and mouse clicks on second screen, e->pos() is QPoint(0,0) and the menu doesn't hide. This trick makes + // possible to hide the menu when mouse clicks on another screen (e->screenPos() returns correct value). + // Only when mouse clicks in QPoint(0,0) on second screen, the menu doesn't hide. + if ((e->pos().isNull() && !e->screenPos().isNull()) || !rect().contains(e->pos())) { if (d->noReplayFor && QRect(d->noReplayFor->mapToGlobal(QPoint()), d->noReplayFor->size()).contains(e->globalPos())) setAttribute(Qt::WA_NoMouseReplay); @@ -2586,7 +2682,7 @@ QMenu::event(QEvent *e) if (kev->key() == Qt::Key_Up || kev->key() == Qt::Key_Down || kev->key() == Qt::Key_Left || kev->key() == Qt::Key_Right || kev->key() == Qt::Key_Enter || kev->key() == Qt::Key_Return - || kev->key() == Qt::Key_Escape) { + || kev->matches(QKeySequence::Cancel)) { e->accept(); return true; } @@ -2872,27 +2968,6 @@ void QMenu::keyPressEvent(QKeyEvent *e) } break; - case Qt::Key_Escape: -#ifdef QT_KEYPAD_NAVIGATION - case Qt::Key_Back: -#endif - key_consumed = true; - if (d->tornoff) { - close(); - return; - } - { - QPointer<QWidget> caused = d->causedPopup.widget; - d->hideMenu(this); // hide after getting causedPopup -#ifndef QT_NO_MENUBAR - if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) { - mb->d_func()->setCurrentAction(d->menuAction); - mb->d_func()->setKeyboardMode(true); - } -#endif - } - break; - case Qt::Key_Space: if (!style()->styleHint(QStyle::SH_Menu_SpaceActivatesItem, 0, this)) break; @@ -2929,6 +3004,28 @@ void QMenu::keyPressEvent(QKeyEvent *e) key_consumed = false; } + if (!key_consumed && (e->matches(QKeySequence::Cancel) +#ifdef QT_KEYPAD_NAVIGATION + || e->key() == Qt::Key_Back +#endif + )) { + key_consumed = true; + if (d->tornoff) { + close(); + return; + } + { + QPointer<QWidget> caused = d->causedPopup.widget; + d->hideMenu(this); // hide after getting causedPopup +#ifndef QT_NO_MENUBAR + if (QMenuBar *mb = qobject_cast<QMenuBar*>(caused)) { + mb->d_func()->setCurrentAction(d->menuAction); + mb->d_func()->setKeyboardMode(true); + } +#endif + } + } + if (!key_consumed) { // send to menu bar if ((!e->modifiers() || e->modifiers() == Qt::AltModifier || e->modifiers() == Qt::ShiftModifier) && e->text().length()==1) { @@ -3049,7 +3146,7 @@ void QMenu::mouseMoveEvent(QMouseEvent *e) d->activeMenu->d_func()->setCurrentAction(0); QMenuSloppyState::MouseEventResult sloppyEventResult = d->sloppyState.processMouseEvent(e->localPos(), action, d->currentAction); - if (sloppyEventResult == QMenuSloppyState::EventShouldBePropogated) { + if (sloppyEventResult == QMenuSloppyState::EventShouldBePropagated) { d->setCurrentAction(action, d->mousePopupDelay); } else if (sloppyEventResult == QMenuSloppyState::EventDiscardsSloppyState) { d->sloppyState.reset(); diff --git a/src/widgets/widgets/qmenu.h b/src/widgets/widgets/qmenu.h index 5dda8b2370..6bbe54186e 100644 --- a/src/widgets/widgets/qmenu.h +++ b/src/widgets/widgets/qmenu.h @@ -68,8 +68,8 @@ private: Q_PROPERTY(bool toolTipsVisible READ toolTipsVisible WRITE setToolTipsVisible) public: - explicit QMenu(QWidget *parent = 0); - explicit QMenu(const QString &title, QWidget *parent = 0); + explicit QMenu(QWidget *parent = Q_NULLPTR); + explicit QMenu(const QString &title, QWidget *parent = Q_NULLPTR); ~QMenu(); using QWidget::addAction; @@ -78,6 +78,72 @@ public: QAction *addAction(const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0); QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member, const QKeySequence &shortcut = 0); +#ifdef Q_QDOC + QAction *addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0); + QAction *addAction(const QString &text, Functor functor, const QKeySequence &shortcut = 0); + QAction *addAction(const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut = 0); + QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method, const QKeySequence &shortcut = 0); + QAction *addAction(const QIcon &icon, const QString &text, Functor functor, const QKeySequence &shortcut = 0); + QAction *addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor, const QKeySequence &shortcut = 0); +#else + // addAction(QString): Connect to a QObject slot / functor or function pointer (with context) + template<class Obj, typename Func1> + inline typename QtPrivate::QEnableIf<!QtPrivate::is_same<const char*, Func1>::value + && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::Type + addAction(const QString &text, const Obj *object, Func1 slot, const QKeySequence &shortcut = 0) + { + QAction *result = addAction(text); +#ifdef QT_NO_SHORTCUT + Q_UNUSED(shortcut) +#else + result->setShortcut(shortcut); +#endif + connect(result, &QAction::triggered, object, slot); + return result; + } + // addAction(QString): Connect to a functor or function pointer (without context) + template <typename Func1> + inline QAction *addAction(const QString &text, Func1 slot, const QKeySequence &shortcut = 0) + { + QAction *result = addAction(text); +#ifdef QT_NO_SHORTCUT + Q_UNUSED(shortcut) +#else + result->setShortcut(shortcut); +#endif + connect(result, &QAction::triggered, slot); + return result; + } + // addAction(QIcon, QString): Connect to a QObject slot / functor or function pointer (with context) + template<class Obj, typename Func1> + inline typename QtPrivate::QEnableIf<!QtPrivate::is_same<const char*, Func1>::value + && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::Type + addAction(const QIcon &actionIcon, const QString &text, const Obj *object, Func1 slot, const QKeySequence &shortcut = 0) + { + QAction *result = addAction(actionIcon, text); +#ifdef QT_NO_SHORTCUT + Q_UNUSED(shortcut) +#else + result->setShortcut(shortcut); +#endif + connect(result, &QAction::triggered, object, slot); + return result; + } + // addAction(QIcon, QString): Connect to a functor or function pointer (without context) + template <typename Func1> + inline QAction *addAction(const QIcon &actionIcon, const QString &text, Func1 slot, const QKeySequence &shortcut = 0) + { + QAction *result = addAction(actionIcon, text); +#ifdef QT_NO_SHORTCUT + Q_UNUSED(shortcut) +#else + result->setShortcut(shortcut); +#endif + connect(result, &QAction::triggered, slot); + return result; + } +#endif // !Q_QDOC + QAction *addMenu(QMenu *menu); QMenu *addMenu(const QString &title); QMenu *addMenu(const QIcon &icon, const QString &title); @@ -107,14 +173,14 @@ public: void setActiveAction(QAction *act); QAction *activeAction() const; - void popup(const QPoint &pos, QAction *at=0); + void popup(const QPoint &pos, QAction *at = Q_NULLPTR); QAction *exec(); - QAction *exec(const QPoint &pos, QAction *at=0); + QAction *exec(const QPoint &pos, QAction *at = Q_NULLPTR); #if QT_VERSION >= QT_VERSION_CHECK(6,0,0) - static QAction *exec(const QList<QAction *> &actions, const QPoint &pos, QAction *at = 0, QWidget *parent = 0); + static QAction *exec(const QList<QAction *> &actions, const QPoint &pos, QAction *at = Q_NULLPTR, QWidget *parent = Q_NULLPTR); #else - static QAction *exec(QList<QAction*> actions, const QPoint &pos, QAction *at=0, QWidget *parent=0); + static QAction *exec(QList<QAction*> actions, const QPoint &pos, QAction *at = Q_NULLPTR, QWidget *parent = Q_NULLPTR); #endif QSize sizeHint() const Q_DECL_OVERRIDE; @@ -189,7 +255,7 @@ private: Q_PRIVATE_SLOT(d_func(), void _q_platformMenuAboutToShow()) protected: - QMenu(QMenuPrivate &dd, QWidget* parent = 0); + QMenu(QMenuPrivate &dd, QWidget* parent = Q_NULLPTR); private: Q_DISABLE_COPY(QMenu) diff --git a/src/widgets/widgets/qmenu_mac.mm b/src/widgets/widgets/qmenu_mac.mm index a42879fc73..8b29011178 100644 --- a/src/widgets/widgets/qmenu_mac.mm +++ b/src/widgets/widgets/qmenu_mac.mm @@ -115,6 +115,7 @@ void QMenuPrivate::moveWidgetToPlatformItem(QWidget *widget, QPlatformMenuItem* QObject::connect(platformMenu, SIGNAL(destroyed()), container, SLOT(deleteLater())); container->resize(widget->sizeHint()); widget->setParent(container); + widget->setVisible(true); NSView *containerView = container->nativeView(); QWindow *containerWindow = container->windowHandle(); diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index ab6ca068fb..e717d923ae 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -126,7 +126,7 @@ public: enum MouseEventResult { EventIsProcessed, - EventShouldBePropogated, + EventShouldBePropagated, EventDiscardsSloppyState }; @@ -187,14 +187,14 @@ public: m_parent->stopTimer(); if (!m_enabled) - return EventShouldBePropogated; + return EventShouldBePropagated; if (!m_time.isActive()) startTimer(); if (!m_sub_menu) { reset(); - return EventShouldBePropogated; + return EventShouldBePropagated; } QSetValueOnDestroy<bool> setFirstMouse(m_first_mouse, false); @@ -208,7 +208,7 @@ public: if (m_action_rect.contains(mousePos)) { startTimer(); - return currentAction == m_menu->menuAction() ? EventIsProcessed : EventShouldBePropogated; + return currentAction == m_menu->menuAction() ? EventIsProcessed : EventShouldBePropagated; } if (m_uni_directional && !m_first_mouse && resetAction != m_origin_action) { @@ -247,7 +247,7 @@ public: } - return m_select_other_actions ? EventShouldBePropogated : EventIsProcessed; + return m_select_other_actions ? EventShouldBePropagated : EventIsProcessed; } void setSubMenuPopup(const QRect &actionRect, QAction *resetAction, QMenu *subMenu); @@ -422,7 +422,7 @@ public: QPointer<QWidget> widget; QPointer<QAction> action; }; - virtual QList<QPointer<QWidget> > calcCausedStack() const; + virtual QVector<QPointer<QWidget> > calcCausedStack() const; QMenuCaused causedPopup; void hideUpToMenuBar(); void hideMenu(QMenu *menu); @@ -450,7 +450,7 @@ public: //firing of events void activateAction(QAction *, QAction::ActionEvent, bool self=true); - void activateCausedStack(const QList<QPointer<QWidget> > &, QAction *, QAction::ActionEvent, bool); + void activateCausedStack(const QVector<QPointer<QWidget> > &, QAction *, QAction::ActionEvent, bool); void _q_actionTriggered(); void _q_actionHovered(); diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index 883fd3a945..2e48607f82 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -195,7 +195,9 @@ void QMenuBarPrivate::updateGeometries() for(int j = 0; j < shortcutIndexMap.size(); ++j) q->releaseShortcut(shortcutIndexMap.value(j)); shortcutIndexMap.resize(0); // faster than clear - for(int i = 0; i < actions.count(); i++) + const int actionsCount = actions.count(); + shortcutIndexMap.reserve(actionsCount); + for (int i = 0; i < actionsCount; i++) shortcutIndexMap.append(q->grabShortcut(QKeySequence::mnemonic(actions.at(i)->text()))); } #endif @@ -636,7 +638,7 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti \row \li quit or exit \li Application Menu | Quit <application name> \li If this entry is not found a default Quit item will be - created to call QApplication::quit() + created to call QCoreApplication::quit() \endtable You can override this behavior by using the QAction::menuRole() @@ -1120,14 +1122,14 @@ void QMenuBar::keyPressEvent(QKeyEvent *e) } break; } - case Qt::Key_Escape: + default: + key_consumed = false; + } + + if (!key_consumed && e->matches(QKeySequence::Cancel)) { d->setCurrentAction(0); d->setKeyboardMode(false); key_consumed = true; - break; - - default: - key_consumed = false; } if(!key_consumed && @@ -1430,7 +1432,7 @@ bool QMenuBar::event(QEvent *e) case QEvent::ShortcutOverride: { QKeyEvent *kev = static_cast<QKeyEvent*>(e); //we only filter out escape if there is a current action - if (kev->key() == Qt::Key_Escape && d->currentAction) { + if (kev->matches(QKeySequence::Cancel) && d->currentAction) { e->accept(); return true; } diff --git a/src/widgets/widgets/qmenubar.h b/src/widgets/widgets/qmenubar.h index 461dec8a94..3b3980c860 100644 --- a/src/widgets/widgets/qmenubar.h +++ b/src/widgets/widgets/qmenubar.h @@ -54,7 +54,7 @@ class Q_WIDGETS_EXPORT QMenuBar : public QWidget Q_PROPERTY(bool nativeMenuBar READ isNativeMenuBar WRITE setNativeMenuBar) public: - explicit QMenuBar(QWidget *parent = 0); + explicit QMenuBar(QWidget *parent = Q_NULLPTR); ~QMenuBar(); using QWidget::addAction; diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp index 93c9ddc285..91788a3383 100644 --- a/src/widgets/widgets/qplaintextedit.cpp +++ b/src/widgets/widgets/qplaintextedit.cpp @@ -1615,7 +1615,7 @@ void QPlainTextEdit::timerEvent(QTimerEvent *e) Note that the undo/redo history is cleared by this function. - \sa toText() + \sa toPlainText() */ void QPlainTextEdit::setPlainText(const QString &text) diff --git a/src/widgets/widgets/qplaintextedit.h b/src/widgets/widgets/qplaintextedit.h index 69bd2ab647..60f1d6e984 100644 --- a/src/widgets/widgets/qplaintextedit.h +++ b/src/widgets/widgets/qplaintextedit.h @@ -82,8 +82,8 @@ public: }; Q_ENUM(LineWrapMode) - explicit QPlainTextEdit(QWidget *parent = 0); - explicit QPlainTextEdit(const QString &text, QWidget *parent = 0); + explicit QPlainTextEdit(QWidget *parent = Q_NULLPTR); + explicit QPlainTextEdit(const QString &text, QWidget *parent = Q_NULLPTR); virtual ~QPlainTextEdit(); void setDocument(QTextDocument *document); @@ -136,9 +136,9 @@ public: void setCenterOnScroll(bool enabled); bool centerOnScroll() const; - bool find(const QString &exp, QTextDocument::FindFlags options = 0); + bool find(const QString &exp, QTextDocument::FindFlags options = QTextDocument::FindFlags()); #ifndef QT_NO_REGEXP - bool find(const QRegExp &exp, QTextDocument::FindFlags options = 0); + bool find(const QRegExp &exp, QTextDocument::FindFlags options = QTextDocument::FindFlags()); #endif inline QString toPlainText() const diff --git a/src/widgets/widgets/qprogressbar.cpp b/src/widgets/widgets/qprogressbar.cpp index 8034a0237a..5b06e75abe 100644 --- a/src/widgets/widgets/qprogressbar.cpp +++ b/src/widgets/widgets/qprogressbar.cpp @@ -107,10 +107,8 @@ void QProgressBarPrivate::resetLayoutItemMargins() /*! Initialize \a option with the values from this QProgressBar. This method is useful - for subclasses when they need a QStyleOptionProgressBar or QStyleOptionProgressBarV2, - but don't want to fill in all the information themselves. This function will check the version - of the QStyleOptionProgressBar and fill in the additional values for a - QStyleOptionProgressBarV2. + for subclasses when they need a QStyleOptionProgressBar, + but don't want to fill in all the information themselves. \sa QStyleOption::initFrom() */ @@ -129,13 +127,9 @@ void QProgressBar::initStyleOption(QStyleOptionProgressBar *option) const option->textAlignment = d->alignment; option->textVisible = d->textVisible; option->text = text(); - - if (QStyleOptionProgressBarV2 *optionV2 - = qstyleoption_cast<QStyleOptionProgressBarV2 *>(option)) { - optionV2->orientation = d->orientation; // ### Qt 6: remove this member from QStyleOptionProgressBarV2 - optionV2->invertedAppearance = d->invertedAppearance; - optionV2->bottomToTop = (d->textDirection == QProgressBar::BottomToTop); - } + option->orientation = d->orientation; // ### Qt 6: remove this member from QStyleOptionProgressBar + option->invertedAppearance = d->invertedAppearance; + option->bottomToTop = d->textDirection == QProgressBar::BottomToTop; } bool QProgressBarPrivate::repaintRequired() const @@ -158,7 +152,7 @@ bool QProgressBarPrivate::repaintRequired() const } // Check if the bar needs to be repainted - QStyleOptionProgressBarV2 opt; + QStyleOptionProgressBar opt; q->initStyleOption(&opt); int cw = q->style()->pixelMetric(QStyle::PM_ProgressBarChunkWidth, &opt, q); QRect groove = q->style()->subElementRect(QStyle::SE_ProgressBarGroove, &opt, q); @@ -410,7 +404,7 @@ Qt::Alignment QProgressBar::alignment() const void QProgressBar::paintEvent(QPaintEvent *) { QStylePainter paint(this); - QStyleOptionProgressBarV2 opt; + QStyleOptionProgressBar opt; initStyleOption(&opt); paint.drawControl(QStyle::CE_ProgressBar, opt); d_func()->lastPaintedValue = d_func()->value; @@ -423,7 +417,7 @@ QSize QProgressBar::sizeHint() const { ensurePolished(); QFontMetrics fm = fontMetrics(); - QStyleOptionProgressBarV2 opt; + QStyleOptionProgressBar opt; initStyleOption(&opt); int cw = style()->pixelMetric(QStyle::PM_ProgressBarChunkWidth, &opt, this); QSize size = QSize(qMax(9, cw) * 7 + fm.width(QLatin1Char('0')) * 4, fm.height() + 8); diff --git a/src/widgets/widgets/qprogressbar.h b/src/widgets/widgets/qprogressbar.h index 0c3200f82c..e17e01c17b 100644 --- a/src/widgets/widgets/qprogressbar.h +++ b/src/widgets/widgets/qprogressbar.h @@ -62,7 +62,7 @@ public: enum Direction { TopToBottom, BottomToTop }; Q_ENUM(Direction) - explicit QProgressBar(QWidget *parent = 0); + explicit QProgressBar(QWidget *parent = Q_NULLPTR); ~QProgressBar(); int minimum() const; diff --git a/src/widgets/widgets/qpushbutton.h b/src/widgets/widgets/qpushbutton.h index 2521c0982e..3db12be380 100644 --- a/src/widgets/widgets/qpushbutton.h +++ b/src/widgets/widgets/qpushbutton.h @@ -52,9 +52,9 @@ class Q_WIDGETS_EXPORT QPushButton : public QAbstractButton Q_PROPERTY(bool flat READ isFlat WRITE setFlat) public: - explicit QPushButton(QWidget *parent=0); - explicit QPushButton(const QString &text, QWidget *parent=0); - QPushButton(const QIcon& icon, const QString &text, QWidget *parent=0); + explicit QPushButton(QWidget *parent = Q_NULLPTR); + explicit QPushButton(const QString &text, QWidget *parent = Q_NULLPTR); + QPushButton(const QIcon& icon, const QString &text, QWidget *parent = Q_NULLPTR); ~QPushButton(); QSize sizeHint() const Q_DECL_OVERRIDE; @@ -88,7 +88,7 @@ protected: void focusInEvent(QFocusEvent *) Q_DECL_OVERRIDE; void focusOutEvent(QFocusEvent *) Q_DECL_OVERRIDE; void initStyleOption(QStyleOptionButton *option) const; - QPushButton(QPushButtonPrivate &dd, QWidget* parent = 0); + QPushButton(QPushButtonPrivate &dd, QWidget* parent = Q_NULLPTR); public: diff --git a/src/widgets/widgets/qradiobutton.h b/src/widgets/widgets/qradiobutton.h index f323f5af99..df0b1051bf 100644 --- a/src/widgets/widgets/qradiobutton.h +++ b/src/widgets/widgets/qradiobutton.h @@ -47,8 +47,8 @@ class Q_WIDGETS_EXPORT QRadioButton : public QAbstractButton Q_OBJECT public: - explicit QRadioButton(QWidget *parent=0); - explicit QRadioButton(const QString &text, QWidget *parent=0); + explicit QRadioButton(QWidget *parent = Q_NULLPTR); + explicit QRadioButton(const QString &text, QWidget *parent = Q_NULLPTR); ~QRadioButton(); QSize sizeHint() const Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qrubberband.h b/src/widgets/widgets/qrubberband.h index 3ff6eb47fa..b0dc14ed98 100644 --- a/src/widgets/widgets/qrubberband.h +++ b/src/widgets/widgets/qrubberband.h @@ -50,7 +50,7 @@ class Q_WIDGETS_EXPORT QRubberBand : public QWidget public: enum Shape { Line, Rectangle }; - explicit QRubberBand(Shape, QWidget * =0); + explicit QRubberBand(Shape, QWidget * = Q_NULLPTR); ~QRubberBand(); Shape shape() const; diff --git a/src/widgets/widgets/qscrollarea.h b/src/widgets/widgets/qscrollarea.h index cafb1ec6de..1658236034 100644 --- a/src/widgets/widgets/qscrollarea.h +++ b/src/widgets/widgets/qscrollarea.h @@ -50,7 +50,7 @@ class Q_WIDGETS_EXPORT QScrollArea : public QAbstractScrollArea Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment) public: - explicit QScrollArea(QWidget* parent=0); + explicit QScrollArea(QWidget *parent = Q_NULLPTR); ~QScrollArea(); QWidget *widget() const; @@ -71,7 +71,7 @@ public: void ensureWidgetVisible(QWidget *childWidget, int xmargin = 50, int ymargin = 50); protected: - QScrollArea(QScrollAreaPrivate &dd, QWidget *parent = 0); + QScrollArea(QScrollAreaPrivate &dd, QWidget *parent = Q_NULLPTR); bool event(QEvent *) Q_DECL_OVERRIDE; bool eventFilter(QObject *, QEvent *) Q_DECL_OVERRIDE; void resizeEvent(QResizeEvent *) Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qscrollbar.h b/src/widgets/widgets/qscrollbar.h index 5934469045..4af5fb4a55 100644 --- a/src/widgets/widgets/qscrollbar.h +++ b/src/widgets/widgets/qscrollbar.h @@ -49,8 +49,8 @@ class Q_WIDGETS_EXPORT QScrollBar : public QAbstractSlider { Q_OBJECT public: - explicit QScrollBar(QWidget *parent=0); - explicit QScrollBar(Qt::Orientation, QWidget *parent=0); + explicit QScrollBar(QWidget *parent = Q_NULLPTR); + explicit QScrollBar(Qt::Orientation, QWidget *parent = Q_NULLPTR); ~QScrollBar(); QSize sizeHint() const Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qslider.h b/src/widgets/widgets/qslider.h index 3a528382a7..801a684fdf 100644 --- a/src/widgets/widgets/qslider.h +++ b/src/widgets/widgets/qslider.h @@ -61,8 +61,8 @@ public: }; Q_ENUM(TickPosition) - explicit QSlider(QWidget *parent = 0); - explicit QSlider(Qt::Orientation orientation, QWidget *parent = 0); + explicit QSlider(QWidget *parent = Q_NULLPTR); + explicit QSlider(Qt::Orientation orientation, QWidget *parent = Q_NULLPTR); ~QSlider(); diff --git a/src/widgets/widgets/qspinbox.h b/src/widgets/widgets/qspinbox.h index 606206d4f0..066fe88562 100644 --- a/src/widgets/widgets/qspinbox.h +++ b/src/widgets/widgets/qspinbox.h @@ -56,7 +56,7 @@ class Q_WIDGETS_EXPORT QSpinBox : public QAbstractSpinBox Q_PROPERTY(int displayIntegerBase READ displayIntegerBase WRITE setDisplayIntegerBase) public: - explicit QSpinBox(QWidget *parent = 0); + explicit QSpinBox(QWidget *parent = Q_NULLPTR); ~QSpinBox(); int value() const; @@ -117,7 +117,7 @@ class Q_WIDGETS_EXPORT QDoubleSpinBox : public QAbstractSpinBox Q_PROPERTY(double singleStep READ singleStep WRITE setSingleStep) Q_PROPERTY(double value READ value WRITE setValue NOTIFY valueChanged USER true) public: - explicit QDoubleSpinBox(QWidget *parent = 0); + explicit QDoubleSpinBox(QWidget *parent = Q_NULLPTR); ~QDoubleSpinBox(); double value() const; diff --git a/src/widgets/widgets/qsplashscreen.h b/src/widgets/widgets/qsplashscreen.h index 58b8484f4c..dec24a5608 100644 --- a/src/widgets/widgets/qsplashscreen.h +++ b/src/widgets/widgets/qsplashscreen.h @@ -47,8 +47,8 @@ class Q_WIDGETS_EXPORT QSplashScreen : public QWidget { Q_OBJECT public: - explicit QSplashScreen(const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = 0); - QSplashScreen(QWidget *parent, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = 0); + explicit QSplashScreen(const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags()); + QSplashScreen(QWidget *parent, const QPixmap &pixmap = QPixmap(), Qt::WindowFlags f = Qt::WindowFlags()); virtual ~QSplashScreen(); void setPixmap(const QPixmap &pixmap); diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp index de6e45234c..c2081c15f8 100644 --- a/src/widgets/widgets/qsplitter.cpp +++ b/src/widgets/widgets/qsplitter.cpp @@ -58,6 +58,10 @@ QT_BEGIN_NAMESPACE //#define QSPLITTER_DEBUG +QSplitterPrivate::~QSplitterPrivate() +{ +} + /*! \class QSplitterHandle \brief The QSplitterHandle class provides handle functionality for the splitter. @@ -1498,8 +1502,11 @@ QList<int> QSplitter::sizes() const Q_D(const QSplitter); ensurePolished(); + const int numSizes = d->list.size(); QList<int> list; - for (int i = 0; i < d->list.size(); ++i) { + list.reserve(numSizes); + + for (int i = 0; i < numSizes; ++i) { QSplitterLayoutStruct *s = d->list.at(i); list.append(d->pick(s->rect.size())); } @@ -1594,8 +1601,10 @@ QByteArray QSplitter::saveState() const stream << qint32(SplitterMagic); stream << qint32(version); + const int numSizes = d->list.size(); QList<int> list; - for (int i = 0; i < d->list.size(); ++i) { + list.reserve(numSizes); + for (int i = 0; i < numSizes; ++i) { QSplitterLayoutStruct *s = d->list.at(i); list.append(s->sizer); } diff --git a/src/widgets/widgets/qsplitter.h b/src/widgets/widgets/qsplitter.h index 4da92acd22..84010c236b 100644 --- a/src/widgets/widgets/qsplitter.h +++ b/src/widgets/widgets/qsplitter.h @@ -58,8 +58,8 @@ class Q_WIDGETS_EXPORT QSplitter : public QFrame Q_PROPERTY(bool childrenCollapsible READ childrenCollapsible WRITE setChildrenCollapsible) public: - explicit QSplitter(QWidget* parent = 0); - explicit QSplitter(Qt::Orientation, QWidget* parent = 0); + explicit QSplitter(QWidget* parent = Q_NULLPTR); + explicit QSplitter(Qt::Orientation, QWidget* parent = Q_NULLPTR); ~QSplitter(); void addWidget(QWidget *widget); diff --git a/src/widgets/widgets/qsplitter_p.h b/src/widgets/widgets/qsplitter_p.h index a45f776da1..890bd535ec 100644 --- a/src/widgets/widgets/qsplitter_p.h +++ b/src/widgets/widgets/qsplitter_p.h @@ -76,6 +76,7 @@ class QSplitterPrivate : public QFramePrivate public: QSplitterPrivate() : rubberBand(0), opaque(true), firstShow(true), childrenCollapsible(true), compatMode(false), handleWidth(-1), blockChildAdd(false), opaqueResizeSet(false) {} + ~QSplitterPrivate(); QPointer<QRubberBand> rubberBand; mutable QList<QSplitterLayoutStruct *> list; diff --git a/src/widgets/widgets/qstackedwidget.h b/src/widgets/widgets/qstackedwidget.h index 4267d8241f..9fcdf80833 100644 --- a/src/widgets/widgets/qstackedwidget.h +++ b/src/widgets/widgets/qstackedwidget.h @@ -50,7 +50,7 @@ class Q_WIDGETS_EXPORT QStackedWidget : public QFrame Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged) Q_PROPERTY(int count READ count) public: - explicit QStackedWidget(QWidget *parent=0); + explicit QStackedWidget(QWidget *parent = Q_NULLPTR); ~QStackedWidget(); int addWidget(QWidget *w); diff --git a/src/widgets/widgets/qstatusbar.h b/src/widgets/widgets/qstatusbar.h index 42248d7958..92785aa4c4 100644 --- a/src/widgets/widgets/qstatusbar.h +++ b/src/widgets/widgets/qstatusbar.h @@ -50,7 +50,7 @@ class Q_WIDGETS_EXPORT QStatusBar: public QWidget Q_PROPERTY(bool sizeGripEnabled READ isSizeGripEnabled WRITE setSizeGripEnabled) public: - explicit QStatusBar(QWidget* parent=0); + explicit QStatusBar(QWidget *parent = Q_NULLPTR); virtual ~QStatusBar(); void addWidget(QWidget *widget, int stretch = 0); diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index f2e98474b3..7ea5455bf7 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -118,10 +118,8 @@ void QTabBarPrivate::updateMacBorderMetrics() /*! Initialize \a option with the values from the tab at \a tabIndex. This method - is useful for subclasses when they need a QStyleOptionTab, QStyleOptionTabV2, - or QStyleOptionTabV3 but don't want to fill in all the information themselves. - This function will check the version of the QStyleOptionTab and fill in the - additional values for a QStyleOptionTabV2 and QStyleOptionTabV3. + is useful for subclasses when they need a QStyleOptionTab, + but don't want to fill in all the information themselves. \sa QStyleOption::initFrom(), QTabWidget::initStyleOption() */ @@ -158,14 +156,11 @@ void QTabBar::initStyleOption(QStyleOptionTab *option, int tabIndex) const option->palette.setColor(foregroundRole(), tab.textColor); option->icon = tab.icon; - if (QStyleOptionTabV2 *optionV2 = qstyleoption_cast<QStyleOptionTabV2 *>(option)) - optionV2->iconSize = iconSize(); // Will get the default value then. + option->iconSize = iconSize(); // Will get the default value then. - if (QStyleOptionTabV3 *optionV3 = qstyleoption_cast<QStyleOptionTabV3 *>(option)) { - optionV3->leftButtonSize = tab.leftWidget ? tab.leftWidget->size() : QSize(); - optionV3->rightButtonSize = tab.rightWidget ? tab.rightWidget->size() : QSize(); - optionV3->documentMode = d->documentMode; - } + option->leftButtonSize = tab.leftWidget ? tab.leftWidget->size() : QSize(); + option->rightButtonSize = tab.rightWidget ? tab.rightWidget->size() : QSize(); + option->documentMode = d->documentMode; if (tabIndex > 0 && tabIndex - 1 == d->currentIndex) option->selectedPosition = QStyleOptionTab::PreviousIsSelected; @@ -600,7 +595,7 @@ void QTabBarPrivate::layoutTab(int index) if (!(tab.leftWidget || tab.rightWidget)) return; - QStyleOptionTabV3 opt; + QStyleOptionTab opt; q->initStyleOption(&opt, index); if (tab.leftWidget) { QRect rect = q->style()->subElementRect(QStyle::SE_TabBarTabLeftButton, &opt, q); @@ -778,7 +773,7 @@ void QTabBar::setShape(Shape shape) If true then QTabBar draws a base in relation to the styles overlab. Otherwise only the tabs are drawn. - \sa QStyle::pixelMetric(), QStyle::PM_TabBarBaseOverlap, QStyleOptionTabBarBaseV2 + \sa QStyle::pixelMetric(), QStyle::PM_TabBarBaseOverlap, QStyleOptionTabBarBase */ void QTabBar::setDrawBase(bool drawBase) @@ -857,7 +852,7 @@ int QTabBar::insertTab(int index, const QIcon& icon, const QString &text) ++d->currentIndex; if (d->closeButtonOnTabs) { - QStyleOptionTabV3 opt; + QStyleOptionTab opt; initStyleOption(&opt, index); ButtonPosition closeSide = (ButtonPosition)style()->styleHint(QStyle::SH_TabBar_CloseButtonPosition, 0, this); QAbstractButton *closeButton = new CloseButton(this); @@ -1363,7 +1358,7 @@ QSize QTabBar::tabSizeHint(int index) const //Note: this must match with the computations in QCommonStylePrivate::tabLayout Q_D(const QTabBar); if (const QTabBarPrivate::Tab *tab = d->at(index)) { - QStyleOptionTabV3 opt; + QStyleOptionTab opt; initStyleOption(&opt, index); opt.text = d->tabList.at(index).text; QSize iconSize = tab->icon.isNull() ? QSize(0, 0) : opt.iconSize; @@ -1571,7 +1566,7 @@ void QTabBar::paintEvent(QPaintEvent *) { Q_D(QTabBar); - QStyleOptionTabBarBaseV2 optTabBase; + QStyleOptionTabBarBase optTabBase; QTabBarPrivate::initStyleBaseOption(&optTabBase, this, size()); QStylePainter p(this); @@ -1593,7 +1588,7 @@ void QTabBar::paintEvent(QPaintEvent *) p.drawPrimitive(QStyle::PE_FrameTabBarBase, optTabBase); for (int i = 0; i < d->tabList.count(); ++i) { - QStyleOptionTabV3 tab; + QStyleOptionTab tab; initStyleOption(&tab, i); if (d->paintWithOffsets && d->tabList[i].dragOffset != 0) { if (vertical) { @@ -1626,7 +1621,7 @@ void QTabBar::paintEvent(QPaintEvent *) // Draw the selected tab last to get it "on top" if (selected >= 0) { - QStyleOptionTabV3 tab; + QStyleOptionTab tab; initStyleOption(&tab, selected); if (d->paintWithOffsets && d->tabList[selected].dragOffset != 0) { if (vertical) @@ -1806,7 +1801,7 @@ void QTabBar::mousePressEvent(QMouseEvent *event) d->previousPressedIndex = d->pressedIndex; #endif if (d->validIndex(d->pressedIndex)) { - QStyleOptionTabBarBaseV2 optTabBase; + QStyleOptionTabBarBase optTabBase; optTabBase.init(this); optTabBase.documentMode = d->documentMode; if (event->type() == style()->styleHint(QStyle::SH_TabBar_SelectMouseType, &optTabBase, this)) @@ -1902,7 +1897,7 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) event->ignore(); return; } - QStyleOptionTabBarBaseV2 optTabBase; + QStyleOptionTabBarBase optTabBase; optTabBase.init(this); optTabBase.documentMode = d->documentMode; } @@ -1922,7 +1917,7 @@ void QTabBarPrivate::setupMovableTab() QStylePainter p(&grabImage, q); p.initFrom(q); - QStyleOptionTabV3 tab; + QStyleOptionTab tab; q->initStyleOption(&tab, pressedIndex); tab.rect.moveTopLeft(QPoint(taboverlap, 0)); p.drawControl(QStyle::CE_TabBarTab, tab); @@ -2006,7 +2001,7 @@ void QTabBar::mouseReleaseEvent(QMouseEvent *event) int i = d->indexAtPos(event->pos()) == d->pressedIndex ? d->pressedIndex : -1; d->pressedIndex = -1; - QStyleOptionTabBarBaseV2 optTabBase; + QStyleOptionTabBarBase optTabBase; optTabBase.initFrom(this); optTabBase.documentMode = d->documentMode; if (style()->styleHint(QStyle::SH_TabBar_SelectMouseType, &optTabBase, this) == QEvent::MouseButtonRelease) diff --git a/src/widgets/widgets/qtabbar.h b/src/widgets/widgets/qtabbar.h index 6d8bdb0c86..94a83142b0 100644 --- a/src/widgets/widgets/qtabbar.h +++ b/src/widgets/widgets/qtabbar.h @@ -65,7 +65,7 @@ class Q_WIDGETS_EXPORT QTabBar: public QWidget Q_PROPERTY(bool changeCurrentOnDrag READ changeCurrentOnDrag WRITE setChangeCurrentOnDrag) public: - explicit QTabBar(QWidget* parent=0); + explicit QTabBar(QWidget *parent = Q_NULLPTR); ~QTabBar(); enum Shape { RoundedNorth, RoundedSouth, RoundedWest, RoundedEast, diff --git a/src/widgets/widgets/qtabbar_p.h b/src/widgets/widgets/qtabbar_p.h index d5a59b05ad..38a3c138cc 100644 --- a/src/widgets/widgets/qtabbar_p.h +++ b/src/widgets/widgets/qtabbar_p.h @@ -206,7 +206,7 @@ public: int previousPressedIndex; #endif // shared by tabwidget and qtabbar - static void initStyleBaseOption(QStyleOptionTabBarBaseV2 *optTabBase, QTabBar *tabbar, QSize size) + static void initStyleBaseOption(QStyleOptionTabBarBase *optTabBase, QTabBar *tabbar, QSize size) { QStyleOptionTab tabOverlap; tabOverlap.shape = tabbar->shape(); diff --git a/src/widgets/widgets/qtabwidget.cpp b/src/widgets/widgets/qtabwidget.cpp index 1edb548206..0379bad723 100644 --- a/src/widgets/widgets/qtabwidget.cpp +++ b/src/widgets/widgets/qtabwidget.cpp @@ -331,13 +331,11 @@ void QTabWidget::initStyleOption(QStyleOptionTabWidgetFrame *option) const option->tabBarSize = t; - if (QStyleOptionTabWidgetFrameV2 *tabframe = qstyleoption_cast<QStyleOptionTabWidgetFrameV2*>(option)) { - QRect tbRect = tabBar()->geometry(); - QRect selectedTabRect = tabBar()->tabRect(tabBar()->currentIndex()); - tabframe->tabBarRect = tbRect; - selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + tbRect.topLeft()); - tabframe->selectedTabRect = selectedTabRect; - } + QRect tbRect = tabBar()->geometry(); + QRect selectedTabRect = tabBar()->tabRect(tabBar()->currentIndex()); + option->tabBarRect = tbRect; + selectedTabRect.moveTopLeft(selectedTabRect.topLeft() + tbRect.topLeft()); + option->selectedTabRect = selectedTabRect; } /*! @@ -768,7 +766,7 @@ void QTabWidget::setUpLayout(bool onlyCheck) if (onlyCheck && !d->dirty) return; // nothing to do - QStyleOptionTabWidgetFrameV2 option; + QStyleOptionTabWidgetFrame option; initStyleOption(&option); // this must be done immediately, because QWidgetItem relies on it (even if !isVisible()) @@ -817,7 +815,7 @@ QSize QTabWidget::sizeHint() const { Q_D(const QTabWidget); QSize lc(0, 0), rc(0, 0); - QStyleOptionTabWidgetFrameV2 opt; + QStyleOptionTabWidgetFrame opt; initStyleOption(&opt); opt.state = QStyle::State_None; @@ -866,7 +864,7 @@ QSize QTabWidget::minimumSizeHint() const QSize sz = basicSize(d->pos == North || d->pos == South, lc, rc, s, t); - QStyleOptionTabWidgetFrameV2 opt; + QStyleOptionTabWidgetFrame opt; initStyleOption(&opt); opt.palette = palette(); opt.state = QStyle::State_None; @@ -880,7 +878,7 @@ QSize QTabWidget::minimumSizeHint() const int QTabWidget::heightForWidth(int width) const { Q_D(const QTabWidget); - QStyleOptionTabWidgetFrameV2 opt; + QStyleOptionTabWidgetFrame opt; initStyleOption(&opt); opt.state = QStyle::State_None; @@ -1226,14 +1224,14 @@ void QTabWidget::paintEvent(QPaintEvent *) if (documentMode()) { QStylePainter p(this, tabBar()); if (QWidget *w = cornerWidget(Qt::TopLeftCorner)) { - QStyleOptionTabBarBaseV2 opt; + QStyleOptionTabBarBase opt; QTabBarPrivate::initStyleBaseOption(&opt, tabBar(), w->size()); opt.rect.moveLeft(w->x() + opt.rect.x()); opt.rect.moveTop(w->y() + opt.rect.y()); p.drawPrimitive(QStyle::PE_FrameTabBarBase, opt); } if (QWidget *w = cornerWidget(Qt::TopRightCorner)) { - QStyleOptionTabBarBaseV2 opt; + QStyleOptionTabBarBase opt; QTabBarPrivate::initStyleBaseOption(&opt, tabBar(), w->size()); opt.rect.moveLeft(w->x() + opt.rect.x()); opt.rect.moveTop(w->y() + opt.rect.y()); @@ -1243,7 +1241,7 @@ void QTabWidget::paintEvent(QPaintEvent *) } QStylePainter p(this); - QStyleOptionTabWidgetFrameV2 opt; + QStyleOptionTabWidgetFrame opt; initStyleOption(&opt); opt.rect = d->panelRect; p.drawPrimitive(QStyle::PE_FrameTabWidget, opt); diff --git a/src/widgets/widgets/qtabwidget.h b/src/widgets/widgets/qtabwidget.h index 702563127d..f12d584475 100644 --- a/src/widgets/widgets/qtabwidget.h +++ b/src/widgets/widgets/qtabwidget.h @@ -62,7 +62,7 @@ class Q_WIDGETS_EXPORT QTabWidget : public QWidget Q_PROPERTY(bool tabBarAutoHide READ tabBarAutoHide WRITE setTabBarAutoHide) public: - explicit QTabWidget(QWidget *parent = 0); + explicit QTabWidget(QWidget *parent = Q_NULLPTR); ~QTabWidget(); int addTab(QWidget *widget, const QString &); diff --git a/src/widgets/widgets/qtextbrowser.cpp b/src/widgets/widgets/qtextbrowser.cpp index 9bf305a055..2c073342b0 100644 --- a/src/widgets/widgets/qtextbrowser.cpp +++ b/src/widgets/widgets/qtextbrowser.cpp @@ -139,6 +139,7 @@ public: int lastKeypadScrollValue; #endif }; +Q_DECLARE_TYPEINFO(QTextBrowserPrivate::HistoryEntry, Q_MOVABLE_TYPE); QString QTextBrowserPrivate::findFile(const QUrl &name) const { diff --git a/src/widgets/widgets/qtextbrowser.h b/src/widgets/widgets/qtextbrowser.h index 4d4d9f4880..339814e948 100644 --- a/src/widgets/widgets/qtextbrowser.h +++ b/src/widgets/widgets/qtextbrowser.h @@ -57,7 +57,7 @@ class Q_WIDGETS_EXPORT QTextBrowser : public QTextEdit Q_PROPERTY(bool openLinks READ openLinks WRITE setOpenLinks) public: - explicit QTextBrowser(QWidget* parent = 0); + explicit QTextBrowser(QWidget* parent = Q_NULLPTR); virtual ~QTextBrowser(); QUrl source() const; diff --git a/src/widgets/widgets/qtextedit.h b/src/widgets/widgets/qtextedit.h index 689f45bea9..88b7444daa 100644 --- a/src/widgets/widgets/qtextedit.h +++ b/src/widgets/widgets/qtextedit.h @@ -94,8 +94,8 @@ public: Q_DECLARE_FLAGS(AutoFormatting, AutoFormattingFlag) - explicit QTextEdit(QWidget *parent = 0); - explicit QTextEdit(const QString &text, QWidget *parent = 0); + explicit QTextEdit(QWidget *parent = Q_NULLPTR); + explicit QTextEdit(const QString &text, QWidget *parent = Q_NULLPTR); virtual ~QTextEdit(); void setDocument(QTextDocument *document); @@ -153,9 +153,9 @@ public: QTextOption::WrapMode wordWrapMode() const; void setWordWrapMode(QTextOption::WrapMode policy); - bool find(const QString &exp, QTextDocument::FindFlags options = 0); + bool find(const QString &exp, QTextDocument::FindFlags options = QTextDocument::FindFlags()); #ifndef QT_NO_REGEXP - bool find(const QRegExp &exp, QTextDocument::FindFlags options = 0); + bool find(const QRegExp &exp, QTextDocument::FindFlags options = QTextDocument::FindFlags()); #endif QString toPlainText() const; diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp index ecba6f1974..1e4a39088c 100644 --- a/src/widgets/widgets/qtoolbar.cpp +++ b/src/widgets/widgets/qtoolbar.cpp @@ -793,6 +793,82 @@ QAction *QToolBar::addAction(const QIcon &icon, const QString &text, return action; } +/*!\fn QAction *QToolBar::addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method) + + \since 5.6 + + \overload + + Creates a new action with the given \a text. This action is added to + the end of the toolbar. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a method of the \a receiver. +*/ + +/*!\fn QAction *QToolBar::addAction(const QString &text, Functor functor) + + \since 5.6 + + \overload + + Creates a new action with the given \a text. This action is added to + the end of the toolbar. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. +*/ + +/*!\fn QAction *QToolBar::addAction(const QString &text, const QObject *context, Functor functor) + + \since 5.6 + + \overload + + Creates a new action with the given \a text. This action is added to + the end of the toolbar. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. + + If \a context is destroyed, the functor will not be called. +*/ + +/*!\fn QAction *QToolBar::addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method) + + \since 5.6 + + \overload + + Creates a new action with the given \a icon and \a text. This + action is added to the end of the toolbar. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a method of the \a receiver. +*/ + +/*!\fn QAction *QToolBar::addAction(const QIcon &icon, const QString &text, Functor functor) + + \since 5.6 + + \overload + + Creates a new action with the given \a icon and \a text. This + action is added to the end of the toolbar. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. +*/ + +/*!\fn QAction *QToolBar::addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor) + + \since 5.6 + + \overload + + Creates a new action with the given \a icon and \a text. This + action is added to the end of the toolbar. The action's + \l{QAction::triggered()}{triggered()} signal is connected to the + \a functor. + + If \a context is destroyed, the functor will not be called. +*/ + /*! Adds a separator to the end of the toolbar. diff --git a/src/widgets/widgets/qtoolbar.h b/src/widgets/widgets/qtoolbar.h index f925577646..9eeb7ccd71 100644 --- a/src/widgets/widgets/qtoolbar.h +++ b/src/widgets/widgets/qtoolbar.h @@ -34,6 +34,7 @@ #ifndef QDYNAMICTOOLBAR_H #define QDYNAMICTOOLBAR_H +#include <QtWidgets/qaction.h> #include <QtWidgets/qwidget.h> QT_BEGIN_NAMESPACE @@ -68,8 +69,8 @@ class Q_WIDGETS_EXPORT QToolBar : public QWidget Q_PROPERTY(bool floatable READ isFloatable WRITE setFloatable) public: - explicit QToolBar(const QString &title, QWidget *parent = 0); - explicit QToolBar(QWidget *parent = 0); + explicit QToolBar(const QString &title, QWidget *parent = Q_NULLPTR); + explicit QToolBar(QWidget *parent = Q_NULLPTR); ~QToolBar(); void setMovable(bool movable); @@ -92,6 +93,51 @@ public: QAction *addAction(const QString &text, const QObject *receiver, const char* member); QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, const char* member); +#ifdef Q_QDOC + QAction *addAction(const QString &text, const QObject *receiver, PointerToMemberFunction method); + QAction *addAction(const QString &text, Functor functor); + QAction *addAction(const QString &text, const QObject *context, Functor functor); + QAction *addAction(const QIcon &icon, const QString &text, const QObject *receiver, PointerToMemberFunction method); + QAction *addAction(const QIcon &icon, const QString &text, Functor functor); + QAction *addAction(const QIcon &icon, const QString &text, const QObject *context, Functor functor); +#else + // addAction(QString): Connect to a QObject slot / functor or function pointer (with context) + template<class Obj, typename Func1> + inline typename QtPrivate::QEnableIf<!QtPrivate::is_same<const char*, Func1>::value + && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::Type + addAction(const QString &text, const Obj *object, Func1 slot) + { + QAction *result = addAction(text); + connect(result, &QAction::triggered, object, slot); + return result; + } + // addAction(QString): Connect to a functor or function pointer (without context) + template <typename Func1> + inline QAction *addAction(const QString &text, Func1 slot) + { + QAction *result = addAction(text); + connect(result, &QAction::triggered, slot); + return result; + } + // addAction(QString): Connect to a QObject slot / functor or function pointer (with context) + template<class Obj, typename Func1> + inline typename QtPrivate::QEnableIf<!QtPrivate::is_same<const char*, Func1>::value + && QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value, QAction *>::Type + addAction(const QIcon &actionIcon, const QString &text, const Obj *object, Func1 slot) + { + QAction *result = addAction(actionIcon, text); + connect(result, &QAction::triggered, object, slot); + return result; + } + // addAction(QIcon, QString): Connect to a functor or function pointer (without context) + template <typename Func1> + inline QAction *addAction(const QIcon &actionIcon, const QString &text, Func1 slot) + { + QAction *result = addAction(actionIcon, text); + connect(result, &QAction::triggered, slot); + return result; + } +#endif // !Q_QDOC QAction *addSeparator(); QAction *insertSeparator(QAction *before); diff --git a/src/widgets/widgets/qtoolbararealayout.cpp b/src/widgets/widgets/qtoolbararealayout.cpp index 89e3da1383..16b1115dd6 100644 --- a/src/widgets/widgets/qtoolbararealayout.cpp +++ b/src/widgets/widgets/qtoolbararealayout.cpp @@ -1129,7 +1129,7 @@ QLayoutItem *QToolBarAreaLayout::plug(const QList<int> &path) { QToolBarAreaLayoutItem *item = this->item(path); if (!item) { - qWarning() << Q_FUNC_INFO << "No item at" << path; + qWarning() << "No item at" << path; return 0; } Q_ASSERT(item->gap); diff --git a/src/widgets/widgets/qtoolbarlayout.cpp b/src/widgets/widgets/qtoolbarlayout.cpp index d478b028a6..42fd93fda2 100644 --- a/src/widgets/widgets/qtoolbarlayout.cpp +++ b/src/widgets/widgets/qtoolbarlayout.cpp @@ -153,7 +153,7 @@ void QToolBarLayout::checkUsePopupMenu() void QToolBarLayout::addItem(QLayoutItem*) { - qWarning() << "QToolBarLayout::addItem(): please use addAction() instead"; + qWarning("QToolBarLayout::addItem(): please use addAction() instead"); return; } diff --git a/src/widgets/widgets/qtoolbox.cpp b/src/widgets/widgets/qtoolbox.cpp index 32fcdc3665..beb70f1283 100644 --- a/src/widgets/widgets/qtoolbox.cpp +++ b/src/widgets/widgets/qtoolbox.cpp @@ -206,26 +206,24 @@ void QToolBoxButton::initStyleOption(QStyleOptionToolBox *option) const option->text = text(); option->icon = icon(); - if (QStyleOptionToolBoxV2 *optionV2 = qstyleoption_cast<QStyleOptionToolBoxV2 *>(option)) { - QToolBox *toolBox = static_cast<QToolBox *>(parentWidget()); // I know I'm in a tool box. - int widgetCount = toolBox->count(); - int currIndex = toolBox->currentIndex(); - if (widgetCount == 1) { - optionV2->position = QStyleOptionToolBoxV2::OnlyOneTab; - } else if (indexInPage == 0) { - optionV2->position = QStyleOptionToolBoxV2::Beginning; - } else if (indexInPage == widgetCount - 1) { - optionV2->position = QStyleOptionToolBoxV2::End; - } else { - optionV2->position = QStyleOptionToolBoxV2::Middle; - } - if (currIndex == indexInPage - 1) { - optionV2->selectedPosition = QStyleOptionToolBoxV2::PreviousIsSelected; - } else if (currIndex == indexInPage + 1) { - optionV2->selectedPosition = QStyleOptionToolBoxV2::NextIsSelected; - } else { - optionV2->selectedPosition = QStyleOptionToolBoxV2::NotAdjacent; - } + QToolBox *toolBox = static_cast<QToolBox *>(parentWidget()); // I know I'm in a tool box. + const int widgetCount = toolBox->count(); + const int currIndex = toolBox->currentIndex(); + if (widgetCount == 1) { + option->position = QStyleOptionToolBox::OnlyOneTab; + } else if (indexInPage == 0) { + option->position = QStyleOptionToolBox::Beginning; + } else if (indexInPage == widgetCount - 1) { + option->position = QStyleOptionToolBox::End; + } else { + option->position = QStyleOptionToolBox::Middle; + } + if (currIndex == indexInPage - 1) { + option->selectedPosition = QStyleOptionToolBox::PreviousIsSelected; + } else if (currIndex == indexInPage + 1) { + option->selectedPosition = QStyleOptionToolBox::NextIsSelected; + } else { + option->selectedPosition = QStyleOptionToolBox::NotAdjacent; } } @@ -233,7 +231,7 @@ void QToolBoxButton::paintEvent(QPaintEvent *) { QPainter paint(this); QPainter *p = &paint; - QStyleOptionToolBoxV2 opt; + QStyleOptionToolBox opt; initStyleOption(&opt); style()->drawControl(QStyle::CE_ToolBoxTab, &opt, p, parentWidget()); } diff --git a/src/widgets/widgets/qtoolbox.h b/src/widgets/widgets/qtoolbox.h index cff5ae09ae..42b06e205c 100644 --- a/src/widgets/widgets/qtoolbox.h +++ b/src/widgets/widgets/qtoolbox.h @@ -51,7 +51,7 @@ class Q_WIDGETS_EXPORT QToolBox : public QFrame Q_PROPERTY(int count READ count) public: - explicit QToolBox(QWidget *parent = 0, Qt::WindowFlags f = 0); + explicit QToolBox(QWidget *parent = Q_NULLPTR, Qt::WindowFlags f = Qt::WindowFlags()); ~QToolBox(); int addItem(QWidget *widget, const QString &text); diff --git a/src/widgets/widgets/qtoolbutton.h b/src/widgets/widgets/qtoolbutton.h index 69ad032324..c76f58577b 100644 --- a/src/widgets/widgets/qtoolbutton.h +++ b/src/widgets/widgets/qtoolbutton.h @@ -64,7 +64,7 @@ public: }; Q_ENUM(ToolButtonPopupMode) - explicit QToolButton(QWidget * parent=0); + explicit QToolButton(QWidget *parent = Q_NULLPTR); ~QToolButton(); QSize sizeHint() const Q_DECL_OVERRIDE; diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index 759e41a5fa..436937be72 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -189,7 +189,7 @@ void QWidgetLineControl::commitPreedit() m_preeditCursor = 0; setPreeditArea(-1, QString()); - m_textLayout.clearAdditionalFormats(); + m_textLayout.clearFormats(); updateDisplayText(/*force*/ true); #endif } @@ -557,7 +557,8 @@ void QWidgetLineControl::processInputMethodEvent(QInputMethodEvent *event) const int oldPreeditCursor = m_preeditCursor; m_preeditCursor = event->preeditString().length(); m_hideCursor = false; - QList<QTextLayout::FormatRange> formats; + QVector<QTextLayout::FormatRange> formats; + formats.reserve(event->attributes().size()); for (int i = 0; i < event->attributes().size(); ++i) { const QInputMethodEvent::Attribute &a = event->attributes().at(i); if (a.type == QInputMethodEvent::Cursor) { @@ -574,7 +575,7 @@ void QWidgetLineControl::processInputMethodEvent(QInputMethodEvent *event) } } } - m_textLayout.setAdditionalFormats(formats); + m_textLayout.setFormats(formats); updateDisplayText(/*force*/ true); if (cursorPositionChanged) emitCursorPositionChanged(); diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp index 72007ac3e8..deca002bf5 100644 --- a/src/widgets/widgets/qwidgettextcontrol.cpp +++ b/src/widgets/widgets/qwidgettextcontrol.cpp @@ -883,7 +883,8 @@ void QWidgetTextControl::setTextCursor(const QTextCursor &cursor) const bool posChanged = cursor.position() != d->cursor.position(); const QTextCursor oldSelection = d->cursor; d->cursor = cursor; - d->cursorOn = d->hasFocus && (d->interactionFlags & Qt::TextEditable); + d->cursorOn = d->hasFocus + && (d->interactionFlags & (Qt::TextSelectableByKeyboard | Qt::TextEditable)); d->_q_updateCurrentCharFormatAndSelection(); ensureCursorVisible(); d->repaintOldAndNewSelection(oldSelection); @@ -2028,7 +2029,8 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) QTextLayout *layout = block.layout(); if (isGettingInput) layout->setPreeditArea(cursor.position() - block.position(), e->preeditString()); - QList<QTextLayout::FormatRange> overrides; + QVector<QTextLayout::FormatRange> overrides; + overrides.reserve(e->attributes().size()); const int oldPreeditCursor = preeditCursor; preeditCursor = e->preeditString().length(); hideCursor = false; @@ -2048,7 +2050,7 @@ void QWidgetTextControlPrivate::inputMethodEvent(QInputMethodEvent *e) } } } - layout->setAdditionalFormats(overrides); + layout->setFormats(overrides); cursor.endEditBlock(); @@ -2138,7 +2140,7 @@ void QWidgetTextControlPrivate::focusEvent(QFocusEvent *e) #ifdef QT_KEYPAD_NAVIGATION if (!QApplication::keypadNavigationEnabled() || (hasEditFocus && (e->reason() == Qt::PopupFocusReason))) { #endif - cursorOn = (interactionFlags & Qt::TextSelectableByKeyboard); + cursorOn = (interactionFlags & (Qt::TextSelectableByKeyboard | Qt::TextEditable)); if (interactionFlags & Qt::TextEditable) { setBlinkingCursorEnabled(true); } @@ -2437,10 +2439,13 @@ QList<QTextEdit::ExtraSelection> QWidgetTextControl::extraSelections() const { Q_D(const QWidgetTextControl); QList<QTextEdit::ExtraSelection> selections; - for (int i = 0; i < d->extraSelections.count(); ++i) { + const int numExtraSelections = d->extraSelections.count(); + selections.reserve(numExtraSelections); + for (int i = 0; i < numExtraSelections; ++i) { QTextEdit::ExtraSelection sel; - sel.cursor = d->extraSelections.at(i).cursor; - sel.format = d->extraSelections.at(i).format; + const QAbstractTextDocumentLayout::Selection &sel2 = d->extraSelections.at(i); + sel.cursor = sel2.cursor; + sel.format = sel2.format; selections.append(sel); } return selections; @@ -2877,7 +2882,7 @@ void QWidgetTextControlPrivate::commitPreedit() QTextBlock block = cursor.block(); QTextLayout *layout = block.layout(); layout->setPreeditArea(-1, QString()); - layout->clearAdditionalFormats(); + layout->clearFormats(); cursor.endEditBlock(); } |