Merge remote-tracking branch 'origin/5.8' into 5.9

Change-Id: I3bd83a839b16822035ed56a5cffe77bd6bc3f08d
This commit is contained in:
Liang Qi 2017-04-12 20:08:56 +02:00
commit 94c576cf66
21 changed files with 139 additions and 118 deletions

View File

@ -3311,19 +3311,19 @@ MakefileGenerator::writePkgConfigFile()
} }
t << shellQuote(pkgConfiglibName) << " \n"; t << shellQuote(pkgConfiglibName) << " \n";
ProStringList libs; if (project->isActiveConfig("staticlib")) {
if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) { ProStringList libs;
libs = project->values("QMAKE_INTERNAL_PRL_LIBS"); if (!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
} else { libs = project->values("QMAKE_INTERNAL_PRL_LIBS");
libs << "QMAKE_LIBS"; //obvious one else
libs << "QMAKE_LIBS"; //obvious one
libs << "QMAKE_LIBS_PRIVATE";
libs << "QMAKE_LFLAGS_THREAD"; //not sure about this one, but what about things like -pthread?
t << "Libs.private:";
for (ProStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it)
t << ' ' << fixLibFlags((*it).toKey()).join(' ');
t << endl;
} }
libs << "QMAKE_LIBS_PRIVATE";
libs << "QMAKE_LFLAGS_THREAD"; //not sure about this one, but what about things like -pthread?
t << "Libs.private: ";
for (ProStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it) {
t << fixLibFlags((*it).toKey()).join(' ') << ' ';
}
t << endl;
// flags // flags
// ### too many // ### too many

View File

@ -4,7 +4,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:2.2.0' classpath 'com.android.tools.build:gradle:2.2.3'
} }
} }

View File

@ -3183,12 +3183,16 @@ static QBasicMutex environmentMutex;
Returns the value of the environment variable with name \a Returns the value of the environment variable with name \a
varName. To get the variable string, use QByteArray::constData(). varName. To get the variable string, use QByteArray::constData().
To convert the data to a QString use QString::fromLocal8Bit().
\note qgetenv() was introduced because getenv() from the standard \note qgetenv() was introduced because getenv() from the standard
C library was deprecated in VC2005 (and later versions). qgetenv() C library was deprecated in VC2005 (and later versions). qgetenv()
uses the new replacement function in VC, and calls the standard C uses the new replacement function in VC, and calls the standard C
library's implementation on all other platforms. library's implementation on all other platforms.
\warning Don't use qgetenv on Windows if the content may contain
non-US-ASCII characters, like file paths.
\sa qputenv(), qEnvironmentVariableIsSet(), qEnvironmentVariableIsEmpty() \sa qputenv(), qEnvironmentVariableIsSet(), qEnvironmentVariableIsEmpty()
*/ */
QByteArray qgetenv(const char *varName) QByteArray qgetenv(const char *varName)

View File

