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";
if (project->isActiveConfig("staticlib")) {
ProStringList libs;
if(!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS")) {
if (!project->isEmpty("QMAKE_INTERNAL_PRL_LIBS"))
libs = project->values("QMAKE_INTERNAL_PRL_LIBS");
} else {
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 << "Libs.private:";
for (ProStringList::ConstIterator it = libs.begin(); it != libs.end(); ++it)
t << ' ' << fixLibFlags((*it).toKey()).join(' ');
t << endl;
}
// flags
// ### too many

View File

@ -4,7 +4,7 @@ buildscript {
}
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
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
C library was deprecated in VC2005 (and later versions). qgetenv()
uses the new replacement function in VC, and calls the standard C
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()
*/
QByteArray qgetenv(const char *varName)

View File

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

View File

@ -2526,8 +2526,9 @@ QRegularExpression QVariant::toRegularExpression() const
/*!
\since 5.0
Returns the variant as a QUuid if the variant has userType() \l
QUuid; otherwise returns a default constructed QUuid.
Returns the variant as a QUuid if the variant has type()
\l QMetaType::QUuid or \l QMetaType::QString;
otherwise returns a default-constructed QUuid.
\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::QFont, \l QMetaType::Int, \l QMetaType::QKeySequence,
\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,
\l QMetaType::QString (if the list contains exactly one item)
\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,
\l QMetaType::QChar, \l QMetaType::Double, \l QMetaType::Int,
\l QMetaType::LongLong, \l QMetaType::QString, \l QMetaType::UInt
\row \li \l QMetaType::QUuid \li \l QMetaType::QString
\endtable
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); }
const Node *end() const { return static_cast<const Node *>(&header); }
Node *end() { return static_cast<Node *>(&header); }
// using reinterpret_cast because QMapDataBase::header is not
// 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(); }
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(QT_BOOTSTRAPPED)
# 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)
/* GCC requires attributes for a function */
# define QT_FUNCTION_TARGET(x) __attribute__((__target__(QT_FUNCTION_TARGET_STRING_ ## x)))

View File

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

View File

@ -528,7 +528,9 @@ QImage QOpenGLWindow::grabFramebuffer()
return QImage();
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 (ftp && state != Disconnecting)
ftp->abort();
disconnectFromFtp();
disconnectFromFtp(RemoveCachedConnection);
}
void QNetworkAccessFtpBackend::open()

View File

@ -82,8 +82,8 @@ static jobject m_serviceObject = nullptr;
static jmethodID m_setSurfaceGeometryMethodID = nullptr;
static jmethodID m_destroySurfaceMethodID = nullptr;
static bool m_activityActive = true; // defaults to true because when the platform plugin is
// initialized, QtActivity::onResume() has already been called
static int m_pendingApplicationState = -1;
static QBasicMutex m_pendingAppStateMtx;
static jclass m_bitmapClass = 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_methodErrorMsg[] = "Can't find method \"%s%s\"";
static void flushPendingApplicationState();
namespace QtAndroid
{
void setAndroidPlatformIntegration(QAndroidPlatformIntegration *androidPlatformIntegration)
{
m_surfacesMutex.lock();
QMutexLocker lock(&m_surfacesMutex);
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()
@ -215,12 +224,6 @@ namespace QtAndroid
m_statusBarShowing = false;
}
void setApplicationActive()
{
if (m_activityActive)
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationActive);
}
jobject createBitmap(QImage img, JNIEnv *env)
{
if (!m_bitmapClass)
@ -402,10 +405,15 @@ namespace QtAndroid
if (surfaceId == -1)
return;
QJNIEnvironmentPrivate env;
if (!env)
return;
{
QMutexLocker lock(&m_surfacesMutex);
const auto &it = m_surfaces.find(surfaceId);
if (it != m_surfaces.end())
m_surfaces.erase(it);
}
QJNIEnvironmentPrivate env;
if (env)
env->CallStaticVoidMethod(m_applicationClass,
m_destroySurfaceMethodID,
surfaceId);
@ -441,6 +449,16 @@ 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*/)
{
@ -584,18 +602,12 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface,
{
QMutexLocker lock(&m_surfacesMutex);
const auto &it = m_surfaces.find(id);
if (it == m_surfaces.end()) {
qWarning()<<"Can't find surface" << id;
if (it == m_surfaces.end())
return;
}
auto surfaceClient = it.value();
if (!surfaceClient) // This should never happen...
return;
if (surfaceClient)
surfaceClient->surfaceChanged(env, jSurface, w, h);
if (!jSurface)
m_surfaces.erase(it);
}
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)
{
m_activityActive = (state == Qt::ApplicationActive);
if (!m_main || !m_androidPlatformIntegration || !QGuiApplicationPrivate::platformIntegration()) {
QAndroidPlatformIntegration::setDefaultApplicationState(Qt::ApplicationState(state));
if (!m_main || !QtAndroid::androidPlatformIntegration()) {
QMutexLocker locker(&m_pendingAppStateMtx);
m_pendingApplicationState = Qt::ApplicationState(state);
return;
}
flushPendingApplicationState();
if (state == Qt::ApplicationActive)
QtAndroidPrivate::handleResume();
else if (state == Qt::ApplicationInactive)

View File

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

View File

@ -81,8 +81,6 @@ int QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight = 71;
Qt::ScreenOrientation QAndroidPlatformIntegration::m_orientation = Qt::PrimaryOrientation;
Qt::ScreenOrientation QAndroidPlatformIntegration::m_nativeOrientation = Qt::PrimaryOrientation;
Qt::ApplicationState QAndroidPlatformIntegration::m_defaultApplicationState = Qt::ApplicationActive;
bool QAndroidPlatformIntegration::m_showPasswordEnabled = false;
void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteArray &resource)
@ -121,6 +119,12 @@ void *QAndroidPlatformNativeInterface::nativeResourceForIntegration(const QByteA
return 0;
}
void QAndroidPlatformNativeInterface::customEvent(QEvent *event)
{
if (event->type() == QEvent::User)
QtAndroid::setAndroidPlatformIntegration(static_cast<QAndroidPlatformIntegration *>(QGuiApplicationPrivate::platformIntegration()));
}
QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &paramList)
: m_touchDevice(nullptr)
#ifndef QT_NO_ACCESSIBILITY
@ -148,7 +152,6 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
m_primaryScreen->setAvailableGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight));
m_mainThread = QThread::currentThread();
QtAndroid::setAndroidPlatformIntegration(this);
m_androidFDB = new QAndroidPlatformFontDatabase();
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()

