Merge "Merge remote-tracking branch 'origin/stable' into dev" into refs/staging/dev

This commit is contained in:
Konstantin Ritt 2014-02-13 09:35:08 +01:00 committed by The Qt Project
commit 7ac97d7efb
42 changed files with 330 additions and 171 deletions

7
dist/changes-5.2.0 vendored
View File

@ -768,3 +768,10 @@ X11
* [QTBUG-34392][MSVS] Fixed /SAFESEH:NO with VS2010+.
* [QTBUG-34357][MSVS] Fixed breakage with multiple VS versions in PATH.
* [MSVS] Fixed sub-project dependency generation.
- moc
* Porting moc to QCommandLineParser has changed one specific option in its
command line handling: using the -f option without argument
is not supported anymore (it wasn't necessary, since including the header
file is the default behavior).

View File

@ -7,8 +7,6 @@ SOURCES = main.cpp \
widgetgallery.cpp
RESOURCES = styles.qrc
REQUIRES += "contains(styles, windows)"
# install
target.path = $$[QT_INSTALL_EXAMPLES]/widgets/widgets/styles
INSTALLS += target

View File

@ -16,6 +16,7 @@ SUBDIRS = analogclock \
shapedclock \
sliders \
spinboxes \
styles \
stylesheet \
tablet \
tetrix \
@ -23,5 +24,3 @@ SUBDIRS = analogclock \
validators \
wiggly \
windowflags
contains(styles, windows): SUBDIRS += styles

View File

@ -45,7 +45,8 @@ QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions
# Disabling exceptions disabled - workaround for QTBUG-36577
#QMAKE_CXXFLAGS_EXCEPTIONS_OFF = -fno-exceptions
QMAKE_CXXFLAGS_CXX11 = -std=c++0x
QMAKE_INCDIR =

View File

@ -870,7 +870,7 @@ public:
};
#define Q_FOREACH(variable, container) \
for (QForeachContainer<__typeof__(container)> _container_(container); \
for (QForeachContainer<__typeof__((container))> _container_((container)); \
!_container_.brk && _container_.i != _container_.e; \
__extension__ ({ ++_container_.brk; ++_container_.i; })) \
for (variable = *_container_.i;; __extension__ ({--_container_.brk; break;}))

View File

@ -383,7 +383,7 @@ QDebugStateSaver::QDebugStateSaver(QDebug &dbg)
}
/*!
Destroyes a QDebugStateSaver instance, which restores the settings
Destroys a QDebugStateSaver instance, which restores the settings
used when the QDebugStateSaver instance was created.
\sa QDebug::setAutoInsertSpaces(), QDebug::autoInsertSpaces()

View File

@ -1944,8 +1944,9 @@ QString QDir::homePath()
On Unix/Linux systems this is the path in the \c TMPDIR environment
variable or \c{/tmp} if \c TMPDIR is not defined. On Windows this is
usually the path in the \c TEMP or \c TMP environment
variable. Whether a directory separator is added to the end or
not, depends on the operating system.
variable.
The path returned by this method doesn't end with a directory separator
unless it is the root directory (of a drive).
\sa temp(), currentPath(), homePath(), rootPath()
*/

View File

@ -721,13 +721,13 @@ QString QFileSystemEngine::tempPath()
if (temp.isEmpty()) {
qWarning("Neither the TEMP nor the TMPDIR environment variable is set, falling back to /tmp.");
temp = QLatin1String("/tmp/");
temp = QLatin1String("/tmp");
}
return QDir::cleanPath(temp);
#else
QString temp = QFile::decodeName(qgetenv("TMPDIR"));
if (temp.isEmpty())
temp = QLatin1String("/tmp/");
temp = QLatin1String("/tmp");
return QDir::cleanPath(temp);
#endif
}

View File