@ -64,9 +64,7 @@ static QString qt_convertJString(jstring string)
static inline bool exceptionCheckAndClear(JNIEnv *env) static inline bool exceptionCheckAndClear(JNIEnv *env)
{ {
if (Q_UNLIKELY(env->ExceptionCheck())) { if (Q_UNLIKELY(env->ExceptionCheck())) {
#ifdef QT_DEBUG
env->ExceptionDescribe(); env->ExceptionDescribe();
#endif // QT_DEBUG
env->ExceptionClear(); env->ExceptionClear();
return true; return true;
} }

View File

@ -2526,8 +2526,9 @@ QRegularExpression QVariant::toRegularExpression() const
/*! /*!
\since 5.0 \since 5.0
Returns the variant as a QUuid if the variant has userType() \l Returns the variant as a QUuid if the variant has type()
QUuid; otherwise returns a default constructed QUuid. \l QMetaType::QUuid or \l QMetaType::QString;
otherwise returns a default-constructed QUuid.
\sa canConvert(), convert() \sa canConvert(), convert()
*/ */
@ -2995,7 +2996,7 @@ static bool canConvertMetaObject(int fromId, int toId, QObject *fromObject)
\l QMetaType::QDate, \l QMetaType::QDateTime, \l QMetaType::Double, \l QMetaType::QDate, \l QMetaType::QDateTime, \l QMetaType::Double,
\l QMetaType::QFont, \l QMetaType::Int, \l QMetaType::QKeySequence, \l QMetaType::QFont, \l QMetaType::Int, \l QMetaType::QKeySequence,
\l QMetaType::LongLong, \l QMetaType::QStringList, \l QMetaType::QTime, \l QMetaType::LongLong, \l QMetaType::QStringList, \l QMetaType::QTime,
\l QMetaType::UInt, \l QMetaType::ULongLong \l QMetaType::UInt, \l QMetaType::ULongLong, \l QMetaType::QUuid
\row \li \l QMetaType::QStringList \li \l QMetaType::QVariantList, \row \li \l QMetaType::QStringList \li \l QMetaType::QVariantList,
\l QMetaType::QString (if the list contains exactly one item) \l QMetaType::QString (if the list contains exactly one item)
\row \li \l QMetaType::QTime \li \l QMetaType::QString \row \li \l QMetaType::QTime \li \l QMetaType::QString
@ -3005,6 +3006,7 @@ static bool canConvertMetaObject(int fromId, int toId, QObject *fromObject)
\row \li \l QMetaType::ULongLong \li \l QMetaType::Bool, \row \li \l QMetaType::ULongLong \li \l QMetaType::Bool,
\l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int, \l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
\l QMetaType::LongLong, \l QMetaType::QString, \l QMetaType::UInt \l QMetaType::LongLong, \l QMetaType::QString, \l QMetaType::UInt
\row \li \l QMetaType::QUuid \li \l QMetaType::QString
\endtable \endtable
A QVariant containing a pointer to a type derived from QObject will also return true for this A QVariant containing a pointer to a type derived from QObject will also return true for this

View File

@ -209,8 +209,10 @@ struct QMapData : public QMapDataBase
Node *root() const { return static_cast<Node *>(header.left); } Node *root() const { return static_cast<Node *>(header.left); }
const Node *end() const { return static_cast<const Node *>(&header); } // using reinterpret_cast because QMapDataBase::header is not
Node *end() { return static_cast<Node *>(&header); } // actually a QMapNode.
const Node *end() const { return reinterpret_cast<const Node *>(&header); }
Node *end() { return reinterpret_cast<Node *>(&header); }
const Node *begin() const { if (root()) return static_cast<const Node*>(mostLeftNode); return end(); } const Node *begin() const { if (root()) return static_cast<const Node*>(mostLeftNode); return end(); }
Node *begin() { if (root()) return static_cast<Node*>(mostLeftNode); return end(); } Node *begin() { if (root()) return static_cast<Node*>(mostLeftNode); return end(); }

View File

@ -169,7 +169,7 @@
|| (defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && (__GNUC__-0) * 100 + (__GNUC_MINOR__-0) >= 409)) \ || (defined(Q_CC_GNU) && !defined(Q_CC_CLANG) && (__GNUC__-0) * 100 + (__GNUC_MINOR__-0) >= 409)) \
&& !defined(QT_BOOTSTRAPPED) && !defined(QT_BOOTSTRAPPED)
# define QT_COMPILER_SUPPORTS_SIMD_ALWAYS # define QT_COMPILER_SUPPORTS_SIMD_ALWAYS
# define QT_COMPILER_SUPPORTS_HERE(x) QT_COMPILER_SUPPORTS(x) # define QT_COMPILER_SUPPORTS_HERE(x) (__ ## x ## __) || QT_COMPILER_SUPPORTS(x)
# if defined(Q_CC_GNU) && !defined(Q_CC_INTEL) # if defined(Q_CC_GNU) && !defined(Q_CC_INTEL)
/* GCC requires attributes for a function */ /* GCC requires attributes for a function */
# define QT_FUNCTION_TARGET(x) __attribute__((__target__(QT_FUNCTION_TARGET_STRING_ ## x))) # define QT_FUNCTION_TARGET(x) __attribute__((__target__(QT_FUNCTION_TARGET_STRING_ ## x)))

View File

