Merge "Merge remote-tracking branch 'origin/5.3' into 5.4" into refs/staging/5.4

This commit is contained in:
Giuseppe D'Angelo 2014-08-18 21:09:04 +02:00 committed by The Qt Project
commit 75b62f3a17
42 changed files with 668 additions and 151 deletions

View File

@ -104,6 +104,9 @@ TextEdit::TextEdit(QWidget *parent)
textEdit->setFocus(); textEdit->setFocus();
setCurrentFileName(QString()); setCurrentFileName(QString());
QFont textFont("Helvetica");
textFont.setStyleHint(QFont::SansSerif);
textEdit->setFont(textFont);
fontChanged(textEdit->font()); fontChanged(textEdit->font());
colorChanged(textEdit->textColor()); colorChanged(textEdit->textColor());
alignmentChanged(textEdit->alignment()); alignmentChanged(textEdit->alignment());

View File

@ -0,0 +1,23 @@
Index: pcre_compile.c
===================================================================
--- pcre_compile.c (revision 1494)
+++ pcre_compile.c (revision 1495)
@@ -8267,12 +8267,16 @@
/* If it was a capturing subpattern, check to see if it contained any
recursive back references. If so, we must wrap it in atomic brackets.
- In any event, remove the block from the chain. */
+ Because we are moving code along, we must ensure that any pending recursive
+ references are updated. In any event, remove the block from the chain. */
if (capnumber > 0)
{
if (cd->open_caps->flag)
{
+ *code = OP_END;
+ adjust_recurse(start_bracket, 1 + LINK_SIZE,
+ (options & PCRE_UTF8) != 0, cd, cd->hwm);
memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
IN_UCHARS(code - start_bracket));
*start_bracket = OP_ONCE;

View File

@ -0,0 +1,45 @@
Index: pcre_compile.c
===================================================================
--- pcre_compile.c (revision 1497)
+++ pcre_compile.c (revision 1498)
@@ -2374,6 +2374,7 @@
if (c == OP_RECURSE)
{
const pcre_uchar *scode = cd->start_code + GET(code, 1);
+ const pcre_uchar *endgroup = scode;
BOOL empty_branch;
/* Test for forward reference or uncompleted reference. This is disabled
@@ -2388,24 +2389,20 @@
if (GET(scode, 1) == 0) return TRUE; /* Unclosed */
}
- /* If we are scanning a completed pattern, there are no forward references
- and all groups are complete. We need to detect whether this is a recursive
- call, as otherwise there will be an infinite loop. If it is a recursion,
- just skip over it. Simple recursions are easily detected. For mutual
- recursions we keep a chain on the stack. */
+ /* If the reference is to a completed group, we need to detect whether this
+ is a recursive call, as otherwise there will be an infinite loop. If it is
+ a recursion, just skip over it. Simple recursions are easily detected. For
+ mutual recursions we keep a chain on the stack. */
+ do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
+ if (code >= scode && code <= endgroup) continue; /* Simple recursion */
else
- {
+ {
recurse_check *r = recurses;
- const pcre_uchar *endgroup = scode;
-
- do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
- if (code >= scode && code <= endgroup) continue; /* Simple recursion */
-
for (r = recurses; r != NULL; r = r->prev)
if (r->group == scode) break;
if (r != NULL) continue; /* Mutual recursion */
- }
+ }
/* Completed reference; scan the referenced group, remembering it on the
stack chain to detect mutual recursions. */

View File

@ -2370,6 +2370,7 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
if (c == OP_RECURSE) if (c == OP_RECURSE)
{ {
const pcre_uchar *scode = cd->start_code + GET(code, 1); const pcre_uchar *scode = cd->start_code + GET(code, 1);
const pcre_uchar *endgroup = scode;
BOOL empty_branch; BOOL empty_branch;
/* Test for forward reference or uncompleted reference. This is disabled /* Test for forward reference or uncompleted reference. This is disabled
@ -2384,20 +2385,16 @@ for (code = first_significant_code(code + PRIV(OP_lengths)[*code], TRUE);
if (GET(scode, 1) == 0) return TRUE; /* Unclosed */ if (GET(scode, 1) == 0) return TRUE; /* Unclosed */
} }
/* If we are scanning a completed pattern, there are no forward references /* If the reference is to a completed group, we need to detect whether this
and all groups are complete. We need to detect whether this is a recursive is a recursive call, as otherwise there will be an infinite loop. If it is
call, as otherwise there will be an infinite loop. If it is a recursion, a recursion, just skip over it. Simple recursions are easily detected. For
just skip over it. Simple recursions are easily detected. For mutual mutual recursions we keep a chain on the stack. */
recursions we keep a chain on the stack. */
do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
if (code >= scode && code <= endgroup) continue; /* Simple recursion */
else else
{ {
recurse_check *r = recurses; recurse_check *r = recurses;
const pcre_uchar *endgroup = scode;
do endgroup += GET(endgroup, 1); while (*endgroup == OP_ALT);
if (code >= scode && code <= endgroup) continue; /* Simple recursion */
for (r = recurses; r != NULL; r = r->prev) for (r = recurses; r != NULL; r = r->prev)
if (r->group == scode) break; if (r->group == scode) break;
if (r != NULL) continue; /* Mutual recursion */ if (r != NULL) continue; /* Mutual recursion */
@ -8244,12 +8241,16 @@ for (;;)
/* If it was a capturing subpattern, check to see if it contained any /* If it was a capturing subpattern, check to see if it contained any
recursive back references. If so, we must wrap it in atomic brackets. recursive back references. If so, we must wrap it in atomic brackets.
In any event, remove the block from the chain. */ Because we are moving code along, we must ensure that any pending recursive
references are updated. In any event, remove the block from the chain. */
if (capnumber > 0) if (capnumber > 0)
{ {
if (cd->open_caps->flag) if (cd->open_caps->flag)
{ {
*code = OP_END;
adjust_recurse(start_bracket, 1 + LINK_SIZE,
(options & PCRE_UTF8) != 0, cd, cd->hwm);
memmove(start_bracket + 1 + LINK_SIZE, start_bracket, memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
IN_UCHARS(code - start_bracket)); IN_UCHARS(code - start_bracket));
*start_bracket = OP_ONCE; *start_bracket = OP_ONCE;

View File

@ -108,15 +108,20 @@ public class QtNative
} }
} }
public static void openURL(String url) public static boolean openURL(String url)
{ {
boolean ok = true;
try { try {
Uri uri = Uri.parse(url); Uri uri = Uri.parse(url);
Intent intent = new Intent(Intent.ACTION_VIEW, uri); Intent intent = new Intent(Intent.ACTION_VIEW, uri);
activity().startActivity(intent); activity().startActivity(intent);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
ok = false;
} }
return ok;
} }
// this method loads full path libs // this method loads full path libs

View File

@ -721,7 +721,7 @@ jboolean QJNIObjectPrivate::callStaticMethod<jboolean>(jclass clazz,
{ {
va_list args; va_list args;
va_start(args, sig); va_start(args, sig);
jboolean res = callStaticMethod<jboolean>(clazz, methodName, sig); jboolean res = callStaticMethod<jboolean>(clazz, methodName, sig, args);
va_end(args); va_end(args);
return res; return res;
} }
@ -1026,7 +1026,7 @@ jlong QJNIObjectPrivate::callStaticMethod<jlong>(jclass clazz,
{ {
va_list args; va_list args;
va_start(args, sig); va_start(args, sig);
jlong res = callStaticMethod<jlong>(clazz, methodName, sig); jlong res = callStaticMethod<jlong>(clazz, methodName, sig, args);
va_end(args); va_end(args);
return res; return res;
} }
@ -1119,7 +1119,7 @@ jdouble QJNIObjectPrivate::callStaticMethod<jdouble>(const char *className,
{ {
va_list args; va_list args;
va_start(args, sig); va_start(args, sig);
jdouble res = callStaticMethod<jdouble>(className, methodName, sig); jdouble res = callStaticMethod<jdouble>(className, methodName, sig, args);
va_end(args); va_end(args);
return res; return res;
} }

View File

@ -4749,10 +4749,14 @@ bool QObject::disconnectImpl(const QObject *sender, void **signal, const QObject
int signal_index = -1; int signal_index = -1;
if (signal) { if (signal) {
void *args[] = { &signal_index, signal }; void *args[] = { &signal_index, signal };
senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args); for (; senderMetaObject && signal_index < 0; senderMetaObject = senderMetaObject->superClass()) {
if (signal_index < 0 || signal_index >= QMetaObjectPrivate::get(senderMetaObject)->signalCount) { senderMetaObject->static_metacall(QMetaObject::IndexOfMethod, 0, args);
qWarning("QObject::disconnect: signal not found in %s", senderMetaObject->className()); if (signal_index >= 0 && signal_index < QMetaObjectPrivate::get(senderMetaObject)->signalCount)
return false; break;
}
if (!senderMetaObject) {
qWarning("QObject::disconnect: signal not found in %s", sender->metaObject()->className());
return QMetaObject::Connection(0);
} }
signal_index += QMetaObjectPrivate::signalOffset(senderMetaObject); signal_index += QMetaObjectPrivate::signalOffset(senderMetaObject);
} }

View File

@ -526,10 +526,6 @@ QList<QAbstractState*> QStateMachinePrivate::computeStatesToEnter(const QList<QA
QAbstractState *s = lst.at(j); QAbstractState *s = lst.at(j);
addStatesToEnter(s, lca, statesToEnter, statesForDefaultEntry); addStatesToEnter(s, lca, statesToEnter, statesForDefaultEntry);
} }
for (int j = src ? 1 : 0; j < lst.size(); ++j) {
QAbstractState *s = lst.at(j);
addAncestorStatesToEnter(s, lca, statesToEnter, statesForDefaultEntry);
}
if (isParallel(lca)) { if (isParallel(lca)) {
QList<QAbstractState*> lcac = QStatePrivate::get(lca)->childStates(); QList<QAbstractState*> lcac = QStatePrivate::get(lca)->childStates();
foreach (QAbstractState* child,lcac) { foreach (QAbstractState* child,lcac) {
@ -727,6 +723,7 @@ void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root,
return; return;
} }
} }
addAncestorStatesToEnter(s, root, statesToEnter, statesForDefaultEntry);
} }
} }
@ -1095,7 +1092,6 @@ void QStateMachinePrivate::setError(QStateMachine::Error errorCode, QAbstractSta
if (currentErrorState != 0) { if (currentErrorState != 0) {
QState *lca = findLCA(QList<QAbstractState*>() << currentErrorState << currentContext); QState *lca = findLCA(QList<QAbstractState*>() << currentErrorState << currentContext);
addStatesToEnter(currentErrorState, lca, pendingErrorStates, pendingErrorStatesForDefaultEntry); addStatesToEnter(currentErrorState, lca, pendingErrorStates, pendingErrorStatesForDefaultEntry);
addAncestorStatesToEnter(currentErrorState, lca, pendingErrorStates, pendingErrorStatesForDefaultEntry);
} else { } else {
qWarning("Unrecoverable error detected in running state machine: %s", qWarning("Unrecoverable error detected in running state machine: %s",
qPrintable(errorString)); qPrintable(errorString));

View File

@ -8029,6 +8029,11 @@ QString &QString::setRawData(const QChar *unicode, int size)
Returns the Latin-1 string stored in this object. Returns the Latin-1 string stored in this object.
*/ */
/*! \fn const char *QLatin1String::data() const
Returns the Latin-1 string stored in this object.
*/
/*! \fn int QLatin1String::size() const /*! \fn int QLatin1String::size() const
Returns the size of the Latin-1 string stored in this object. Returns the size of the Latin-1 string stored in this object.
@ -8059,6 +8064,20 @@ QString &QString::setRawData(const QChar *unicode, int size)
go through QObject::tr(), for example. go through QObject::tr(), for example.
*/ */
/*!
\fn bool QLatin1String::operator==(const QByteArray &other) const
\since 5.0
\overload
The \a other byte array is converted to a QString using
the QString::fromUtf8() function.
You can disable this operator by defining \c
QT_NO_CAST_FROM_ASCII when you compile your applications. This
can be useful if you want to ensure that all user-visible strings
go through QObject::tr(), for example.
*/
/*! \fn bool QLatin1String::operator!=(const QString &other) const /*! \fn bool QLatin1String::operator!=(const QString &other) const
Returns \c true if this string is not equal to string \a other; Returns \c true if this string is not equal to string \a other;
@ -8084,6 +8103,20 @@ QString &QString::setRawData(const QChar *unicode, int size)
go through QObject::tr(), for example. go through QObject::tr(), for example.
*/ */
/*!
\fn bool QLatin1String::operator!=(const QByteArray &other) const
\since 5.0
\overload operator!=()
The \a other byte array is converted to a QString using
the QString::fromUtf8() function.
You can disable this operator by defining \c
QT_NO_CAST_FROM_ASCII when you compile your applications. This
can be useful if you want to ensure that all user-visible strings
go through QObject::tr(), for example.
*/
/*! /*!
\fn bool QLatin1String::operator>(const QString &other) const \fn bool QLatin1String::operator>(const QString &other) const
@ -8110,6 +8143,20 @@ QString &QString::setRawData(const QChar *unicode, int size)
for example. for example.
*/ */
/*!
\fn bool QLatin1String::operator>(const QByteArray &other) const
\since 5.0
\overload
The \a other const char pointer is converted to a QString using
the QString::fromUtf8() function.
You can disable this operator by defining \c QT_NO_CAST_FROM_ASCII
when you compile your applications. This can be useful if you want
to ensure that all user-visible strings go through QObject::tr(),
for example.
*/
/*! /*!
\fn bool QLatin1String::operator<(const QString &other) const \fn bool QLatin1String::operator<(const QString &other) const
@ -8136,6 +8183,20 @@ QString &QString::setRawData(const QChar *unicode, int size)
go through QObject::tr(), for example. go through QObject::tr(), for example.
*/ */
/*!
\fn bool QLatin1String::operator<(const QByteArray &other) const
\since 5.0
\overload
The \a other const char pointer is converted to a QString using
the QString::fromUtf8() function.
You can disable this operator by defining \c
QT_NO_CAST_FROM_ASCII when you compile your applications. This
can be useful if you want to ensure that all user-visible strings
go through QObject::tr(), for example.
*/
/*! /*!
\fn bool QLatin1String::operator>=(const QString &other) const \fn bool QLatin1String::operator>=(const QString &other) const
@ -8162,6 +8223,20 @@ QString &QString::setRawData(const QChar *unicode, int size)
go through QObject::tr(), for example. go through QObject::tr(), for example.
*/ */
/*!
\fn bool QLatin1String::operator>=(const QByteArray &other) const
\since 5.0
\overload
The \a other array is converted to a QString using
the QString::fromUtf8() function.
You can disable this operator by defining \c
QT_NO_CAST_FROM_ASCII when you compile your applications. This
can be useful if you want to ensure that all user-visible strings
go through QObject::tr(), for example.
*/
/*! \fn bool QLatin1String::operator<=(const QString &other) const /*! \fn bool QLatin1String::operator<=(const QString &other) const
Returns \c true if this string is lexically less than or equal Returns \c true if this string is lexically less than or equal
@ -8187,6 +8262,19 @@ QString &QString::setRawData(const QChar *unicode, int size)
go through QObject::tr(), for example. go through QObject::tr(), for example.
*/ */
/*!
\fn bool QLatin1String::operator<=(const QByteArray &other) const
\since 5.0
\overload
The \a other array is converted to a QString using
the QString::fromUtf8() function.
You can disable this operator by defining \c
QT_NO_CAST_FROM_ASCII when you compile your applications. This
can be useful if you want to ensure that all user-visible strings
go through QObject::tr(), for example.
*/
/*! \fn bool operator==(QLatin1String s1, QLatin1String s2) /*! \fn bool operator==(QLatin1String s1, QLatin1String s2)

View File

@ -639,6 +639,7 @@ bool QOpenGLContext::create()
*/ */
void QOpenGLContext::destroy() void QOpenGLContext::destroy()
{ {
deleteQGLContext();
Q_D(QOpenGLContext); Q_D(QOpenGLContext);
if (d->platformGLContext) if (d->platformGLContext)
emit aboutToBeDestroyed(); emit aboutToBeDestroyed();
@ -1086,6 +1087,9 @@ void *QOpenGLContext::qGLContextHandle() const
} }
/*! /*!
internal: If the delete function is specified QOpenGLContext "owns"
the passed context handle and will use the delete function to destroy it.
\internal \internal
*/ */
void QOpenGLContext::setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *)) void QOpenGLContext::setQGLContextHandle(void *handle,void (*qGLContextDeleteFunction)(void *))

View File

@ -198,6 +198,7 @@ class Q_GUI_EXPORT QOpenGLContextPrivate : public QObjectPrivate
public: public:
QOpenGLContextPrivate() QOpenGLContextPrivate()
: qGLContextHandle(0) : qGLContextHandle(0)
, qGLContextDeleteFunction(0)
, platformGLContext(0) , platformGLContext(0)
, shareContext(0) , shareContext(0)
, shareGroup(0) , shareGroup(0)

View File

@ -98,8 +98,10 @@ void QAbstractOpenGLFunctionsPrivate::removeFunctionsBackend(QOpenGLContext *con
Qt now provides a family of classes which all inherit from Qt now provides a family of classes which all inherit from
QAbstractOpenGLFunctions which expose every core OpenGL function by way of a QAbstractOpenGLFunctions which expose every core OpenGL function by way of a
corresponding member function. There is a class for every valid combination corresponding member function. There is a class for every valid combination
of OpenGL version and profile. Each class follows the naming convention of OpenGL version and profile. Each class follows the naming convention:
QOpenGLFunctions_<MAJOR VERSION>_<MINOR VERSION>[_PROFILE]. \badcode
QOpenGLFunctions_<MAJOR VERSION>_<MINOR VERSION>[_PROFILE]
\endcode
For OpenGL versions 1.0 through to 3.0 there are no profiles, leading to the For OpenGL versions 1.0 through to 3.0 there are no profiles, leading to the
classes: classes:

View File

@ -921,7 +921,7 @@ void QRasterPaintEngine::renderHintsChanged()
bool was_aa = s->flags.antialiased; bool was_aa = s->flags.antialiased;
bool was_bilinear = s->flags.bilinear; bool was_bilinear = s->flags.bilinear;
s->flags.antialiased = bool(s->renderHints & QPainter::Antialiasing); s->flags.antialiased = bool(s->renderHints & (QPainter::Antialiasing | QPainter::HighQualityAntialiasing));
s->flags.bilinear = bool(s->renderHints & QPainter::SmoothPixmapTransform); s->flags.bilinear = bool(s->renderHints & QPainter::SmoothPixmapTransform);
s->flags.legacy_rounding = !bool(s->renderHints & QPainter::Antialiasing) && bool(s->renderHints & QPainter::Qt4CompatiblePainting); s->flags.legacy_rounding = !bool(s->renderHints & QPainter::Antialiasing) && bool(s->renderHints & QPainter::Qt4CompatiblePainting);
@ -2726,7 +2726,7 @@ void QRasterPaintEngine::alphaPenBlt(const void* src, int bpl, int depth, int rx
scanline += bpl; scanline += bpl;
} }
} else { // 32-bit alpha... } else { // 32-bit alpha...
uint *sl = (uint *) src; uint *sl = (uint *) scanline;
for (int y = y0; y < y1; ++y) { for (int y = y0; y < y1; ++y) {
for (int x = x0; x < x1; ) { for (int x = x0; x < x1; ) {
// Skip those with 0 coverage // Skip those with 0 coverage

View File

@ -401,6 +401,16 @@ QString QPlatformFontDatabase::fontDir() const
return fontpath; return fontpath;
} }
/*!
Returns true if the font family is private. For any given family name,
the result is platform dependent.
*/
bool QPlatformFontDatabase::isPrivateFontFamily(const QString &family) const
{
Q_UNUSED(family);
return false;
}
/*! /*!
Returns the default system font. Returns the default system font.

View File

@ -110,6 +110,7 @@ public:
virtual QString fontDir() const; virtual QString fontDir() const;
virtual QFont defaultFont() const; virtual QFont defaultFont() const;
virtual bool isPrivateFontFamily(const QString &family) const;
virtual QString resolveFontFamilyAlias(const QString &family) const; virtual QString resolveFontFamilyAlias(const QString &family) const;
virtual bool fontsAlwaysScalable() const; virtual bool fontsAlwaysScalable() const;

View File

@ -2008,6 +2008,9 @@ static int qt_timeout_value(int msecs, int elapsed)
\note Multiple calls to this functions do not accumulate the time. \note Multiple calls to this functions do not accumulate the time.
If the function times out, the connecting process will be aborted. If the function times out, the connecting process will be aborted.
\note This function may fail randomly on Windows. Consider using the event
loop and the connected() signal if your software will run on Windows.
\sa connectToHost(), connected() \sa connectToHost(), connected()
*/ */
bool QAbstractSocket::waitForConnected(int msecs) bool QAbstractSocket::waitForConnected(int msecs)
@ -2107,6 +2110,9 @@ bool QAbstractSocket::waitForConnected(int msecs)
there is new data available for reading; otherwise it returns \c false there is new data available for reading; otherwise it returns \c false
(if an error occurred or the operation timed out). (if an error occurred or the operation timed out).
\note This function may fail randomly on Windows. Consider using the event
loop and the readyRead() signal if your software will run on Windows.
\sa waitForBytesWritten() \sa waitForBytesWritten()
*/ */
bool QAbstractSocket::waitForReadyRead(int msecs) bool QAbstractSocket::waitForReadyRead(int msecs)
@ -2166,6 +2172,20 @@ bool QAbstractSocket::waitForReadyRead(int msecs)
} }
/*! \reimp /*! \reimp
This function blocks until at least one byte has been written on the socket
and the \l{QIODevice::}{bytesWritten()} signal has been emitted. The
function will timeout after \a msecs milliseconds; the default timeout is
30000 milliseconds.
The function returns \c true if the bytesWritten() signal is emitted;
otherwise it returns \c false (if an error occurred or the operation timed
out).
\note This function may fail randomly on Windows. Consider using the event
loop and the bytesWritten() signal if your software will run on Windows.
\sa waitForReadyRead()
*/ */
bool QAbstractSocket::waitForBytesWritten(int msecs) bool QAbstractSocket::waitForBytesWritten(int msecs)
{ {
@ -2247,6 +2267,9 @@ bool QAbstractSocket::waitForBytesWritten(int msecs)
If msecs is -1, this function will not time out. If msecs is -1, this function will not time out.
\note This function may fail randomly on Windows. Consider using the event
loop and the disconnected() signal if your software will run on Windows.
\sa disconnectFromHost(), close() \sa disconnectFromHost(), close()
*/ */
bool QAbstractSocket::waitForDisconnected(int msecs) bool QAbstractSocket::waitForDisconnected(int msecs)

View File

@ -2126,7 +2126,7 @@ QGLContext::QGLContext(const QGLFormat &format)
d->init(0, format); d->init(0, format);
} }
void qDeleteQGLContext(void *handle) static void qDeleteQGLContext(void *handle)
{ {
QGLContext *context = static_cast<QGLContext *>(handle); QGLContext *context = static_cast<QGLContext *>(handle);
delete context; delete context;
@ -3475,7 +3475,7 @@ bool QGLContext::chooseContext(const QGLContext* shareContext)
d->valid = d->guiGlContext->create(); d->valid = d->guiGlContext->create();
if (d->valid) if (d->valid)
d->guiGlContext->setQGLContextHandle(this, qDeleteQGLContext); d->guiGlContext->setQGLContextHandle(this, 0);
d->glFormat = QGLFormat::fromSurfaceFormat(d->guiGlContext->format()); d->glFormat = QGLFormat::fromSurfaceFormat(d->guiGlContext->format());
d->setupSharing(); d->setupSharing();

View File

@ -242,6 +242,7 @@ public:
void swapRegion(const QRegion &region); void swapRegion(const QRegion &region);
QOpenGLContext *guiGlContext; QOpenGLContext *guiGlContext;
// true if QGLContext owns the QOpenGLContext (for who deletes who)
bool ownContext; bool ownContext;
void setupSharing(); void setupSharing();

View File

@ -211,6 +211,13 @@ void QCoreTextFontDatabase::populateFontDatabase()
QPlatformFontDatabase::registerAliasToFontFamily(familyName, localizedFamilyName); QPlatformFontDatabase::registerAliasToFontFamily(familyName, localizedFamilyName);
#endif #endif
} }
// Force creating the theme fonts to get the descriptors in m_systemFontDescriptors
if (m_themeFonts.isEmpty())
(void)themeFonts();
Q_FOREACH (CTFontDescriptorRef fontDesc, m_systemFontDescriptors)
populateFromDescriptor(fontDesc);
} }
void QCoreTextFontDatabase::populateFamily(const QString &familyName) void QCoreTextFontDatabase::populateFamily(const QString &familyName)
@ -231,16 +238,29 @@ void QCoreTextFontDatabase::populateFamily(const QString &familyName)
populateFromDescriptor(CTFontDescriptorRef(CFArrayGetValueAtIndex(matchingFonts, i))); populateFromDescriptor(CTFontDescriptorRef(CFArrayGetValueAtIndex(matchingFonts, i)));
} }
void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font) struct FontDescription {
QCFString familyName;
QCFString styleName;
QString foundryName;
QFont::Weight weight;
QFont::Style style;
QFont::Stretch stretch;
int pixelSize;
bool fixedPitch;
QSupportedWritingSystems writingSystems;
};
static void getFontDescription(CTFontDescriptorRef font, FontDescription *fd)
{ {
QString foundryName = QStringLiteral("CoreText");
QCFString familyName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
QCFString styleName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute);
QCFType<CFDictionaryRef> styles = (CFDictionaryRef) CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute); QCFType<CFDictionaryRef> styles = (CFDictionaryRef) CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute);
QFont::Weight weight = QFont::Normal;
QFont::Style style = QFont::StyleNormal; fd->foundryName = QStringLiteral("CoreText");
QFont::Stretch stretch = QFont::Unstretched; fd->familyName = (CFStringRef) CTFontDescriptorCopyAttribute(font, kCTFontFamilyNameAttribute);
bool fixedPitch = false; fd->styleName = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontStyleNameAttribute);
fd->weight = QFont::Normal;
fd->style = QFont::StyleNormal;
fd->stretch = QFont::Unstretched;
fd->fixedPitch = false;
if (styles) { if (styles) {
if (CFNumberRef weightValue = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontWeightTrait)) { if (CFNumberRef weightValue = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontWeightTrait)) {
@ -248,15 +268,15 @@ void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font)
double normalizedWeight; double normalizedWeight;
if (CFNumberGetValue(weightValue, kCFNumberDoubleType, &normalizedWeight)) { if (CFNumberGetValue(weightValue, kCFNumberDoubleType, &normalizedWeight)) {
if (normalizedWeight >= 0.62) if (normalizedWeight >= 0.62)
weight = QFont::Black; fd->weight = QFont::Black;
else if (normalizedWeight >= 0.4) else if (normalizedWeight >= 0.4)
weight = QFont::Bold; fd->weight = QFont::Bold;
else if (normalizedWeight >= 0.3) else if (normalizedWeight >= 0.3)
weight = QFont::DemiBold; fd->weight = QFont::DemiBold;
else if (normalizedWeight == 0.0) else if (normalizedWeight == 0.0)
weight = QFont::Normal; fd->weight = QFont::Normal;
else if (normalizedWeight <= -0.4) else if (normalizedWeight <= -0.4)
weight = QFont::Light; fd->weight = QFont::Light;
} }
} }
if (CFNumberRef italic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSlantTrait)) { if (CFNumberRef italic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSlantTrait)) {
@ -264,34 +284,32 @@ void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font)
double d; double d;
if (CFNumberGetValue(italic, kCFNumberDoubleType, &d)) { if (CFNumberGetValue(italic, kCFNumberDoubleType, &d)) {
if (d > 0.0) if (d > 0.0)
style = QFont::StyleItalic; fd->style = QFont::StyleItalic;
} }
} }
if (CFNumberRef symbolic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSymbolicTrait)) { if (CFNumberRef symbolic = (CFNumberRef) CFDictionaryGetValue(styles, kCTFontSymbolicTrait)) {
int d; int d;
if (CFNumberGetValue(symbolic, kCFNumberSInt32Type, &d)) { if (CFNumberGetValue(symbolic, kCFNumberSInt32Type, &d)) {
if (d & kCTFontMonoSpaceTrait) if (d & kCTFontMonoSpaceTrait)
fixedPitch = true; fd->fixedPitch = true;
if (d & kCTFontExpandedTrait) if (d & kCTFontExpandedTrait)
stretch = QFont::Expanded; fd->stretch = QFont::Expanded;
else if (d & kCTFontCondensedTrait) else if (d & kCTFontCondensedTrait)
stretch = QFont::Condensed; fd->stretch = QFont::Condensed;
} }
} }
} }
int pixelSize = 0;
if (QCFType<CFNumberRef> size = (CFNumberRef) CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) { if (QCFType<CFNumberRef> size = (CFNumberRef) CTFontDescriptorCopyAttribute(font, kCTFontSizeAttribute)) {
if (CFNumberIsFloatType(size)) { if (CFNumberIsFloatType(size)) {
double d; double d;
CFNumberGetValue(size, kCFNumberDoubleType, &d); CFNumberGetValue(size, kCFNumberDoubleType, &d);
pixelSize = d; fd->pixelSize = d;
} else { } else {
CFNumberGetValue(size, kCFNumberIntType, &pixelSize); CFNumberGetValue(size, kCFNumberIntType, &fd->pixelSize);
} }
} }
QSupportedWritingSystems writingSystems;
if (QCFType<CFArrayRef> languages = (CFArrayRef) CTFontDescriptorCopyAttribute(font, kCTFontLanguagesAttribute)) { if (QCFType<CFArrayRef> languages = (CFArrayRef) CTFontDescriptorCopyAttribute(font, kCTFontLanguagesAttribute)) {
CFIndex length = CFArrayGetCount(languages); CFIndex length = CFArrayGetCount(languages);
for (int i = 1; i < LanguageCount; ++i) { for (int i = 1; i < LanguageCount; ++i) {
@ -299,14 +317,24 @@ void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font)
continue; continue;
QCFString lang = CFStringCreateWithCString(NULL, languageForWritingSystem[i], kCFStringEncodingASCII); QCFString lang = CFStringCreateWithCString(NULL, languageForWritingSystem[i], kCFStringEncodingASCII);
if (CFArrayContainsValue(languages, CFRangeMake(0, length), lang)) if (CFArrayContainsValue(languages, CFRangeMake(0, length), lang))
writingSystems.setSupported(QFontDatabase::WritingSystem(i)); fd->writingSystems.setSupported(QFontDatabase::WritingSystem(i));
} }
} }
}
void QCoreTextFontDatabase::populateFromDescriptor(CTFontDescriptorRef font)
{
FontDescription fd;
getFontDescription(font, &fd);
populateFromFontDescription(font, fd);
}
void QCoreTextFontDatabase::populateFromFontDescription(CTFontDescriptorRef font, const FontDescription &fd)
{
CFRetain(font); CFRetain(font);
QPlatformFontDatabase::registerFont(familyName, styleName, foundryName, weight, style, stretch, QPlatformFontDatabase::registerFont(fd.familyName, fd.styleName, fd.foundryName, fd.weight, fd.style, fd.stretch,
true /* antialiased */, true /* scalable */, true /* antialiased */, true /* scalable */,
pixelSize, fixedPitch, writingSystems, (void *) font); fd.pixelSize, fd.fixedPitch, fd.writingSystems, (void *) font);
} }
void QCoreTextFontDatabase::releaseHandle(void *handle) void QCoreTextFontDatabase::releaseHandle(void *handle)
@ -612,6 +640,113 @@ QStringList QCoreTextFontDatabase::addApplicationFont(const QByteArray &fontData
return families; return families;
} }
bool QCoreTextFontDatabase::isPrivateFontFamily(const QString &family) const
{
if (family.startsWith(QLatin1Char('.')))
return true;
return QPlatformFontDatabase::isPrivateFontFamily(family);
}
static CTFontUIFontType fontTypeFromTheme(QPlatformTheme::Font f)
{
switch (f) {
case QPlatformTheme::SystemFont:
return kCTFontSystemFontType;
case QPlatformTheme::MenuFont:
case QPlatformTheme::MenuBarFont:
case QPlatformTheme::MenuItemFont:
return kCTFontMenuItemFontType;
case QPlatformTheme::MessageBoxFont:
return kCTFontEmphasizedSystemFontType;
case QPlatformTheme::LabelFont:
return kCTFontSystemFontType;
case QPlatformTheme::TipLabelFont:
return kCTFontToolTipFontType;
case QPlatformTheme::StatusBarFont:
return kCTFontSystemFontType;
case QPlatformTheme::TitleBarFont:
return kCTFontWindowTitleFontType;
case QPlatformTheme::MdiSubWindowTitleFont:
case QPlatformTheme::DockWidgetTitleFont:
return kCTFontSystemFontType;
case QPlatformTheme::PushButtonFont:
return kCTFontPushButtonFontType;
case QPlatformTheme::CheckBoxFont:
case QPlatformTheme::RadioButtonFont:
return kCTFontSystemFontType;
case QPlatformTheme::ToolButtonFont:
return kCTFontSmallToolbarFontType;
case QPlatformTheme::ItemViewFont:
return kCTFontSystemFontType;
case QPlatformTheme::ListViewFont:
return kCTFontViewsFontType;
case QPlatformTheme::HeaderViewFont:
return kCTFontSmallSystemFontType;
case QPlatformTheme::ListBoxFont:
return kCTFontViewsFontType;
case QPlatformTheme::ComboMenuItemFont:
return kCTFontSystemFontType;
case QPlatformTheme::ComboLineEditFont:
return kCTFontViewsFontType;
case QPlatformTheme::SmallFont:
return kCTFontSmallSystemFontType;
case QPlatformTheme::MiniFont:
return kCTFontMiniSystemFontType;
case QPlatformTheme::FixedFont:
return kCTFontUserFixedPitchFontType;
default:
return kCTFontSystemFontType;
}
}
const QHash<QPlatformTheme::Font, QFont *> &QCoreTextFontDatabase::themeFonts() const
{
if (m_themeFonts.isEmpty()) {
for (long f = QPlatformTheme::SystemFont; f < QPlatformTheme::NFonts; f++) {
QPlatformTheme::Font ft = static_cast<QPlatformTheme::Font>(f);
m_themeFonts.insert(ft, themeFont(ft));
}
}
return m_themeFonts;
}
QFont *QCoreTextFontDatabase::themeFont(QPlatformTheme::Font f) const
{
CTFontUIFontType fontType = fontTypeFromTheme(f);
QCFType<CTFontRef> ctFont = CTFontCreateUIFontForLanguage(fontType, 0.0, NULL);
CTFontDescriptorRef fontDesc = CTFontCopyFontDescriptor(ctFont);
FontDescription fd;
getFontDescription(fontDesc, &fd);
m_systemFontDescriptors.insert(fontDesc);
QFont *font = new QFont(fd.familyName, fd.pixelSize, fd.weight, fd.style == QFont::StyleItalic);
return font;
}
QFont QCoreTextFontDatabase::defaultFont() const QFont QCoreTextFontDatabase::defaultFont() const
{ {
if (defaultFontName.isEmpty()) { if (defaultFontName.isEmpty()) {

View File

@ -47,6 +47,7 @@
#define HAVE_ATS QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_5, __IPHONE_NA) #define HAVE_ATS QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_5, __IPHONE_NA)
#include <qpa/qplatformfontdatabase.h> #include <qpa/qplatformfontdatabase.h>
#include <qpa/qplatformtheme.h>
#include <private/qcore_mac_p.h> #include <private/qcore_mac_p.h>
#ifndef Q_OS_IOS #ifndef Q_OS_IOS
@ -66,6 +67,8 @@ Q_DECLARE_METATYPE(ATSFontContainerRef);
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
struct FontDescription;
class QCoreTextFontDatabase : public QPlatformFontDatabase class QCoreTextFontDatabase : public QPlatformFontDatabase
{ {
public: public:
@ -79,17 +82,25 @@ public:
QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const; QStringList fallbacksForFamily(const QString &family, QFont::Style style, QFont::StyleHint styleHint, QChar::Script script) const;
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName); QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
void releaseHandle(void *handle); void releaseHandle(void *handle);
bool isPrivateFontFamily(const QString &family) const;
QFont defaultFont() const; QFont defaultFont() const;
QList<int> standardSizes() const; QList<int> standardSizes() const;
// For iOS and OS X platform themes
QFont *themeFont(QPlatformTheme::Font) const;
const QHash<QPlatformTheme::Font, QFont *> &themeFonts() const;
private: private:
void populateFromDescriptor(CTFontDescriptorRef font); void populateFromDescriptor(CTFontDescriptorRef font);
void populateFromFontDescription(CTFontDescriptorRef font, const FontDescription &fd);
mutable QString defaultFontName; mutable QString defaultFontName;
void removeApplicationFonts(); void removeApplicationFonts();
QVector<QVariant> m_applicationFonts; QVector<QVariant> m_applicationFonts;
mutable QSet<CTFontDescriptorRef> m_systemFontDescriptors;
mutable QHash<QPlatformTheme::Font, QFont *> m_themeFonts;
}; };
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -401,10 +401,8 @@ namespace QtAndroid
{ {
QMutexLocker lock(&m_surfacesMutex); QMutexLocker lock(&m_surfacesMutex);
const auto &it = m_surfaces.find(surfaceId); const auto &it = m_surfaces.find(surfaceId);
if (it == m_surfaces.end()) if (it != m_surfaces.end())
return; m_surfaces.remove(surfaceId);
m_surfaces.remove(surfaceId);
if (m_surfaces.isEmpty()) if (m_surfaces.isEmpty())
m_surfaceId = 1; m_surfaceId = 1;

View File

@ -54,11 +54,10 @@ QAndroidPlatformServices::QAndroidPlatformServices()
bool QAndroidPlatformServices::openUrl(const QUrl &url) bool QAndroidPlatformServices::openUrl(const QUrl &url)
{ {
QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString()); QJNIObjectPrivate urlString = QJNIObjectPrivate::fromString(url.toString());
QJNIObjectPrivate::callStaticMethod<void>(QtAndroid::applicationClass(), return QJNIObjectPrivate::callStaticMethod<jboolean>(QtAndroid::applicationClass(),
"openURL", "openURL",
"(Ljava/lang/String;)V", "(Ljava/lang/String;)Z",
urlString.object()); urlString.object());
return true;
} }
bool QAndroidPlatformServices::openDocument(const QUrl &url) bool QAndroidPlatformServices::openDocument(const QUrl &url)

View File

@ -50,7 +50,6 @@ QT_BEGIN_NAMESPACE
QPalette * qt_mac_createSystemPalette(); QPalette * qt_mac_createSystemPalette();
QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes(); QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes();
QHash<QPlatformTheme::Font, QFont *> qt_mac_createRoleFonts();
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -213,48 +213,4 @@ QHash<QPlatformTheme::Palette, QPalette*> qt_mac_createRolePalettes()
return palettes; return palettes;
} }
QFont *qt_mac_qfontForThemeFont(ThemeFontID themeID)
{
CTFontUIFontType ctID = HIThemeGetUIFontType(themeID);
QCFType<CTFontRef> ctfont = CTFontCreateUIFontForLanguage(ctID, 0, 0);
QString familyName = QCFString(CTFontCopyFamilyName(ctfont));
QCFType<CFDictionaryRef> dict = CTFontCopyTraits(ctfont);
CFNumberRef num = static_cast<CFNumberRef>(CFDictionaryGetValue(dict, kCTFontWeightTrait));
float fW;
CFNumberGetValue(num, kCFNumberFloat32Type, &fW);
QFont::Weight wght = fW > 0. ? QFont::Bold : QFont::Normal;
num = static_cast<CFNumberRef>(CFDictionaryGetValue(dict, kCTFontSlantTrait));
CFNumberGetValue(num, kCFNumberFloatType, &fW);
bool italic = (fW != 0.0);
return new QFont(familyName, CTFontGetSize(ctfont), wght, italic);
}
QHash<QPlatformTheme::Font, QFont *> qt_mac_createRoleFonts()
{
QHash<QPlatformTheme::Font, QFont *> fonts;
fonts.insert(QPlatformTheme::SystemFont, qt_mac_qfontForThemeFont(kThemeApplicationFont));
fonts.insert(QPlatformTheme::PushButtonFont, qt_mac_qfontForThemeFont(kThemePushButtonFont));
fonts.insert(QPlatformTheme::ListViewFont, qt_mac_qfontForThemeFont(kThemeViewsFont));
fonts.insert(QPlatformTheme::ListBoxFont, qt_mac_qfontForThemeFont(kThemeViewsFont));
fonts.insert(QPlatformTheme::TitleBarFont, qt_mac_qfontForThemeFont(kThemeWindowTitleFont));
fonts.insert(QPlatformTheme::MenuFont, qt_mac_qfontForThemeFont(kThemeMenuItemFont));
fonts.insert(QPlatformTheme::MenuBarFont, qt_mac_qfontForThemeFont(kThemeMenuItemFont));
fonts.insert(QPlatformTheme::ComboMenuItemFont, qt_mac_qfontForThemeFont(kThemeSystemFont));
fonts.insert(QPlatformTheme::HeaderViewFont, qt_mac_qfontForThemeFont(kThemeSmallSystemFont));
fonts.insert(QPlatformTheme::TipLabelFont, qt_mac_qfontForThemeFont(kThemeSmallSystemFont));
fonts.insert(QPlatformTheme::LabelFont, qt_mac_qfontForThemeFont(kThemeSystemFont));
fonts.insert(QPlatformTheme::ToolButtonFont, qt_mac_qfontForThemeFont(kThemeSmallSystemFont));
fonts.insert(QPlatformTheme::MenuItemFont, qt_mac_qfontForThemeFont(kThemeMenuItemFont));
fonts.insert(QPlatformTheme::ComboLineEditFont, qt_mac_qfontForThemeFont(kThemeViewsFont));
fonts.insert(QPlatformTheme::SmallFont, qt_mac_qfontForThemeFont(kThemeSmallSystemFont));
fonts.insert(QPlatformTheme::MiniFont, qt_mac_qfontForThemeFont(kThemeMiniSystemFont));
QFont* fixedFont = new QFont(QStringLiteral("Monaco"), fonts[QPlatformTheme::SystemFont]->pointSize());
fixedFont->setStyleHint(QFont::TypeWriter);
fonts.insert(QPlatformTheme::FixedFont, fixedFont);
return fonts;
}
QT_END_NAMESPACE QT_END_NAMESPACE

View File

@ -60,6 +60,7 @@
#include <QtCore/qfileinfo.h> #include <QtCore/qfileinfo.h>
#include <QtGui/private/qguiapplication_p.h> #include <QtGui/private/qguiapplication_p.h>
#include <QtGui/qpainter.h> #include <QtGui/qpainter.h>
#include <QtPlatformSupport/private/qcoretextfontdatabase_p.h>
#include <qpa/qplatformintegration.h> #include <qpa/qplatformintegration.h>
#include <qpa/qplatformnativeinterface.h> #include <qpa/qplatformnativeinterface.h>
@ -134,6 +135,12 @@ const QPalette *QCocoaTheme::palette(Palette type) const
return 0; return 0;
} }
QHash<QPlatformTheme::Font, QFont *> qt_mac_createRoleFonts()
{
QCoreTextFontDatabase *ctfd = static_cast<QCoreTextFontDatabase *>(QGuiApplicationPrivate::platformIntegration()->fontDatabase());
return ctfd->themeFonts();
}
const QFont *QCocoaTheme::font(Font type) const const QFont *QCocoaTheme::font(Font type) const
{ {
if (m_fonts.isEmpty()) { if (m_fonts.isEmpty()) {

View File

@ -46,6 +46,10 @@
#include <QtGui/QFont> #include <QtGui/QFont>
#include <QtPlatformSupport/private/qcoretextfontdatabase_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
#include <UIKit/UIFont.h> #include <UIKit/UIFont.h>
#include <UIKit/UIInterface.h> #include <UIKit/UIInterface.h>
@ -75,19 +79,8 @@ QVariant QIOSTheme::themeHint(ThemeHint hint) const
const QFont *QIOSTheme::font(Font type) const const QFont *QIOSTheme::font(Font type) const
{ {
if (m_fonts.isEmpty()) { if (m_fonts.isEmpty()) {
// The real system font on iOS is '.Helvetica Neue UI', as returned by both [UIFont systemFontOfSize] QCoreTextFontDatabase *ctfd = static_cast<QCoreTextFontDatabase *>(QGuiApplicationPrivate::platformIntegration()->fontDatabase());
// and CTFontCreateUIFontForLanguage(kCTFontSystemFontType, ...), but this font is not included when m_fonts = ctfd->themeFonts();
// populating the available fonts in QCoreTextFontDatabase::populateFontDatabase(), since the font
// is internal to iOS and not supposed to be used by applications. We could potentially add this
// font to the font-database, but it would then show up when enumerating user fonts from Qt
// applications since we don't have a flag in Qt to mark a font as a private system font.
// For now we hard-code the font to Helvetica, which should be very close to the actual
// system font.
QLatin1String systemFontFamilyName("Helvetica");
m_fonts.insert(QPlatformTheme::SystemFont, new QFont(systemFontFamilyName, [UIFont systemFontSize]));
m_fonts.insert(QPlatformTheme::SmallFont, new QFont(systemFontFamilyName, [UIFont smallSystemFontSize]));
m_fonts.insert(QPlatformTheme::LabelFont, new QFont(systemFontFamilyName, [UIFont labelFontSize]));
m_fonts.insert(QPlatformTheme::PushButtonFont, new QFont(systemFontFamilyName, [UIFont buttonFontSize]));
} }
return m_fonts.value(type, 0); return m_fonts.value(type, 0);

View File

@ -1345,6 +1345,7 @@ void QWindowsMultiFontEngine::loadEngine(int at)
fontEngine->fontDef.pixelSize, fontEngine->fontDef.pixelSize,
data); data);
fedw->fontDef = fontDef; fedw->fontDef = fontDef;
fedw->fontDef.family = fam;
fedw->ref.ref(); fedw->ref.ref();
engines[at] = fedw; engines[at] = fedw;
@ -1370,6 +1371,7 @@ void QWindowsMultiFontEngine::loadEngine(int at)
engines[at] = new QWindowsFontEngine(fam, hfont, stockFont, lf, data); engines[at] = new QWindowsFontEngine(fam, hfont, stockFont, lf, data);
engines[at]->ref.ref(); engines[at]->ref.ref();
engines[at]->fontDef = fontDef; engines[at]->fontDef = fontDef;
engines[at]->fontDef.family = fam;
qCDebug(lcQpaFonts) << __FUNCTION__ << at << fam; qCDebug(lcQpaFonts) << __FUNCTION__ << at << fam;
// TODO: increase cost in QFontCache for the font engine loaded here // TODO: increase cost in QFontCache for the font engine loaded here

View File

@ -308,7 +308,13 @@ QUrl QGtk2FileDialogHelper::directory() const
void QGtk2FileDialogHelper::selectFile(const QUrl &filename) void QGtk2FileDialogHelper::selectFile(const QUrl &filename)
{ {
GtkDialog *gtkDialog = d->gtkDialog(); GtkDialog *gtkDialog = d->gtkDialog();
gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(gtkDialog), filename.toLocalFile().toUtf8()); if (options()->acceptMode() == QFileDialogOptions::AcceptSave) {
QFileInfo fi(filename.toLocalFile());
gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(gtkDialog), fi.path().toUtf8());
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(gtkDialog), fi.fileName().toUtf8());
} else {
gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(gtkDialog), filename.toLocalFile().toUtf8());
}
} }
QList<QUrl> QGtk2FileDialogHelper::selectedFiles() const QList<QUrl> QGtk2FileDialogHelper::selectedFiles() const