@ -205,6 +205,8 @@ QString QStandardPaths::writableLocation(StandardLocation type)
// value can start with $HOME
if (value.startsWith(QLatin1String("$HOME")))
value = QDir::homePath() + value.mid(5);
if (value.length() > 1 && value.endsWith(QLatin1Char('/')))
value.chop(1);
return value;
}
}
@ -257,10 +259,17 @@ static QStringList xdgDataDirs()
dirs.append(QString::fromLatin1("/usr/local/share"));
dirs.append(QString::fromLatin1("/usr/share"));
} else {
dirs = xdgDataDirsEnv.split(QLatin1Char(':'));
// Normalize paths
for (int i = 0; i < dirs.count(); i++)
dirs[i] = QDir::cleanPath(dirs.at(i));
dirs = xdgDataDirsEnv.split(QLatin1Char(':'), QString::SkipEmptyParts);
// Normalize paths, skip relative paths
QMutableListIterator<QString> it(dirs);
while (it.hasNext()) {
const QString dir = it.next();
if (!dir.startsWith(QLatin1Char('/')))
it.remove();
else
it.setValue(QDir::cleanPath(dir));
}
// Remove duplicates from the list, there's no use for duplicated
// paths in XDG_DATA_DIRS - if it's not found in the given

View File

@ -414,10 +414,16 @@ static inline QString fileScheme()
return QStringLiteral("file");
}
#ifdef Q_COMPILER_CLASS_ENUM
# define colon_uchar : uchar
#else
# define colon_uchar
#endif
class QUrlPrivate
{
public:
enum Section {
enum Section colon_uchar {
Scheme = 0x01,
UserName = 0x02,
Password = 0x04,
@ -432,6 +438,10 @@ public:
FullUrl = 0xff
};
enum Flags colon_uchar {
IsLocalFile = 0x01
};
enum ErrorCode {
// the high byte of the error code matches the Section
// the first item in each value must be the generic "Invalid xxx Error"
@ -519,6 +529,8 @@ public:
inline bool hasQuery() const { return sectionIsPresent & Query; }
inline bool hasFragment() const { return sectionIsPresent & Fragment; }
inline bool isLocalFile() const { return flags & IsLocalFile; }
QString mergePaths(const QString &relativePath) const;
QAtomicInt ref;
@ -539,12 +551,18 @@ public:
// - Path (there's no path delimiter, so we optimize its use out of existence)
// Schemes are never supposed to be empty, but we keep the flag anyway
uchar sectionIsPresent;
uchar flags;
// 32-bit: 2 bytes tail padding available
// 64-bit: 6 bytes tail padding available
};
#undef colon_uchar
inline QUrlPrivate::QUrlPrivate()
: ref(1), port(-1),
error(0),
sectionIsPresent(0)
sectionIsPresent(0),
flags(0)
{
}
@ -558,7 +576,8 @@ inline QUrlPrivate::QUrlPrivate(const QUrlPrivate &copy)
query(copy.query),
fragment(copy.fragment),
error(copy.cloneError()),
sectionIsPresent(copy.sectionIsPresent)
sectionIsPresent(copy.sectionIsPresent),
flags(copy.flags)
{
}
@ -956,6 +975,12 @@ inline bool QUrlPrivate::setScheme(const QString &value, int len, bool doSetErro
schemeData[i] = c + 0x20;
}
}
// did we set to the file protocol?
if (scheme == fileScheme())
flags |= IsLocalFile;
else
flags &= ~IsLocalFile;
return true;
}
@ -1312,6 +1337,7 @@ inline void QUrlPrivate::parse(const QString &url, QUrl::ParsingMode parsingMode
// / other path types here
sectionIsPresent = 0;
flags = 0;
clearError();
// find the important delimiters
@ -1867,6 +1893,7 @@ void QUrl::setScheme(const QString &scheme)
if (scheme.isEmpty()) {
// schemes are not allowed to be empty
d->sectionIsPresent &= ~QUrlPrivate::Scheme;
d->flags &= ~QUrlPrivate::IsLocalFile;
d->scheme.clear();
} else {
d->setScheme(scheme, scheme.length(), /* do set error */ true);
@ -3104,6 +3131,7 @@ QUrl QUrl::resolved(const QUrl &relative) const
t.d->sectionIsPresent |= QUrlPrivate::Scheme;
else
t.d->sectionIsPresent &= ~QUrlPrivate::Scheme;
t.d->flags |= d->flags & QUrlPrivate::IsLocalFile;
}
t.d->fragment = relative.d->fragment;
if (relative.d->hasFragment())
@ -3177,7 +3205,6 @@ QString QUrl::toString(FormattingOptions options) const
// - there's no query or fragment to return
// that is, either they aren't present, or we're removing them
// - it's a local file
// (test done last since it's the most expensive)
if (options.testFlag(QUrl::PreferLocalFile) && !options.testFlag(QUrl::RemovePath)
&& (!d->hasQuery() || options.testFlag(QUrl::RemoveQuery))
&& (!d->hasFragment() || options.testFlag(QUrl::RemoveFragment))
@ -3201,6 +3228,7 @@ QString QUrl::toString(FormattingOptions options) const
url += QLatin1String("//");
d->appendAuthority(url, options, QUrlPrivate::FullUrl);
} else if (isLocalFile() && pathIsAbsolute) {
// Comply with the XDG file URI spec, which requires triple slashes.
url += QLatin1String("//");
}
@ -3755,11 +3783,7 @@ QString QUrl::toLocalFile() const
*/
bool QUrl::isLocalFile() const
{
if (!d) return false;
if (d->scheme != fileScheme())
return false; // not file
return true;
return d && d->isLocalFile();
}
/*!

View File

@ -2603,7 +2603,7 @@ QStringList QUrl::idnWhitelist()
Note that if you call this function, you need to do so \e before
you start any threads that might access idnWhitelist().
Qt has comes a default list that contains the Internet top-level domains
Qt comes with a default list that contains the Internet top-level domains
that have published support for Internationalized Domain Names (IDNs)
and rules to guarantee that no deception can happen between similarly-looking
characters (such as the Latin lowercase letter \c 'a' and the Cyrillic

View File

@ -3663,9 +3663,15 @@ void QMetaObject::activate(QObject *sender, int signalOffset, int local_signal_i
const int method_relative = c->method_relative;
if (c->isSlotObject) {
c->slotObj->ref();
const QScopedPointer<QtPrivate::QSlotObjectBase, QSlotObjectBaseDeleter> obj(c->slotObj);
QScopedPointer<QtPrivate::QSlotObjectBase, QSlotObjectBaseDeleter> obj(c->slotObj);
locker.unlock();
obj->call(receiver, argv ? argv : empty_argv);
// Make sure the slot object gets destroyed before the mutex is locked again, as the
// destructor of the slot object might also lock a mutex from the signalSlotLock() mutex pool,
// and that would deadlock if the pool happens to return the same mutex.
obj.reset();
locker.relock();
} else if (callFunction && c->method_offset <= receiver->metaObject()->methodOffset()) {
//we compare the vtable to make sure we are not in the destructor of the object.

View File

@ -1894,7 +1894,7 @@ Image_Converter qimage_converter_map[QImage::NImageFormats][QImage::NImageFormat
0,
convert_RGBA_to_RGB,
convert_RGBA_to_ARGB,
convert_RGBA_to_ARGB_PM,
convert_RGBA_to_ARGB,
0,
0,
0,

View File

@ -1110,6 +1110,17 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target
would be to transform your texture coordinates.
*/
/*!
\enum QOpenGLTexture::Filter
This enum defines the filtering parameters for a QOpenGLTexture object.
\value Nearest Equivalent to GL_NEAREST
\value Linear Equivalent to GL_LINEAR
\value NearestMipMapNearest Equivalent to GL_NEAREST_MIPMAP_NEAREST
\value NearestMipMapLinear Equivalent to GL_NEAREST_MIPMAP_LINEAR
\value LinearMipMapNearest Equivalent to GL_LINEAR_MIPMAP_NEAREST
\value LinearMipMapLinear Equivalent to GL_LINEAR_MIPMAP_LINEAR
*/
/*!
\enum QOpenGLTexture::Target
This enum defines the texture target of a QOpenGLTexture object.
@ -1164,7 +1175,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target
*/
/*!
\enum TextureUnitReset
\enum QOpenGLTexture::TextureUnitReset
This enum defines options ot control texture unit activation.
\value ResetTextureUnit The previous active texture unit will be reset
@ -1320,7 +1331,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target
*/
/*!
\enum PixelType
\enum QOpenGLTexture::PixelType
This enum defines the possible pixel data types for a pixel transfer operation
\value NoPixelType Equivalent to GL_NONE
@ -1394,7 +1405,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target
*/
/*!
\enum WrapMode
\enum QOpenGLTexture::WrapMode
This enum defines the possible texture coordinate wrapping modes.
\value Repeat Texture coordinate is repeated. Equivalent to GL_REPEAT
@ -1405,7 +1416,7 @@ QOpenGLTexture *QOpenGLTexturePrivate::createTextureView(QOpenGLTexture::Target
*/
/*!
\enum CoordinateDirection
\enum QOpenGLTexture::CoordinateDirection
This enum defines the possible texture coordinate directions
\value DirectionS The horizontal direction. Equivalent to GL_TEXTURE_WRAP_S

View File

@ -5841,7 +5841,7 @@ inline void qt_bitmapblit_template(QRasterBuffer *rasterBuffer,
}
}
static void qt_gradient_quint32(int count, const QSpan *spans, void *userData)
static void qt_gradient_argb32(int count, const QSpan *spans, void *userData)
{
QSpanData *data = reinterpret_cast<QSpanData *>(userData);
@ -6298,7 +6298,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGB32,
{
blend_color_argb,
qt_gradient_quint32,
qt_gradient_argb32,
qt_bitmapblit_quint32,
qt_alphamapblit_quint32,
qt_alphargbblit_quint32,
@ -6307,7 +6307,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_ARGB32,
{
blend_color_generic,
qt_gradient_quint32,
qt_gradient_argb32,
qt_bitmapblit_quint32,
qt_alphamapblit_quint32,
qt_alphargbblit_quint32,
@ -6316,7 +6316,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_ARGB32_Premultiplied
{
blend_color_argb,
qt_gradient_quint32,
qt_gradient_argb32,
qt_bitmapblit_quint32,
qt_alphamapblit_quint32,
qt_alphargbblit_quint32,
@ -6382,7 +6382,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGBX8888
{
blend_color_generic,
qt_gradient_quint32,
blend_src_generic,
qt_bitmapblit_quint32,
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
qt_alphamapblit_quint32,
@ -6396,7 +6396,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGBA8888
{
blend_color_generic,
qt_gradient_quint32,
blend_src_generic,
qt_bitmapblit_quint32,
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
qt_alphamapblit_quint32,
@ -6410,7 +6410,7 @@ DrawHelper qDrawHelper[QImage::NImageFormats] =
// Format_RGB8888_Premultiplied
{
blend_color_generic,
qt_gradient_quint32,
blend_src_generic,
qt_bitmapblit_quint32,
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
qt_alphamapblit_quint32,

View File

@ -919,12 +919,9 @@ void QTextEngine::shapeText(int item) const
QFontEngine *fontEngine = this->fontEngine(si, &si.ascent, &si.descent, &si.leading);
// split up the item into parts that come from different font engines
// k * 3 entries, array[k] == index in string, array[k + 1] == index in glyphs, array[k + 2] == engine index
QVector<uint> itemBoundaries;
itemBoundaries.reserve(16);
// k * 2 entries, array[k] == index in string, array[k + 1] == index in glyphs
itemBoundaries.append(0);
itemBoundaries.append(0);
itemBoundaries.reserve(24);
if (fontEngine->type() == QFontEngine::Multi) {
// ask the font engine to find out which glyphs (as an index in the specific font)
// to use for the text in one item.
@ -935,22 +932,31 @@ void QTextEngine::shapeText(int item) const
if (!fontEngine->stringToCMap(reinterpret_cast<const QChar *>(string), itemLength, &initialGlyphs, &nGlyphs, shaperFlags))
Q_UNREACHABLE();
uint lastEngine = 0;
uint lastEngine = ~0u;
for (int i = 0, glyph_pos = 0; i < itemLength; ++i, ++glyph_pos) {
const uint engineIdx = initialGlyphs.glyphs[glyph_pos] >> 24;
if (lastEngine != engineIdx && glyph_pos > 0) {
if (lastEngine != engineIdx) {
itemBoundaries.append(i);
itemBoundaries.append(glyph_pos);
itemBoundaries.append(engineIdx);
QFontEngine *actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
si.descent = qMax(actualFontEngine->descent(), si.descent);
si.leading = qMax(actualFontEngine->leading(), si.leading);
if (engineIdx != 0) {
QFontEngine *actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
si.ascent = qMax(actualFontEngine->ascent(), si.ascent);
si.descent = qMax(actualFontEngine->descent(), si.descent);
si.leading = qMax(actualFontEngine->leading(), si.leading);
}
lastEngine = engineIdx;
}
lastEngine = engineIdx;
if (QChar::isHighSurrogate(string[i]) && i + 1 < itemLength && QChar::isLowSurrogate(string[i + 1]))
++i;
}
} else {
itemBoundaries.append(0);
itemBoundaries.append(0);
itemBoundaries.append(0);
}
bool kerningEnabled;
@ -1027,16 +1033,6 @@ void QTextEngine::shapeText(int item) const
si.width += glyphs.advances[i] * !glyphs.attributes[i].dontPrint;
}
static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num)
{
if (num > 0 && destination.glyphs != source.glyphs) {
memmove(destination.glyphs, source.glyphs, num * sizeof(glyph_t));
memmove(destination.attributes, source.attributes, num * sizeof(QGlyphAttributes));
memmove(destination.advances, source.advances, num * sizeof(QFixed));
memmove(destination.offsets, source.offsets, num * sizeof(QFixedPoint));
}
}
#ifdef QT_ENABLE_HARFBUZZ_NG
QT_BEGIN_INCLUDE_NAMESPACE
@ -1063,20 +1059,15 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
uint glyphs_shaped = 0;
int remaining_glyphs = itemLength;
for (int k = 0; k < itemBoundaries.size(); k += 2) { // for the +2, see the comment at the definition of itemBoundaries
for (int k = 0; k < itemBoundaries.size(); k += 3) {
uint item_pos = itemBoundaries[k];
uint item_length = itemLength;
uint item_length = (k + 4 < itemBoundaries.size() ? itemBoundaries[k + 3] : itemLength) - item_pos;
uint item_glyph_pos = itemBoundaries[k + 1];
if (k + 3 < itemBoundaries.size())
item_length = itemBoundaries[k + 2];
item_length -= item_pos;
uint engineIdx = itemBoundaries[k + 2];
QFontEngine *actualFontEngine = fontEngine;
uint engineIdx = 0;
if (fontEngine->type() == QFontEngine::Multi) {
engineIdx = availableGlyphs(&si).glyphs[glyphs_shaped] >> 24;
if (fontEngine->type() == QFontEngine::Multi)
actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
}
// prepare buffer
@ -1093,18 +1084,6 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
buffer_flags |= HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES;
hb_buffer_set_flags(buffer, hb_buffer_flags_t(buffer_flags));
const uint num_codes = hb_buffer_get_length(buffer);
{
// adjust clusters
hb_glyph_info_t *infos = hb_buffer_get_glyph_infos(buffer, 0);
const ushort *uc = string + item_pos;
for (uint i = 0, code_pos = 0; i < item_length; ++i, ++code_pos) {
if (QChar::isHighSurrogate(uc[i]) && i + 1 < item_length && QChar::isLowSurrogate(uc[i + 1]))
++i;
infos[code_pos].cluster = code_pos + item_glyph_pos;
}
}
// shape
bool shapedOk = false;
@ -1127,8 +1106,7 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
if (si.analysis.bidiLevel % 2)
hb_buffer_reverse(buffer);
remaining_glyphs -= num_codes;
remaining_glyphs -= item_glyph_pos;
// ensure we have enough space for shaped glyphs and metrics
const uint num_glyphs = hb_buffer_get_length(buffer);
@ -1139,43 +1117,33 @@ int QTextEngine::shapeTextWithHarfbuzzNG(const QScriptItem &si, const ushort *st
// fetch the shaped glyphs and metrics
QGlyphLayout g = availableGlyphs(&si).mid(glyphs_shaped, num_glyphs);
if (num_glyphs > num_codes)
moveGlyphData(g.mid(num_glyphs), g.mid(num_codes), remaining_glyphs);
ushort *log_clusters = logClusters(&si) + item_pos;
hb_glyph_info_t *infos = hb_buffer_get_glyph_infos(buffer, 0);
hb_glyph_position_t *positions = hb_buffer_get_glyph_positions(buffer, 0);
uint last_cluster = -1;
uint str_pos = 0;
uint last_cluster = ~0u;
uint last_glyph_pos = glyphs_shaped;
for (uint i = 0; i < num_glyphs; ++i) {
g.glyphs[i] = infos[i].codepoint;
log_clusters[i] = infos[i].cluster;
g.advances[i] = QFixed::fromFixed(positions[i].x_advance);
g.offsets[i].x = QFixed::fromFixed(positions[i].x_offset);
g.offsets[i].y = QFixed::fromFixed(positions[i].y_offset);
if (infos[i].cluster != last_cluster) {
last_cluster = infos[i].cluster;
uint cluster = infos[i].cluster;
if (last_cluster != cluster) {
// fix up clusters so that the cluster indices will be monotonic
// and thus we never return out-of-order indices
while (last_cluster++ < cluster && str_pos < item_length)
log_clusters[str_pos++] = last_glyph_pos;
last_glyph_pos = i + glyphs_shaped;
last_cluster = cluster;
g.attributes[i].clusterStart = true;
}
}
{
// adjust clusters
uint glyph_pos = 0;
for (uint i = 0; i < item_length; ++i) {
if (i + item_pos != infos[glyph_pos].cluster) {
for (uint j = glyph_pos + 1; j < num_glyphs; ++j) {
if (i + item_pos <= infos[j].cluster) {
if (i + item_pos == infos[j].cluster)
glyph_pos = j;
break;
}
}
}
log_clusters[i] = glyph_pos + item_glyph_pos;
}
}
while (str_pos < item_length)
log_clusters[str_pos++] = last_glyph_pos;
if (engineIdx != 0) {
for (quint32 i = 0; i < num_glyphs; ++i)
@ -1211,6 +1179,12 @@ Q_STATIC_ASSERT(sizeof(HB_GlyphAttributes) == sizeof(QGlyphAttributes));
Q_STATIC_ASSERT(sizeof(HB_Fixed) == sizeof(QFixed));
Q_STATIC_ASSERT(sizeof(HB_FixedPoint) == sizeof(QFixedPoint));
static inline void moveGlyphData(const QGlyphLayout &destination, const QGlyphLayout &source, int num)
{
if (num > 0 && destination.glyphs != source.glyphs)
memmove(destination.glyphs, source.glyphs, num * sizeof(glyph_t));
}
int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *string, int itemLength, QFontEngine *fontEngine, const QVector<uint> &itemBoundaries, bool kerningEnabled) const
{
HB_ShaperItem entire_shaper_item;
@ -1239,14 +1213,12 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
int remaining_glyphs = entire_shaper_item.num_glyphs;
int glyph_pos = 0;
// for each item shape using harfbuzz and store the results in our layoutData's glyphs array.
for (int k = 0; k < itemBoundaries.size(); k += 2) { // for the +2, see the comment at the definition of itemBoundaries
for (int k = 0; k < itemBoundaries.size(); k += 3) {
HB_ShaperItem shaper_item = entire_shaper_item;
shaper_item.item.pos = itemBoundaries[k];
if (k < itemBoundaries.size() - 3) {
shaper_item.item.length = itemBoundaries[k + 2] - shaper_item.item.pos;
shaper_item.num_glyphs = itemBoundaries[k + 3] - itemBoundaries[k + 1];
if (k + 4 < itemBoundaries.size()) {
shaper_item.item.length = itemBoundaries[k + 3] - shaper_item.item.pos;
shaper_item.num_glyphs = itemBoundaries[k + 4] - itemBoundaries[k + 1];
} else { // last combo in the list, avoid out of bounds access.
shaper_item.item.length -= shaper_item.item.pos - entire_shaper_item.item.pos;
shaper_item.num_glyphs -= itemBoundaries[k + 1];
@ -1255,10 +1227,9 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
if (shaper_item.num_glyphs < shaper_item.item.length)
shaper_item.num_glyphs = shaper_item.item.length;
uint engineIdx = itemBoundaries[k + 2];
QFontEngine *actualFontEngine = fontEngine;
uint engineIdx = 0;
if (fontEngine->type() == QFontEngine::Multi) {
engineIdx = uint(availableGlyphs(&si).glyphs[glyph_pos] >> 24);
actualFontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
if ((si.analysis.bidiLevel % 2) == 0)
@ -1275,7 +1246,7 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
return 0;
const QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos);
if (shaper_item.num_glyphs > shaper_item.item.length)
if (fontEngine->type() == QFontEngine::Multi && shaper_item.num_glyphs > shaper_item.item.length)
moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs);
shaper_item.glyphs = reinterpret_cast<HB_Glyph *>(g.glyphs);
@ -1292,7 +1263,8 @@ int QTextEngine::shapeTextWithHarfbuzz(const QScriptItem &si, const ushort *stri
} while (!qShapeItem(&shaper_item)); // this does the actual shaping via harfbuzz.
QGlyphLayout g = availableGlyphs(&si).mid(glyph_pos, shaper_item.num_glyphs);
moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs);
if (fontEngine->type() == QFontEngine::Multi)
moveGlyphData(g.mid(shaper_item.num_glyphs), g.mid(shaper_item.initialGlyphCount), remaining_glyphs);
for (quint32 i = 0; i < shaper_item.item.length; ++i)
shaper_item.log_clusters[i] += glyph_pos;

View File

@ -341,8 +341,9 @@ static QByteArray _q_SubjectInfoToString(QSslCertificate::SubjectInfo info)
\fn QString QSslCertificate::issuerInfo(SubjectInfo subject) const
Returns the issuer information for the \a subject from the
certificate, or an empty string if there is no information for
\a subject in the certificate.
certificate, or an empty list if there is no information for
\a subject in the certificate. There can be more than one entry
of each type.
\sa subjectInfo()
*/
@ -359,8 +360,8 @@ QStringList QSslCertificate::issuerInfo(SubjectInfo info) const
/*!
Returns the issuer information for \a attribute from the certificate,
or an empty string if there is no information for \a attribute in the
certificate.
or an empty list if there is no information for \a attribute in the
certificate. There can be more than one entry for an attribute.
\sa subjectInfo()
*/
@ -379,8 +380,9 @@ QStringList QSslCertificate::issuerInfo(const QByteArray &attribute) const
\fn QString QSslCertificate::subjectInfo(SubjectInfo subject) const
Returns the information for the \a subject, or an empty string if
there is no information for \a subject in the certificate.
Returns the information for the \a subject, or an empty list if
there is no information for \a subject in the certificate. There
can be more than one entry of each type.
\sa issuerInfo()
*/
@ -396,8 +398,9 @@ QStringList QSslCertificate::subjectInfo(SubjectInfo info) const
}
/*!
Returns the subject information for \a attribute, or an empty string if
there is no information for \a attribute in the certificate.
Returns the subject information for \a attribute, or an empty list if
there is no information for \a attribute in the certificate. There
can be more than one entry for an attribute.
\sa issuerInfo()
*/