@ -234,7 +234,7 @@
] ]
}, },
"xcb_syslibs": { "xcb_syslibs": {
"label": "XCB (secondary)", "label": "XCB (extensions)",
"test": "qpa/xcb-syslibs", "test": "qpa/xcb-syslibs",
"sources": [ "sources": [
{ "type": "pkgConfig", { "type": "pkgConfig",
@ -723,11 +723,11 @@
"output": [ "privateFeature" ] "output": [ "privateFeature" ]
}, },
"system-xcb": { "system-xcb": {
"label": "Using system provided XCB libraries", "label": "Using system-provided XCB libraries",
"enable": "input.xcb == 'system' || input.xcb == 'yes'", "enable": "input.xcb == 'system'",
"disable": "input.xcb == 'qt' || input.xcb == 'no'", "disable": "input.xcb == 'qt'",
"autoDetect": "!config.darwin", "autoDetect": "!config.darwin",
"condition": "libs.xcb && libs.xcb_syslibs", "condition": "features.xcb && libs.xcb_syslibs",
"output": [ "privateFeature" ] "output": [ "privateFeature" ]
}, },
"x11-prefix": { "x11-prefix": {
@ -743,8 +743,14 @@
}, },
"xcb-render": { "xcb-render": {
"label": "XCB render", "label": "XCB render",
"emitIf": "features.system-xcb", "emitIf": "features.xcb",
"condition": "libs.xcb_render", "condition": "!features.system-xcb || libs.xcb_render",
"output": [ "privateFeature" ]
},
"xkb": {
"label": "XCB XKB",
"emitIf": "features.xcb",
"condition": "!features.system-xcb || libs.xcb_xkb",
"output": [ "privateFeature" ] "output": [ "privateFeature" ]
}, },
"xcb-xlib": { "xcb-xlib": {
@ -761,6 +767,7 @@
}, },
"xinput2": { "xinput2": {
"label": "Xinput2", "label": "Xinput2",
"emitIf": "features.xcb",
"condition": "libs.xinput2", "condition": "libs.xinput2",
"output": [ "privateFeature" ] "output": [ "privateFeature" ]
}, },
@ -777,11 +784,6 @@
"condition": "libs.xkbcommon_x11", "condition": "libs.xkbcommon_x11",
"output": [ "privateFeature" ] "output": [ "privateFeature" ]
}, },
"xkb": {
"label": "XCB XKB",
"condition": "features.system-xcb && libs.xcb_xkb",
"output": [ "privateFeature" ]
},
"xkb-config-root": { "xkb-config-root": {
"label": "XKB config root", "label": "XKB config root",
"emitIf": "features.xcb", "emitIf": "features.xcb",

View File

@ -528,7 +528,9 @@ QImage QOpenGLWindow::grabFramebuffer()
return QImage(); return QImage();
makeCurrent(); makeCurrent();
return qt_gl_read_framebuffer(size() * devicePixelRatio(), false, false); QImage img = qt_gl_read_framebuffer(size() * devicePixelRatio(), false, false);
img.setDevicePixelRatio(devicePixelRatio());
return img;
} }
/*! /*!

View File

@ -114,7 +114,7 @@ QNetworkAccessFtpBackend::~QNetworkAccessFtpBackend()
//if backend destroyed while in use, then abort (this is the code path from QNetworkReply::abort) //if backend destroyed while in use, then abort (this is the code path from QNetworkReply::abort)
if (ftp && state != Disconnecting) if (ftp && state != Disconnecting)
ftp->abort(); ftp->abort();
disconnectFromFtp(); disconnectFromFtp(RemoveCachedConnection);
} }
void QNetworkAccessFtpBackend::open() void QNetworkAccessFtpBackend::open()

View File

@ -82,8 +82,8 @@ static jobject m_serviceObject = nullptr;
static jmethodID m_setSurfaceGeometryMethodID = nullptr; static jmethodID m_setSurfaceGeometryMethodID = nullptr;
static jmethodID m_destroySurfaceMethodID = nullptr; static jmethodID m_destroySurfaceMethodID = nullptr;
static bool m_activityActive = true; // defaults to true because when the platform plugin is static int m_pendingApplicationState = -1;
// initialized, QtActivity::onResume() has already been called static QBasicMutex m_pendingAppStateMtx;
static jclass m_bitmapClass = nullptr; static jclass m_bitmapClass = nullptr;
static jmethodID m_createBitmapMethodID = nullptr; static jmethodID m_createBitmapMethodID = nullptr;
@ -130,13 +130,22 @@ static const char m_qtTag[] = "Qt";
static const char m_classErrorMsg[] = "Can't find class \"%s\""; static const char m_classErrorMsg[] = "Can't find class \"%s\"";
static const char m_methodErrorMsg[] = "Can't find method \"%s%s\""; static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
static void flushPendingApplicationState();
namespace QtAndroid namespace QtAndroid
{ {
void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration) void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration)
{ {
m_surfacesMutex.lock(); QMutexLocker lock(&m_surfacesMutex);
m_androidPlatformIntegration = androidPlatformIntegration; m_androidPlatformIntegration = androidPlatformIntegration;
m_surfacesMutex.unlock();
// flush the pending state if necessary.
if (m_androidPlatformIntegration) {
flushPendingApplicationState();
} else {
QMutexLocker locker(&m_pendingAppStateMtx);
m_pendingApplicationState = -1;
}
} }
QAndroidPlatformIntegration *androidPlatformIntegration() QAndroidPlatformIntegration *androidPlatformIntegration()
@ -215,12 +224,6 @@ namespace QtAndroid
m_statusBarShowing = false; m_statusBarShowing = false;
} }
void setApplicationActive()
{
if (m_activityActive)
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
}
jobject createBitmap(QImage img, JNIEnv *env) jobject createBitmap(QImage img, JNIEnv *env)
{ {
if (!m_bitmapClass) if (!m_bitmapClass)
@ -402,11 +405,16 @@ namespace QtAndroid
if (surfaceId == -1) if (surfaceId == -1)
return; return;
QJNIEnvironmentPrivate env; {
if (!env) QMutexLocker lock(&m_surfacesMutex);
return; const auto &it = m_surfaces.find(surfaceId);
if (it != m_surfaces.end())
m_surfaces.erase(it);
}
env->CallStaticVoidMethod(m_applicationClass, QJNIEnvironmentPrivate env;
if (env)
env->CallStaticVoidMethod(m_applicationClass,
m_destroySurfaceMethodID, m_destroySurfaceMethodID,
surfaceId); surfaceId);
} }
@ -441,6 +449,16 @@ namespace QtAndroid
} // namespace QtAndroid } // namespace QtAndroid
// Force an update of the pending application state (state set before the platform plugin was created)
static void flushPendingApplicationState()
{
QMutexLocker locker(&m_pendingAppStateMtx);
if (m_pendingApplicationState == -1)
return;
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(m_pendingApplicationState));
m_pendingApplicationState = -1;
}
static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobject applicationAssetManager*/) static jboolean startQtAndroidPlugin(JNIEnv* /*env*/, jobject /*object*//*, jobject applicationAssetManager*/)
{ {
@ -584,18 +602,12 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface,
{ {
QMutexLocker lock(&m_surfacesMutex); QMutexLocker lock(&m_surfacesMutex);
const auto &it = m_surfaces.find(id); const auto &it = m_surfaces.find(id);
if (it == m_surfaces.end()) { if (it == m_surfaces.end())
qWarning()<<"Can't find surface" << id;
return; return;
}
auto surfaceClient = it.value(); auto surfaceClient = it.value();
if (!surfaceClient) // This should never happen... if (surfaceClient)
return; surfaceClient->surfaceChanged(env, jSurface, w, h);
surfaceClient->surfaceChanged(env, jSurface, w, h);
if (!jSurface)
m_surfaces.erase(it);
} }
static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/, static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
@ -656,13 +668,14 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state) static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state)
{ {
m_activityActive = (state == Qt::ApplicationActive); if (!m_main || !QtAndroid::androidPlatformIntegration()) {
QMutexLocker locker(&m_pendingAppStateMtx);
if (!m_main || !m_androidPlatformIntegration || !QGuiApplicationPrivate::platformIntegration()) { m_pendingApplicationState = Qt::ApplicationState(state);
QAndroidPlatformIntegration::setDefaultApplicationState(Qt::ApplicationState(state));
return; return;
} }
flushPendingApplicationState();
if (state == Qt::ApplicationActive) if (state == Qt::ApplicationActive)
QtAndroidPrivate::handleResume(); QtAndroidPrivate::handleResume();
else if (state == Qt::ApplicationInactive) else if (state == Qt::ApplicationInactive)

View File

@ -85,8 +85,6 @@ namespace QtAndroid
jobject activity(); jobject activity();
jobject service(); jobject service();
void setApplicationActive();
void showStatusBar(); void showStatusBar();
void hideStatusBar(); void hideStatusBar();

View File

@ -81,8 +81,6 @@ int QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight = 71;
Qt::ScreenOrientation QAndroidPlatformIntegration::m_orientation = Qt::PrimaryOrientation; Qt::ScreenOrientation QAndroidPlatformIntegration::m_orientation = Qt::PrimaryOrientation;
Qt::ScreenOrientation QAndroidPlatformIntegration::m_nativeOrientation = Qt::PrimaryOrientation; Qt::ScreenOrientation QAndroidPlatformIntegration::m_nativeOrientation = Qt::PrimaryOrientation;
Qt::ApplicationState QAndroidPlatformIntegration::m_defaultApplicationState = Qt::ApplicationActive;
bool QAndroidPlatformIntegration::m_showPasswordEnabled = false; bool QAndroidPlatformIntegration::m_showPasswordEnabled = false;
void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource) void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource)
@ -121,6 +119,12 @@ void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteA
return 0; return 0;
} }
void QAndroidPlatformNativeInterface::customEvent(QEvent *event)
{
if (event->type() == QEvent::User)
QtAndroid::setAndroidPlatformIntegration(static_cast<QAndroidPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration()));
}
QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &paramList) QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &paramList)
: m_touchDevice(nullptr) : m_touchDevice(nullptr)
#ifndef QT_NO_ACCESSIBILITY #ifndef QT_NO_ACCESSIBILITY
@ -148,7 +152,6 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
m_primaryScreen->setAvailableGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight)); m_primaryScreen->setAvailableGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight));
m_mainThread = QThread::currentThread(); m_mainThread = QThread::currentThread();
QtAndroid::setAndroidPlatformIntegration(this);
m_androidFDB = new QAndroidPlatformFontDatabase(); m_androidFDB = new QAndroidPlatformFontDatabase();
m_androidPlatformServices = new QAndroidPlatformServices(); m_androidPlatformServices = new QAndroidPlatformServices();
@ -211,7 +214,9 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
} }
} }
QGuiApplicationPrivate::instance()->setApplicationState(m_defaultApplicationState); // We can't safely notify the jni bridge that we're up and running just yet, so let's postpone
// it for now.
QCoreApplication::postEvent(m_androidPlatformNativeInterface, new QEvent(QEvent::User));
} }
static bool needsBasicRenderloopWorkaround() static bool needsBasicRenderloopWorkaround()

