Merge remote-tracking branch 'origin/5.12' into dev
Change-Id: Ifb032dc19053481e1b0ede5c5c72540110d62567
This commit is contained in:
commit
e1c2183374
@ -1181,6 +1181,11 @@ void QCborArray::detach(qsizetype reserved)
|
||||
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)
|
||||
QDebug operator<<(QDebug dbg, const QCborArray &a)
|
||||
{
|
||||
|
@ -286,6 +286,8 @@ inline QCborArray QCborValueRef::toArray(const QCborArray &a) const
|
||||
return concrete().toArray(a);
|
||||
}
|
||||
|
||||
Q_CORE_EXPORT uint qHash(const QCborArray &array, uint seed = 0);
|
||||
|
||||
#if !defined(QT_NO_DEBUG_STREAM)
|
||||
Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborArray &a);
|
||||
#endif
|
||||
|
@ -1734,6 +1734,11 @@ void QCborMap::detach(qsizetype reserved)
|
||||
\sa operator+=(), operator-()
|
||||
*/
|
||||
|
||||
uint qHash(const QCborMap &map, uint seed)
|
||||
{
|
||||
return qHashRange(map.begin(), map.end(), seed);
|
||||
}
|
||||
|
||||
#if !defined(QT_NO_DEBUG_STREAM)
|
||||
QDebug operator<<(QDebug dbg, const QCborMap &m)
|
||||
{
|
||||
|
@ -337,6 +337,8 @@ inline QCborMap QCborValueRef::toMap(const QCborMap &m) const
|
||||
return concrete().toMap(m);
|
||||
}
|
||||
|
||||
Q_CORE_EXPORT uint qHash(const QCborMap &map, uint seed = 0);
|
||||
|
||||
#if !defined(QT_NO_DEBUG_STREAM)
|
||||
Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborMap &m);
|
||||
#endif
|
||||
|
@ -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)
|
||||
static QDebug debugContents(QDebug &dbg, const QCborValue &v)
|
||||
{
|
||||
|
@ -451,6 +451,8 @@ private:
|
||||
qsizetype i;
|
||||
};
|
||||
|
||||
Q_CORE_EXPORT uint qHash(const QCborValue &value, uint seed = 0);
|
||||
|
||||
#if !defined(QT_NO_DEBUG_STREAM)
|
||||
Q_CORE_EXPORT QDebug operator<<(QDebug, const QCborValue &v);
|
||||
#endif
|
||||
|
@ -1237,6 +1237,10 @@ void QJsonArray::compact()
|
||||
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)
|
||||
QDebug operator<<(QDebug dbg, const QJsonArray &a)
|
||||
|
@ -265,6 +265,8 @@ private:
|
||||
|
||||
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)
|
||||
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonArray &);
|
||||
#endif
|
||||
|
@ -1292,6 +1292,17 @@ void QJsonObject::setValueAt(int i, const QJsonValue &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)
|
||||
QDebug operator<<(QDebug dbg, const QJsonObject &o)
|
||||
{
|
||||
|
@ -262,6 +262,8 @@ private:
|
||||
|
||||
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)
|
||||
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonObject &);
|
||||
#endif
|
||||
|
@ -876,6 +876,28 @@ QJsonValue QJsonValueRef::toValue() const
|
||||
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)
|
||||
QDebug operator<<(QDebug dbg, const QJsonValue &o)
|
||||
{
|
||||
|
@ -247,6 +247,8 @@ public:
|
||||
|
||||
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)
|
||||
Q_CORE_EXPORT QDebug operator<<(QDebug, const QJsonValue &);
|
||||
#endif
|
||||
|
@ -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 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
|
||||
{
|
||||
return qHash(reinterpret_cast<quintptr>(key), seed);
|
||||
|
@ -799,9 +799,9 @@ enum PlatformFieldValue {
|
||||
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 MS_LangIdEnglish = 0x009;
|
||||
|
||||
@ -947,7 +947,7 @@ QString qt_getEnglishName(const QString &familyName, bool includeStyle)
|
||||
goto error;
|
||||
|
||||
{
|
||||
const FontNames names = qt_getCanonicalFontNames(table, bytes);
|
||||
const QFontNames names = qt_getCanonicalFontNames(table, bytes);
|
||||
i18n_name = names.name;
|
||||
if (includeStyle)
|
||||
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.
|
||||
FontNames qt_getCanonicalFontNames(const LOGFONT &lf)
|
||||
QFontNames qt_getCanonicalFontNames(const LOGFONT &lf)
|
||||
{
|
||||
FontNames fontNames;
|
||||
QFontNames fontNames;
|
||||
HDC hdc = GetDC(0);
|
||||
HFONT hfont = CreateFontIndirect(&lf);
|
||||
|
||||
@ -1054,7 +1054,7 @@ static bool addFontToDatabase(QString familyName,
|
||||
QString subFamilyStyle;
|
||||
if (ttf) {
|
||||
// Look-up names registered in the font
|
||||
FontNames canonicalNames = qt_getCanonicalFontNames(logFont);
|
||||
QFontNames canonicalNames = qt_getCanonicalFontNames(logFont);
|
||||
if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty())
|
||||
englishName = canonicalNames.name;
|
||||
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,
|
||||
QList<FontNames> *families,
|
||||
QList<QFontNames> *families,
|
||||
QVector<FONTSIGNATURE> *signatures)
|
||||
{
|
||||
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);
|
||||
if (!table)
|
||||
continue;
|
||||
FontNames names = qt_getCanonicalFontNames(table, length);
|
||||
QFontNames names = qt_getCanonicalFontNames(table, length);
|
||||
if (names.name.isEmpty())
|
||||
continue;
|
||||
|
||||
@ -1535,7 +1535,7 @@ QStringList QWindowsFontDatabase::addApplicationFont(const QByteArray &fontData,
|
||||
WinApplicationFont font;
|
||||
font.fileName = fileName;
|
||||
QVector<FONTSIGNATURE> signatures;
|
||||
QList<FontNames> families;
|
||||
QList<QFontNames> families;
|
||||
QStringList familyNames;
|
||||
|
||||
if (!fontData.isEmpty()) {
|
||||
|
@ -210,7 +210,7 @@ static bool addFontToDatabase(QString familyName,
|
||||
QString subFamilyStyle;
|
||||
if (ttf) {
|
||||
// Look-up names registered in the font
|
||||
FontNames canonicalNames = qt_getCanonicalFontNames(logFont);
|
||||
QFontNames canonicalNames = qt_getCanonicalFontNames(logFont);
|
||||
if (qt_localizedName(familyName) && !canonicalNames.name.isEmpty())
|
||||
englishName = canonicalNames.name;
|
||||
if (!canonicalNames.preferredName.isEmpty()) {
|
||||
|
@ -168,7 +168,8 @@ inline quint16 qt_getUShort(const unsigned char *p)
|
||||
return val;
|
||||
}
|
||||
|
||||
struct FontNames {
|
||||
struct QFontNames
|
||||
{
|
||||
QString name; // e.g. "DejaVu Sans Condensed"
|
||||
QString style; // e.g. "Italic"
|
||||
QString preferredName; // e.g. "DejaVu Sans"
|
||||
@ -177,7 +178,7 @@ struct FontNames {
|
||||
|
||||
bool qt_localizedName(const QString &name);
|
||||
QString qt_getEnglishName(const QString &familyName, bool includeStyle = false);
|
||||
FontNames qt_getCanonicalFontNames(const LOGFONT &lf);
|
||||
QFontNames qt_getCanonicalFontNames(const LOGFONT &lf);
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
|
@ -197,6 +197,7 @@ void QWindowsUser32DLL::init()
|
||||
enableMouseInPointer = (EnableMouseInPointer)library.resolve("EnableMouseInPointer");
|
||||
getPointerType = (GetPointerType)library.resolve("GetPointerType");
|
||||
getPointerInfo = (GetPointerInfo)library.resolve("GetPointerInfo");
|
||||
getPointerDeviceRects = (GetPointerDeviceRects)library.resolve("GetPointerDeviceRects");
|
||||
getPointerTouchInfo = (GetPointerTouchInfo)library.resolve("GetPointerTouchInfo");
|
||||
getPointerFrameTouchInfo = (GetPointerFrameTouchInfo)library.resolve("GetPointerFrameTouchInfo");
|
||||
getPointerPenInfo = (GetPointerPenInfo)library.resolve("GetPointerPenInfo");
|
||||
@ -212,7 +213,8 @@ void QWindowsUser32DLL::init()
|
||||
|
||||
bool QWindowsUser32DLL::supportsPointerApi()
|
||||
{
|
||||
return enableMouseInPointer && getPointerType && getPointerInfo && getPointerTouchInfo && getPointerFrameTouchInfo && getPointerPenInfo;
|
||||
return enableMouseInPointer && getPointerType && getPointerInfo && getPointerDeviceRects
|
||||
&& getPointerTouchInfo && getPointerFrameTouchInfo && getPointerPenInfo;
|
||||
}
|
||||
|
||||
void QWindowsShcoreDLL::init()
|
||||
|
@ -89,6 +89,7 @@ struct QWindowsUser32DLL
|
||||
typedef BOOL (WINAPI *EnableMouseInPointer)(BOOL);
|
||||
typedef BOOL (WINAPI *GetPointerType)(UINT32, PVOID);
|
||||
typedef BOOL (WINAPI *GetPointerInfo)(UINT32, PVOID);
|
||||
typedef BOOL (WINAPI *GetPointerDeviceRects)(HANDLE, RECT *, RECT *);
|
||||
typedef BOOL (WINAPI *GetPointerTouchInfo)(UINT32, PVOID);
|
||||
typedef BOOL (WINAPI *GetPointerFrameTouchInfo)(UINT32, UINT32 *, PVOID);
|
||||
typedef BOOL (WINAPI *GetPointerPenInfo)(UINT32, PVOID);
|
||||
@ -105,6 +106,7 @@ struct QWindowsUser32DLL
|
||||
EnableMouseInPointer enableMouseInPointer = nullptr;
|
||||
GetPointerType getPointerType = nullptr;
|
||||
GetPointerInfo getPointerInfo = nullptr;
|
||||
GetPointerDeviceRects getPointerDeviceRects = nullptr;
|
||||
GetPointerTouchInfo getPointerTouchInfo = nullptr;
|
||||
GetPointerFrameTouchInfo getPointerFrameTouchInfo = nullptr;
|
||||
GetPointerPenInfo getPointerPenInfo = nullptr;
|
||||
|
@ -428,9 +428,18 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
||||
return false; // Let DefWindowProc() handle Non Client messages.
|
||||
|
||||
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 QPoint globalPos = QPoint(penInfo->pointerInfo.ptPixelLocation.x, penInfo->pointerInfo.ptPixelLocation.y);
|
||||
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 rotation = (penInfo->penMask & PEN_MASK_ROTATION) ? qreal(penInfo->rotation) : 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 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;
|
||||
QTabletEvent::PointerType type;
|
||||
Qt::MouseButtons mouseButtons;
|
||||
@ -491,16 +507,18 @@ bool QWindowsPointerHandler::translatePenEvent(QWindow *window, HWND hwnd, QtWin
|
||||
}
|
||||
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,
|
||||
pointerId, keyModifiers);
|
||||
|
||||
QEvent::Type eventType;
|
||||
Qt::MouseButton button;
|
||||
getMouseEventInfo(msg.message, penInfo->pointerInfo.ButtonChangeType, globalPos, &eventType, &button);
|
||||
if (!(QWindowsIntegration::instance()->options() & QWindowsIntegration::DontPassOsMouseEventsSynthesizedFromTouch)) {
|
||||
QEvent::Type eventType;
|
||||
Qt::MouseButton button;
|
||||
getMouseEventInfo(msg.message, penInfo->pointerInfo.ButtonChangeType, globalPos, &eventType, &button);
|
||||
|
||||
QWindowSystemInterface::handleMouseEvent(target, localPos, globalPos, mouseButtons, button, eventType,
|
||||
keyModifiers, Qt::MouseEventSynthesizedByQt);
|
||||
QWindowSystemInterface::handleMouseEvent(target, localPos, globalPos, mouseButtons, button, eventType,
|
||||
keyModifiers, Qt::MouseEventSynthesizedByQt);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags,
|
||||
_glyphs, positions);
|
||||
if (_glyphs.size() == 0) {
|
||||
if (_glyphs.isEmpty()) {
|
||||
SelectObject(hdc, old_font);
|
||||
return;
|
||||
}
|
||||
|
||||
bool outputEntireItem = _glyphs.size() > 0;
|
||||
|
||||
if (outputEntireItem) {
|
||||
options |= ETO_PDY;
|
||||
QVarLengthArray<INT> glyphDistances(_glyphs.size() * 2);
|
||||
QVarLengthArray<wchar_t> g(_glyphs.size());
|
||||
for (int i=0; i<_glyphs.size() - 1; ++i) {
|
||||
glyphDistances[i * 2] = qRound(positions[i + 1].x) - qRound(positions[i].x);
|
||||
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;
|
||||
}
|
||||
options |= ETO_PDY;
|
||||
QVarLengthArray<INT> glyphDistances(_glyphs.size() * 2);
|
||||
QVarLengthArray<wchar_t> g(_glyphs.size());
|
||||
const int lastGlyph = _glyphs.size() - 1;
|
||||
for (int i = 0; i < lastGlyph; ++i) {
|
||||
glyphDistances[i * 2] = qRound(positions[i + 1].x) - qRound(positions[i].x);
|
||||
glyphDistances[i * 2 + 1] = qRound(positions[i + 1].y) - qRound(positions[i].y);
|
||||
g[i] = _glyphs[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;
|
||||
|
@ -942,10 +942,12 @@ void QSqlQuery::clear()
|
||||
query. See the \l{QSqlQuery examples}{Detailed Description} for
|
||||
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
|
||||
syntactically wrong query succeeds, but every consecutive exec()
|
||||
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.
|
||||
If more than one statement is given, the function returns \c false.
|
||||
|
@ -75,7 +75,7 @@ public:
|
||||
void initColOffsets(int size);
|
||||
int columnInQuery(int modelColumn) const;
|
||||
|
||||
mutable QSqlQuery query;
|
||||
mutable QSqlQuery query = { QSqlQuery(0) };
|
||||
mutable QSqlError error;
|
||||
QModelIndex bottom;
|
||||
QSqlRecord rec;
|
||||
|
@ -93,7 +93,7 @@ public:
|
||||
QSqlTableModel::EditStrategy strategy;
|
||||
bool busyInsertingRows;
|
||||
|
||||
QSqlQuery editQuery;
|
||||
QSqlQuery editQuery = { QSqlQuery(0) };
|
||||
QSqlIndex primaryIndex;
|
||||
QString tableName;
|
||||
QString filter;
|
||||
|
@ -3369,7 +3369,9 @@ void QHeaderViewPrivate::setupSectionIndicator(int section, int position)
|
||||
sectionIndicator->resize(w, h);
|
||||
#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));
|
||||
QRect rect(0, 0, w, h);
|
||||
|
||||
|
@ -2744,6 +2744,37 @@ void tst_QLocale::formattedDataSize_data()
|
||||
#undef ROWQ
|
||||
#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()
|
||||
|
@ -1,5 +1,6 @@
|
||||
[]
|
||||
rhel-7.4
|
||||
ubuntu-18.04
|
||||
[customGesture]
|
||||
# QTBUG-67254
|
||||
ubuntu
|
||||
|
@ -31,11 +31,29 @@
|
||||
#include "../../kernel/qsqldatabase/tst_databases.h"
|
||||
#include <QtSql>
|
||||
#include <QtSql/private/qsqltablemodel_p.h>
|
||||
#include <QThread>
|
||||
|
||||
const QString test(qTableName("test", __FILE__, QSqlDatabase())),
|
||||
test2(qTableName("test2", __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
|
||||
{
|
||||
@ -116,6 +134,7 @@ private slots:
|
||||
|
||||
void sqlite_bigTable_data() { generic_data("QSQLITE"); }
|
||||
void sqlite_bigTable();
|
||||
void modelInAnotherThread();
|
||||
|
||||
// bug specific tests
|
||||
void insertRecordBeforeSelect_data() { generic_data(); }
|
||||
@ -276,6 +295,10 @@ void tst_QSqlTableModel::init()
|
||||
void tst_QSqlTableModel::cleanup()
|
||||
{
|
||||
recreateTestTables();
|
||||
if (oldHandler) {
|
||||
qInstallMessageHandler(oldHandler);
|
||||
oldHandler = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QSqlTableModel::select()
|
||||
@ -2100,5 +2123,29 @@ void tst_QSqlTableModel::invalidFilterAndHeaderData()
|
||||
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)
|
||||
#include "tst_qsqltablemodel.moc"
|
||||
|
Loading…
Reference in New Issue
Block a user