View File

@ -203,7 +203,7 @@ bool QWin32PrintEngine::newPage()
bool transparent = GetBkMode(d->hdc) == TRANSPARENT; bool transparent = GetBkMode(d->hdc) == TRANSPARENT;
if (!EndPage(d->hdc)) { if (EndPage(d->hdc) <= 0) {
qErrnoWarning("QWin32PrintEngine::newPage: EndPage failed"); qErrnoWarning("QWin32PrintEngine::newPage: EndPage failed");
return false; return false;
} }
@ -216,7 +216,7 @@ bool QWin32PrintEngine::newPage()
d->reinit = false; d->reinit = false;
} }
if (!StartPage(d->hdc)) { if (StartPage(d->hdc) <= 0) {
qErrnoWarning("Win32PrintEngine::newPage: StartPage failed"); qErrnoWarning("Win32PrintEngine::newPage: StartPage failed");
return false; return false;
} }
@ -235,7 +235,7 @@ bool QWin32PrintEngine::newPage()
bool success = false; bool success = false;
if (d->hdc && d->state == QPrinter::Active) { if (d->hdc && d->state == QPrinter::Active) {
if (EndPage(d->hdc) != SP_ERROR) { if (EndPage(d->hdc) > 0) {
// reinitialize the DC before StartPage if needed, // reinitialize the DC before StartPage if needed,
// because resetdc is disabled between calls to the StartPage and EndPage functions // because resetdc is disabled between calls to the StartPage and EndPage functions
// (see StartPage documentation in the Platform SDK:Windows GDI) // (see StartPage documentation in the Platform SDK:Windows GDI)
@ -248,7 +248,7 @@ bool QWin32PrintEngine::newPage()
qErrnoWarning("QWin32PrintEngine::newPage(), ResetDC failed (2)"); qErrnoWarning("QWin32PrintEngine::newPage(), ResetDC failed (2)");
d->reinit = false; d->reinit = false;
} }
success = (StartPage(d->hdc) != SP_ERROR); success = (StartPage(d->hdc) > 0);
} }
if (!success) { if (!success) {
d->state = QPrinter::Aborted; d->state = QPrinter::Aborted;

View File

@ -91,9 +91,7 @@ Q_GLOBAL_STATIC(QUrl, lastVisitedDir)
The QFileDialog class enables a user to traverse the file system in The QFileDialog class enables a user to traverse the file system in
order to select one or many files or a directory. order to select one or many files or a directory.
The easiest way to create a QFileDialog is to use the static The easiest way to create a QFileDialog is to use the static functions.
functions. On Windows, Mac OS X, KDE and GNOME, these static functions will
call the native file dialog when possible.
\snippet code/src_gui_dialogs_qfiledialog.cpp 0 \snippet code/src_gui_dialogs_qfiledialog.cpp 0

View File

@ -65,6 +65,10 @@
#include <private/qdialog_p.h> #include <private/qdialog_p.h>
#include <private/qfont_p.h> #include <private/qfont_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformfontdatabase.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QFontListView : public QListView class QFontListView : public QListView
@ -485,8 +489,13 @@ void QFontDialogPrivate::updateFamilies()
const QFontDialog::FontDialogOptions spacingMask = (QFontDialog::ProportionalFonts | QFontDialog::MonospacedFonts); const QFontDialog::FontDialogOptions spacingMask = (QFontDialog::ProportionalFonts | QFontDialog::MonospacedFonts);
const QFontDialog::FontDialogOptions options = q->options(); const QFontDialog::FontDialogOptions options = q->options();
QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
QStringList familyNames; QStringList familyNames;
foreach (const QString &family, fdb.families(writingSystem)) { foreach (const QString &family, fdb.families(writingSystem)) {
if (pfdb->isPrivateFontFamily(family))
continue;
if ((options & scalableMask) && (options & scalableMask) != scalableMask) { if ((options & scalableMask) && (options & scalableMask) != scalableMask) {
if (bool(options & QFontDialog::ScalableFonts) != fdb.isSmoothlyScalable(family)) if (bool(options & QFontDialog::ScalableFonts) != fdb.isSmoothlyScalable(family))
continue; continue;

View File

@ -1370,6 +1370,15 @@ bool QAbstractItemView::tabKeyNavigation() const
return d->tabKeyNavigation; return d->tabKeyNavigation;
} }
/*!
\since 5.2
\reimp
*/
QSize QAbstractItemView::viewportSizeHint() const
{
return QAbstractScrollArea::viewportSizeHint();
}
#ifndef QT_NO_DRAGANDDROP #ifndef QT_NO_DRAGANDDROP
/*! /*!
\property QAbstractItemView::showDropIndicator \property QAbstractItemView::showDropIndicator
@ -1390,15 +1399,6 @@ bool QAbstractItemView::showDropIndicator() const
return d->showDropIndicator; return d->showDropIndicator;
} }
/*!
\since 5.2
\reimp
*/
QSize QAbstractItemView::viewportSizeHint() const
{
return QAbstractScrollArea::viewportSizeHint();
}
/*! /*!
\property QAbstractItemView::dragEnabled \property QAbstractItemView::dragEnabled
\brief whether the view supports dragging of its own items \brief whether the view supports dragging of its own items

View File

@ -53,6 +53,10 @@
#include <QDesktopWidget> #include <QDesktopWidget>
#include <qdebug.h> #include <qdebug.h>
#include <QtGui/private/qguiapplication_p.h>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformfontdatabase.h>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
static QFontDatabase::WritingSystem writingSystemFromScript(QLocale::Script script) static QFontDatabase::WritingSystem writingSystemFromScript(QLocale::Script script)
@ -328,7 +332,12 @@ void QFontComboBoxPrivate::_q_updateModel()
int offset = 0; int offset = 0;
QFontInfo fi(currentFont); QFontInfo fi(currentFont);
QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase();
for (int i = 0; i < list.size(); ++i) { for (int i = 0; i < list.size(); ++i) {
if (pfdb->isPrivateFontFamily(list.at(i)))
continue;
if ((filters & scalableMask) && (filters & scalableMask) != scalableMask) { if ((filters & scalableMask) && (filters & scalableMask) != scalableMask) {
if (bool(filters & QFontComboBox::ScalableFonts) != fdb.isSmoothlyScalable(list.at(i))) if (bool(filters & QFontComboBox::ScalableFonts) != fdb.isSmoothlyScalable(list.at(i)))
continue; continue;

View File

@ -41,6 +41,7 @@
#include <QtCore/qpropertyanimation.h> #include <QtCore/qpropertyanimation.h>
#include <QtWidgets/qwidget.h> #include <QtWidgets/qwidget.h>
#include <QtWidgets/qstyle.h>
#include <private/qmainwindowlayout_p.h> #include <private/qmainwindowlayout_p.h>
#include "qwidgetanimator_p.h" #include "qwidgetanimator_p.h"

View File

@ -29,10 +29,7 @@ load(qt_installs)
TARGET = $$qtLibraryTarget($$TARGET$$QT_LIBINFIX) #do this towards the end TARGET = $$qtLibraryTarget($$TARGET$$QT_LIBINFIX) #do this towards the end
load(qt_targets) load(qt_targets)
load(qt_build_paths)
load(qt_common)
wince*:QMAKE_POST_LINK = wince*:QMAKE_POST_LINK =
lib_replace.match = $$[QT_INSTALL_LIBS/get]
lib_replace.replace = $$[QT_INSTALL_LIBS/raw]
lib_replace.CONFIG = path
QMAKE_PRL_INSTALL_REPLACE += lib_replace

View File

@ -6174,6 +6174,18 @@ void tst_QObject::connectBase()
QCOMPARE( r1.count_slot1, 1 ); QCOMPARE( r1.count_slot1, 1 );
QCOMPARE( r1.count_slot2, 1 ); QCOMPARE( r1.count_slot2, 1 );
QCOMPARE( r1.count_slot3, 1 ); QCOMPARE( r1.count_slot3, 1 );
QVERIFY( QObject::disconnect( &sub, &SubSender::signal1 , &r1, &ReceiverObject::slot1 ) );
QVERIFY( QObject::disconnect( &sub, static_cast<void (SenderObject::*)()>(&SubSender::signal2) , &r1, &ReceiverObject::slot2 ) );
QVERIFY( QObject::disconnect( &sub, static_cast<void (SubSender::*)()>(&SubSender::signal3) , &r1, &ReceiverObject::slot3 ) );
sub.emitSignal1();
sub.emitSignal2();
sub.emitSignal3();
QCOMPARE( r1.count_slot1, 1 );
QCOMPARE( r1.count_slot2, 1 );
QCOMPARE( r1.count_slot3, 1 );
} }
struct QmlReceiver : public QtPrivate::QSlotObjectBase struct QmlReceiver : public QtPrivate::QSlotObjectBase

View File

@ -5766,6 +5766,9 @@ void tst_QStateMachine::propertiesAreAssignedBeforeEntryCallbacks()
// QTBUG-25958 // QTBUG-25958
void tst_QStateMachine::multiTargetTransitionInsideParallelStateGroup() void tst_QStateMachine::multiTargetTransitionInsideParallelStateGroup()
{ {
// TODO QTBUG-25958 was reopened, see https://codereview.qt-project.org/89775
return;
QStateMachine machine; QStateMachine machine;
QState *s1 = new QState(&machine); QState *s1 = new QState(&machine);
DEFINE_ACTIVE_SPY(s1); DEFINE_ACTIVE_SPY(s1);

View File

@ -84,6 +84,14 @@ private slots:
void eraseValidIteratorOnSharedHash(); void eraseValidIteratorOnSharedHash();
}; };
struct IdentityTracker {
int value, id;
};
inline uint qHash(IdentityTracker key) { return qHash(key.value); }
inline bool operator==(IdentityTracker lhs, IdentityTracker rhs) { return lhs.value == rhs.value; }
struct Foo { struct Foo {
static int count; static int count;
Foo():c(count) { ++count; } Foo():c(count) { ++count; }
@ -443,6 +451,32 @@ void tst_QHash::insert1()
QVERIFY(((const QHash<int,int*>*) &hash)->operator[](7) == 0); QVERIFY(((const QHash<int,int*>*) &hash)->operator[](7) == 0);
} }
} }
{
QHash<IdentityTracker, int> hash;
QCOMPARE(hash.size(), 0);
const int dummy = -1;
IdentityTracker id00 = {0, 0}, id01 = {0, 1}, searchKey = {0, dummy};
QCOMPARE(hash.insert(id00, id00.id).key().id, id00.id);
QCOMPARE(hash.size(), 1);
QCOMPARE(hash.insert(id01, id01.id).key().id, id00.id); // first key inserted is kept
QCOMPARE(hash.size(), 1);
QCOMPARE(hash.find(searchKey).value(), id01.id); // last-inserted value
QCOMPARE(hash.find(searchKey).key().id, id00.id); // but first-inserted key
}
{
QMultiHash<IdentityTracker, int> hash;
QCOMPARE(hash.size(), 0);
const int dummy = -1;
IdentityTracker id00 = {0, 0}, id01 = {0, 1}, searchKey = {0, dummy};
QCOMPARE(hash.insert(id00, id00.id).key().id, id00.id);
QCOMPARE(hash.size(), 1);
QCOMPARE(hash.insert(id01, id01.id).key().id, id01.id);
QCOMPARE(hash.size(), 2);
QMultiHash<IdentityTracker, int>::const_iterator pos = hash.constFind(searchKey);
QCOMPARE(pos.value(), pos.key().id); // key fits to value it was inserted with
++pos;
QCOMPARE(pos.value(), pos.key().id); // key fits to value it was inserted with
}
} }
void tst_QHash::erase() void tst_QHash::erase()

View File

@ -89,6 +89,12 @@ private slots:
void eraseValidIteratorOnSharedMap(); void eraseValidIteratorOnSharedMap();
}; };
struct IdentityTracker {
int value, id;
};
inline bool operator<(IdentityTracker lhs, IdentityTracker rhs) { return lhs.value < rhs.value; }
typedef QMap<QString, QString> StringMap; typedef QMap<QString, QString> StringMap;
class MyClass class MyClass
@ -1122,6 +1128,33 @@ void tst_QMap::insert()
QCOMPARE(intMap.size(), 1000); QCOMPARE(intMap.size(), 1000);
QCOMPARE(intMap.value(i), -1); QCOMPARE(intMap.value(i), -1);
} }
{
QMap<IdentityTracker, int> map;
QCOMPARE(map.size(), 0);
const int dummy = -1;
IdentityTracker id00 = {0, 0}, id01 = {0, 1}, searchKey = {0, dummy};
QCOMPARE(map.insert(id00, id00.id).key().id, id00.id);
QCOMPARE(map.size(), 1);
QCOMPARE(map.insert(id01, id01.id).key().id, id00.id); // first key inserted is kept
QCOMPARE(map.size(), 1);
QCOMPARE(map.find(searchKey).value(), id01.id); // last-inserted value
QCOMPARE(map.find(searchKey).key().id, id00.id); // but first-inserted key
}
{
QMultiMap<IdentityTracker, int> map;
QCOMPARE(map.size(), 0);
const int dummy = -1;
IdentityTracker id00 = {0, 0}, id01 = {0, 1}, searchKey = {0, dummy};
QCOMPARE(map.insert(id00, id00.id).key().id, id00.id);
QCOMPARE(map.size(), 1);
QCOMPARE(map.insert(id01, id01.id).key().id, id01.id);
QCOMPARE(map.size(), 2);
QMultiMap<IdentityTracker, int>::const_iterator pos = map.constFind(searchKey);
QCOMPARE(pos.value(), pos.key().id); // key fits to value it was inserted with
++pos;
QCOMPARE(pos.value(), pos.key().id); // key fits to value it was inserted with
}
} }
void tst_QMap::checkMostLeftNode() void tst_QMap::checkMostLeftNode()

View File

@ -82,6 +82,13 @@ private slots:
void initializerList(); void initializerList();
}; };
struct IdentityTracker {
int value, id;
};
inline uint qHash(IdentityTracker key) { return qHash(key.value); }
inline bool operator==(IdentityTracker lhs, IdentityTracker rhs) { return lhs.value == rhs.value; }
void tst_QSet::operator_eq() void tst_QSet::operator_eq()
{ {
{ {
@ -530,6 +537,18 @@ void tst_QSet::insert()
QVERIFY(set1.size() == 2); QVERIFY(set1.size() == 2);
QVERIFY(set1.contains(2)); QVERIFY(set1.contains(2));
} }
{
QSet<IdentityTracker> set;
QCOMPARE(set.size(), 0);
const int dummy = -1;
IdentityTracker id00 = {0, 0}, id01 = {0, 1}, searchKey = {0, dummy};
QCOMPARE(set.insert(id00)->id, id00.id);
QCOMPARE(set.size(), 1);
QCOMPARE(set.insert(id01)->id, id00.id); // first inserted is kept
QCOMPARE(set.size(), 1);
QCOMPARE(set.find(searchKey)->id, id00.id);
}
} }
void tst_QSet::setOperations() void tst_QSet::setOperations()
@ -930,6 +949,13 @@ void tst_QSet::initializerList()
QVERIFY(set.contains(4)); QVERIFY(set.contains(4));
QVERIFY(set.contains(5)); QVERIFY(set.contains(5));
// check _which_ of the equal elements gets inserted (in the QHash/QMap case, it's the last):
const QSet<IdentityTracker> set2 = {{1, 0}, {1, 1}, {2, 2}, {3, 3}, {4, 4}, {5, 5}};
QCOMPARE(set2.count(), 5);
const int dummy = -1;
const IdentityTracker searchKey = {1, dummy};
QCOMPARE(set2.find(searchKey)->id, 0);
QSet<int> emptySet{}; QSet<int> emptySet{};
QVERIFY(emptySet.isEmpty()); QVERIFY(emptySet.isEmpty());

View File

@ -147,7 +147,7 @@ tst_QStyleSheetStyle::~tst_QStyleSheetStyle()
void tst_QStyleSheetStyle::numinstances() void tst_QStyleSheetStyle::numinstances()
{ {
/*QWidget w; QWidget w;
w.resize(200, 200); w.resize(200, 200);
centerOnScreen(&w); centerOnScreen(&w);
QCommonStyle *style = new QCommonStyle; QCommonStyle *style = new QCommonStyle;
@ -180,7 +180,7 @@ void tst_QStyleSheetStyle::numinstances()
c.setStyle(style); c.setStyle(style);
QCOMPARE(QStyleSheetStyle::numinstances, 2); QCOMPARE(QStyleSheetStyle::numinstances, 2);
w.setStyleSheet(""); w.setStyleSheet("");
QCOMPARE(QStyleSheetStyle::numinstances, 0);*/ QCOMPARE(QStyleSheetStyle::numinstances, 0);
} }
void tst_QStyleSheetStyle::widgetsBeforeAppStyleSheet() void tst_QStyleSheetStyle::widgetsBeforeAppStyleSheet()
@ -351,7 +351,7 @@ void tst_QStyleSheetStyle::repolish()
void tst_QStyleSheetStyle::widgetStyle() void tst_QStyleSheetStyle::widgetStyle()
{ {
/*qApp->setStyleSheet(""); qApp->setStyleSheet("");
QWidget *window1 = new QWidget; QWidget *window1 = new QWidget;
window1->setObjectName("window1"); window1->setObjectName("window1");
@ -488,12 +488,12 @@ void tst_QStyleSheetStyle::widgetStyle()
delete widget2; delete widget2;
delete window2; delete window2;
delete style1; delete style1;
delete style2;*/ delete style2;
} }
void tst_QStyleSheetStyle::appStyle() void tst_QStyleSheetStyle::appStyle()
{ {
/* qApp->setStyleSheet(""); qApp->setStyleSheet("");
// qApp style can never be 0 // qApp style can never be 0
QVERIFY(QApplication::style() != 0); QVERIFY(QApplication::style() != 0);
QPointer<QStyle> style1 = QStyleFactory::create("Windows"); QPointer<QStyle> style1 = QStyleFactory::create("Windows");
@ -531,7 +531,7 @@ void tst_QStyleSheetStyle::appStyle()
QVERIFY(qApp->style() == style1); QVERIFY(qApp->style() == style1);
qApp->setStyleSheet(""); qApp->setStyleSheet("");
QVERIFY(qApp->style() == style1);*/ QVERIFY(qApp->style() == style1);
} }
void tst_QStyleSheetStyle::dynamicProperty() void tst_QStyleSheetStyle::dynamicProperty()

View File

@ -49,6 +49,7 @@
#include <QtNetwork/qnetworkaccessmanager.h> #include <QtNetwork/qnetworkaccessmanager.h>
#include <QtNetwork/qsslconfiguration.h> #include <QtNetwork/qsslconfiguration.h>
#include <QtNetwork/qhttpmultipart.h> #include <QtNetwork/qhttpmultipart.h>
#include <QtNetwork/qauthenticator.h>
#include <QtCore/QJsonDocument> #include <QtCore/QJsonDocument>
#include "../../auto/network-settings.h" #include "../../auto/network-settings.h"
@ -73,9 +74,13 @@ private slots:
void spdy_data(); void spdy_data();
void spdy(); void spdy();
void spdyMultipleRequestsPerHost(); void spdyMultipleRequestsPerHost();
void proxyAuthentication_data();
void proxyAuthentication();
void authentication();
protected slots: protected slots:
void spdyReplyFinished(); // only used by spdyMultipleRequestsPerHost test void spdyReplyFinished(); // only used by spdyMultipleRequestsPerHost test
void authenticationRequiredSlot(QNetworkReply *, QAuthenticator *authenticator);
private: private:
QHttpMultiPart *createFacebookMultiPart(const QByteArray &accessToken); QHttpMultiPart *createFacebookMultiPart(const QByteArray &accessToken);
@ -504,6 +509,83 @@ void tst_qnetworkreply::spdyMultipleRequestsPerHost()
#endif // defined(QT_BUILD_INTERNAL) && !defined(QT_NO_SSL) ... #endif // defined(QT_BUILD_INTERNAL) && !defined(QT_NO_SSL) ...
} }
void tst_qnetworkreply::proxyAuthentication_data()
{
QTest::addColumn<QUrl>("url");
QTest::newRow("http://www.google.com") << QUrl("http://www.google.com");
QTest::newRow("https://www.google.com") << QUrl("https://www.google.com");
}
void tst_qnetworkreply::proxyAuthentication()
{
QFETCH(QUrl, url);
QNetworkRequest request(url);
QNetworkAccessManager manager;
QByteArray proxyHostName = qgetenv("QT_PROXY_HOST");
QByteArray proxyPort = qgetenv("QT_PROXY_PORT");
QByteArray proxyUser = qgetenv("QT_PROXY_USER");
QByteArray proxyPassword = qgetenv("QT_PROXY_PASSWORD");
if (proxyHostName.isEmpty() || proxyPort.isEmpty() || proxyUser.isEmpty()
|| proxyPassword.isEmpty())
QSKIP("This test requires the QT_PROXY_* environment variables to be set. "
"Do something like:\n"
"export QT_PROXY_HOST=myNTLMHost\n"
"export QT_PROXY_PORT=8080\n"
"export QT_PROXY_USER='myDomain\\myUser'\n"
"export QT_PROXY_PASSWORD=myPassword\n");
QNetworkProxy proxy(QNetworkProxy::HttpProxy);
proxy.setHostName(proxyHostName);
proxy.setPort(proxyPort.toInt());
proxy.setUser(proxyUser);
proxy.setPassword(proxyPassword);
manager.setProxy(proxy);
reply = manager.get(request);
QObject::connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
QTestEventLoop::instance().enterLoop(15);
QVERIFY(!QTestEventLoop::instance().timeout());
QCOMPARE(reply->error(), QNetworkReply::NoError);
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QVERIFY(statusCode >= 200 && statusCode < 400);
}
void tst_qnetworkreply::authenticationRequiredSlot(QNetworkReply *,
QAuthenticator *authenticator)
{
QString authUser = QString::fromLocal8Bit(qgetenv("QT_AUTH_USER"));
QString authPassword = QString::fromLocal8Bit(qgetenv("QT_AUTH_PASSWORD"));
authenticator->setUser(authUser);
authenticator->setPassword(authPassword);
}
void tst_qnetworkreply::authentication()
{
QByteArray authUrl = qgetenv("QT_AUTH_URL");
if (authUrl.isEmpty())
QSKIP("This test requires the QT_AUTH_* environment variables to be set. "
"Do something like:\n"
"export QT_AUTH_URL='http://myUrl.com/myPath'\n"
"export QT_AUTH_USER='myDomain\\myUser'\n"
"export QT_AUTH_PASSWORD=myPassword\n");
QUrl url(QString::fromLocal8Bit(authUrl));
QNetworkRequest request(url);
QNetworkAccessManager manager;
QObject::connect(&manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)),
this, SLOT(authenticationRequiredSlot(QNetworkReply*,QAuthenticator*)));
reply = manager.get(request);
QObject::connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
QTestEventLoop::instance().enterLoop(15);
QVERIFY(!QTestEventLoop::instance().timeout());
QVERIFY2(reply->error() == QNetworkReply::NoError, reply->errorString().toLocal8Bit());
int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
QVERIFY(statusCode >= 200 && statusCode < 400);
}
QTEST_MAIN(tst_qnetworkreply) QTEST_MAIN(tst_qnetworkreply)
#include "main.moc" #include "main.moc"