View File

@ -65,6 +65,9 @@ class QAndroidPlatformNativeInterface: public QPlatformNativeInterface
public: public:
void *nativeResourceForIntegration(const QByteArray &resource) override; void *nativeResourceForIntegration(const QByteArray &resource) override;
std::shared_ptr<AndroidStyle> m_androidStyle; std::shared_ptr<AndroidStyle> m_androidStyle;
protected:
void customEvent(QEvent *event) override;
}; };
class QAndroidPlatformIntegration : public QPlatformIntegration class QAndroidPlatformIntegration : public QPlatformIntegration
@ -122,7 +125,6 @@ public:
QTouchDevice *touchDevice() const { return m_touchDevice; } QTouchDevice *touchDevice() const { return m_touchDevice; }
void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; } void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; }
static void setDefaultApplicationState(Qt::ApplicationState applicationState) { m_defaultApplicationState = applicationState; }
private: private:
EGLDisplay m_eglDisplay; EGLDisplay m_eglDisplay;
@ -141,9 +143,6 @@ private:
static Qt::ScreenOrientation m_orientation; static Qt::ScreenOrientation m_orientation;
static Qt::ScreenOrientation m_nativeOrientation; static Qt::ScreenOrientation m_nativeOrientation;
static Qt::ApplicationState m_defaultApplicationState;
static bool m_showPasswordEnabled; static bool m_showPasswordEnabled;
QPlatformFontDatabase *m_androidFDB; QPlatformFontDatabase *m_androidFDB;