View File

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

View File

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

View File

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

View File

@ -96,11 +96,6 @@ void QAndroidPlatformWindow::setVisible(bool visible)
QRect availableGeometry = screen()->availableGeometry();
if (geometry().width() > 0 && geometry().height() > 0 && availableGeometry.width() > 0 && availableGeometry.height() > 0)
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)

View File

@ -62,7 +62,7 @@
\endtable
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
Linux. The completeness of the support for other systems depends on the
availability and quality of client libraries.
@ -92,7 +92,7 @@
on Windows), then pass the following parameter to configure: \c
-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
\c{C:\progra~1\mysql} instead of \c{C:\Program Files\mysql}.
@ -110,7 +110,7 @@
\section3 QMYSQL Stored Procedure Support
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().
Example stored procedure:
@ -141,8 +141,8 @@
\section3 How to Build the QMYSQL Plugin on Unix and \macos
You need the MySQL header files and as well as the shared library
\c{libmysqlclient.so}. Depending on your Linux distribution you may
You need the MySQL header files, as well as the shared library
\c{libmysqlclient.so}. Depending on your Linux distribution, you may
need to install a package which is usually called "mysql-devel".
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
make in the line above.
\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
built in release mode only. If you are expecting a debug version
to be built as well, don't use the \c{"-o Makefile"} option.
\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
built in release mode only. If you intend to build a debug version
as well, don't use the \c{"-o Makefile"} option.
\target QOCI
\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.
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
@ -230,13 +230,13 @@
\snippet code/doc_src_sql-driver.qdoc 7
\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
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:
\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
\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
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:
\snippet code/doc_src_sql-driver.qdoc 9
@ -271,25 +271,25 @@
driver manager that is installed on your system. The QODBC plugin
then allows you to use these data sources in your Qt applications.
\b{Note:} You should use native drivers in preference to the ODBC
driver where they are available. ODBC support can be used as a fallback
for compliant databases if no native drivers are available.
\b{Note:} You should use the native driver, if it is available, instead
of the ODBC driver. ODBC support can be used as a fallback for compliant
databases if no native driver is available.
On Windows an ODBC driver manager should be installed by default.
For Unix systems there are some implementations which must be
On Windows, an ODBC driver manager should be installed by default.
For Unix systems, there are some implementations which must be
installed first. Note that every client that uses your application is
required to have an ODBC driver manager installed, otherwise the
QODBC plugin will not work.
Be aware that when connecting to an ODBC datasource you must pass in
the name of the ODBC datasource to the QSqlDatabase::setDatabaseName()
function rather than the actual database name.
When connecting to an ODBC datasource, you should pass the name
of the ODBC datasource to the QSqlDatabase::setDatabaseName()
function, rather than the actual database name.
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
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
ODBC_CHECK_DRIVER} line from the file \c{qsql_odbc.cpp}. Do this at
your own risk!
@ -332,7 +332,7 @@
driver and the DBMS must also support Unicode.
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.
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.
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
library depending on your platform.
library, depending on your platform.
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
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::seek(). The current row index is returned by
QSqlQuery::at(), and the total number of rows in the result set
@ -242,11 +242,10 @@
\snippet sqldatabase/sqldatabase.cpp 33
If you iterate through a result set only using next() and seek()
with positive values, you can call
QSqlQuery::setForwardOnly(true) before calling exec(). This is an
easy optimization that will speed up the query significantly when
operating on large result sets.
If you navigate within a result set, and use next() and seek()
only for browsing forward, you can call QSqlQuery::setForwardOnly(true)
before calling exec(). This is an easy optimization that will speed up
the query significantly when operating on large result sets.
\section2 Inserting, Updating, and Deleting Records
@ -592,7 +591,7 @@
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,
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.
\image qdatawidgetmapper-simple.png

View File

@ -269,12 +269,13 @@ int QDesktopWidget::screenNumber(const QWidget *w) const
QRect frame = w->frameGeometry();
if (!w->isWindow())
frame.moveTopLeft(w->mapToGlobal(QPoint(0, 0)));
const QRect nativeFrame = QHighDpi::toNativePixels(frame, winHandle);
QScreen *widgetScreen = Q_NULLPTR;
int largestArea = 0;
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();
if (largestArea < area) {
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)
{
QCOMPARE(testImage.devicePixelRatio(), referenceImage.devicePixelRatio());
QCOMPARE(testImage.width(), referenceImage.width());
QCOMPARE(testImage.height(), referenceImage.height());