Merge remote-tracking branch 'origin/5.12' into dev

Change-Id: Ifb032dc19053481e1b0ede5c5c72540110d62567
This commit is contained in:
Qt Forward Merge Bot 2018-08-29 01:00:40 +02:00
commit e1c2183374
27 changed files with 255 additions and 51 deletions

View File

@ -1181,6 +1181,11 @@ void QCborArray::detach(qsizetype reserved)
Returns the offset of this iterator relative to \a other. Returns the offset of this iterator relative to \a other.
*/ */
uint qHash(const QCborArray &array, uint seed)
{
return qHashRange(array.begin(), array.end(), seed);
}
#if !defined(QT_NO_DEBUG_STREAM) #if !defined(QT_NO_DEBUG_STREAM)
QDebug operator<<(QDebug dbg, const QCborArray &a) QDebug operator<<(QDebug dbg, const QCborArray &a)
{ {

View File

@ -286,6 +286,8 @@ inline QCborArray QCborValueRef::toArray(const QCborArray &a) const
return concrete().toArray(a); return concrete().toArray(a);
} }
Q_CORE_EXPORT uint qHash(const QCborArray &array, uint seed = 0);
#if !defined(QT_NO_DEBUG_STREAM) #if !defined(QT_NO_DEBUG_STREAM)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborArray &a); Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborArray &a);
#endif #endif

View File

@ -1734,6 +1734,11 @@ void QCborMap::detach(qsizetype reserved)
\sa operator+=(), operator-() \sa operator+=(), operator-()
*/ */
uint qHash(const QCborMap &map, uint seed)
{
return qHashRange(map.begin(), map.end(), seed);
}
#if !defined(QT_NO_DEBUG_STREAM) #if !defined(QT_NO_DEBUG_STREAM)
QDebug operator<<(QDebug dbg, const QCborMap &m) QDebug operator<<(QDebug dbg, const QCborMap &m)
{ {

View File

@ -337,6 +337,8 @@ inline QCborMap QCborValueRef::toMap(const QCborMap &m) const
return concrete().toMap(m); return concrete().toMap(m);
} }
Q_CORE_EXPORT uint qHash(const QCborMap &map, uint seed = 0);
#if !defined(QT_NO_DEBUG_STREAM) #if !defined(QT_NO_DEBUG_STREAM)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborMap &m); Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborMap &m);
#endif #endif

View File

@ -2365,6 +2365,53 @@ inline QCborMap::QCborMap(QCborContainerPrivate &dd) noexcept
{ {
} }
uint qHash(const QCborValue &value, uint seed)
{
switch (value.type()) {
case QCborValue::Integer:
return qHash(value.toInteger(), seed);
case QCborValue::ByteArray:
return qHash(value.toByteArray(), seed);
case QCborValue::String:
return qHash(value.toString(), seed);
case QCborValue::Array:
return qHash(value.toArray(), seed);
case QCborValue::Map:
return qHash(value.toMap(), seed);
case QCborValue::Tag: {
QtPrivate::QHashCombine hash;
seed = hash(seed, value.tag());
seed = hash(seed, value.taggedValue());
return seed;
}
case QCborValue::SimpleType:
break;
case QCborValue::False:
return qHash(false, seed);
case QCborValue::True:
return qHash(true, seed);
case QCborValue::Null:
return qHash(nullptr, seed);
case QCborValue::Undefined:
return seed;
case QCborValue::Double:
return qHash(value.toDouble(), seed);
case QCborValue::DateTime:
return qHash(value.toDateTime(), seed);
case QCborValue::Url:
return qHash(value.toUrl(), seed);
case QCborValue::RegularExpression:
return qHash(value.toRegularExpression(), seed);
case QCborValue::Uuid:
return qHash(value.toUuid(), seed);
case QCborValue::Invalid:
return seed;
}
Q_ASSERT(value.isSimpleType());
return qHash(value.toSimpleType(), seed);
}
#if !defined(QT_NO_DEBUG_STREAM) #if !defined(QT_NO_DEBUG_STREAM)
static QDebug debugContents(QDebug &dbg, const QCborValue &v) static QDebug debugContents(QDebug &dbg, const QCborValue &v)
{ {

View File

@ -451,6 +451,8 @@ private:
qsizetype i; qsizetype i;
}; };
Q_CORE_EXPORT uint qHash(const QCborValue &value, uint seed = 0);
#if !defined(QT_NO_DEBUG_STREAM) #if !defined(QT_NO_DEBUG_STREAM)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborValue &v); Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborValue &v);
#endif #endif