View File

@ -69,10 +69,7 @@ void QAndroidPlatformOpenGLContext::swapBuffers(QPlatformSurface *surface)
bool QAndroidPlatformOpenGLContext::makeCurrent(QPlatformSurface *surface) bool QAndroidPlatformOpenGLContext::makeCurrent(QPlatformSurface *surface)
{ {
bool ret = QEGLPlatformContext::makeCurrent(surface); return QEGLPlatformContext::makeCurrent(surface);
QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(context());
return ret;
} }
EGLSurface QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface) EGLSurface QAndroidPlatformOpenGLContext::eglSurfaceForPlatformSurface(QPlatformSurface *surface)

View File

@ -311,10 +311,13 @@ void QAndroidPlatformScreen::doRedraw()
} }
} }
if (!hasVisibleRasterWindows) { if (!hasVisibleRasterWindows) {
lockSurface();
if (m_id != -1) { if (m_id != -1) {
QtAndroid::destroySurface(m_id); QtAndroid::destroySurface(m_id);
releaseSurface();
m_id = -1; m_id = -1;
} }
unlockSurface();
return; return;
} }
QMutexLocker lock(&m_surfaceMutex); QMutexLocker lock(&m_surfaceMutex);

View File

@ -96,11 +96,6 @@ void QAndroidPlatformWindow::setVisible(bool visible)
QRect availableGeometry = screen()->availableGeometry(); QRect availableGeometry = screen()->availableGeometry();
if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0) if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
QPlatformWindow::setVisible(visible); QPlatformWindow::setVisible(visible);
// The Android Activity is activated before Qt is initialized, causing the application state to
// never be set to 'active'. We explicitly set this state when the first window becomes visible.
if (visible)
QtAndroid::setApplicationActive();
} }
void QAndroidPlatformWindow::setWindowState(Qt::WindowState state) void QAndroidPlatformWindow::setWindowState(Qt::WindowState state)