View File

@ -40,6 +40,9 @@
****************************************************************************/
#include "qgraphicsshadereffect_p.h"
#ifndef QT_NO_GRAPHICSEFFECT
#include "qglshaderprogram.h"
#include "gl2paintengineex/qglcustomshaderstage_p.h"
#define QGL_HAVE_CUSTOM_SHADERS 1
@ -311,3 +314,5 @@ void QGraphicsShaderEffect::setUniforms(QGLShaderProgram *program)
}
QT_END_NAMESPACE
#endif // QT_NO_GRAPHICSEFFECT

View File

@ -54,6 +54,9 @@
//
#include <QtWidgets/qgraphicseffect.h>
#ifndef QT_NO_GRAPHICSEFFECT
#include <QtOpenGL/qtopenglglobal.h>
QT_BEGIN_NAMESPACE
@ -87,4 +90,6 @@ private:
QT_END_NAMESPACE
#endif // QT_NO_GRAPHICSEFFECT
#endif // QGRAPHICSSHADEREFFECT_P_H

View File

@ -1391,13 +1391,6 @@ bool AtSpiAdaptor::accessibleInterface(QAccessibleInterface *interface, const QS
if (interface->tableInterface()) {
setSpiStateBit(&spiState, ATSPI_STATE_MANAGES_DESCENDANTS);
}
// FIXME: figure out if this is a top level window and set its active state accordingly
// if (interface->object() && interface->object()->isWidgetType()) {
// QWidget *w = qobject_cast<QWidget*>(interface->object());
// if (w->topLevelWidget() && w->isActiveWindow()) {
// setSpiStateBit(&spiState, ATSPI_STATE_ACTIVE);
// }
// }
QAccessible::Role role = interface->role();
if (role == QAccessible::TreeItem ||
role == QAccessible::ListItem) {

View File

@ -61,6 +61,8 @@ quint64 spiStatesFromQState(QAccessible::State state)
{
quint64 spiState = 0;
if (state.active)
setSpiStateBit(&spiState, ATSPI_STATE_ACTIVE);
if (state.editable)
setSpiStateBit(&spiState, ATSPI_STATE_EDITABLE);
if (!state.disabled) {

View File

@ -1069,7 +1069,6 @@ QString QAccessibleTableCell::text(QAccessible::Text t) const
QAbstractItemModel *model = view->model();
QString value;
switch (t) {
case QAccessible::Value:
case QAccessible::Name:
value = model->data(m_index, Qt::AccessibleTextRole).toString();
if (value.isEmpty())
@ -1161,7 +1160,6 @@ QString QAccessibleTableHeaderCell::text(QAccessible::Text t) const
QAbstractItemModel *model = view->model();
QString value;
switch (t) {
case QAccessible::Value:
case QAccessible::Name:
value = model->headerData(index, orientation, Qt::AccessibleTextRole).toString();
if (value.isEmpty())

View File

@ -631,7 +631,7 @@ QDockWidget *QAccessibleDockWidget::dockWidget() const
QString QAccessibleDockWidget::text(QAccessible::Text t) const
{
if (t == QAccessible::Name || t == QAccessible::Value) {
if (t == QAccessible::Name) {
return qt_accStripAmp(dockWidget()->windowTitle());
}
return QString();

View File

@ -507,8 +507,10 @@ QString QAccessibleGroupBox::text(QAccessible::Text t) const
switch (t) {
case QAccessible::Name:
txt = qt_accStripAmp(groupBox()->title());
break;
case QAccessible::Description:
txt = qt_accStripAmp(groupBox()->title());
txt = qt_accStripAmp(groupBox()->toolTip());
break;
default:
break;
}

View File

@ -48,8 +48,6 @@
#include <QPoint>
#include <qpa/qwindowsysteminterface.h>
#include <Qt>
#include <errno.h>
#include <tslib.h>
@ -65,21 +63,21 @@ QTsLibMouseHandler::QTsLibMouseHandler(const QString &key,
setObjectName(QLatin1String("TSLib Mouse Handler"));
QByteArray device = qgetenv("TSLIB_TSDEVICE");
if (device.isEmpty())
device = QByteArrayLiteral("/dev/input/event1");
if (specification.startsWith("/dev/"))
device = specification.toLocal8Bit();
if (device.isEmpty())
device = QByteArrayLiteral("/dev/input/event1");
m_dev = ts_open(device.constData(), 1);
if (!m_dev) {
qErrnoWarning(errno, "ts_open() failed");
return;
}
if (ts_config(m_dev)) {
if (ts_config(m_dev))
perror("Error configuring\n");
}
m_rawMode = !key.compare(QLatin1String("TslibRaw"), Qt::CaseInsensitive);
@ -89,7 +87,6 @@ QTsLibMouseHandler::QTsLibMouseHandler(const QString &key,
connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData()));
} else {
qWarning("Cannot open mouse input device '%s': %s", device.constData(), strerror(errno));
return;
}
}
@ -103,12 +100,10 @@ QTsLibMouseHandler::~QTsLibMouseHandler()
static bool get_sample(struct tsdev *dev, struct ts_sample *sample, bool rawMode)
{
if (rawMode) {
if (rawMode)
return (ts_read_raw(dev, sample, 1) == 1);
} else {
int ret = ts_read(dev, sample, 1);
return ( ret == 1);
}
else
return (ts_read(dev, sample, 1) == 1);
}

View File

@ -347,7 +347,7 @@ ushort TableGenerator::keysymToUtf8(quint32 sym)
qDebug() << QString("keysym - 0x%1 : utf8 - %2").arg(QString::number(sym, 16))
.arg(codec->toUnicode(chars));
#endif
return QString::fromLocal8Bit(chars).at(0).unicode();
return QString::fromUtf8(chars).at(0).unicode();
}
static inline int fromBase8(const char *s, const char *end)

View File

@ -335,6 +335,8 @@ bool QLinuxFbScreen::initialize()
QRegularExpressionMatch match;
if (arg == QLatin1String("nographicsmodeswitch"))
doSwitchToGraphicsMode = false;
else if (arg.contains(mmSizeRx, &match))
userMmSize = QSize(match.captured(1).toInt(), match.captured(2).toInt());
else if (arg.contains(sizeRx, &match))
userGeometry.setSize(QSize(match.captured(1).toInt(), match.captured(2).toInt()));
else if (arg.contains(offsetRx, &match))
@ -343,8 +345,6 @@ bool QLinuxFbScreen::initialize()
ttyDevice = match.captured(1);
else if (arg.contains(fbRx, &match))
fbDevice = match.captured(1);
else if (arg.contains(mmSizeRx, &match))
userMmSize = QSize(match.captured(1).toInt(), match.captured(2).toInt());
}
if (fbDevice.isEmpty()) {

View File

@ -1012,6 +1012,8 @@ HRESULT STDMETHODCALLTYPE QWindowsMsaaAccessible::get_accState(VARIANT varID, VA
st |= STATE_SYSTEM_SIZEABLE;
if (state.traversed)
st |= STATE_SYSTEM_TRAVERSED;
if (state.disabled)
st |= STATE_SYSTEM_UNAVAILABLE;
(*pvarState).vt = VT_I4;
(*pvarState).lVal = st;

View File

@ -1993,13 +1993,17 @@ static void draw_text_item_win(const QPointF &pos, const QTextItemInt &ti, HDC h
void QWin32PrintEnginePrivate::updateCustomPaperSize()
{
const uint paperSize = devMode->dmPaperSize;
const double multiplier = qt_multiplierForUnit(QPrinter::Millimeter, resolution);
has_custom_paper_size = false;
if (paperSize > 0 && mapDevmodePaperSize(paperSize) == QPrinter::Custom) {
if (paperSize == DMPAPER_USER) {
has_custom_paper_size = true;
paper_size = QSizeF((devMode->dmPaperWidth / 10.0) * multiplier, (devMode->dmPaperLength / 10.0) * multiplier);
} else if (mapDevmodePaperSize(paperSize) == QPrinter::Custom) {
has_custom_paper_size = true;
const QList<QPair<QSizeF, int> > paperSizes = printerPaperSizes(name);
for (int i=0; i<paperSizes.size(); i++) {
if ((uint)paperSizes.at(i).second == paperSize) {
paper_size = paperSizes.at(i).first;
paper_size = paperSizes.at(i).first * multiplier;
has_custom_paper_size = false;
break;
}

View File

@ -258,7 +258,7 @@ int runMoc(int argc, char **argv)
parser.addOption(pathPrefixOption);
QCommandLineOption forceIncludeOption(QStringLiteral("f"));
forceIncludeOption.setDescription(QStringLiteral("Force #include [optional <file>] (overwrite default)."));
forceIncludeOption.setDescription(QStringLiteral("Force #include <file> (overwrite default)."));
forceIncludeOption.setValueName(QStringLiteral("file"));
parser.addOption(forceIncludeOption);

View File

@ -246,16 +246,15 @@ QMultiMap<QString,QString> outFileNames;
*/
void Generator::writeOutFileNames()
{
QFile* files = new QFile("/Users/msmith/depot/qt5/qtdoc/outputlist.txt");
files->open(QFile::WriteOnly);
QTextStream* filesout = new QTextStream(files);
QFile files("outputlist.txt");
if (!files.open(QFile::WriteOnly))
return;
QTextStream filesout(&files);
QMultiMap<QString,QString>::ConstIterator i = outFileNames.begin();
while (i != outFileNames.end()) {
(*filesout) << i.key() << "\n";
filesout << i.key() << "\n";
++i;
}
filesout->flush();
files->close();
}
/*!

View File

@ -425,10 +425,9 @@ QString QAccessibleWidget::text(QAccessible::Text t) const
}
break;
case QAccessible::Description:
if (!widget()->accessibleDescription().isEmpty())
str = widget()->accessibleDescription();
str = widget()->accessibleDescription();
#ifndef QT_NO_TOOLTIP
else
if (str.isEmpty())
str = widget()->toolTip();
#endif
break;

View File

@ -627,7 +627,8 @@ void QFileDialogPrivate::helperPrepareShow(QPlatformDialogHelper *)
options->setInitialDirectory(directory.exists() ?
QUrl::fromLocalFile(directory.absolutePath()) :
QUrl());
options->setInitiallySelectedNameFilter(q->selectedNameFilter());
if (options->initiallySelectedNameFilter().isEmpty())
options->setInitiallySelectedNameFilter(q->selectedNameFilter());
if (options->initiallySelectedFiles().isEmpty())
options->setInitiallySelectedFiles(userSelectedFiles());
}
@ -1450,6 +1451,7 @@ QStringList QFileDialog::nameFilters() const
void QFileDialog::selectNameFilter(const QString &filter)
{
Q_D(QFileDialog);
d->options->setInitiallySelectedNameFilter(filter);
if (!d->usingWidgets()) {
d->selectNameFilter_sys(filter);
return;

View File

@ -2515,7 +2515,9 @@ void QTableWidget::removeColumn(int column)
/*!
Removes all items in the view.
This will also remove all selections.
This will also remove all selections and headers.
If you don't want to remove the headers, use
QTableWidget::clearContents().
The table dimensions stay the same.
*/

View File

@ -755,8 +755,8 @@ Qt::Alignment QTextEdit::alignment() const
\note The editor \e{does not take ownership of the document} unless it
is the document's parent object. The parent object of the provided document
remains the owner of the object. The editor does not delete any previously
assigned document, even if it is a child of the editor.
remains the owner of the object. If the previously assigned document is a
child of the editor then it will be deleted.
*/
void QTextEdit::setDocument(QTextDocument *document)
{

View File

@ -778,15 +778,16 @@ void QToolButtonPrivate::popupTimerDone()
actualMenu->d_func()->causedPopup.action = defaultAction;
actionsCopy = q->actions(); //(the list of action may be modified in slots)
actualMenu->exec(p);
if (!that)
return;
QObject::disconnect(actualMenu, SIGNAL(aboutToHide()), q, SLOT(_q_updateButtonDown()));
if (mustDeleteActualMenu)
delete actualMenu;
else
QObject::disconnect(actualMenu, SIGNAL(triggered(QAction*)), q, SLOT(_q_menuTriggered(QAction*)));
if (!that)
return;
actionsCopy.clear();
if (repeat)

View File

@ -101,6 +101,13 @@ void tst_QGlobal::for_each()
QCOMPARE(i, counter++);
}
QCOMPARE(counter, list.count());
// check whether we can pass a constructor as container argument
counter = 0;
foreach (int i, QList<int>(list)) {
QCOMPARE(i, counter++);
}
QCOMPARE(counter, list.count());
}
void tst_QGlobal::qassert()

View File

@ -77,6 +77,7 @@ private slots:
void testAllWritableLocations_data();
void testAllWritableLocations();
void testCleanPath();
void testXdgPathCleanup();
private:
#ifdef Q_XDG_PLATFORM
@ -477,6 +478,8 @@ void tst_qstandardpaths::testAllWritableLocations()
QString loc = QStandardPaths::writableLocation(location);
if (loc.size() > 1) // workaround for unlikely case of locations that return '/'
QCOMPARE(loc.endsWith(QLatin1Char('/')), false);
QVERIFY(loc.contains(QLatin1Char('/')));
QVERIFY(!loc.contains(QLatin1Char('\\')));
}
void tst_qstandardpaths::testCleanPath()
@ -491,6 +494,19 @@ void tst_qstandardpaths::testCleanPath()
}
}
void tst_qstandardpaths::testXdgPathCleanup()
{
#ifdef Q_XDG_PLATFORM
setCustomLocations();
const QString uncleanGlobalAppDir = "/./" + QFile::encodeName(m_globalAppDir);
qputenv("XDG_DATA_DIRS", QFile::encodeName(uncleanGlobalAppDir) + "::relative/path");
const QStringList appsDirs = QStandardPaths::standardLocations(QStandardPaths::ApplicationsLocation);
QVERIFY(!appsDirs.contains("/applications"));
QVERIFY(!appsDirs.contains(uncleanGlobalAppDir + "/applications"));
QVERIFY(!appsDirs.contains("relative/path/applications"));
#endif
}
QTEST_MAIN(tst_qstandardpaths)
#include "tst_qstandardpaths.moc"

View File

@ -147,6 +147,7 @@ private slots:
void connectFunctorOverloads();
void connectFunctorQueued();
void connectFunctorWithContext();
void connectFunctorDeadlock();
void connectStaticSlotWithObject();
void disconnectDoesNotLeakFunctor();
void contextDoesNotLeakFunctor();
@ -5740,6 +5741,47 @@ void tst_QObject::connectFunctorWithContext()
context->deleteLater();
}
class MyFunctor
{
public:
explicit MyFunctor(QObject *objectToDisconnect)
: m_objectToDisconnect(objectToDisconnect)
{}
~MyFunctor() {
// Do operations that will lock the internal signalSlotLock mutex on many QObjects.
// The more QObjects, the higher the chance that the signalSlotLock mutex used
// is already in use. If the number of objects is higher than the number of mutexes in
// the pool (currently 131), the deadlock should always trigger. Use an even higher number
// to be on the safe side.
const int objectCount = 1024;
SenderObject lotsOfObjects[objectCount];
for (int i = 0; i < objectCount; ++i) {
QObject::connect(&lotsOfObjects[i], &SenderObject::signal1,
&lotsOfObjects[i], &SenderObject::aPublicSlot);
}
}
void operator()() {
// This will cause the slot object associated with this functor to be destroyed after
// this function returns. That in turn will destroy this functor.
// If our dtor runs with the signalSlotLock held, the bunch of connect()
// performed there will deadlock trying to lock that lock again.
m_objectToDisconnect->disconnect();
}
private:
QObject *m_objectToDisconnect;
};
void tst_QObject::connectFunctorDeadlock()
{
SenderObject sender;
MyFunctor functor(&sender);
QObject::connect(&sender, &SenderObject::signal1, functor);
sender.emitSignal1();
}
static int s_static_slot_checker = 1;
class StaticSlotChecker : public QObject

View File

@ -202,6 +202,9 @@ private slots:
void linearGradientSymmetry();
void gradientInterpolation();
void gradientPixelFormat_data();
void gradientPixelFormat();
void fpe_pixmapTransform();
void fpe_zeroLengthLines();
void fpe_divByZero();
@ -3727,6 +3730,49 @@ void tst_QPainter::linearGradientSymmetry()
QCOMPARE(a, b);
}
void tst_QPainter::gradientPixelFormat_data()
{
QTest::addColumn<QImage::Format>("format");
QTest::newRow("argb32") << QImage::Format_ARGB32;
QTest::newRow("rgb32") << QImage::Format_RGB32;
QTest::newRow("rgb888") << QImage::Format_RGB888;
QTest::newRow("rgbx8888") << QImage::Format_RGBX8888;
QTest::newRow("rgba8888") << QImage::Format_RGBA8888;
QTest::newRow("rgba8888_pm") << QImage::Format_RGBA8888_Premultiplied;
}
void tst_QPainter::gradientPixelFormat()
{
QFETCH(QImage::Format, format);
QImage a(8, 64, QImage::Format_ARGB32_Premultiplied);
QImage b(8, 64, format);
QGradientStops stops;
stops << qMakePair(qreal(0.0), QColor(Qt::blue));
stops << qMakePair(qreal(0.3), QColor(Qt::red));
stops << qMakePair(qreal(0.6), QColor(Qt::green));
stops << qMakePair(qreal(1.0), QColor(Qt::black));
a.fill(0);
b.fill(0);
QLinearGradient gradient(QRectF(b.rect()).topLeft(), QRectF(b.rect()).bottomLeft());
gradient.setStops(stops);
QPainter pa(&a);
pa.fillRect(a.rect(), gradient);
pa.end();
QPainter pb(&b);
pb.fillRect(b.rect(), gradient);
pb.end();
QCOMPARE(a, b.convertToFormat(QImage::Format_ARGB32_Premultiplied));
}
void tst_QPainter::gradientInterpolation()
{
QImage image(256, 8, QImage::Format_ARGB32_Premultiplied);

View File

@ -160,7 +160,6 @@ void tst_QHttpNetworkConnection::head_data()
QTest::addColumn<int>("contentLength");
QTest::newRow("success-internal") << "http://" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962;
QTest::newRow("success-external") << "http://" << "www.ietf.org" << "/rfc/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962;
QTest::newRow("failure-path") << "http://" << QtNetworkSettings::serverName() << "/t" << ushort(80) << false << 404 << "Not Found" << -1;
QTest::newRow("failure-protocol") << "" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 400 << "Bad Request" << -1;
@ -217,7 +216,6 @@ void tst_QHttpNetworkConnection::get_data()
QTest::addColumn<int>("downloadSize");
QTest::newRow("success-internal") << "http://" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962 << 25962;
QTest::newRow("success-external") << "http://" << "www.ietf.org" << "/rfc/rfc3252.txt" << ushort(80) << false << 200 << "OK" << 25962 << 25962;
QTest::newRow("failure-path") << "http://" << QtNetworkSettings::serverName() << "/t" << ushort(80) << false << 404 << "Not Found" << -1 << -1;
QTest::newRow("failure-protocol") << "" << QtNetworkSettings::serverName() << "/qtest/rfc3252.txt" << ushort(80) << false << 400 << "Bad Request" << -1 << -1;

View File

@ -63,6 +63,7 @@ private slots:
void collapseTextOnPriority();
void task230994_iconSize();
void task176137_autoRepeatOfAction();
void qtbug_26956_popupTimerDone();
protected slots:
void sendMouseClick();
@ -223,5 +224,14 @@ void tst_QToolButton::sendMouseClick()
QTest::mouseClick(w, Qt::LeftButton, 0, QPoint(7,7));
}
void tst_QToolButton::qtbug_26956_popupTimerDone()
{
QToolButton *tb = new QToolButton;
tb->setMenu(new QMenu(tb));
tb->menu()->addAction("Qt");
tb->deleteLater();
tb->showMenu();
}
QTEST_MAIN(tst_QToolButton)
#include "tst_qtoolbutton.moc"