View File

@ -1237,6 +1237,10 @@ void QJsonArray::compact()
a = static_cast<QJsonPrivate::Array *>(d->header->root()); a = static_cast<QJsonPrivate::Array *>(d->header->root());
} }
uint qHash(const QJsonArray &array, uint seed)
{
return qHashRange(array.begin(), array.end(), seed);
}
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonArray &a) QDebug operator<<(QDebug dbg, const QJsonArray &a)

View File

@ -265,6 +265,8 @@ private:
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QJsonArray) Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QJsonArray)
Q_CORE_EXPORT uint qHash(const QJsonArray &array, uint seed = 0);
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonArray &); Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonArray &);
#endif #endif

View File

@ -1292,6 +1292,17 @@ void QJsonObject::setValueAt(int i, const QJsonValue &val)
insert(e->key(), val); insert(e->key(), val);
} }
uint qHash(const QJsonObject &object, uint seed)
{
QtPrivate::QHashCombine hash;
for (auto it = object.begin(), end = object.end(); it != end; ++it) {
const QString key = it.key();
const QJsonValue value = it.value();
seed = hash(seed, std::pair<const QString&, const QJsonValue&>(key, value));
}
return seed;
}
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonObject &o) QDebug operator<<(QDebug dbg, const QJsonObject &o)
{ {

View File

@ -262,6 +262,8 @@ private:
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QJsonObject) Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QJsonObject)
Q_CORE_EXPORT uint qHash(const QJsonObject &object, uint seed = 0);
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &); Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
#endif #endif

View File

@ -876,6 +876,28 @@ QJsonValue QJsonValueRef::toValue() const
return o->valueAt(index); return o->valueAt(index);
} }
uint qHash(const QJsonValue &value, uint seed)
{
switch (value.type()) {
case QJsonValue::Null:
return qHash(nullptr, seed);
case QJsonValue::Bool:
return qHash(value.toBool(), seed);
case QJsonValue::Double:
return qHash(value.toDouble(), seed);
case QJsonValue::String:
return qHash(value.toString(), seed);
case QJsonValue::Array:
return qHash(value.toArray(), seed);
case QJsonValue::Object:
return qHash(value.toObject(), seed);
case QJsonValue::Undefined:
return seed;
}
Q_UNREACHABLE();
return 0;
}
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
QDebug operator<<(QDebug dbg, const QJsonValue &o) QDebug operator<<(QDebug dbg, const QJsonValue &o)
{ {

View File

@ -247,6 +247,8 @@ public:
Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QJsonValue) Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QJsonValue)
Q_CORE_EXPORT uint qHash(const QJsonValue &value, uint seed = 0);
#if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY) #if !defined(QT_NO_DEBUG_STREAM) && !defined(QT_JSON_READONLY)
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &); Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
#endif #endif

View File