View File

@ -62,7 +62,7 @@
\endtable \endtable
SQLite is the in-process database system with the best test coverage SQLite is the in-process database system with the best test coverage
and support on all platforms. Oracle via OCI, and PostreSQL and MySQL and support on all platforms. Oracle via OCI, PostgreSQL, and MySQL
through either ODBC or a native driver are well-tested on Windows and through either ODBC or a native driver are well-tested on Windows and
Linux. The completeness of the support for other systems depends on the Linux. The completeness of the support for other systems depends on the
availability and quality of client libraries. availability and quality of client libraries.
@ -92,7 +92,7 @@
on Windows), then pass the following parameter to configure: \c on Windows), then pass the following parameter to configure: \c
-I/usr/local/mysql (or \c{-I C:\mysql\include} for Windows). -I/usr/local/mysql (or \c{-I C:\mysql\include} for Windows).
On Windows the \c -I parameter doesn't accept spaces in On Windows, the \c -I parameter doesn't accept spaces in
filenames, so use the 8.3 name instead; for example, use filenames, so use the 8.3 name instead; for example, use
\c{C:\progra~1\mysql} instead of \c{C:\Program Files\mysql}. \c{C:\progra~1\mysql} instead of \c{C:\Program Files\mysql}.
@ -110,7 +110,7 @@
\section3 QMYSQL Stored Procedure Support \section3 QMYSQL Stored Procedure Support
MySQL 5 introduces stored procedure support at the SQL level, but no MySQL 5 introduces stored procedure support at the SQL level, but no
API to control IN, OUT and INOUT parameters. Therefore, parameters API to control IN, OUT, and INOUT parameters. Therefore, parameters
have to be set and read using SQL commands instead of QSqlQuery::bindValue(). have to be set and read using SQL commands instead of QSqlQuery::bindValue().
Example stored procedure: Example stored procedure:
@ -141,8 +141,8 @@
\section3 How to Build the QMYSQL Plugin on Unix and \macos \section3 How to Build the QMYSQL Plugin on Unix and \macos
You need the MySQL header files and as well as the shared library You need the MySQL header files, as well as the shared library
\c{libmysqlclient.so}. Depending on your Linux distribution you may \c{libmysqlclient.so}. Depending on your Linux distribution, you may
need to install a package which is usually called "mysql-devel". need to install a package which is usually called "mysql-devel".
Tell \l qmake where to find the MySQL header files and shared Tell \l qmake where to find the MySQL header files and shared
@ -168,10 +168,10 @@
If you are not using a Microsoft compiler, replace \c nmake with \c If you are not using a Microsoft compiler, replace \c nmake with \c
make in the line above. make in the line above.
\note Including \c{"-o Makefile"} as an argument to \l qmake to \note Including \c{"-o Makefile"} as an argument to \l qmake, to
tell it where to build the makefile can cause the plugin to be tell it where to build the makefile, can cause the plugin to be
built in release mode only. If you are expecting a debug version built in release mode only. If you intend to build a debug version
to be built as well, don't use the \c{"-o Makefile"} option. as well, don't use the \c{"-o Makefile"} option.
\target QOCI \target QOCI
\section2 QOCI for the Oracle Call Interface (OCI) \section2 QOCI for the Oracle Call Interface (OCI)
@ -184,7 +184,7 @@
It's possible to connect to a Oracle database without a tnsnames.ora file. It's possible to connect to a Oracle database without a tnsnames.ora file.
This requires that the database SID is passed to the driver as the database This requires that the database SID is passed to the driver as the database
name and that a hostname is given. name, and that a hostname is given.
\section3 OCI User Authentication \section3 OCI User Authentication
@ -230,13 +230,13 @@
\snippet code/doc_src_sql-driver.qdoc 7 \snippet code/doc_src_sql-driver.qdoc 7
\b{Note:} If you are using the Oracle Instant Client package, \b{Note:} If you are using the Oracle Instant Client package,
you will need to set LD_LIBRARY_PATH when building the OCI SQL plugin you will need to set LD_LIBRARY_PATH when building the OCI SQL plugin,
and when running an application that uses the OCI SQL plugin. You can and when running an application that uses the OCI SQL plugin. You can
avoid this requirement by setting and RPATH and listing all of the avoid this requirement by setting RPATH, and listing all of the
libraries to link to. Here is an example: libraries to link to. Here is an example:
\snippet code/doc_src_sql-driver.qdoc 32 \snippet code/doc_src_sql-driver.qdoc 32
If you wish to build the OCI plugin manually with this method the procedure looks like this: If you wish to build the OCI plugin manually with this method, the procedure looks like this:
\snippet code/doc_src_sql-driver.qdoc 33 \snippet code/doc_src_sql-driver.qdoc 33
\section3 How to Build the OCI Plugin on Windows \section3 How to Build the OCI Plugin on Windows
@ -254,7 +254,7 @@
If you are not using a Microsoft compiler, replace \c nmake with \c If you are not using a Microsoft compiler, replace \c nmake with \c
make in the line above. make in the line above.
When you run your application you will also need to add the \c oci.dll When you run your application, you will also need to add the \c oci.dll
path to your \c PATH environment variable: path to your \c PATH environment variable:
\snippet code/doc_src_sql-driver.qdoc 9 \snippet code/doc_src_sql-driver.qdoc 9
@ -271,25 +271,25 @@
driver manager that is installed on your system. The QODBC plugin driver manager that is installed on your system. The QODBC plugin
then allows you to use these data sources in your Qt applications. then allows you to use these data sources in your Qt applications.
\b{Note:} You should use native drivers in preference to the ODBC \b{Note:} You should use the native driver, if it is available, instead
driver where they are available. ODBC support can be used as a fallback of the ODBC driver. ODBC support can be used as a fallback for compliant
for compliant databases if no native drivers are available. databases if no native driver is available.
On Windows an ODBC driver manager should be installed by default. On Windows, an ODBC driver manager should be installed by default.
For Unix systems there are some implementations which must be For Unix systems, there are some implementations which must be
installed first. Note that every client that uses your application is installed first. Note that every client that uses your application is
required to have an ODBC driver manager installed, otherwise the required to have an ODBC driver manager installed, otherwise the
QODBC plugin will not work. QODBC plugin will not work.
Be aware that when connecting to an ODBC datasource you must pass in When connecting to an ODBC datasource, you should pass the name
the name of the ODBC datasource to the QSqlDatabase::setDatabaseName() of the ODBC datasource to the QSqlDatabase::setDatabaseName()
function rather than the actual database name. function, rather than the actual database name.
The QODBC Plugin needs an ODBC compliant driver manager version 2.0 or The QODBC Plugin needs an ODBC compliant driver manager version 2.0 or
later to work. Some ODBC drivers claim to be version 2.0 compliant, later. Some ODBC drivers claim to be version-2.0-compliant,
but do not offer all the necessary functionality. The QODBC plugin but do not offer all the necessary functionality. The QODBC plugin
therefore checks whether the data source can be used after a therefore checks whether the data source can be used after a
connection has been established and refuses to work if the check connection has been established, and refuses to work if the check
fails. If you don't like this behavior, you can remove the \c{#define fails. If you don't like this behavior, you can remove the \c{#define
ODBC_CHECK_DRIVER} line from the file \c{qsql_odbc.cpp}. Do this at ODBC_CHECK_DRIVER} line from the file \c{qsql_odbc.cpp}. Do this at
your own risk! your own risk!
@ -332,7 +332,7 @@
driver and the DBMS must also support Unicode. driver and the DBMS must also support Unicode.
Some driver managers and drivers don't support UNICODE. To use the Some driver managers and drivers don't support UNICODE. To use the
QODBC plugin with such drivers it has to be compiled with the QODBC plugin with such drivers, it has to be compiled with
Q_ODBC_VERSION_2 defined. Q_ODBC_VERSION_2 defined.
For the Oracle 9 ODBC driver (Windows), it is necessary to check For the Oracle 9 ODBC driver (Windows), it is necessary to check
@ -368,9 +368,9 @@
The QPSQL driver supports version 7.3 and higher of the PostgreSQL server. The QPSQL driver supports version 7.3 and higher of the PostgreSQL server.
We recommend that you use a client library from version 7.3.15, 7.4.13, We recommend that you use a client library from version 7.3.15, 7.4.13,
8.0.8, 8.1.4 or more recent as these versions contain security fixes, and 8.0.8, 8.1.4, or more recent, as these versions contain security fixes, and
as the QPSQL driver might not build with older versions of the client as the QPSQL driver might not build with older versions of the client
library depending on your platform. library, depending on your platform.
For more information about PostgreSQL visit \l http://www.postgresql.org. For more information about PostgreSQL visit \l http://www.postgresql.org.

