summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-05-12 07:31:50 +0200
committerLiang Qi <liang.qi@qt.io>2016-05-12 08:33:08 +0200
commit990969655c5fb4d03682e96df9b12101f5ee9815 (patch)
treeb8fb5c50285105c8bc5a938fb50f93ff9f24889d /src/widgets
parenta213011a53f12f101d08a04afc8fdacd2d54a232 (diff)
parente64b2234e829cc47872225debcf80d6c06db18f0 (diff)
Merge remote-tracking branch 'origin/5.7' into dev
Conflicts: config_help.txt configure src/corelib/io/qprocess_wince.cpp src/plugins/platforms/windows/qwindowstheme.cpp src/plugins/platforms/xcb/qxcbbackingstore.cpp tests/auto/corelib/tools/qtimezone/BLACKLIST tests/auto/network/socket/qudpsocket/tst_qudpsocket.cpp tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp Change-Id: I26644d1cb3b78412c8ff285e2a55bea1bd641c01
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/dialogs/qfiledialog.cpp2
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.cpp8
-rw-r--r--src/widgets/dialogs/qfilesystemmodel.h1
-rw-r--r--src/widgets/dialogs/qmessagebox.cpp13
-rw-r--r--src/widgets/itemviews/qheaderview.cpp116
-rw-r--r--src/widgets/kernel/qapplication.cpp6
-rw-r--r--src/widgets/kernel/qmacgesturerecognizer.cpp3
-rw-r--r--src/widgets/kernel/qwidget.cpp7
-rw-r--r--src/widgets/styles/qandroidstyle.cpp29
-rw-r--r--src/widgets/styles/qcommonstyle.cpp4
-rw-r--r--src/widgets/styles/qfusionstyle.cpp18
-rw-r--r--src/widgets/styles/qstyle.cpp4
-rw-r--r--src/widgets/styles/qwindowsvistastyle.cpp73
-rw-r--r--src/widgets/styles/qwindowsvistastyle_p_p.h8
-rw-r--r--src/widgets/styles/qwindowsxpstyle.cpp70
-rw-r--r--src/widgets/styles/qwindowsxpstyle_p_p.h7
-rw-r--r--src/widgets/widgets/qabstractscrollarea.cpp2
-rw-r--r--src/widgets/widgets/qabstractslider.cpp5
-rw-r--r--src/widgets/widgets/qabstractspinbox_p.h1
-rw-r--r--src/widgets/widgets/qcombobox.cpp2
-rw-r--r--src/widgets/widgets/qdatetimeedit_p.h15
-rw-r--r--src/widgets/widgets/qlineedit.cpp18
-rw-r--r--src/widgets/widgets/qplaintextedit.cpp9
-rw-r--r--src/widgets/widgets/qsplitter.cpp6
-rw-r--r--src/widgets/widgets/qtabbar.cpp3
-rw-r--r--src/widgets/widgets/qtextedit.cpp9
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol.cpp51
-rw-r--r--src/widgets/widgets/qwidgetlinecontrol_p.h8
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp33
-rw-r--r--src/widgets/widgets/qwidgettextcontrol_p_p.h3
30 files changed, 324 insertions, 210 deletions
diff --git a/src/widgets/dialogs/qfiledialog.cpp b/src/widgets/dialogs/qfiledialog.cpp
index 5357cf28f7..e5f11e78da 100644
--- a/src/widgets/dialogs/qfiledialog.cpp
+++ b/src/widgets/dialogs/qfiledialog.cpp
@@ -3588,7 +3588,7 @@ void QFileDialogPrivate::_q_enterDirectory(const QModelIndex &index)
}
} else {
// Do not accept when shift-clicking to multi-select a file in environments with single-click-activation (KDE)
- if (!q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick)
+ if (!q->style()->styleHint(QStyle::SH_ItemView_ActivateItemOnSingleClick, Q_NULLPTR, qFileDialogUi->treeView)
|| q->fileMode() != QFileDialog::ExistingFiles || !(QGuiApplication::keyboardModifiers() & Qt::CTRL)) {
q->accept();
}
diff --git a/src/widgets/dialogs/qfilesystemmodel.cpp b/src/widgets/dialogs/qfilesystemmodel.cpp
index 2f7edd8d07..1d07c31476 100644
--- a/src/widgets/dialogs/qfilesystemmodel.cpp
+++ b/src/widgets/dialogs/qfilesystemmodel.cpp
@@ -867,9 +867,11 @@ bool QFileSystemModel::setData(const QModelIndex &idx, const QVariant &value, in
if (newName == idx.data().toString())
return true;
+ const QString parentPath = filePath(parent(idx));
+
if (newName.isEmpty()
|| QDir::toNativeSeparators(newName).contains(QDir::separator())
- || !QDir(filePath(parent(idx))).rename(oldName, newName)) {
+ || !QDir(parentPath).rename(oldName, newName)) {
#ifndef QT_NO_MESSAGEBOX
QMessageBox::information(0, QFileSystemModel::tr("Invalid filename"),
QFileSystemModel::tr("<b>The name \"%1\" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks.")
@@ -896,7 +898,7 @@ bool QFileSystemModel::setData(const QModelIndex &idx, const QVariant &value, in
parentNode->visibleChildren.removeAt(visibleLocation);
QFileSystemModelPrivate::QFileSystemNode * oldValue = parentNode->children.value(oldName);
parentNode->children[newName] = oldValue;
- QFileInfo info(d->rootDir, newName);
+ QFileInfo info(parentPath, newName);
oldValue->fileName = newName;
oldValue->parent = parentNode;
#ifndef QT_NO_FILESYSTEMWATCHER
@@ -908,7 +910,7 @@ bool QFileSystemModel::setData(const QModelIndex &idx, const QVariant &value, in
parentNode->visibleChildren.insert(visibleLocation, newName);
d->delayedSort();
- emit fileRenamed(filePath(idx.parent()), oldName, newName);
+ emit fileRenamed(parentPath, oldName, newName);
}
return true;
}
diff --git a/src/widgets/dialogs/qfilesystemmodel.h b/src/widgets/dialogs/qfilesystemmodel.h
index b7e77f31db..6d50d0b606 100644
--- a/src/widgets/dialogs/qfilesystemmodel.h
+++ b/src/widgets/dialogs/qfilesystemmodel.h
@@ -81,6 +81,7 @@ public:
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
QModelIndex index(const QString &path, int column = 0) const;
QModelIndex parent(const QModelIndex &child) const Q_DECL_OVERRIDE;
+ using QObject::parent;
QModelIndex sibling(int row, int column, const QModelIndex &idx) const Q_DECL_OVERRIDE;
bool hasChildren(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE;
bool canFetchMore(const QModelIndex &parent) const Q_DECL_OVERRIDE;
diff --git a/src/widgets/dialogs/qmessagebox.cpp b/src/widgets/dialogs/qmessagebox.cpp
index 994015030f..3c46f4faca 100644
--- a/src/widgets/dialogs/qmessagebox.cpp
+++ b/src/widgets/dialogs/qmessagebox.cpp
@@ -2605,8 +2605,17 @@ QPixmap QMessageBoxPrivate::standardIcon(QMessageBox::Icon icon, QMessageBox *mb
default:
break;
}
- if (!tmpIcon.isNull())
- return tmpIcon.pixmap(iconSize, iconSize);
+ if (!tmpIcon.isNull()) {
+ QWindow *window = Q_NULLPTR;
+ if (mb) {
+ window = mb->windowHandle();
+ if (!window) {
+ if (const QWidget *nativeParent = mb->nativeParentWidget())
+ window = nativeParent->windowHandle();
+ }
+ }
+ return tmpIcon.pixmap(window, QSize(iconSize, iconSize));
+ }
return QPixmap();
}
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index 9306b20043..7b393463a6 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -3013,30 +3013,41 @@ QRegion QHeaderView::visualRegionForSelection(const QItemSelection &selection) c
{
Q_D(const QHeaderView);
const int max = d->modelSectionCount();
- if (d->orientation == Qt::Horizontal) {
- int left = max;
- int right = 0;
- int rangeLeft, rangeRight;
- for (const auto &r : selection) {
- if (r.parent().isValid() || !r.isValid())
- continue; // we only know about toplevel items and we don't want invalid ranges
- // FIXME an item inside the range may be the leftmost or rightmost
- rangeLeft = visualIndex(r.left());
- if (rangeLeft == -1) // in some cases users may change the selections
- continue; // before we have a chance to do the layout
- rangeRight = visualIndex(r.right());
- if (rangeRight == -1) // in some cases users may change the selections
- continue; // before we have a chance to do the layout
- if (rangeLeft < left)
- left = rangeLeft;
- if (rangeRight > right)
- right = rangeRight;
+ if (d->orientation == Qt::Horizontal) {
+ int logicalLeft = max;
+ int logicalRight = 0;
+
+ if (d->visualIndices.empty()) {
+ // If no reordered sections, skip redundant visual-to-logical transformations
+ for (const auto &r : selection) {
+ if (r.parent().isValid() || !r.isValid())
+ continue; // we only know about toplevel items and we don't want invalid ranges
+ if (r.left() < logicalLeft)
+ logicalLeft = r.left();
+ if (r.right() > logicalRight)
+ logicalRight = r.right();
+ }
+ } else {
+ int left = max;
+ int right = 0;
+ for (const auto &r : selection) {
+ if (r.parent().isValid() || !r.isValid())
+ continue; // we only know about toplevel items and we don't want invalid ranges
+ for (int k = r.left(); k <= r.right(); ++k) {
+ int visual = visualIndex(k);
+ if (visual == -1) // in some cases users may change the selections
+ continue; // before we have a chance to do the layout
+ if (visual < left)
+ left = visual;
+ if (visual > right)
+ right = visual;
+ }
+ }
+ logicalLeft = logicalIndex(left);
+ logicalRight = logicalIndex(right);
}
- int logicalLeft = logicalIndex(left);
- int logicalRight = logicalIndex(right);
-
if (logicalLeft < 0 || logicalLeft >= count() ||
logicalRight < 0 || logicalRight >= count())
return QRegion();
@@ -3047,31 +3058,44 @@ QRegion QHeaderView::visualRegionForSelection(const QItemSelection &selection) c
return QRect(leftPos, 0, rightPos - leftPos, height());
}
// orientation() == Qt::Vertical
- int top = max;
- int bottom = 0;
- int rangeTop, rangeBottom;
-
- for (const auto &r : selection) {
- if (r.parent().isValid() || !r.isValid())
- continue; // we only know about toplevel items
- // FIXME an item inside the range may be the leftmost or rightmost
- rangeTop = visualIndex(r.top());
- if (rangeTop == -1) // in some cases users may change the selections
- continue; // before we have a chance to do the layout
- rangeBottom = visualIndex(r.bottom());
- if (rangeBottom == -1) // in some cases users may change the selections
- continue; // before we have a chance to do the layout
- if (rangeTop < top)
- top = rangeTop;
- if (rangeBottom > bottom)
- bottom = rangeBottom;
- }
-
- int logicalTop = logicalIndex(top);
- int logicalBottom = logicalIndex(bottom);
-
- if (logicalTop == -1 || logicalBottom == -1)
- return QRect();
+ int logicalTop = max;
+ int logicalBottom = 0;
+
+ if (d->visualIndices.empty()) {
+ // If no reordered sections, skip redundant visual-to-logical transformations
+ for (const auto &r : selection) {
+ if (r.parent().isValid() || !r.isValid())
+ continue; // we only know about toplevel items and we don't want invalid ranges
+ if (r.top() < logicalTop)
+ logicalTop = r.top();
+ if (r.bottom() > logicalBottom)
+ logicalBottom = r.bottom();
+ }
+ } else {
+ int top = max;
+ int bottom = 0;
+
+ for (const auto &r : selection) {
+ if (r.parent().isValid() || !r.isValid())
+ continue; // we only know about toplevel items and we don't want invalid ranges
+ for (int k = r.top(); k <= r.bottom(); ++k) {
+ int visual = visualIndex(k);
+ if (visual == -1) // in some cases users may change the selections
+ continue; // before we have a chance to do the layout
+ if (visual < top)
+ top = visual;
+ if (visual > bottom)
+ bottom = visual;
+ }
+ }
+
+ logicalTop = logicalIndex(top);
+ logicalBottom = logicalIndex(bottom);
+ }
+
+ if (logicalTop < 0 || logicalTop >= count() ||
+ logicalBottom < 0 || logicalBottom >= count())
+ return QRegion();
int topPos = sectionViewportPosition(logicalTop);
int bottomPos = sectionViewportPosition(logicalBottom) + sectionSize(logicalBottom);
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index a8a0968ff8..4ff466e04b 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -454,6 +454,9 @@ QDesktopWidget *qt_desktopWidget = 0; // root window widgets
*/
void QApplicationPrivate::process_cmdline()
{
+ if (styleOverride.isEmpty() && qEnvironmentVariableIsSet("QT_STYLE_OVERRIDE"))
+ styleOverride = QString::fromLocal8Bit(qgetenv("QT_STYLE_OVERRIDE"));
+
if (!styleOverride.isEmpty()) {
if (app_style) {
delete app_style;
@@ -1086,11 +1089,8 @@ QStyle *QApplication::style()
// Compile-time search for default style
//
QString style;
- QString envStyle = QString::fromLocal8Bit(qgetenv("QT_STYLE_OVERRIDE"));
if (!QApplicationPrivate::styleOverride.isEmpty()) {
style = QApplicationPrivate::styleOverride.toLower();
- } else if (!envStyle.isEmpty()) {
- style = envStyle;
} else {
style = QApplicationPrivate::desktopStyleKey();
}
diff --git a/src/widgets/kernel/qmacgesturerecognizer.cpp b/src/widgets/kernel/qmacgesturerecognizer.cpp
index 7adccb9ed3..6dedd3c2d0 100644
--- a/src/widgets/kernel/qmacgesturerecognizer.cpp
+++ b/src/widgets/kernel/qmacgesturerecognizer.cpp
@@ -121,7 +121,8 @@ QMacPinchGestureRecognizer::recognize(QGesture *gesture, QObject *obj, QEvent *e
case Qt::ZoomNativeGesture:
g->setLastScaleFactor(g->scaleFactor());
g->setLastRotationAngle(g->rotationAngle());
- g->setScaleFactor(g->scaleFactor() * (1 + ev->value()));
+ g->setScaleFactor(1 + ev->value());
+ g->setTotalScaleFactor(g->totalScaleFactor() * g->scaleFactor());
g->setChangeFlags(QPinchGesture::ScaleFactorChanged);
g->setTotalChangeFlags(g->totalChangeFlags() | g->changeFlags());
g->setHotSpot(ev->screenPos());
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 426f206480..217a075b07 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -385,6 +385,7 @@ void QWidgetPrivate::updateWidgetTransform(QEvent *event)
t.translate(p.x(), p.y());
QGuiApplication::inputMethod()->setInputItemTransform(t);
QGuiApplication::inputMethod()->setInputItemRectangle(q->rect());
+ QGuiApplication::inputMethod()->update(Qt::ImInputItemClipRectangle);
}
}
@@ -5258,7 +5259,9 @@ QPixmap QWidget::grab(const QRect &rectangle)
if (!r.intersects(rect()))
return QPixmap();
- QPixmap res(r.size());
+ const qreal dpr = devicePixelRatioF();
+ QPixmap res((QSizeF(r.size()) * dpr).toSize());
+ res.setDevicePixelRatio(dpr);
if (!d->isOpaque)
res.fill(Qt::transparent);
d->render(&res, QPoint(), QRegion(r), renderFlags);
@@ -9763,6 +9766,8 @@ QVariant QWidget::inputMethodQuery(Qt::InputMethodQuery query) const
return inputMethodQuery(Qt::ImCursorPosition);
case Qt::ImHints:
return (int)inputMethodHints();
+ case Qt::ImInputItemClipRectangle:
+ return d_func()->clipRect();
default:
return QVariant();
}
diff --git a/src/widgets/styles/qandroidstyle.cpp b/src/widgets/styles/qandroidstyle.cpp
index e59c35ed68..743166549b 100644
--- a/src/widgets/styles/qandroidstyle.cpp
+++ b/src/widgets/styles/qandroidstyle.cpp
@@ -838,7 +838,7 @@ int QAndroidStyle::Android9PatchDrawable::calculateStretch(int boundsLimit,
void QAndroidStyle::Android9PatchDrawable::extractIntArray(const QVariantList &values,
QVector<int> & array)
{
- foreach (QVariant value, values)
+ for (const QVariant &value : values)
array << value.toInt();
}
@@ -1140,8 +1140,8 @@ QAndroidStyle::AndroidStateDrawable::AndroidStateDrawable(const QVariantMap &dra
QAndroidStyle::ItemType itemType)
: AndroidDrawable(drawable, itemType)
{
- QVariantList states = drawable.value(QLatin1String("stateslist")).toList();
- foreach (QVariant stateVariant, states) {
+ const QVariantList states = drawable.value(QLatin1String("stateslist")).toList();
+ for (const QVariant &stateVariant : states) {
QVariantMap state = stateVariant.toMap();
const int s = extractState(state.value(QLatin1String("states")).toMap());
if (-1 == s)
@@ -1158,7 +1158,7 @@ QAndroidStyle::AndroidStateDrawable::AndroidStateDrawable(const QVariantMap &dra
QAndroidStyle::AndroidStateDrawable::~AndroidStateDrawable()
{
- foreach (const StateType type, m_states)
+ for (const StateType &type : qAsConst(m_states))
delete type.second;
}
@@ -1192,7 +1192,7 @@ const QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidStateDrawable::best
}
uint bestCost = 0xffff;
- foreach (const StateType & state, m_states) {
+ for (const StateType & state : m_states) {
if (int(opt->state) == state.first)
return state.second;
uint cost = 1;
@@ -1234,8 +1234,9 @@ const QAndroidStyle::AndroidDrawable * QAndroidStyle::AndroidStateDrawable::best
int QAndroidStyle::AndroidStateDrawable::extractState(const QVariantMap &value)
{
QStyle::State state = QStyle::State_Enabled | QStyle::State_Active;;
- foreach (const QString &key, value.keys()) {
- bool val = value.value(key).toString() == QLatin1String("true");
+ for (auto it = value.cbegin(), end = value.cend(); it != end; ++it) {
+ const QString &key = it.key();
+ bool val = it.value().toString() == QLatin1String("true");
if (key == QLatin1String("enabled")) {
state.setFlag(QStyle::State_Enabled, val);
continue;
@@ -1282,7 +1283,7 @@ int QAndroidStyle::AndroidStateDrawable::extractState(const QVariantMap &value)
void QAndroidStyle::AndroidStateDrawable::setPaddingLeftToSizeWidth()
{
- foreach (const StateType type, m_states)
+ for (const StateType &type : qAsConst(m_states))
const_cast<AndroidDrawable *>(type.second)->setPaddingLeftToSizeWidth();
}
@@ -1293,8 +1294,8 @@ QAndroidStyle::AndroidLayerDrawable::AndroidLayerDrawable(const QVariantMap &dra
m_id = 0;
m_factor = 1;
m_orientation = Qt::Horizontal;
- QVariantList layers = drawable.value(QLatin1String("layers")).toList();
- foreach (QVariant layer, layers) {
+ const QVariantList layers = drawable.value(QLatin1String("layers")).toList();
+ for (const QVariant &layer : layers) {
QVariantMap layerMap = layer.toMap();
AndroidDrawable *ad = fromMap(layerMap, itemType);
if (ad) {
@@ -1308,7 +1309,7 @@ QAndroidStyle::AndroidLayerDrawable::AndroidLayerDrawable(const QVariantMap &dra
QAndroidStyle::AndroidLayerDrawable::~AndroidLayerDrawable()
{
- foreach (const LayerType &layer, m_layers)
+ for (const LayerType &layer : qAsConst(m_layers))
delete layer.second;
}
@@ -1326,7 +1327,7 @@ void QAndroidStyle::AndroidLayerDrawable::setFactor(int id, double factor, Qt::O
void QAndroidStyle::AndroidLayerDrawable::draw(QPainter *painter, const QStyleOption *opt) const
{
- foreach (const LayerType &layer, m_layers) {
+ for (const LayerType &layer : m_layers) {
if (layer.first == m_id) {
QStyleOption copy(*opt);
if (m_orientation == Qt::Horizontal)
@@ -1342,7 +1343,7 @@ void QAndroidStyle::AndroidLayerDrawable::draw(QPainter *painter, const QStyleOp
QAndroidStyle::AndroidDrawable *QAndroidStyle::AndroidLayerDrawable::layer(int id) const
{
- foreach (const LayerType &layer, m_layers)
+ for (const LayerType &layer : m_layers)
if (layer.first == id)
return layer.second;
return 0;
@@ -1351,7 +1352,7 @@ QAndroidStyle::AndroidDrawable *QAndroidStyle::AndroidLayerDrawable::layer(int i
QSize QAndroidStyle::AndroidLayerDrawable::size() const
{
QSize sz;
- foreach (const LayerType &layer, m_layers)
+ for (const LayerType &layer : m_layers)
sz = sz.expandedTo(layer.second->size());
return sz;
}
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 91d4bcc7ab..6b9e5577a4 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -4985,7 +4985,11 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
break;
case SH_BlinkCursorWhenTextSelected:
+#if defined(Q_OS_DARWIN)
+ ret = 0;
+#else
ret = 1;
+#endif
break;
case SH_Table_GridLineColor:
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index a9cea0e2ab..8a768443d1 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -3414,12 +3414,28 @@ QRect QFusionStyle::subControlRect(ComplexControl control, const QStyleOptionCom
QSize textSize = option->fontMetrics.boundingRect(groupBox->text).size() + QSize(2, 2);
int indicatorWidth = proxy()->pixelMetric(PM_IndicatorWidth, option, widget);
int indicatorHeight = proxy()->pixelMetric(PM_IndicatorHeight, option, widget);
+
+ const int width = textSize.width()
+ + (option->subControls & QStyle::SC_GroupBoxCheckBox ? indicatorWidth + 5 : 0);
+
rect = QRect();
+
+ if (option->rect.width() > width) {
+ switch (groupBox->textAlignment & Qt::AlignHorizontal_Mask) {
+ case Qt::AlignHCenter:
+ rect.moveLeft((option->rect.width() - width) / 2);
+ break;
+ case Qt::AlignRight:
+ rect.moveLeft(option->rect.width() - width);
+ break;
+ }
+ }
+
if (subControl == SC_GroupBoxCheckBox) {
rect.setWidth(indicatorWidth);
rect.setHeight(indicatorHeight);
rect.moveTop(textSize.height() > indicatorHeight ? (textSize.height() - indicatorHeight) / 2 : 0);
- rect.moveLeft(1);
+ rect.translate(1, 0);
} else if (subControl == SC_GroupBoxLabel) {
rect.setSize(textSize);
rect.moveTop(1);
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 16a11e6029..d72a898ee9 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -157,10 +157,10 @@ static int unpackControlTypes(QSizePolicy::ControlTypes controls, QSizePolicy::C
Qt's built-in widgets use QStyle to perform nearly all of their
drawing, ensuring that they look exactly like the equivalent
- native widgets. The diagram below shows a QComboBox in eight
+ native widgets. The diagram below shows a QComboBox in nine
different styles.
- \image qstyle-comboboxes.png Eight combo boxes
+ \image qstyle-comboboxes.png Nine combo boxes
Topics:
diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp
index 2b2b919818..dce0a93e10 100644
--- a/src/widgets/styles/qwindowsvistastyle.cpp
+++ b/src/widgets/styles/qwindowsvistastyle.cpp
@@ -426,9 +426,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
case PE_IndicatorBranch:
{
- XPThemeData theme(widget, painter, QWindowsXPStylePrivate::TreeViewTheme);
+ XPThemeData theme(widget, painter, QWindowsXPStylePrivate::VistaTreeViewTheme);
static int decoration_size = 0;
- if (!decoration_size && d->initTreeViewTheming() && theme.isValid()) {
+ if (!decoration_size && theme.isValid()) {
XPThemeData themeSize = theme;
themeSize.partId = TVP_HOTGLYPH;
themeSize.stateId = GLPS_OPENED;
@@ -728,9 +728,9 @@ void QWindowsVistaStyle::drawPrimitive(PrimitiveElement element, const QStyleOpt
QPainter pixmapPainter(&pixmap);
XPThemeData theme(widget, &pixmapPainter,
- QWindowsXPStylePrivate::TreeViewTheme,
+ QWindowsXPStylePrivate::VistaTreeViewTheme,
LVP_LISTITEM, state, QRect(0, 0, sectionSize.width(), sectionSize.height()));
- if (d->initTreeViewTheming() && theme.isValid()) {
+ if (theme.isValid()) {
d->drawBackground(theme);
} else {
QWindowsXPStyle::drawPrimitive(PE_PanelItemViewItem, option, painter, widget);
@@ -1149,7 +1149,7 @@ void QWindowsVistaStyle::drawControl(ControlElement element, const QStyleOption
if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget))
alignment |= Qt::TextHideMnemonic;
- if (widget) { // Not needed for QtQuick Controls
+ if (widget && mbi->palette.color(QPalette::Window) != Qt::transparent) { // Not needed for QtQuick Controls
//The rect adjustment is a workaround for the menu not really filling its background.
XPThemeData theme(widget, painter,
QWindowsXPStylePrivate::MenuTheme,
@@ -2357,10 +2357,6 @@ void QWindowsVistaStyle::unpolish(QWidget *widget)
QWindowsXPStyle::unpolish(widget);
QWindowsVistaStylePrivate *d = d_func();
- // Delete the tree view helper in case the XP style cleaned the
- // theme handle map due to a theme or QStyle change (QProxyStyle).
- if (!QWindowsXPStylePrivate::hasTheme(QWindowsXPStylePrivate::TreeViewTheme))
- d->cleanupTreeViewTheming();
d->stopAnimation(widget);
@@ -2426,15 +2422,10 @@ QPixmap QWindowsVistaStyle::standardPixmap(StandardPixmap standardPixmap, const
}
QWindowsVistaStylePrivate::QWindowsVistaStylePrivate() :
- QWindowsXPStylePrivate(), m_treeViewHelper(0)
+ QWindowsXPStylePrivate()
{
}
-QWindowsVistaStylePrivate::~QWindowsVistaStylePrivate()
-{
- cleanupTreeViewTheming();
-}
-
bool QWindowsVistaStylePrivate::transitionsEnabled() const
{
BOOL animEnabled = false;
@@ -2446,58 +2437,6 @@ bool QWindowsVistaStylePrivate::transitionsEnabled() const
return false;
}
-/*
- * We need to set the windows "explorer" theme explicitly on a native
- * window and open the "TREEVIEW" theme handle passing its window handle
- * in order to get Vista-style item view themes (particulary drawBackground()
- * for selected items needs this).
- * We invoke a service of the native Windows interface to create
- * a non-visible window handle, open the theme on it and insert it into
- * the cache so that it is found by XPThemeData::handle() first.
- */
-
-static inline HWND createTreeViewHelperWindow()
-{
- if (QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface()) {
- void *hwnd = 0;
- void *wndProc = reinterpret_cast<void *>(DefWindowProc);
- if (QMetaObject::invokeMethod(ni, "createMessageWindow", Qt::DirectConnection,
- Q_RETURN_ARG(void *, hwnd),
- Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindowClass")),
- Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindow")),
- Q_ARG(void *, wndProc)) && hwnd) {
- return reinterpret_cast<HWND>(hwnd);
- }
- }
- return 0;
-}
-
-bool QWindowsVistaStylePrivate::initTreeViewTheming()
-{
- if (m_treeViewHelper)
- return true;
-
- m_treeViewHelper = createTreeViewHelperWindow();
- if (Q_UNLIKELY(!m_treeViewHelper)) {
- qWarning("Unable to create the treeview helper window.");
- return false;
- }
- const HRESULT hr = QWindowsXPStylePrivate::pSetWindowTheme(m_treeViewHelper, L"explorer", NULL);
- if (Q_UNLIKELY(hr != S_OK)) {
- qErrnoWarning("SetWindowTheme() failed.");
- return false;
- }
- return QWindowsXPStylePrivate::createTheme(QWindowsXPStylePrivate::TreeViewTheme, m_treeViewHelper);
-}
-
-void QWindowsVistaStylePrivate::cleanupTreeViewTheming()
-{
- if (m_treeViewHelper) {
- DestroyWindow(m_treeViewHelper);
- m_treeViewHelper = 0;
- }
-}
-
/*!
\reimp
*/
diff --git a/src/widgets/styles/qwindowsvistastyle_p_p.h b/src/widgets/styles/qwindowsvistastyle_p_p.h
index 7adfbb08ec..e207a27a66 100644
--- a/src/widgets/styles/qwindowsvistastyle_p_p.h
+++ b/src/widgets/styles/qwindowsvistastyle_p_p.h
@@ -168,16 +168,10 @@ class QWindowsVistaStylePrivate : public QWindowsXPStylePrivate
public:
QWindowsVistaStylePrivate();
- ~QWindowsVistaStylePrivate();
+
static int fixedPixelMetric(QStyle::PixelMetric pm);
static inline bool useVista();
bool transitionsEnabled() const;
-
-private:
- bool initTreeViewTheming();
- void cleanupTreeViewTheming();
-
- HWND m_treeViewHelper;
};
QT_END_NAMESPACE
diff --git a/src/widgets/styles/qwindowsxpstyle.cpp b/src/widgets/styles/qwindowsxpstyle.cpp
index 1f910d41cb..b39cecbd73 100644
--- a/src/widgets/styles/qwindowsxpstyle.cpp
+++ b/src/widgets/styles/qwindowsxpstyle.cpp
@@ -54,6 +54,8 @@
#include <qbackingstore.h>
#include <qapplication.h>
#include <qpixmapcache.h>
+#include <private/qapplication_p.h>
+#include <qpa/qplatformnativeinterface.h>
#include <qdesktopwidget.h>
#include <qtoolbutton.h>
@@ -163,7 +165,7 @@ static const wchar_t *themeNames[QWindowsXPStylePrivate::NThemes] =
L"BUTTON", L"COMBOBOX", L"EDIT", L"HEADER", L"LISTVIEW",
L"MENU", L"PROGRESS", L"REBAR", L"SCROLLBAR", L"SPIN",
L"TAB", L"TASKDIALOG", L"TOOLBAR", L"TOOLTIP", L"TRACKBAR",
- L"TREEVIEW", L"WINDOW", L"STATUS"
+ L"TREEVIEW", L"WINDOW", L"STATUS", L"TREEVIEW"
};
static inline QBackingStore *backingStoreForWidget(const QWidget *widget)
@@ -244,6 +246,7 @@ HRGN XPThemeData::mask(QWidget *widget)
// QWindowsXPStylePrivate -------------------------------------------------------------------------
// Static initializations
QPixmap *QWindowsXPStylePrivate::tabbody = 0;
+HWND QWindowsXPStylePrivate::m_vistaTreeViewHelper = 0;
HTHEME QWindowsXPStylePrivate::m_themes[NThemes];
bool QWindowsXPStylePrivate::use_xp = false;
QBasicAtomicInt QWindowsXPStylePrivate::ref = Q_BASIC_ATOMIC_INITIALIZER(-1); // -1 based refcounting
@@ -327,6 +330,58 @@ void QWindowsXPStylePrivate::cleanup(bool force)
tabbody = 0;
}
+/* In order to obtain the correct VistaTreeViewTheme (arrows for PE_IndicatorBranch),
+ * we need to set the windows "explorer" theme explicitly on a native
+ * window and open the "TREEVIEW" theme handle passing its window handle
+ * in order to get Vista-style item view themes (particulary drawBackground()
+ * for selected items needs this).
+ * We invoke a service of the native Windows interface to create
+ * a non-visible window handle, open the theme on it and insert it into
+ * the cache so that it is found by XPThemeData::handle() first.
+ */
+
+static inline HWND createTreeViewHelperWindow()
+{
+ if (QPlatformNativeInterface *ni = QGuiApplication::platformNativeInterface()) {
+ void *hwnd = 0;
+ void *wndProc = reinterpret_cast<void *>(DefWindowProc);
+ if (QMetaObject::invokeMethod(ni, "createMessageWindow", Qt::DirectConnection,
+ Q_RETURN_ARG(void *, hwnd),
+ Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindowClass")),
+ Q_ARG(QString, QStringLiteral("QTreeViewThemeHelperWindow")),
+ Q_ARG(void *, wndProc)) && hwnd) {
+ return reinterpret_cast<HWND>(hwnd);
+ }
+ }
+ return 0;
+}
+
+bool QWindowsXPStylePrivate::initVistaTreeViewTheming()
+{
+ if (m_vistaTreeViewHelper)
+ return true;
+
+ m_vistaTreeViewHelper = createTreeViewHelperWindow();
+ if (!m_vistaTreeViewHelper) {
+ qWarning("Unable to create the treeview helper window.");
+ return false;
+ }
+ if (FAILED(QWindowsXPStylePrivate::pSetWindowTheme(m_vistaTreeViewHelper, L"explorer", NULL))) {
+ qErrnoWarning("SetWindowTheme() failed.");
+ cleanupVistaTreeViewTheming();
+ return false;
+ }
+ return true;
+}
+
+void QWindowsXPStylePrivate::cleanupVistaTreeViewTheming()
+{
+ if (m_vistaTreeViewHelper) {
+ DestroyWindow(m_vistaTreeViewHelper);
+ m_vistaTreeViewHelper = 0;
+ }
+}
+
/* \internal
Closes all open theme data handles to ensure that we don't leak
resources, and that we don't refere to old handles when for
@@ -339,6 +394,7 @@ void QWindowsXPStylePrivate::cleanupHandleMap()
pCloseThemeData(m_themes[i]);
m_themes[i] = 0;
}
+ QWindowsXPStylePrivate::cleanupVistaTreeViewTheming();
}
HTHEME QWindowsXPStylePrivate::createTheme(int theme, HWND hwnd)
@@ -349,6 +405,8 @@ HTHEME QWindowsXPStylePrivate::createTheme(int theme, HWND hwnd)
}
if (!m_themes[theme]) {
const wchar_t *name = themeNames[theme];
+ if (theme == VistaTreeViewTheme && QWindowsXPStylePrivate::initVistaTreeViewTheming())
+ hwnd = QWindowsXPStylePrivate::m_vistaTreeViewHelper;
m_themes[theme] = pOpenThemeData(hwnd, name);
if (Q_UNLIKELY(!m_themes[theme]))
qErrnoWarning("OpenThemeData() failed for theme %d (%s).",
@@ -1952,7 +2010,7 @@ case PE_Frame:
bef_v -= delta;
aft_h += delta;
aft_v += delta;
- XPThemeData theme(0, p, QWindowsXPStylePrivate::TreeViewTheme);
+ XPThemeData theme(0, p, QWindowsXPStylePrivate::XpTreeViewTheme);
theme.rect = QRect(bef_h, bef_v, decoration_size, decoration_size);
theme.partId = TVP_GLYPH;
theme.stateId = flags & QStyle::State_Open ? GLPS_OPENED : GLPS_CLOSED;
@@ -3740,10 +3798,12 @@ QSize QWindowsXPStyle::sizeFromContents(ContentsType ct, const QStyleOption *opt
{
XPThemeData buttontheme(widget, 0, QWindowsXPStylePrivate::ButtonTheme, BP_PUSHBUTTON, PBS_NORMAL);
if (buttontheme.isValid()) {
- const QMarginsF borderSize = buttontheme.margins() / QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const qreal devicePixelRatio = QWindowsXPStylePrivate::devicePixelRatio(widget);
+ const QMarginsF borderSize = buttontheme.margins() / devicePixelRatio;
if (!borderSize.isNull()) {
- sz.rwidth() += qRound(borderSize.left() + borderSize.right() - 2);
- sz.rheight() += qRound(borderSize.bottom() + borderSize.top() - 2);
+ const qreal margin = qreal(2) / devicePixelRatio;
+ sz.rwidth() += qRound(borderSize.left() + borderSize.right() - margin);
+ sz.rheight() += int(borderSize.bottom() + borderSize.top() - margin + devicePixelRatio - 1);
}
const int textMargins = 2*(proxy()->pixelMetric(PM_FocusFrameHMargin) + 1);
sz += QSize(qMax(pixelMetric(QStyle::PM_ScrollBarExtent, option, widget)
diff --git a/src/widgets/styles/qwindowsxpstyle_p_p.h b/src/widgets/styles/qwindowsxpstyle_p_p.h
index 68aa10e12a..8ee4d1a641 100644
--- a/src/widgets/styles/qwindowsxpstyle_p_p.h
+++ b/src/widgets/styles/qwindowsxpstyle_p_p.h
@@ -356,9 +356,10 @@ public:
ToolBarTheme,
ToolTipTheme,
TrackBarTheme,
- TreeViewTheme,
+ XpTreeViewTheme, // '+'/'-' shape treeview indicators (XP)
WindowTheme,
StatusTheme,
+ VistaTreeViewTheme, // arrow shape treeview indicators (Vista) obtained from "explorer" theme.
NThemes
};
@@ -419,6 +420,9 @@ private:
void showProperties(XPThemeData &themeData);
#endif
+ static bool initVistaTreeViewTheming();
+ static void cleanupVistaTreeViewTheming();
+
static QBasicAtomicInt ref;
static bool use_xp;
static QPixmap *tabbody;
@@ -430,6 +434,7 @@ private:
uchar *bufferPixels;
int bufferW, bufferH;
+ static HWND m_vistaTreeViewHelper;
static HTHEME m_themes[NThemes];
};
diff --git a/src/widgets/widgets/qabstractscrollarea.cpp b/src/widgets/widgets/qabstractscrollarea.cpp
index 90cd6bde99..f1ede20f1f 100644
--- a/src/widgets/widgets/qabstractscrollarea.cpp
+++ b/src/widgets/widgets/qabstractscrollarea.cpp
@@ -310,7 +310,7 @@ void QAbstractScrollAreaPrivate::init()
viewportFilter.reset(new QAbstractScrollAreaFilter(this));
viewport->installEventFilter(viewportFilter.data());
viewport->setFocusProxy(q);
- q->setFocusPolicy(Qt::WheelFocus);
+ q->setFocusPolicy(Qt::StrongFocus);
q->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
q->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
layoutChildren();
diff --git a/src/widgets/widgets/qabstractslider.cpp b/src/widgets/widgets/qabstractslider.cpp
index 3f6185b4e7..4221ff40ef 100644
--- a/src/widgets/widgets/qabstractslider.cpp
+++ b/src/widgets/widgets/qabstractslider.cpp
@@ -734,9 +734,10 @@ bool QAbstractSliderPrivate::scrollByDelta(Qt::Orientation orientation, Qt::Keyb
if (stepsToScroll == 0) {
// We moved less than a line, but might still have accumulated partial scroll,
// unless we already are at one of the ends.
- if (offset_accumulated > 0.f && value < maximum)
+ const float effective_offset = invertedControls ? -offset_accumulated : offset_accumulated;
+ if (effective_offset > 0.f && value < maximum)
return true;
- if (offset_accumulated < 0.f && value > minimum)
+ if (effective_offset < 0.f && value > minimum)
return true;
offset_accumulated = 0;
return false;
diff --git a/src/widgets/widgets/qabstractspinbox_p.h b/src/widgets/widgets/qabstractspinbox_p.h
index 7ebd9db6bd..a54659ecaa 100644
--- a/src/widgets/widgets/qabstractspinbox_p.h
+++ b/src/widgets/widgets/qabstractspinbox_p.h
@@ -61,7 +61,6 @@
#include "QtCore/qdatetime.h"
#include "QtCore/qvariant.h"
#include "private/qwidget_p.h"
-#include "private/qdatetime_p.h"
QT_BEGIN_NAMESPACE
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index 7992409265..51e23ca7f9 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -3352,6 +3352,8 @@ QVariant QComboBox::inputMethodQuery(Qt::InputMethodQuery query) const
return QWidget::inputMethodQuery(query);
}
+/*!\internal
+*/
QVariant QComboBox::inputMethodQuery(Qt::InputMethodQuery query, const QVariant &argument) const
{
Q_D(const QComboBox);
diff --git a/src/widgets/widgets/qdatetimeedit_p.h b/src/widgets/widgets/qdatetimeedit_p.h
index 6abb3cd9a3..be7bc213a2 100644
--- a/src/widgets/widgets/qdatetimeedit_p.h
+++ b/src/widgets/widgets/qdatetimeedit_p.h
@@ -78,15 +78,14 @@ public:
void init(const QVariant &var);
void readLocaleSettings();
- void emitSignals(EmitPolicy ep, const QVariant &old);
- QString textFromValue(const QVariant &f) const;
- QVariant valueFromText(const QString &f) const;
-
QDateTime validateAndInterpret(QString &input, int &, QValidator::State &state,
bool fixup = false) const;
void clearSection(int index);
// Override QAbstractSpinBoxPrivate:
+ void emitSignals(EmitPolicy ep, const QVariant &old) Q_DECL_OVERRIDE;
+ QString textFromValue(const QVariant &f) const Q_DECL_OVERRIDE;
+ QVariant valueFromText(const QString &f) const Q_DECL_OVERRIDE;
void _q_editorCursorPositionChanged(int oldpos, int newpos) Q_DECL_OVERRIDE;
void interpret(EmitPolicy ep) Q_DECL_OVERRIDE;
void clearCache() const Q_DECL_OVERRIDE;
@@ -94,16 +93,18 @@ public:
void updateEditFieldGeometry() Q_DECL_OVERRIDE;
QVariant getZeroVariant() const Q_DECL_OVERRIDE;
void setRange(const QVariant &min, const QVariant &max) Q_DECL_OVERRIDE;
+ void updateEdit() Q_DECL_OVERRIDE;
- // Override QDateTimePraser:
+ // Override QDateTimeParser:
QString displayText() const Q_DECL_OVERRIDE { return edit->text(); }
QDateTime getMinimum() const Q_DECL_OVERRIDE { return minimum.toDateTime(); }
QDateTime getMaximum() const Q_DECL_OVERRIDE { return maximum.toDateTime(); }
QLocale locale() const Q_DECL_OVERRIDE { return q_func()->locale(); }
+ QString getAmPmText(AmPm ap, Case cs) const Q_DECL_OVERRIDE;
+ int cursorPosition() const Q_DECL_OVERRIDE { return edit ? edit->cursorPosition() : -1; }
int absoluteIndex(QDateTimeEdit::Section s, int index) const;
int absoluteIndex(const SectionNode &s) const;
- void updateEdit();
QDateTime stepBy(int index, int steps, bool test = false) const;
int sectionAt(int pos) const;
int closestSection(int index, bool forward) const;
@@ -114,8 +115,6 @@ public:
void updateTimeSpec();
QString valueToText(const QVariant &var) const { return textFromValue(var); }
- QString getAmPmText(AmPm ap, Case cs) const;
- int cursorPosition() const { return edit ? edit->cursorPosition() : -1; }
void _q_resetButton();
void updateArrow(QStyle::StateFlag state);
diff --git a/src/widgets/widgets/qlineedit.cpp b/src/widgets/widgets/qlineedit.cpp
index 9be20ebb74..3c9cab4e17 100644
--- a/src/widgets/widgets/qlineedit.cpp
+++ b/src/widgets/widgets/qlineedit.cpp
@@ -1421,11 +1421,11 @@ bool QLineEdit::event(QEvent * e)
d->control->processShortcutOverrideEvent(ke);
#endif
} else if (e->type() == QEvent::KeyRelease) {
- d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
+ d->control->updateCursorBlinking();
} else if (e->type() == QEvent::Show) {
//In order to get the cursor blinking if QComboBox::setEditable is called when the combobox has focus
if (hasFocus()) {
- d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
+ d->control->setBlinkingCursorEnabled(true);
QStyleOptionFrame opt;
initStyleOption(&opt);
if ((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
@@ -1442,10 +1442,10 @@ bool QLineEdit::event(QEvent * e)
if (e->type() == QEvent::EnterEditFocus) {
end(false);
d->setCursorVisible(true);
- d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
+ d->control->setCursorBlinkEnabled(true);
} else if (e->type() == QEvent::LeaveEditFocus) {
d->setCursorVisible(false);
- d->control->setCursorBlinkPeriod(0);
+ d->control->setCursorBlinkEnabled(false);
if (d->control->hasAcceptableInput() || d->control->fixup())
emit editingFinished();
}
@@ -1692,7 +1692,7 @@ void QLineEdit::keyPressEvent(QKeyEvent *event)
if (event->isAccepted()) {
if (layoutDirection() != d->control->layoutDirection())
setLayoutDirection(d->control->layoutDirection());
- d->control->setCursorBlinkPeriod(0);
+ d->control->updateCursorBlinking();
}
}
@@ -1743,12 +1743,14 @@ void QLineEdit::inputMethodEvent(QInputMethodEvent *e)
#endif
}
+/*!\reimp
+*/
QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property) const
{
return inputMethodQuery(property, QVariant());
}
-/*!\reimp
+/*!\internal
*/
QVariant QLineEdit::inputMethodQuery(Qt::InputMethodQuery property, QVariant argument) const
{
@@ -1802,7 +1804,7 @@ void QLineEdit::focusInEvent(QFocusEvent *e)
#ifdef QT_KEYPAD_NAVIGATION
if (!QApplication::keypadNavigationEnabled() || (hasEditFocus() && ( e->reason() == Qt::PopupFocusReason))) {
#endif
- d->control->setCursorBlinkPeriod(QApplication::cursorFlashTime());
+ d->control->setBlinkingCursorEnabled(true);
QStyleOptionFrame opt;
initStyleOption(&opt);
if((!hasSelectedText() && d->control->preeditAreaText().isEmpty())
@@ -1846,7 +1848,7 @@ void QLineEdit::focusOutEvent(QFocusEvent *e)
deselect();
d->setCursorVisible(false);
- d->control->setCursorBlinkPeriod(0);
+ d->control->setBlinkingCursorEnabled(false);
#ifdef QT_KEYPAD_NAVIGATION
// editingFinished() is already emitted on LeaveEditFocus
if (!QApplication::keypadNavigationEnabled())
diff --git a/src/widgets/widgets/qplaintextedit.cpp b/src/widgets/widgets/qplaintextedit.cpp
index 1da8028efb..27f1b16f60 100644
--- a/src/widgets/widgets/qplaintextedit.cpp
+++ b/src/widgets/widgets/qplaintextedit.cpp
@@ -802,7 +802,7 @@ void QPlainTextEditPrivate::init(const QString &txt)
viewport->setBackgroundRole(QPalette::Base);
q->setAcceptDrops(true);
- q->setFocusPolicy(Qt::WheelFocus);
+ q->setFocusPolicy(Qt::StrongFocus);
q->setAttribute(Qt::WA_KeyCompression);
q->setAttribute(Qt::WA_InputMethodEnabled);
q->setInputMethodHints(Qt::ImhMultiLine);
@@ -2198,8 +2198,13 @@ QVariant QPlainTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
QVariant QPlainTextEdit::inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const
{
Q_D(const QPlainTextEdit);
- if (query == Qt::ImHints)
+ switch (query) {
+ case Qt::ImHints:
+ case Qt::ImInputItemClipRectangle:
return QWidget::inputMethodQuery(query);
+ default:
+ break;
+ }
const QPointF offset = contentOffset();
switch (argument.type()) {
diff --git a/src/widgets/widgets/qsplitter.cpp b/src/widgets/widgets/qsplitter.cpp
index 3f1fa2d015..910904e96e 100644
--- a/src/widgets/widgets/qsplitter.cpp
+++ b/src/widgets/widgets/qsplitter.cpp
@@ -1096,6 +1096,8 @@ void QSplitter::resizeEvent(QResizeEvent *)
If \a widget is already in the splitter, it will be moved to the new position.
+ \note The splitter takes ownership of the widget.
+
\sa insertWidget(), widget(), indexOf()
*/
void QSplitter::addWidget(QWidget *widget)
@@ -1110,7 +1112,9 @@ void QSplitter::addWidget(QWidget *widget)
If \a widget is already in the splitter, it will be moved to the new position.
- if \a index is an invalid index, then the widget will be inserted at the end.
+ If \a index is an invalid index, then the widget will be inserted at the end.
+
+ \note The splitter takes ownership of the widget.
\sa addWidget(), indexOf(), widget()
*/
diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp
index 9cc44007bd..8c808f98cb 100644
--- a/src/widgets/widgets/qtabbar.cpp
+++ b/src/widgets/widgets/qtabbar.cpp
@@ -971,6 +971,9 @@ void QTabBar::removeTab(int index)
{
Q_D(QTabBar);
if (d->validIndex(index)) {
+ if (d->dragInProgress)
+ d->moveTabFinished(d->pressedIndex);
+
#ifndef QT_NO_SHORTCUT
releaseShortcut(d->tabList.at(index).shortcutId);
#endif
diff --git a/src/widgets/widgets/qtextedit.cpp b/src/widgets/widgets/qtextedit.cpp
index a81781bd4d..af6d13a647 100644
--- a/src/widgets/widgets/qtextedit.cpp
+++ b/src/widgets/widgets/qtextedit.cpp
@@ -177,7 +177,7 @@ void QTextEditPrivate::init(const QString &html)
viewport->setBackgroundRole(QPalette::Base);
q->setAcceptDrops(true);
- q->setFocusPolicy(Qt::WheelFocus);
+ q->setFocusPolicy(Qt::StrongFocus);
q->setAttribute(Qt::WA_KeyCompression);
q->setAttribute(Qt::WA_InputMethodEnabled);
q->setInputMethodHints(Qt::ImhMultiLine);
@@ -1728,8 +1728,13 @@ QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery property) const
QVariant QTextEdit::inputMethodQuery(Qt::InputMethodQuery query, QVariant argument) const
{
Q_D(const QTextEdit);
- if (query == Qt::ImHints)
+ switch (query) {
+ case Qt::ImHints:
+ case Qt::ImInputItemClipRectangle:
return QWidget::inputMethodQuery(query);
+ default:
+ break;
+ }
const QPointF offset(-d->horizontalOffset(), -d->verticalOffset());
switch (argument.type()) {
diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp
index 24edca172b..86903dc0c3 100644
--- a/src/widgets/widgets/qwidgetlinecontrol.cpp
+++ b/src/widgets/widgets/qwidgetlinecontrol.cpp
@@ -636,7 +636,7 @@ void QWidgetLineControl::draw(QPainter *painter, const QPoint &offset, const QRe
o.format.setForeground(m_palette.brush(QPalette::HighlightedText));
} else {
// mask selection
- if(!m_blinkPeriod || m_blinkStatus){
+ if (m_blinkStatus){
o.start = m_cursor;
o.length = 1;
o.format.setBackground(m_palette.brush(QPalette::Text));
@@ -653,7 +653,7 @@ void QWidgetLineControl::draw(QPainter *painter, const QPoint &offset, const QRe
int cursor = m_cursor;
if (m_preeditCursor != -1)
cursor += m_preeditCursor;
- if (!m_hideCursor && (!m_blinkPeriod || m_blinkStatus))
+ if (!m_hideCursor && m_blinkStatus)
textLayout()->drawCursor(painter, offset, cursor, m_cursorWidth);
}
}
@@ -1486,38 +1486,55 @@ void QWidgetLineControl::complete(int key)
void QWidgetLineControl::setReadOnly(bool enable)
{
+ if (m_readOnly == enable)
+ return;
+
m_readOnly = enable;
+ updateCursorBlinking();
+}
+
+void QWidgetLineControl::setBlinkingCursorEnabled(bool enable)
+{
+ if (m_blinkEnabled == enable)
+ return;
+
+ m_blinkEnabled = enable;
+
if (enable)
- setCursorBlinkPeriod(0);
+ connect(qApp->styleHints(), &QStyleHints::cursorFlashTimeChanged, this, &QWidgetLineControl::updateCursorBlinking);
else
- setCursorBlinkPeriod(QApplication::cursorFlashTime());
+ disconnect(qApp->styleHints(), &QStyleHints::cursorFlashTimeChanged, this, &QWidgetLineControl::updateCursorBlinking);
+
+ updateCursorBlinking();
}
-void QWidgetLineControl::setCursorBlinkPeriod(int msec)
+void QWidgetLineControl::updateCursorBlinking()
{
- if (msec == m_blinkPeriod)
- return;
if (m_blinkTimer) {
killTimer(m_blinkTimer);
- }
- if (msec > 0 && !m_readOnly) {
- m_blinkTimer = startTimer(msec / 2);
- m_blinkStatus = 1;
- } else {
m_blinkTimer = 0;
- if (m_blinkStatus == 1)
- emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
}
- m_blinkPeriod = msec;
+
+ if (m_blinkEnabled && !m_readOnly) {
+ int flashTime = QGuiApplication::styleHints()->cursorFlashTime();
+ if (flashTime >= 2)
+ m_blinkTimer = startTimer(flashTime / 2);
+ }
+
+ m_blinkStatus = 1;
+ emit updateNeeded(inputMask().isEmpty() ? cursorRect() : QRect());
}
// This is still used by QDeclarativeTextInput in the qtquick1 repo
void QWidgetLineControl::resetCursorBlinkTimer()
{
- if (m_blinkPeriod == 0 || m_blinkTimer == 0)
+ if (!m_blinkEnabled || m_blinkTimer == 0)
return;
killTimer(m_blinkTimer);
- m_blinkTimer = startTimer(m_blinkPeriod / 2);
+ m_blinkTimer = 0;
+ int flashTime = QGuiApplication::styleHints()->cursorFlashTime();
+ if (flashTime >= 2)
+ m_blinkTimer = startTimer(flashTime / 2);
m_blinkStatus = 1;
}
diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h
index 8b723b0224..34d19d1e77 100644
--- a/src/widgets/widgets/qwidgetlinecontrol_p.h
+++ b/src/widgets/widgets/qwidgetlinecontrol_p.h
@@ -83,7 +83,7 @@ public:
: m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LayoutDirectionAuto),
m_hideCursor(false), m_separator(0), m_readOnly(0),
m_dragEnabled(0), m_echoMode(0), m_textDirty(0), m_selDirty(0),
- m_validInput(1), m_blinkStatus(0), m_blinkPeriod(0), m_blinkTimer(0), m_deleteAllTimer(0),
+ m_validInput(1), m_blinkStatus(0), m_blinkEnabled(false), m_blinkTimer(0), m_deleteAllTimer(0),
m_ascent(0), m_maxLength(32767), m_lastCursorPos(-1),
m_tripleClickTimer(0), m_maskData(0), m_modifiedState(0), m_undoState(0),
m_selstart(0), m_selend(0), m_passwordEchoEditing(false)
@@ -354,8 +354,8 @@ public:
void processInputMethodEvent(QInputMethodEvent *event);
void processKeyEvent(QKeyEvent* ev);
- int cursorBlinkPeriod() const { return m_blinkPeriod; }
- void setCursorBlinkPeriod(int msec);
+ void setBlinkingCursorEnabled(bool enable);
+ void updateCursorBlinking();
void resetCursorBlinkTimer();
bool cursorBlinkStatus() const { return m_blinkStatus; }
@@ -433,7 +433,7 @@ private:
uint m_selDirty : 1;
uint m_validInput : 1;
uint m_blinkStatus : 1;
- int m_blinkPeriod; // 0 for non-blinking cursor
+ uint m_blinkEnabled : 1;
int m_blinkTimer;
int m_deleteAllTimer;
int m_ascent;
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index cc1726c362..77b5a4830b 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -112,7 +112,7 @@ static QTextLine currentTextLine(const QTextCursor &cursor)
}
QWidgetTextControlPrivate::QWidgetTextControlPrivate()
- : doc(0), cursorOn(false), cursorIsFocusIndicator(false),
+ : doc(0), cursorOn(false), cursorVisible(false), cursorIsFocusIndicator(false),
#ifndef Q_OS_ANDROID
interactionFlags(Qt::TextEditorInteraction),
#else
@@ -685,17 +685,30 @@ void QWidgetTextControlPrivate::_q_documentLayoutChanged()
}
-void QWidgetTextControlPrivate::setBlinkingCursorEnabled(bool enable)
+void QWidgetTextControlPrivate::setCursorVisible(bool visible)
{
- Q_Q(QWidgetTextControl);
+ if (cursorVisible == visible)
+ return;
- if (enable && QApplication::cursorFlashTime() > 0)
- cursorBlinkTimer.start(QApplication::cursorFlashTime() / 2, q);
+ cursorVisible = visible;
+ updateCursorBlinking();
+
+ if (cursorVisible)
+ connect(qApp->styleHints(), &QStyleHints::cursorFlashTimeChanged, this, &QWidgetTextControlPrivate::updateCursorBlinking);
else
- cursorBlinkTimer.stop();
+ disconnect(qApp->styleHints(), &QStyleHints::cursorFlashTimeChanged, this, &QWidgetTextControlPrivate::updateCursorBlinking);
+}
- cursorOn = enable;
+void QWidgetTextControlPrivate::updateCursorBlinking()
+{
+ cursorBlinkTimer.stop();
+ if (cursorVisible) {
+ int flashTime = QGuiApplication::styleHints()->cursorFlashTime();
+ if (flashTime >= 2)
+ cursorBlinkTimer.start(flashTime / 2, q_func());
+ }
+ cursorOn = cursorVisible;
repaintCursor();
}
@@ -2156,13 +2169,13 @@ void QWidgetTextControlPrivate::focusEvent(QFocusEvent *e)
#endif
cursorOn = (interactionFlags & (Qt::TextSelectableByKeyboard | Qt::TextEditable));
if (interactionFlags & Qt::TextEditable) {
- setBlinkingCursorEnabled(true);
+ setCursorVisible(true);
}
#ifdef QT_KEYPAD_NAVIGATION
}
#endif
} else {
- setBlinkingCursorEnabled(false);
+ setCursorVisible(false);
if (cursorIsFocusIndicator
&& e->reason() != Qt::ActiveWindowFocusReason
@@ -2971,7 +2984,7 @@ void QWidgetTextControl::setTextInteractionFlags(Qt::TextInteractionFlags flags)
d->interactionFlags = flags;
if (d->hasFocus)
- d->setBlinkingCursorEnabled(flags & Qt::TextEditable);
+ d->setCursorVisible(flags & Qt::TextEditable);
}
Qt::TextInteractionFlags QWidgetTextControl::textInteractionFlags() const
diff --git a/src/widgets/widgets/qwidgettextcontrol_p_p.h b/src/widgets/widgets/qwidgettextcontrol_p_p.h
index 4feebdd9ef..fea72d98ff 100644
--- a/src/widgets/widgets/qwidgettextcontrol_p_p.h
+++ b/src/widgets/widgets/qwidgettextcontrol_p_p.h
@@ -111,7 +111,9 @@ public:
void _q_emitCursorPosChanged(const QTextCursor &someCursor);
void _q_contentsChanged(int from, int charsRemoved, int charsAdded);
+ void setCursorVisible(bool visible);
void setBlinkingCursorEnabled(bool enable);
+ void updateCursorBlinking();
void extendWordwiseSelection(int suggestedNewPosition, qreal mouseXPosition);
void extendBlockwiseSelection(int suggestedNewPosition);
@@ -175,6 +177,7 @@ public:
QTextDocument *doc;
bool cursorOn;
+ bool cursorVisible;
QTextCursor cursor;
bool cursorIsFocusIndicator;
QTextCharFormat lastCharFormat;