@ -104,6 +104,11 @@ Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(const QBitArray &key, uint seed =
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(QLatin1String key, uint seed = 0) Q_DECL_NOTHROW; Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qHash(QLatin1String key, uint seed = 0) Q_DECL_NOTHROW;
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(QStringView key, uint chained = 0) Q_DECL_NOTHROW; Q_CORE_EXPORT Q_DECL_PURE_FUNCTION uint qt_hash(QStringView key, uint chained = 0) Q_DECL_NOTHROW;
Q_DECL_CONST_FUNCTION inline uint qHash(std::nullptr_t, uint seed = 0) Q_DECL_NOTHROW
{
return qHash(reinterpret_cast<quintptr>(nullptr), seed);
}
template <class T> inline uint qHash(const T *key, uint seed = 0) Q_DECL_NOTHROW template <class T> inline uint qHash(const T *key, uint seed = 0) Q_DECL_NOTHROW
{ {
return qHash(reinterpret_cast<quintptr>(key), seed); return qHash(reinterpret_cast<quintptr>(key), seed);

View File

@ -799,9 +799,9 @@ enum PlatformFieldValue {
PlatformId_Microsoft = 3 PlatformId_Microsoft = 3
}; };
FontNames qt_getCanonicalFontNames(const uchar *table, quint32 bytes) QFontNames qt_getCanonicalFontNames(const uchar *table, quint32 bytes)
{ {
FontNames out; QFontNames out;
const int NameRecordSize = 12; const int NameRecordSize = 12;
const int MS_LangIdEnglish = 0x009; const int MS_LangIdEnglish = 0x009;
@ -947,7 +947,7 @@ QString qt_getEnglishName(const QString &familyName, bool includeStyle)
goto error; goto error;
{ {
const FontNames names = qt_getCanonicalFontNames(table, bytes); const QFontNames names = qt_getCanonicalFontNames(table, bytes);
i18n_name = names.name; i18n_name = names.name;
if (includeStyle) if (includeStyle)
i18n_name += QLatin1Char(' ') + names.style; i18n_name += QLatin1Char(' ') + names.style;
@ -963,9 +963,9 @@ error:
} }
// Note this duplicates parts of qt_getEnglishName, we should try to unify the two functions. // Note this duplicates parts of qt_getEnglishName, we should try to unify the two functions.
FontNames qt_getCanonicalFontNames(const LOGFONT &lf) QFontNames qt_getCanonicalFontNames(const LOGFONT &lf)
{ {
FontNames fontNames; QFontNames fontNames;
HDC hdc = GetDC(0); HDC hdc = GetDC(0);
HFONT hfont = CreateFontIndirect(&lf); HFONT hfont = CreateFontIndirect(&lf);
@ -1054,7 +1054,7 @@ static bool addFontToDatabase(QString familyName,
QString subFamilyStyle; QString subFamilyStyle;
if (ttf) { if (ttf) {
// Look-up names registered in the font // Look-up names registered in the font
FontNames canonicalNames = qt_getCanonicalFontNames(logFont); QFontNames canonicalNames = qt_getCanonicalFontNames(logFont);
if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty()) if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty())
englishName = canonicalNames.name; englishName = canonicalNames.name;
if (!canonicalNames.preferredName.isEmpty()) { if (!canonicalNames.preferredName.isEmpty()) {
@ -1488,7 +1488,7 @@ static void getFontTable(const uchar *fileBegin, const uchar *data, quint32 tag,
} }
static void getFamiliesAndSignatures(const QByteArray &fontData, static void getFamiliesAndSignatures(const QByteArray &fontData,
QList<FontNames> *families, QList<QFontNames> *families,
QVector<FONTSIGNATURE> *signatures) QVector<FONTSIGNATURE> *signatures)
{ {
const uchar *data = reinterpret_cast<const uchar *>(fontData.constData()); const uchar *data = reinterpret_cast<const uchar *>(fontData.constData());
@ -1504,7 +1504,7 @@ static void getFamiliesAndSignatures(const QByteArray &fontData,
getFontTable(data, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length); getFontTable(data, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length);
if (!table) if (!table)
continue; continue;
FontNames names = qt_getCanonicalFontNames(table, length); QFontNames names = qt_getCanonicalFontNames(table, length);
if (names.name.isEmpty()) if (names.name.isEmpty())
continue; continue;
@ -1535,7 +1535,7 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData,
WinApplicationFont font; WinApplicationFont font;
font.fileName = fileName; font.fileName = fileName;
QVector<FONTSIGNATURE> signatures; QVector<FONTSIGNATURE> signatures;
QList<FontNames> families; QList<QFontNames> families;
QStringList familyNames; QStringList familyNames;
if (!fontData.isEmpty()) { if (!fontData.isEmpty()) {

View File

@ -210,7 +210,7 @@ static bool addFontToDatabase(QString familyName,
QString subFamilyStyle; QString subFamilyStyle;
if (ttf) { if (ttf) {
// Look-up names registered in the font // Look-up names registered in the font
FontNames canonicalNames = qt_getCanonicalFontNames(logFont); QFontNames canonicalNames = qt_getCanonicalFontNames(logFont);
if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty()) if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty())
englishName = canonicalNames.name; englishName = canonicalNames.name;
if (!canonicalNames.preferredName.isEmpty()) { if (!canonicalNames.preferredName.isEmpty()) {

View File

@ -168,7 +168,8 @@ inline quint16 qt_getUShort(const unsigned char *p)
return val; return val;
} }
struct FontNames { struct QFontNames
{
QString name; // e.g. "DejaVu Sans Condensed" QString name; // e.g. "DejaVu Sans Condensed"
QString style; // e.g. "Italic" QString style; // e.g. "Italic"
QString preferredName; // e.g. "DejaVu Sans" QString preferredName; // e.g. "DejaVu Sans"
@ -177,7 +178,7 @@ struct FontNames {
bool qt_localizedName(const QString &name); bool qt_localizedName(const QString &name);
QString qt_getEnglishName(const QString &familyName, bool includeStyle = false); QString qt_getEnglishName(const QString &familyName, bool includeStyle = false);
FontNames qt_getCanonicalFontNames(const LOGFONT &lf); QFontNames qt_getCanonicalFontNames(const LOGFONT &lf);
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -197,6 +197,7 @@ void QWindowsUser32DLL::init()
enableMouseInPointer = (EnableMouseInPointer)library.resolve("EnableMouseInPointer"); enableMouseInPointer = (EnableMouseInPointer)library.resolve("EnableMouseInPointer");
getPointerType = (GetPointerType)library.resolve("GetPointerType"); getPointerType = (GetPointerType)library.resolve("GetPointerType");
getPointerInfo = (GetPointerInfo)library.resolve("GetPointerInfo"); getPointerInfo = (GetPointerInfo)library.resolve("GetPointerInfo");
getPointerDeviceRects = (GetPointerDeviceRects)library.resolve("GetPointerDeviceRects");
getPointerTouchInfo = (GetPointerTouchInfo)library.resolve("GetPointerTouchInfo"); getPointerTouchInfo = (GetPointerTouchInfo)library.resolve("GetPointerTouchInfo");
getPointerFrameTouchInfo = (GetPointerFrameTouchInfo)library.resolve("GetPointerFrameTouchInfo"); getPointerFrameTouchInfo = (GetPointerFrameTouchInfo)library.resolve("GetPointerFrameTouchInfo");
getPointerPenInfo = (GetPointerPenInfo)library.resolve("GetPointerPenInfo"); getPointerPenInfo = (GetPointerPenInfo)library.resolve("GetPointerPenInfo");
@ -212,7 +213,8 @@ void QWindowsUser32DLL::init()
bool QWindowsUser32DLL::supportsPointerApi() bool QWindowsUser32DLL::supportsPointerApi()
{ {
return enableMouseInPointer && getPointerType && getPointerInfo && getPointerTouchInfo && getPointerFrameTouchInfo && getPointerPenInfo; return enableMouseInPointer && getPointerType && getPointerInfo && getPointerDeviceRects
&& getPointerTouchInfo && getPointerFrameTouchInfo && getPointerPenInfo;
} }
void QWindowsShcoreDLL::init() void QWindowsShcoreDLL::init()

View File

@ -89,6 +89,7 @@ struct QWindowsUser32DLL
typedef BOOL (WINAPI *EnableMouseInPointer)(BOOL); typedef BOOL (WINAPI *EnableMouseInPointer)(BOOL);
typedef BOOL (WINAPI *GetPointerType)(UINT32, PVOID); typedef BOOL (WINAPI *GetPointerType)(UINT32, PVOID);
typedef BOOL (WINAPI *GetPointerInfo)(UINT32, PVOID); typedef BOOL (WINAPI *GetPointerInfo)(UINT32, PVOID);
typedef BOOL (WINAPI *GetPointerDeviceRects)(HANDLE, RECT *, RECT *);
typedef BOOL (WINAPI *GetPointerTouchInfo)(UINT32, PVOID); typedef BOOL (WINAPI *GetPointerTouchInfo)(UINT32, PVOID);
typedef BOOL (WINAPI *GetPointerFrameTouchInfo)(UINT32, UINT32 *, PVOID); typedef BOOL (WINAPI *GetPointerFrameTouchInfo)(UINT32, UINT32 *, PVOID);
typedef BOOL (WINAPI *GetPointerPenInfo)(UINT32, PVOID); typedef BOOL (WINAPI *GetPointerPenInfo)(UINT32, PVOID);
@ -105,6 +106,7 @@ struct QWindowsUser32DLL
EnableMouseInPointer enableMouseInPointer = nullptr; EnableMouseInPointer enableMouseInPointer = nullptr;
GetPointerType getPointerType = nullptr; GetPointerType getPointerType = nullptr;
GetPointerInfo getPointerInfo = nullptr; GetPointerInfo getPointerInfo = nullptr;
GetPointerDeviceRects getPointerDeviceRects = nullptr;
GetPointerTouchInfo getPointerTouchInfo = nullptr; GetPointerTouchInfo getPointerTouchInfo = nullptr;
GetPointerFrameTouchInfo getPointerFrameTouchInfo = nullptr; GetPointerFrameTouchInfo getPointerFrameTouchInfo = nullptr;
GetPointerPenInfo getPointerPenInfo = nullptr; GetPointerPenInfo getPointerPenInfo = nullptr;

View File

@ -428,9 +428,18 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
return false; // Let DefWindowProc() handle Non Client messages. return false; // Let DefWindowProc() handle Non Client messages.
POINTER_PEN_INFO *penInfo = static_cast<POINTER_PEN_INFO *>(vPenInfo); POINTER_PEN_INFO *penInfo = static_cast<POINTER_PEN_INFO *>(vPenInfo);
RECT pRect, dRect;
if (!QWindowsContext::user32dll.getPointerDeviceRects(penInfo->pointerInfo.sourceDevice, &pRect, &dRect))
return false;
const quint32 pointerId = penInfo->pointerInfo.pointerId; const quint32 pointerId = penInfo->pointerInfo.pointerId;
const QPoint globalPos = QPoint(penInfo->pointerInfo.ptPixelLocation.x, penInfo->pointerInfo.ptPixelLocation.y); const QPoint globalPos = QPoint(penInfo->pointerInfo.ptPixelLocation.x, penInfo->pointerInfo.ptPixelLocation.y);
const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos); const QPoint localPos = QWindowsGeometryHint::mapFromGlobal(hwnd, globalPos);
const QPointF hiResGlobalPos = QPointF(dRect.left + qreal(penInfo->pointerInfo.ptHimetricLocation.x - pRect.left)
/ (pRect.right - pRect.left) * (dRect.right - dRect.left),
dRect.top + qreal(penInfo->pointerInfo.ptHimetricLocation.y - pRect.top)
/ (pRect.bottom - pRect.top) * (dRect.bottom - dRect.top));
const qreal pressure = (penInfo->penMask & PEN_MASK_PRESSURE) ? qreal(penInfo->pressure) / 1024.0 : 0.5; const qreal pressure = (penInfo->penMask & PEN_MASK_PRESSURE) ? qreal(penInfo->pressure) / 1024.0 : 0.5;
const qreal rotation = (penInfo->penMask & PEN_MASK_ROTATION) ? qreal(penInfo->rotation) : 0.0; const qreal rotation = (penInfo->penMask & PEN_MASK_ROTATION) ? qreal(penInfo->rotation) : 0.0;
const qreal tangentialPressure = 0.0; const qreal tangentialPressure = 0.0;
@ -438,6 +447,13 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
const int yTilt = (penInfo->penMask & PEN_MASK_TILT_Y) ? penInfo->tiltY : 0; const int yTilt = (penInfo->penMask & PEN_MASK_TILT_Y) ? penInfo->tiltY : 0;
const int z = 0; const int z = 0;
if (QWindowsContext::verbose > 1)
qCDebug(lcQpaEvents).noquote().nospace() << showbase
<< __FUNCTION__ << " pointerId=" << pointerId
<< " globalPos=" << globalPos << " localPos=" << localPos << " hiResGlobalPos=" << hiResGlobalPos
<< " message=" << hex << msg.message
<< " flags=" << hex << penInfo->pointerInfo.pointerFlags;
const QTabletEvent::TabletDevice device = QTabletEvent::Stylus; const QTabletEvent::TabletDevice device = QTabletEvent::Stylus;
QTabletEvent::PointerType type; QTabletEvent::PointerType type;
Qt::MouseButtons mouseButtons; Qt::MouseButtons mouseButtons;
@ -491,16 +507,18 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
} }
const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers(); const Qt::KeyboardModifiers keyModifiers = QWindowsKeyMapper::queryKeyboardModifiers();
QWindowSystemInterface::handleTabletEvent(target, localPos, globalPos, device, type, mouseButtons, QWindowSystemInterface::handleTabletEvent(target, localPos, hiResGlobalPos, device, type, mouseButtons,
pressure, xTilt, yTilt, tangentialPressure, rotation, z, pressure, xTilt, yTilt, tangentialPressure, rotation, z,
pointerId, keyModifiers); pointerId, keyModifiers);
QEvent::Type eventType; if (!(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) {
Qt::MouseButton button; QEvent::Type eventType;
getMouseEventInfo(msg.message, penInfo->pointerInfo.ButtonChangeType, globalPos, &eventType, &button); Qt::MouseButton button;
getMouseEventInfo(msg.message, penInfo->pointerInfo.ButtonChangeType, globalPos, &eventType, &button);
QWindowSystemInterface::handleMouseEvent(target, localPos, globalPos, mouseButtons, button, eventType, QWindowSystemInterface::handleMouseEvent(target, localPos, globalPos, mouseButtons, button, eventType,
keyModifiers, Qt::MouseEventSynthesizedByQt); keyModifiers, Qt::MouseEventSynthesizedByQt);
}
break; break;
} }
} }

View File

@ -1779,39 +1779,26 @@ static void draw_text_item_win(const QPointF &pos, const QTextItemInt &ti, HDC h
QTransform matrix = QTransform::fromTranslate(baseline_pos.x(), baseline_pos.y()); QTransform matrix = QTransform::fromTranslate(baseline_pos.x(), baseline_pos.y());
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags,
_glyphs, positions); _glyphs, positions);
if (_glyphs.size() == 0) { if (_glyphs.isEmpty()) {
SelectObject(hdc, old_font); SelectObject(hdc, old_font);
return; return;
} }
bool outputEntireItem = _glyphs.size() > 0; options |= ETO_PDY;
QVarLengthArray<INT> glyphDistances(_glyphs.size() * 2);
if (outputEntireItem) { QVarLengthArray<wchar_t> g(_glyphs.size());
options |= ETO_PDY; const int lastGlyph = _glyphs.size() - 1;
QVarLengthArray<INT> glyphDistances(_glyphs.size() * 2); for (int i = 0; i < lastGlyph; ++i) {
QVarLengthArray<wchar_t> g(_glyphs.size()); glyphDistances[i * 2] = qRound(positions[i + 1].x) - qRound(positions[i].x);
for (int i=0; i<_glyphs.size() - 1; ++i) { glyphDistances[i * 2 + 1] = qRound(positions[i + 1].y) - qRound(positions[i].y);
glyphDistances[i * 2] = qRound(positions[i + 1].x) - qRound(positions[i].x); g[i] = _glyphs[i];
glyphDistances[i * 2 + 1] = qRound(positions[i + 1].y) - qRound(positions[i].y);
g[i] = _glyphs[i];
}
glyphDistances[(_glyphs.size() - 1) * 2] = 0;
glyphDistances[(_glyphs.size() - 1) * 2 + 1] = 0;
g[_glyphs.size() - 1] = _glyphs[_glyphs.size() - 1];
ExtTextOut(hdc, qRound(positions[0].x), qRound(positions[0].y), options, 0,
g.constData(), _glyphs.size(),
glyphDistances.data());
} else {
int i = 0;
while(i < _glyphs.size()) {
wchar_t g = _glyphs[i];
ExtTextOut(hdc, qRound(positions[i].x),
qRound(positions[i].y), options, 0,
&g, 1, 0);
++i;
}
} }
glyphDistances[lastGlyph * 2] = 0;
glyphDistances[lastGlyph * 2 + 1] = 0;
g[lastGlyph] = _glyphs[lastGlyph];
ExtTextOut(hdc, qRound(positions[0].x), qRound(positions[0].y), options, nullptr,
g.constData(), _glyphs.size(),
glyphDistances.data());
} }
win_xform.eM11 = win_xform.eM22 = 1.0; win_xform.eM11 = win_xform.eM22 = 1.0;

View File

@ -942,10 +942,12 @@ void QSqlQuery::clear()
query. See the \l{QSqlQuery examples}{Detailed Description} for query. See the \l{QSqlQuery examples}{Detailed Description} for
examples. examples.
Portability note: Some databases choose to delay preparing a query Portability notes: Some databases choose to delay preparing a query
until it is executed the first time. In this case, preparing a until it is executed the first time. In this case, preparing a
syntactically wrong query succeeds, but every consecutive exec() syntactically wrong query succeeds, but every consecutive exec()
will fail. will fail.
When the database does not support named placeholders directly,
the placeholder can only contain characters in the range [a-zA-Z0-9_].
For SQLite, the query string can contain only one statement at a time. For SQLite, the query string can contain only one statement at a time.
If more than one statement is given, the function returns \c false. If more than one statement is given, the function returns \c false.

View File

@ -75,7 +75,7 @@ public:
void initColOffsets(int size); void initColOffsets(int size);
int columnInQuery(int modelColumn) const; int columnInQuery(int modelColumn) const;
mutable QSqlQuery query; mutable QSqlQuery query = { QSqlQuery(0) };
mutable QSqlError error; mutable QSqlError error;
QModelIndex bottom; QModelIndex bottom;
QSqlRecord rec; QSqlRecord rec;

View File

@ -93,7 +93,7 @@ public:
QSqlTableModel::EditStrategy strategy; QSqlTableModel::EditStrategy strategy;
bool busyInsertingRows; bool busyInsertingRows;
QSqlQuery editQuery; QSqlQuery editQuery = { QSqlQuery(0) };
QSqlIndex primaryIndex; QSqlIndex primaryIndex;
QString tableName; QString tableName;
QString filter; QString filter;

View File

@ -3369,7 +3369,9 @@ void QHeaderViewPrivate::setupSectionIndicator(int section, int position)
sectionIndicator->resize(w, h); sectionIndicator->resize(w, h);
#endif #endif
QPixmap pm(w, h); const qreal pixmapDevicePixelRatio = q->devicePixelRatioF();
QPixmap pm(QSize(w, h) * pixmapDevicePixelRatio);
pm.setDevicePixelRatio(pixmapDevicePixelRatio);
pm.fill(QColor(0, 0, 0, 45)); pm.fill(QColor(0, 0, 0, 45));
QRect rect(0, 0, w, h); QRect rect(0, 0, w, h);

View File

@ -2744,6 +2744,37 @@ void tst_QLocale::formattedDataSize_data()
#undef ROWQ #undef ROWQ
#undef ROWB #undef ROWB
} }
// Languages which don't use a Latin alphabet
const QLocale::DataSizeFormats iecFormat = QLocale::DataSizeIecFormat;
const QLocale::DataSizeFormats traditionalFormat = QLocale::DataSizeTraditionalFormat;
const QLocale::DataSizeFormats siFormat = QLocale::DataSizeSIFormat;
const QLocale::Language lang = QLocale::Russian;
QTest::newRow("Russian-IEC-0") << lang << 2 << iecFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B");
QTest::newRow("Russian-IEC-10") << lang << 2 << iecFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B");
// CLDR doesn't provide IEC prefixes (yet?) so they aren't getting translated
QTest::newRow("Russian-IEC-12Ki") << lang << 2 << iecFormat << 12345 << QString("12,06 KiB");
QTest::newRow("Russian-IEC-16Ki") << lang << 2 << iecFormat << 16384 << QString("16,00 KiB");
QTest::newRow("Russian-IEC-1235k") << lang << 2 << iecFormat << 1234567 << QString("1,18 MiB");
QTest::newRow("Russian-IEC-1374k") << lang << 2 << iecFormat << 1374744 << QString("1,31 MiB");
QTest::newRow("Russian-IEC-1234M") << lang << 2 << iecFormat << 1234567890 << QString("1,15 GiB");
QTest::newRow("Russian-Trad-0") << lang << 2 << traditionalFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B");
QTest::newRow("Russian-Trad-10") << lang << 2 << traditionalFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B");
QTest::newRow("Russian-Trad-12Ki") << lang << 2 << traditionalFormat << 12345 << QString("12,06 \u043A\u0411");
QTest::newRow("Russian-Trad-16Ki") << lang << 2 << traditionalFormat << 16384 << QString("16,00 \u043A\u0411");
QTest::newRow("Russian-Trad-1235k") << lang << 2 << traditionalFormat << 1234567 << QString("1,18 \u041C\u0411");
QTest::newRow("Russian-Trad-1374k") << lang << 2 << traditionalFormat << 1374744 << QString("1,31 \u041C\u0411");
QTest::newRow("Russian-Trad-1234M") << lang << 2 << traditionalFormat << 1234567890 << QString("1,15 \u0413\u0411");
QTest::newRow("Russian-Decimal-0") << lang << 2 << siFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B");
QTest::newRow("Russian-Decimal-10") << lang << 2 << siFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B");
QTest::newRow("Russian-Decimal-16Ki") << lang << 2 << siFormat << 16384 << QString("16,38 \u043A\u0411");
QTest::newRow("Russian-Decimal-1234k") << lang << 2 << siFormat << 1234567 << QString("1,23 \u041C\u0411");
QTest::newRow("Russian-Decimal-1374k") << lang << 2 << siFormat << 1374744 << QString("1,37 \u041C\u0411");
QTest::newRow("Russian-Decimal-1234M") << lang << 2 << siFormat << 1234567890 << QString("1,23 \u0413\u0411");
} }
void tst_QLocale::formattedDataSize() void tst_QLocale::formattedDataSize()

View File

@ -1,5 +1,6 @@
[] []
rhel-7.4 rhel-7.4
ubuntu-18.04
[customGesture] [customGesture]
# QTBUG-67254 # QTBUG-67254
ubuntu ubuntu

View File

@ -31,11 +31,29 @@
#include "../../kernel/qsqldatabase/tst_databases.h" #include "../../kernel/qsqldatabase/tst_databases.h"
#include <QtSql> #include <QtSql>
#include <QtSql/private/qsqltablemodel_p.h> #include <QtSql/private/qsqltablemodel_p.h>
#include <QThread>
const QString test(qTableName("test", __FILE__, QSqlDatabase())), const QString test(qTableName("test", __FILE__, QSqlDatabase())),
test2(qTableName("test2", __FILE__, QSqlDatabase())), test2(qTableName("test2", __FILE__, QSqlDatabase())),
test3(qTableName("test3", __FILE__, QSqlDatabase())); test3(qTableName("test3", __FILE__, QSqlDatabase()));
// In order to catch when the warning message occurs, indicating that the database belongs to another
// thread, we have to install our own message handler. To ensure that the test reporting still happens
// as before, we call the originating one.
//
// For now, this is only called inside the modelInAnotherThread() test
QtMessageHandler oldHandler = nullptr;
void sqlTableModelMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
if (type == QtWarningMsg &&
msg == "QSqlDatabasePrivate::database: requested database does not "
"belong to the calling thread.") {
QFAIL("Requested database does not belong to the calling thread.");
}
if (oldHandler)
oldHandler(type, context, msg);
}
class tst_QSqlTableModel : public QObject class tst_QSqlTableModel : public QObject
{ {
@ -116,6 +134,7 @@ private slots:
void sqlite_bigTable_data() { generic_data("QSQLITE"); } void sqlite_bigTable_data() { generic_data("QSQLITE"); }
void sqlite_bigTable(); void sqlite_bigTable();
void modelInAnotherThread();
// bug specific tests // bug specific tests
void insertRecordBeforeSelect_data() { generic_data(); } void insertRecordBeforeSelect_data() { generic_data(); }
@ -276,6 +295,10 @@ void tst_QSqlTableModel::init()
void tst_QSqlTableModel::cleanup() void tst_QSqlTableModel::cleanup()
{ {
recreateTestTables(); recreateTestTables();
if (oldHandler) {
qInstallMessageHandler(oldHandler);
oldHandler = nullptr;
}
} }
void tst_QSqlTableModel::select() void tst_QSqlTableModel::select()
@ -2100,5 +2123,29 @@ void tst_QSqlTableModel::invalidFilterAndHeaderData()
QVERIFY(!v.isValid()); QVERIFY(!v.isValid());
} }
class SqlThread : public QThread
{
public:
SqlThread() : QThread() {}
void run()
{
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", "non-default-connection");
QSqlTableModel stm(nullptr, db);
isDone = true;
}
bool isDone = false;
};
void tst_QSqlTableModel::modelInAnotherThread()
{
oldHandler = qInstallMessageHandler(sqlTableModelMessageHandler);
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
CHECK_DATABASE(db);
SqlThread t;
t.start();
QTRY_VERIFY(t.isDone);
QVERIFY(t.isFinished());
}
QTEST_MAIN(tst_QSqlTableModel) QTEST_MAIN(tst_QSqlTableModel)
#include "tst_qsqltablemodel.moc" #include "tst_qsqltablemodel.moc"