View File

@ -227,7 +227,7 @@
Databases, please refer to \l{Data Types for Qt-supported Database Databases, please refer to \l{Data Types for Qt-supported Database
Systems} {this table}. Systems} {this table}.
You can iterate back and forth using QSqlQuery::next(), You can navigate within the dataset using QSqlQuery::next(),
QSqlQuery::previous(), QSqlQuery::first(), QSqlQuery::last(), and QSqlQuery::previous(), QSqlQuery::first(), QSqlQuery::last(), and
QSqlQuery::seek(). The current row index is returned by QSqlQuery::seek(). The current row index is returned by
QSqlQuery::at(), and the total number of rows in the result set QSqlQuery::at(), and the total number of rows in the result set
@ -242,11 +242,10 @@
\snippet sqldatabase/sqldatabase.cpp 33 \snippet sqldatabase/sqldatabase.cpp 33
If you iterate through a result set only using next() and seek() If you navigate within a result set, and use next() and seek()
with positive values, you can call only for browsing forward, you can call QSqlQuery::setForwardOnly(true)
QSqlQuery::setForwardOnly(true) before calling exec(). This is an before calling exec(). This is an easy optimization that will speed up
easy optimization that will speed up the query significantly when the query significantly when operating on large result sets.
operating on large result sets.
\section2 Inserting, Updating, and Deleting Records \section2 Inserting, Updating, and Deleting Records
@ -592,7 +591,7 @@
QDataWidgetMapper operates on a specific database table, mapping items QDataWidgetMapper operates on a specific database table, mapping items
in the table on a row-by-row or column-by-column basis. As a result, in the table on a row-by-row or column-by-column basis. As a result,
using QDataWidgetMapper with a SQL model is as simple as using it with using QDataWidgetMapper with an SQL model is as simple as using it with
any other table model. any other table model.
\image qdatawidgetmapper-simple.png \image qdatawidgetmapper-simple.png

View File

@ -269,12 +269,13 @@ int QDesktopWidget::screenNumber(const QWidget *w) const
QRect frame = w->frameGeometry(); QRect frame = w->frameGeometry();
if (!w->isWindow()) if (!w->isWindow())
frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0))); frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0)));
const QRect nativeFrame = QHighDpi::toNativePixels(frame, winHandle);
QScreen *widgetScreen = Q_NULLPTR; QScreen *widgetScreen = Q_NULLPTR;
int largestArea = 0; int largestArea = 0;
foreach (QScreen *screen, screens) { foreach (QScreen *screen, screens) {
const QRect intersected = screen->handle()->geometry().intersected(nativeFrame); const QRect deviceIndependentScreenGeometry =
QHighDpi::fromNativePixels(screen->handle()->geometry(), screen);
const QRect intersected = deviceIndependentScreenGeometry.intersected(frame);
int area = intersected.width() * intersected.height(); int area = intersected.width() * intersected.height();
if (largestArea < area) { if (largestArea < area) {
widgetScreen = screen; widgetScreen = screen;

View File

@ -389,6 +389,7 @@ static bool fuzzyComparePixels(const QRgb testPixel, const QRgb refPixel, const
static void fuzzyCompareImages(const QImage &testImage, const QImage &referenceImage, const char* file, int line) static void fuzzyCompareImages(const QImage &testImage, const QImage &referenceImage, const char* file, int line)
{ {
QCOMPARE(testImage.devicePixelRatio(), referenceImage.devicePixelRatio());
QCOMPARE(testImage.width(), referenceImage.width()); QCOMPARE(testImage.width(), referenceImage.width());
QCOMPARE(testImage.height(), referenceImage.height()); QCOMPARE(testImage.height(), referenceImage.height());