From 90e009e9e273a4fea5166007e4c2b0638c6588cd Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Mon, 7 Jun 2010 11:41:10 +0200 Subject: Fix QTransform::map(const QPainterPath &) not working with paths that have only one element Replaced the isEmpty() check for the shortcut in map() with elementCount() == 0 Task-number: QTBUG-11264 Reviewed-by: Samuel --- src/gui/painting/qtransform.cpp | 2 +- tests/auto/qtransform/tst_qtransform.cpp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gui/painting/qtransform.cpp b/src/gui/painting/qtransform.cpp index 423cce9..47b7758 100644 --- a/src/gui/painting/qtransform.cpp +++ b/src/gui/painting/qtransform.cpp @@ -1626,7 +1626,7 @@ static QPainterPath mapProjective(const QTransform &transform, const QPainterPat QPainterPath QTransform::map(const QPainterPath &path) const { TransformationType t = inline_type(); - if (t == TxNone || path.isEmpty()) + if (t == TxNone || path.elementCount() == 0) return path; if (t >= TxProject) diff --git a/tests/auto/qtransform/tst_qtransform.cpp b/tests/auto/qtransform/tst_qtransform.cpp index a3ded8e..c784b3a 100644 --- a/tests/auto/qtransform/tst_qtransform.cpp +++ b/tests/auto/qtransform/tst_qtransform.cpp @@ -85,6 +85,7 @@ private slots: void inverted(); void projectivePathMapping(); void mapInt(); + void mapPathWithPoint(); private: void mapping_data(); @@ -793,6 +794,13 @@ void tst_QTransform::mapInt() QCOMPARE(y, 10); } +void tst_QTransform::mapPathWithPoint() +{ + QPainterPath p(QPointF(10, 10)); + p = QTransform::fromTranslate(10, 10).map(p); + QCOMPARE(p.currentPosition(), QPointF(20, 20)); +} + QTEST_APPLESS_MAIN(tst_QTransform) -- cgit v0.12 From f409128642c976bde0a7d4f32ed1db96a2af637b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Riku=20Palom=C3=A4ki?= Date: Mon, 7 Jun 2010 12:18:23 +0200 Subject: Splitted attrib_list generation into buildSpec from QGLContext::tryVisual. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge-request: 609 Reviewed-by: Samuel Rødal --- src/opengl/qgl_x11.cpp | 281 +++++++++++++++++++++++++------------------------ 1 file changed, 144 insertions(+), 137 deletions(-) diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index d203646..a6b0fae 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -401,6 +401,148 @@ bool QGLFormat::hasOpenGLOverlays() return trans_colors.size() > 0; } +static bool buildSpec(int* spec, const QGLFormat& f, QPaintDevice* paintDevice, + int bufDepth, bool onlyFBConfig = false) +{ + int i = 0; + spec[i++] = GLX_LEVEL; + spec[i++] = f.plane(); + const QX11Info *xinfo = qt_x11Info(paintDevice); + bool useFBConfig = onlyFBConfig; + +#if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) && !defined(Q_OS_HPUX) + /* + HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions. + Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented. + */ + QWidget* widget = 0; + if (paintDevice->devType() == QInternal::Widget) + widget = static_cast(paintDevice); + + // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual + if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender) + useFBConfig = true; +#endif + +#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) + static bool useTranspExt = false; + static bool useTranspExtChecked = false; + if (f.plane() && !useTranspExtChecked && paintDevice) { + QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); + useTranspExt = extensions.match("GLX_EXT_visual_info"); + //# (A bit simplistic; that could theoretically be a substring) + if (useTranspExt) { + QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR)); + useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround + if (useTranspExt) { + // bug workaround - some systems (eg. FireGL) refuses to return an overlay + // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if + // the implementation supports transparent overlays + int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT, + f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT, + XNone }; + XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec); + if (!vinf) { + useTranspExt = false; + } + } + } + + useTranspExtChecked = true; + } + if (f.plane() && useTranspExt && !useFBConfig) { + // Required to avoid non-transparent overlay visual(!) on some systems + spec[i++] = GLX_TRANSPARENT_TYPE_EXT; + spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; + } +#endif + +#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) + // GLX_RENDER_TYPE is only in glx >=1.3 + if (useFBConfig) { + spec[i++] = GLX_RENDER_TYPE; + spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; + } +#endif + + if (f.doubleBuffer()) + spec[i++] = GLX_DOUBLEBUFFER; + if (useFBConfig) + spec[i++] = True; + if (f.depth()) { + spec[i++] = GLX_DEPTH_SIZE; + spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize(); + } + if (f.stereo()) { + spec[i++] = GLX_STEREO; + if (useFBConfig) + spec[i++] = True; + } + if (f.stencil()) { + spec[i++] = GLX_STENCIL_SIZE; + spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize(); + } + if (f.rgba()) { + if (!useFBConfig) + spec[i++] = GLX_RGBA; + spec[i++] = GLX_RED_SIZE; + spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize(); + spec[i++] = GLX_GREEN_SIZE; + spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize(); + spec[i++] = GLX_BLUE_SIZE; + spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize(); + if (f.alpha()) { + spec[i++] = GLX_ALPHA_SIZE; + spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize(); + } + if (f.accum()) { + spec[i++] = GLX_ACCUM_RED_SIZE; + spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); + spec[i++] = GLX_ACCUM_GREEN_SIZE; + spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); + spec[i++] = GLX_ACCUM_BLUE_SIZE; + spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); + if (f.alpha()) { + spec[i++] = GLX_ACCUM_ALPHA_SIZE; + spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); + } + } + } else { + spec[i++] = GLX_BUFFER_SIZE; + spec[i++] = bufDepth; + } + + if (f.sampleBuffers()) { + spec[i++] = GLX_SAMPLE_BUFFERS_ARB; + spec[i++] = 1; + spec[i++] = GLX_SAMPLES_ARB; + spec[i++] = f.samples() == -1 ? 4 : f.samples(); + } + +#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) + if (useFBConfig) { + spec[i++] = GLX_DRAWABLE_TYPE; + switch(paintDevice->devType()) { + case QInternal::Pixmap: + spec[i++] = GLX_PIXMAP_BIT; + break; + case QInternal::Pbuffer: + spec[i++] = GLX_PBUFFER_BIT; + break; + default: + qWarning("QGLContext: Unknown paint device type %d", paintDevice->devType()); + // Fall-through & assume it's a window + case QInternal::Widget: + spec[i++] = GLX_WINDOW_BIT; + break; + }; + } +#endif + + spec[i] = XNone; + return useFBConfig; +} + /***************************************************************************** QGLContext UNIX/GLX-specific code *****************************************************************************/ @@ -606,143 +748,8 @@ void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) { Q_D(QGLContext); int spec[45]; - int i = 0; - spec[i++] = GLX_LEVEL; - spec[i++] = f.plane(); const QX11Info *xinfo = qt_x11Info(d->paintDevice); - bool useFBConfig = false; - -#if defined(GLX_VERSION_1_3) && !defined(QT_NO_XRENDER) && !defined(Q_OS_HPUX) - /* - HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions. - Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented. - */ - QWidget* widget = 0; - if (d->paintDevice->devType() == QInternal::Widget) - widget = static_cast(d->paintDevice); - - // Only use glXChooseFBConfig for widgets if we're trying to get an ARGB visual - if (widget && widget->testAttribute(Qt::WA_TranslucentBackground) && X11->use_xrender) - useFBConfig = true; -#endif - -#if defined(GLX_VERSION_1_1) && defined(GLX_EXT_visual_info) - static bool useTranspExt = false; - static bool useTranspExtChecked = false; - if (f.plane() && !useTranspExtChecked && d->paintDevice) { - QGLExtensionMatcher extensions(glXQueryExtensionsString(xinfo->display(), xinfo->screen())); - useTranspExt = extensions.match("GLX_EXT_visual_info"); - //# (A bit simplistic; that could theoretically be a substring) - if (useTranspExt) { - QByteArray cstr(glXGetClientString(xinfo->display(), GLX_VENDOR)); - useTranspExt = !cstr.contains("Xi Graphics"); // bug workaround - if (useTranspExt) { - // bug workaround - some systems (eg. FireGL) refuses to return an overlay - // visual if the GLX_TRANSPARENT_TYPE_EXT attribute is specified, even if - // the implementation supports transparent overlays - int tmpSpec[] = { GLX_LEVEL, f.plane(), GLX_TRANSPARENT_TYPE_EXT, - f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT, - XNone }; - XVisualInfo * vinf = glXChooseVisual(xinfo->display(), xinfo->screen(), tmpSpec); - if (!vinf) { - useTranspExt = false; - } - } - } - - useTranspExtChecked = true; - } - if (f.plane() && useTranspExt && !useFBConfig) { - // Required to avoid non-transparent overlay visual(!) on some systems - spec[i++] = GLX_TRANSPARENT_TYPE_EXT; - spec[i++] = f.rgba() ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; - } -#endif - -#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) - // GLX_RENDER_TYPE is only in glx >=1.3 - if (useFBConfig) { - spec[i++] = GLX_RENDER_TYPE; - spec[i++] = f.rgba() ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT; - } -#endif - - if (f.doubleBuffer()) - spec[i++] = GLX_DOUBLEBUFFER; - if (useFBConfig) - spec[i++] = True; - if (f.depth()) { - spec[i++] = GLX_DEPTH_SIZE; - spec[i++] = f.depthBufferSize() == -1 ? 1 : f.depthBufferSize(); - } - if (f.stereo()) { - spec[i++] = GLX_STEREO; - if (useFBConfig) - spec[i++] = True; - } - if (f.stencil()) { - spec[i++] = GLX_STENCIL_SIZE; - spec[i++] = f.stencilBufferSize() == -1 ? 1 : f.stencilBufferSize(); - } - if (f.rgba()) { - if (!useFBConfig) - spec[i++] = GLX_RGBA; - spec[i++] = GLX_RED_SIZE; - spec[i++] = f.redBufferSize() == -1 ? 1 : f.redBufferSize(); - spec[i++] = GLX_GREEN_SIZE; - spec[i++] = f.greenBufferSize() == -1 ? 1 : f.greenBufferSize(); - spec[i++] = GLX_BLUE_SIZE; - spec[i++] = f.blueBufferSize() == -1 ? 1 : f.blueBufferSize(); - if (f.alpha()) { - spec[i++] = GLX_ALPHA_SIZE; - spec[i++] = f.alphaBufferSize() == -1 ? 1 : f.alphaBufferSize(); - } - if (f.accum()) { - spec[i++] = GLX_ACCUM_RED_SIZE; - spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); - spec[i++] = GLX_ACCUM_GREEN_SIZE; - spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); - spec[i++] = GLX_ACCUM_BLUE_SIZE; - spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); - if (f.alpha()) { - spec[i++] = GLX_ACCUM_ALPHA_SIZE; - spec[i++] = f.accumBufferSize() == -1 ? 1 : f.accumBufferSize(); - } - } - } else { - spec[i++] = GLX_BUFFER_SIZE; - spec[i++] = bufDepth; - } - - if (f.sampleBuffers()) { - spec[i++] = GLX_SAMPLE_BUFFERS_ARB; - spec[i++] = 1; - spec[i++] = GLX_SAMPLES_ARB; - spec[i++] = f.samples() == -1 ? 4 : f.samples(); - } - -#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) - if (useFBConfig) { - spec[i++] = GLX_DRAWABLE_TYPE; - switch(d->paintDevice->devType()) { - case QInternal::Pixmap: - spec[i++] = GLX_PIXMAP_BIT; - break; - case QInternal::Pbuffer: - spec[i++] = GLX_PBUFFER_BIT; - break; - default: - qWarning("QGLContext: Unknown paint device type %d", d->paintDevice->devType()); - // Fall-through & assume it's a window - case QInternal::Widget: - spec[i++] = GLX_WINDOW_BIT; - break; - }; - } -#endif - - spec[i] = XNone; - + bool useFBConfig = buildSpec(spec, f, d->paintDevice, bufDepth, false); XVisualInfo* chosenVisualInfo = 0; @@ -755,7 +762,7 @@ void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth) if (!configs) break; // fallback to trying glXChooseVisual - for (i = 0; i < configCount; ++i) { + for (int i = 0; i < configCount; ++i) { XVisualInfo* vi; vi = glXGetVisualFromFBConfig(xinfo->display(), configs[i]); if (!vi) -- cgit v0.12 From d6c1894772ffd0c1ef2c4fd2c7469328dbbf9fc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Riku=20Palom=C3=A4ki?= Date: Mon, 7 Jun 2010 12:18:24 +0200 Subject: Use the new OpenGL 3.* context/profile if asked with X11/GLX. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Merge-request: 609 Reviewed-by: Samuel Rødal --- src/opengl/qgl_x11.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index a6b0fae..9c1f537 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -115,6 +115,20 @@ extern const QX11Info *qt_x11Info(const QPaintDevice *pd); #define GLX_FRONT_LEFT_EXT 0x20DE #endif +#ifndef GLX_ARB_create_context +#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define GLX_CONTEXT_FLAGS_ARB 0x2094 +#endif + +#ifndef GLX_ARB_create_context_profile +#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126 +#endif + /* The qt_gl_choose_cmap function is internal and used by QGLWidget::setContext() and GLX (not Windows). If the application can't find any sharable @@ -635,21 +649,70 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) shareContext = 0; } + const int major = d->reqFormat.majorVersion(); + const int minor = d->reqFormat.minorVersion(); + const int profile = d->reqFormat.profile() == QGLFormat::CompatibilityProfile + ? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB + : GLX_CONTEXT_CORE_PROFILE_BIT_ARB; + d->cx = 0; - if (shareContext) { + + if ((major == 3 && minor >= 2) || major > 3) { + QGLTemporaryContext *tmpContext = 0; + if (!QGLContext::currentContext()) + tmpContext = new QGLTemporaryContext; + + int attributes[] = { GLX_CONTEXT_MAJOR_VERSION_ARB, major, + GLX_CONTEXT_MINOR_VERSION_ARB, minor, + GLX_CONTEXT_PROFILE_MASK_ARB, profile, + 0 }; + + PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = + (PFNGLXCREATECONTEXTATTRIBSARBPROC) qglx_getProcAddress("glXCreateContextAttribsARB"); + + if (glXCreateContextAttribs) { + int spec[45]; + glXGetConfig(disp, (XVisualInfo*)d->vi, GLX_BUFFER_SIZE, &res); + buildSpec(spec, format(), d->paintDevice, res, true); + + GLXFBConfig *configs; + int configCount = 0; + configs = glXChooseFBConfig(disp, xinfo->screen(), spec, &configCount); + + if (configs && configCount > 0) { + d->cx = glXCreateContextAttribs(disp, configs[0], + shareContext ? (GLXContext)shareContext->d_func()->cx : 0, direct, attributes); + if (!d->cx && shareContext) { + shareContext = 0; + d->cx = glXCreateContextAttribs(disp, configs[0], 0, direct, attributes); + } + d->screen = ((XVisualInfo*)d->vi)->screen; + } + XFree(configs); + } else { + qWarning("QGLContext::chooseContext(): OpenGL %d.%d is not supported", major, minor); + } + + if (tmpContext) + delete tmpContext; + } + if (!d->cx && shareContext) { d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, (GLXContext)shareContext->d_func()->cx, direct); d->screen = ((XVisualInfo*)d->vi)->screen; - if (d->cx) { - QGLContext *share = const_cast(shareContext); - d->sharing = true; - share->d_func()->sharing = true; - } } if (!d->cx) { d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, NULL, direct); d->screen = ((XVisualInfo*)d->vi)->screen; + shareContext = 0; + } + + if (shareContext && d->cx) { + QGLContext *share = const_cast(shareContext); + d->sharing = true; + share->d_func()->sharing = true; } + if (!d->cx) return false; d->glFormat.setDirectRendering(glXIsDirect(disp, (GLXContext)d->cx)); -- cgit v0.12 From 679611c26c5b7ecf63b4ed490803073a96ce9d92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 7 Jun 2010 12:16:41 +0200 Subject: Protected call to glXChooseFBConfig with appropriate defines. Reviewed-by: Trond --- src/opengl/qgl_x11.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index 9c1f537..8194c588 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -657,6 +657,11 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) d->cx = 0; +#if defined(GLX_VERSION_1_3) && !defined(Q_OS_HPUX) + /* + HPUX defines GLX_VERSION_1_3 but does not implement the corresponding functions. + Specifically glXChooseFBConfig and glXGetVisualFromFBConfig are not implemented. + */ if ((major == 3 && minor >= 2) || major > 3) { QGLTemporaryContext *tmpContext = 0; if (!QGLContext::currentContext()) @@ -696,6 +701,12 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) if (tmpContext) delete tmpContext; } +#else + Q_UNUSED(major); + Q_UNUSED(minor); + Q_UNUSED(profile); +#endif + if (!d->cx && shareContext) { d->cx = glXCreateContext(disp, (XVisualInfo *)d->vi, (GLXContext)shareContext->d_func()->cx, direct); -- cgit v0.12 From 95fcfccf3c6d9d102fa1c5481e6be52a21749af6 Mon Sep 17 00:00:00 2001 From: David Boddie Date: Mon, 7 Jun 2010 16:51:18 +0200 Subject: Doc: Added details of a system proxy limitation on Windows. Reviewed-by: Markus Goetz Task-number: QTBUG-10106 --- src/network/kernel/qnetworkproxy.cpp | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/network/kernel/qnetworkproxy.cpp b/src/network/kernel/qnetworkproxy.cpp index ada9381..bc5a025 100644 --- a/src/network/kernel/qnetworkproxy.cpp +++ b/src/network/kernel/qnetworkproxy.cpp @@ -1138,6 +1138,20 @@ void QNetworkProxyQuery::setUrl(const QUrl &url) multiple connections, such as QNetworkAccessManager. When set on such object, the factory will be queried for sockets created by that framework only. + + \section1 System Proxies + + You can configure a factory to use the system proxy's settings. + Call the setUseSystemConfiguration() function with true to enable + this behavior, or false to disable it. + + Similarly, you can use a factory to make queries directly to the + system proxy by calling its systemProxyForQuery() function. + + \warning Depending on the configuration of the user's system, the + use of system proxy features on certain platforms may be subject + to limitations. The systemProxyForQuery() documentation contains a + list of these limitations for those platforms that are affected. */ /*! @@ -1159,17 +1173,20 @@ QNetworkProxyFactory::~QNetworkProxyFactory() /*! + \since 4.6 + Enables the use of the platform-specific proxy settings, and only those. See systemProxyForQuery() for more information. Internally, this method (when called with \a enable set to true) sets an application-wide proxy factory. For this reason, this method - is mutually exclusive with setApplicationProxyFactory: calling - setApplicationProxyFactory overrides the use of the system-wide proxy, - and calling setUseSystemConfiguration overrides any + is mutually exclusive with setApplicationProxyFactory(): calling + setApplicationProxyFactory() overrides the use of the system-wide proxy, + and calling setUseSystemConfiguration() overrides any application proxy or proxy factory that was previously set. - \since 4.6 + \note See the systemProxyForQuery() documentation for a list of + limitations related to the use of system proxies. */ void QNetworkProxyFactory::setUseSystemConfiguration(bool enable) { @@ -1264,8 +1281,13 @@ void QNetworkProxyFactory::setApplicationProxyFactory(QNetworkProxyFactory *fact function. Future versions of Qt may lift some of the limitations listed here. - On MacOS X, this function will ignore the Proxy Auto Configuration + \list + \o On MacOS X, this function will ignore the Proxy Auto Configuration settings, since it cannot execute the associated ECMAScript code. + + \o On Windows platforms, this function may take several seconds to + execute depending on the configuration of the user's system. + \endlist */ /*! -- cgit v0.12 From bbf78c9b422c4c7eda7e7fce067578c75d3bc9b3 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Mon, 7 Jun 2010 17:57:56 +0200 Subject: Allow to build Qt in static with mingw Some functions were marked with Q_DECL_IMPORT where they should just be Q_CORE_EXPORT. The reason is that this macro is expanded to nothing in case of static builds whereas Q_DECL_IMPORT isn't (it is a dllimport). That leads the linker to try to import it and it shouldn't. Task-number: QTBUG-10791 Reviewed-by: gabi --- src/declarative/qml/parser/qdeclarativejslexer.cpp | 2 +- src/gui/kernel/qapplication.cpp | 2 +- src/gui/kernel/qwhatsthis.cpp | 2 +- src/script/api/qscriptengine.cpp | 4 +--- src/script/parser/qscriptlexer.cpp | 2 +- src/xmlpatterns/data/qdecimal_p.h | 2 +- 6 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/declarative/qml/parser/qdeclarativejslexer.cpp b/src/declarative/qml/parser/qdeclarativejslexer.cpp index 975ad4c..fcaaece 100644 --- a/src/declarative/qml/parser/qdeclarativejslexer.cpp +++ b/src/declarative/qml/parser/qdeclarativejslexer.cpp @@ -57,7 +57,7 @@ #include QT_BEGIN_NAMESPACE -Q_DECL_IMPORT extern double qstrtod(const char *s00, char const **se, bool *ok); +Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok); QT_END_NAMESPACE QT_QML_BEGIN_NAMESPACE diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index c9a3e8b..02d732b 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -146,7 +146,7 @@ static void initResources() QT_BEGIN_NAMESPACE -Q_DECL_IMPORT extern void qt_call_post_routines(); +Q_CORE_EXPORT void qt_call_post_routines(); int QApplicationPrivate::app_compile_version = 0x040000; //we don't know exactly, but it's at least 4.0.0 diff --git a/src/gui/kernel/qwhatsthis.cpp b/src/gui/kernel/qwhatsthis.cpp index 6181b62..ff4641e 100644 --- a/src/gui/kernel/qwhatsthis.cpp +++ b/src/gui/kernel/qwhatsthis.cpp @@ -143,7 +143,7 @@ QT_BEGIN_NAMESPACE \sa QToolTip */ -Q_DECL_IMPORT extern void qDeleteInEventHandler(QObject *o); +Q_CORE_EXPORT void qDeleteInEventHandler(QObject *o); class QWhatsThat : public QWidget { diff --git a/src/script/api/qscriptengine.cpp b/src/script/api/qscriptengine.cpp index 86915bb..f02ea52 100644 --- a/src/script/api/qscriptengine.cpp +++ b/src/script/api/qscriptengine.cpp @@ -1525,7 +1525,7 @@ void QScriptEnginePrivate::detachAllRegisteredScriptStrings() #ifndef QT_NO_REGEXP -Q_DECL_IMPORT extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); +Q_CORE_EXPORT QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); JSC::JSValue QScriptEnginePrivate::newRegExp(JSC::ExecState *exec, const QRegExp ®exp) { @@ -2020,8 +2020,6 @@ QScriptValue QScriptEngine::newFunction(QScriptEngine::FunctionSignature fun, #ifndef QT_NO_REGEXP -Q_DECL_IMPORT extern QString qt_regexp_toCanonical(const QString &, QRegExp::PatternSyntax); - /*! Creates a QtScript object of class RegExp with the given \a regexp. diff --git a/src/script/parser/qscriptlexer.cpp b/src/script/parser/qscriptlexer.cpp index ca64776..3ddc3aa 100644 --- a/src/script/parser/qscriptlexer.cpp +++ b/src/script/parser/qscriptlexer.cpp @@ -31,7 +31,7 @@ QT_BEGIN_NAMESPACE -Q_DECL_IMPORT extern double qstrtod(const char *s00, char const **se, bool *ok); +Q_CORE_EXPORT double qstrtod(const char *s00, char const **se, bool *ok); #define shiftWindowsLineBreak() \ do { \ diff --git a/src/xmlpatterns/data/qdecimal_p.h b/src/xmlpatterns/data/qdecimal_p.h index d17b647..2a5e0b3 100644 --- a/src/xmlpatterns/data/qdecimal_p.h +++ b/src/xmlpatterns/data/qdecimal_p.h @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE /** * Defined in QtCore's qlocale.cpp. */ -Q_DECL_IMPORT extern char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp); +Q_CORE_EXPORT char *qdtoa(double d, int mode, int ndigits, int *decpt, int *sign, char **rve, char **resultp); namespace QPatternist { -- cgit v0.12 From d0e209747a31c3e06f82e831fc3695986e12e9cd Mon Sep 17 00:00:00 2001 From: Ritt Konstantin Date: Tue, 8 Jun 2010 12:07:04 +0200 Subject: prefer QElapsedTimer over QTime Merge-request: 678 Reviewed-by: Olivier Goffart --- src/corelib/kernel/qeventloop.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp index 628afa7..c19f718 100644 --- a/src/corelib/kernel/qeventloop.cpp +++ b/src/corelib/kernel/qeventloop.cpp @@ -43,7 +43,7 @@ #include "qabstracteventdispatcher.h" #include "qcoreapplication.h" -#include "qdatetime.h" +#include "qelapsedtimer.h" #include "qobject_p.h" #include @@ -247,7 +247,7 @@ void QEventLoop::processEvents(ProcessEventsFlags flags, int maxTime) if (!d->threadData->eventDispatcher) return; - QTime start; + QElapsedTimer start; start.start(); if (flags & DeferredDeletion) QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete); -- cgit v0.12 From a0dc2b8344e2a24d78d5648bfb0f9f76bca37ca9 Mon Sep 17 00:00:00 2001 From: Gordon Schumacher Date: Tue, 8 Jun 2010 13:37:30 +0200 Subject: QVarLenghtArray: Add typedefs for stl compatibility. Merge-request: 599 Reviewed-by: Olivier Goffart --- src/corelib/tools/qvarlengtharray.h | 7 +++++ src/corelib/tools/qvarlengtharray.qdoc | 49 ++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/src/corelib/tools/qvarlengtharray.h b/src/corelib/tools/qvarlengtharray.h index bfede94..4a6bb4b 100644 --- a/src/corelib/tools/qvarlengtharray.h +++ b/src/corelib/tools/qvarlengtharray.h @@ -127,6 +127,13 @@ public: inline T *data() { return ptr; } inline const T *data() const { return ptr; } inline const T * constData() const { return ptr; } + typedef int size_type; + typedef T value_type; + typedef value_type *pointer; + typedef const value_type *const_pointer; + typedef value_type &reference; + typedef const value_type &const_reference; + typedef qptrdiff difference_type; private: friend class QPodList; diff --git a/src/corelib/tools/qvarlengtharray.qdoc b/src/corelib/tools/qvarlengtharray.qdoc index 38901e5..ef2dc58 100644 --- a/src/corelib/tools/qvarlengtharray.qdoc +++ b/src/corelib/tools/qvarlengtharray.qdoc @@ -302,3 +302,52 @@ \a defaultValue. */ +/*! + \typedef QVarLengthArray::size_type + \since 4.7 + + Typedef for int. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::value_type + \since 4.7 + + Typedef for T. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::difference_type + \since 4.7 + + Typedef for ptrdiff_t. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::pointer + \since 4.7 + + Typedef for T *. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::const_pointer + \since 4.7 + + Typedef for const T *. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::reference + \since 4.7 + + Typedef for T &. Provided for STL compatibility. +*/ + +/*! + \typedef QVarLengthArray::const_reference + \since 4.7 + + Typedef for const T &. Provided for STL compatibility. +*/ + -- cgit v0.12 From a1f7df67056c24b8b23393401953859f6e59417e Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 2 Jun 2010 11:07:48 +0200 Subject: small optimisation Don't use fromLocal8Bit() when comparing an ascii string to a QString, use QLatin1String. --- src/declarative/qml/qdeclarativeimport.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/declarative/qml/qdeclarativeimport.cpp b/src/declarative/qml/qdeclarativeimport.cpp index c658a31..a2e3831 100644 --- a/src/declarative/qml/qdeclarativeimport.cpp +++ b/src/declarative/qml/qdeclarativeimport.cpp @@ -823,7 +823,7 @@ void QDeclarativeImportDatabase::addPluginPath(const QString& path) qDebug() << "QDeclarativeImportDatabase::addPluginPath" << path; QUrl url = QUrl(path); - if (url.isRelative() || url.scheme() == QString::fromLocal8Bit("file")) { + if (url.isRelative() || url.scheme() == QLatin1String("file")) { QDir dir = QDir(path); filePluginPath.prepend(dir.canonicalPath()); } else { @@ -842,7 +842,7 @@ void QDeclarativeImportDatabase::addImportPath(const QString& path) QUrl url = QUrl(path); QString cPath; - if (url.isRelative() || url.scheme() == QString::fromLocal8Bit("file")) { + if (url.isRelative() || url.scheme() == QLatin1String("file")) { QDir dir = QDir(path); cPath = dir.canonicalPath(); } else { -- cgit v0.12 From 17427887a2847acc74c61424e812aca0fea23226 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Jun 2010 21:03:52 +0200 Subject: Fix QString::isRightToLeft() to conform with Unicode Bidi algorithm Rules P2 and P3 demand us to ignore the LRE/LRO/RLE/RLO characters for determining the paragraph direction. Task-Number: Part of QT-3292 --- src/corelib/tools/qstring.cpp | 20 +++++++++++--------- src/corelib/tools/qstring.h | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 1172a7b..1d5fab3 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -6916,20 +6916,23 @@ void QString::updateProperties() const p++; } - p = d->data; - d->righttoleft = false; + d->righttoleft = isRightToLeft(); + d->clean = true; +} + +bool QString::isRightToLeft() const +{ + ushort *p = d->data; + const ushort * const end = p + d->size; + bool righttoleft = false; while (p < end) { switch(QChar::direction(*p)) { case QChar::DirL: - case QChar::DirLRO: - case QChar::DirLRE: goto end; case QChar::DirR: case QChar::DirAL: - case QChar::DirRLO: - case QChar::DirRLE: - d->righttoleft = true; + righttoleft = true; goto end; default: break; @@ -6937,8 +6940,7 @@ void QString::updateProperties() const ++p; } end: - d->clean = true; - return; + return righttoleft; } /*! \fn bool QString::isSimpleText() const diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index a1c4e77..e52f59f 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -590,7 +590,7 @@ public: #endif bool isSimpleText() const { if (!d->clean) updateProperties(); return d->simpletext; } - bool isRightToLeft() const { if (!d->clean) updateProperties(); return d->righttoleft; } + bool isRightToLeft() const; QString(int size, Qt::Initialization); -- cgit v0.12 From 0b06274858cab9cedace8e684d16664e49d5f814 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Jun 2010 21:10:08 +0200 Subject: Introduce LayoutDirection Qt::LayoutDirectionAuto Extend the enum to contains a value that can be used to hint that we would like to determine the text direction from the content. Reviewed-by: Simon Hausmann --- src/corelib/global/qnamespace.h | 3 ++- src/corelib/global/qnamespace.qdoc | 12 ++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/corelib/global/qnamespace.h b/src/corelib/global/qnamespace.h index a9c56f6..a12e121 100644 --- a/src/corelib/global/qnamespace.h +++ b/src/corelib/global/qnamespace.h @@ -1561,7 +1561,8 @@ public: enum LayoutDirection { LeftToRight, - RightToLeft + RightToLeft, + LayoutDirectionAuto }; enum AnchorPoint { diff --git a/src/corelib/global/qnamespace.qdoc b/src/corelib/global/qnamespace.qdoc index 7eae3a5..abbc03e 100644 --- a/src/corelib/global/qnamespace.qdoc +++ b/src/corelib/global/qnamespace.qdoc @@ -2572,15 +2572,23 @@ /*! \enum Qt::LayoutDirection - Specifies the direction of Qt's layouts: + Specifies the direction of Qt's layouts and text handling. \value LeftToRight Left-to-right layout. \value RightToLeft Right-to-left layout. + \value LayoutDirectionAuto Automatic layout. Right-to-left layouts are necessary for certain languages, notably Arabic and Hebrew. - \sa QApplication::setLayoutDirection(), QWidget::setLayoutDirection() + LayoutDirectionAuto serves two purposes. When used in conjunction with widgets and layouts, it + will imply to use the layout direction set on the parent widget or QApplication. This + has the same effect as QWidget::unsetLayoutDirection(). + + When LayoutDirectoinAuto is used in conjunction with text layouting, it will imply that the text + directionality is determined from the content of the string to be layouted. + + \sa QApplication::setLayoutDirection(), QWidget::setLayoutDirection(), QTextOption::setTextDirection(), QString::isRightToLeft() */ /*! -- cgit v0.12 From 312c028d44a80f5d6029eb166a0de731f8452525 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Jun 2010 21:11:50 +0200 Subject: Handle setting the layoutDirection to Qt::LayoutDirectionAuto Setting it to LayoutAuto will be ignored on an application level (only LeftToRight or RightToLeft are valid). On a widget level is does the same as calling unsetLayoutDirection(). Reviewed-by: Simon Hausmann --- src/gui/kernel/qapplication.cpp | 2 +- src/gui/kernel/qwidget.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gui/kernel/qapplication.cpp b/src/gui/kernel/qapplication.cpp index 02d732b..52767b8 100644 --- a/src/gui/kernel/qapplication.cpp +++ b/src/gui/kernel/qapplication.cpp @@ -3544,7 +3544,7 @@ int QApplication::startDragDistance() void QApplication::setLayoutDirection(Qt::LayoutDirection direction) { - if (layout_direction == direction) + if (layout_direction == direction || direction == Qt::LayoutDirectionAuto) return; layout_direction = direction; diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index 895c85d..ab84a54 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -4828,6 +4828,11 @@ void QWidget::setLayoutDirection(Qt::LayoutDirection direction) { Q_D(QWidget); + if (direction == Qt::LayoutDirectionAuto) { + unsetLayoutDirection(); + return; + } + setAttribute(Qt::WA_SetLayoutDirection); d->setLayoutDirection_helper(direction); } -- cgit v0.12 From 6287977849ff5cab64a944fb0590d306a79f3637 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Jun 2010 21:15:56 +0200 Subject: The default text direction for QTextOption is Qt::LayoutDirectionAuto The change is binary compatible, even though the changed bitfield is being accessed inline. The reason is that we extend by a bit that has previously been initialized to 0. bitordering will ensure that old code reads Qt::LayoutAuto as Qt::LeftToRight. Task-number: Part of QT-3292 Reviewed-by: Simon Hausmann --- src/gui/text/qtextoption.cpp | 2 +- src/gui/text/qtextoption.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qtextoption.cpp b/src/gui/text/qtextoption.cpp index c1e254c..3b02ebe 100644 --- a/src/gui/text/qtextoption.cpp +++ b/src/gui/text/qtextoption.cpp @@ -65,7 +65,7 @@ QTextOption::QTextOption() tab(-1), d(0) { - direction = QApplication::layoutDirection(); + direction = Qt::LayoutDirectionAuto; } /*! diff --git a/src/gui/text/qtextoption.h b/src/gui/text/qtextoption.h index 1381ed1..fa8c6f2 100644 --- a/src/gui/text/qtextoption.h +++ b/src/gui/text/qtextoption.h @@ -134,8 +134,8 @@ private: uint align : 8; uint wordWrap : 4; uint design : 1; - uint direction : 1; - uint unused : 19; + uint direction : 2; + uint unused : 18; uint f; qreal tab; QTextOptionPrivate *d; -- cgit v0.12 From 1533e7251d1dc4318b87ec799f0367f5fca0b092 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Jun 2010 21:20:23 +0200 Subject: Correct BiDi behavior of QLineEdit * LayoutDirectionChange event doesn't affect the text anymore. * Default text direction is determined from string * Qt::Key_Direction_L/R forces the layout direction Task-number: Part of Qt-3292 Reviewed-by: Simon Hausmann --- src/gui/widgets/qlinecontrol_p.h | 8 ++++++-- src/gui/widgets/qlineedit.cpp | 5 +---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index 5da1831..b419adf 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -78,7 +78,7 @@ class Q_GUI_EXPORT QLineControl : public QObject public: QLineControl(const QString &txt = QString()) - : m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LeftToRight), + : m_cursor(0), m_preeditCursor(0), m_cursorWidth(0), m_layoutDirection(Qt::LayoutDirectionAuto), m_hideCursor(false), m_separator(0), m_readOnly(0), m_dragEnabled(0), m_echoMode(0), m_textDirty(0), m_selDirty(0), m_validInput(1), m_blinkStatus(0), m_blinkPeriod(0), m_blinkTimer(0), m_deleteAllTimer(0), @@ -272,7 +272,11 @@ public: QChar passwordCharacter() const { return m_passwordCharacter; } void setPasswordCharacter(const QChar &character) { m_passwordCharacter = character; updateDisplayText(); } - Qt::LayoutDirection layoutDirection() const { return m_layoutDirection; } + Qt::LayoutDirection layoutDirection() const { + if (m_layoutDirection == Qt::LayoutDirectionAuto) + return m_text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight; + return m_layoutDirection; + } void setLayoutDirection(Qt::LayoutDirection direction) { if (direction != m_layoutDirection) { diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp index c1c4abf..1bffde1 100644 --- a/src/gui/widgets/qlineedit.cpp +++ b/src/gui/widgets/qlineedit.cpp @@ -1860,7 +1860,7 @@ void QLineEdit::paintEvent(QPaintEvent *) p.setClipRect(r); QFontMetrics fm = fontMetrics(); - Qt::Alignment va = QStyle::visualAlignment(layoutDirection(), QFlag(d->alignment)); + Qt::Alignment va = QStyle::visualAlignment(d->control->layoutDirection(), QFlag(d->alignment)); switch (va & Qt::AlignVertical_Mask) { case Qt::AlignBottom: d->vscroll = r.y() + r.height() - fm.height() - d->verticalMargin; @@ -2161,9 +2161,6 @@ void QLineEdit::changeEvent(QEvent *ev) } update(); break; - case QEvent::LayoutDirectionChange: - d->control->setLayoutDirection(layoutDirection()); - break; default: break; } -- cgit v0.12 From 906a68a59c242744568afb12aba1ccc474bf6217 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Jun 2010 21:40:05 +0200 Subject: LayoutDirectionAuto is the default layout direction for QPainter Don't retrieve the layout direction from QWidget or QApplication anymore. Respect if somebody explicitly sets the direction with setLayoutDirection(). Task-number: Part of QT-3292 Reviewed-by: Simon Hausmann --- src/gui/painting/qpainter.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 97f754d..e8c4599 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -1564,7 +1564,6 @@ void QPainter::initFrom(const QWidget *widget) d->engine->setDirty(QPaintEngine::DirtyBrush); d->engine->setDirty(QPaintEngine::DirtyFont); } - d->state->layoutDirection = widget->layoutDirection(); } @@ -1874,7 +1873,7 @@ bool QPainter::begin(QPaintDevice *pd) QWidget *widget = static_cast(d->original_device); initFrom(widget); } else { - d->state->layoutDirection = QApplication::layoutDirection(); + d->state->layoutDirection = Qt::LayoutDirectionAuto; // make sure we have a font compatible with the paintdevice d->state->deviceFont = d->state->font = QFont(d->state->deviceFont, device()); } @@ -8056,7 +8055,10 @@ start_lengthVariant: Sets the layout direction used by the painter when drawing text, to the specified \a direction. - \sa layoutDirection(), drawText(), {QPainter#Settings}{Settings} + The default is Qt::LayoutDirectionAuto, which will implicitly determine the + direction from the text drawn. + + \sa QTextOption::setTextDirection(), layoutDirection(), drawText(), {QPainter#Settings}{Settings} */ void QPainter::setLayoutDirection(Qt::LayoutDirection direction) { @@ -8068,12 +8070,12 @@ void QPainter::setLayoutDirection(Qt::LayoutDirection direction) /*! Returns the layout direction used by the painter when drawing text. - \sa setLayoutDirection(), drawText(), {QPainter#Settings}{Settings} + \sa QTextOption::textDirection(), setLayoutDirection(), drawText(), {QPainter#Settings}{Settings} */ Qt::LayoutDirection QPainter::layoutDirection() const { Q_D(const QPainter); - return d->state ? d->state->layoutDirection : Qt::LeftToRight; + return d->state ? d->state->layoutDirection : Qt::LayoutDirectionAuto; } QPainterState::QPainterState(const QPainterState *s) -- cgit v0.12 From 7358af18674f6dbd9abf67f6e02809f43e2cfc3e Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Jun 2010 21:45:25 +0200 Subject: Make sure LayoutDirectionAuto is the default text direction QTextFormat::intProperty requires a small change to ensure we return the right value for layoutDirection. No need to change QTextFormat::property, as an invalid QVariant will be returned if the layoutDirection is not explicitly set. Reviewed-by: Simon Hausmann --- src/gui/text/qtextformat.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 140cf43..46db253 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -900,11 +900,14 @@ bool QTextFormat::boolProperty(int propertyId) const */ int QTextFormat::intProperty(int propertyId) const { + // required, since the default layout direction has to be LayoutDirectionAuto, which is not integer 0 + int def = (propertyId == QTextFormat::LayoutDirection) ? int(Qt::LayoutDirectionAuto) : 0; + if (!d) - return 0; + return def; const QVariant prop = d->property(propertyId); if (prop.userType() != QVariant::Int) - return 0; + return def; return prop.toInt(); } -- cgit v0.12 From fee7f7d67f780b798a63994a1125f9ca3ade1bd3 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Jun 2010 22:05:44 +0200 Subject: Add QTextBlock::textDirection() The method returns the resolved text direction for the block. It implements P1-P3 of the Unicode bidi algorithm. Task-number: Part of Qt-3292 Reviewed-by: Simon Hausmann --- src/gui/text/qtextobject.cpp | 43 +++++++++++++++++++++++++++++++++++++++++++ src/gui/text/qtextobject.h | 2 ++ 2 files changed, 45 insertions(+) diff --git a/src/gui/text/qtextobject.cpp b/src/gui/text/qtextobject.cpp index 088eb98..f386871 100644 --- a/src/gui/text/qtextobject.cpp +++ b/src/gui/text/qtextobject.cpp @@ -1140,6 +1140,49 @@ int QTextBlock::charFormatIndex() const } /*! + \since 4.7 + + Returns the resolved text direction. + + If the block has no explicit direction set, it will resolve the + direction from the blocks content. Returns either Qt::LeftToRight + or Qt::RightToLeft. + + \sa QTextBlock::layoutDirection(), QString::isRightToLeft(), Qt::LayoutDirection +*/ +Qt::LayoutDirection QTextBlock::textDirection() const +{ + Qt::LayoutDirection dir = blockFormat().layoutDirection(); + if (dir != Qt::LayoutDirectionAuto) + return dir; + + const QString buffer = p->buffer(); + + const int pos = position(); + QTextDocumentPrivate::FragmentIterator it = p->find(pos); + QTextDocumentPrivate::FragmentIterator end = p->find(pos + length() - 1); // -1 to omit the block separator char + for (; it != end; ++it) { + const QTextFragmentData * const frag = it.value(); + const QChar *p = buffer.constData() + frag->stringPosition; + const QChar * const end = p + frag->size_array[0]; + while (p < end) { + switch(QChar::direction(p->unicode())) + { + case QChar::DirL: + return Qt::LeftToRight; + case QChar::DirR: + case QChar::DirAL: + return Qt::RightToLeft; + default: + break; + } + ++p; + } + } + return Qt::LeftToRight; +} + +/*! Returns the block's contents as plain text. \sa length() charFormat() blockFormat() diff --git a/src/gui/text/qtextobject.h b/src/gui/text/qtextobject.h index 67f67d8..a573a26 100644 --- a/src/gui/text/qtextobject.h +++ b/src/gui/text/qtextobject.h @@ -221,6 +221,8 @@ public: QTextCharFormat charFormat() const; int charFormatIndex() const; + Qt::LayoutDirection textDirection() const; + QString text() const; const QTextDocument *document() const; -- cgit v0.12 From 7b0f00e8c8a4ec541dba510debcf786c7edb7fae Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Jun 2010 22:11:57 +0200 Subject: Use the textDirection() of blocks correctly. Task-number: Part of QT-3292 Reviewed-by: Simon Hausmann --- src/gui/text/qtextcursor.cpp | 2 +- src/gui/text/qtextdocument.cpp | 9 +++------ src/gui/text/qtextdocumentlayout.cpp | 8 ++------ src/gui/text/qtextlist.cpp | 2 +- 4 files changed, 7 insertions(+), 14 deletions(-) diff --git a/src/gui/text/qtextcursor.cpp b/src/gui/text/qtextcursor.cpp index d6ac3aa..23849bc 100644 --- a/src/gui/text/qtextcursor.cpp +++ b/src/gui/text/qtextcursor.cpp @@ -362,7 +362,7 @@ bool QTextCursorPrivate::movePosition(QTextCursor::MoveOperation op, QTextCursor QTextBlock blockIt = block(); if (op >= QTextCursor::Left && op <= QTextCursor::WordRight - && blockIt.blockFormat().layoutDirection() == Qt::RightToLeft) { + && blockIt.textDirection() == Qt::RightToLeft) { if (op == QTextCursor::Left) op = QTextCursor::NextCharacter; else if (op == QTextCursor::Right) diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp index c7a9756..48aee8f 100644 --- a/src/gui/text/qtextdocument.cpp +++ b/src/gui/text/qtextdocument.cpp @@ -2496,13 +2496,10 @@ void QTextHtmlExporter::emitBlockAttributes(const QTextBlock &block) QTextBlockFormat format = block.blockFormat(); emitAlignment(format.alignment()); - Qt::LayoutDirection dir = format.layoutDirection(); - if (dir == Qt::LeftToRight) { - // assume default to not bloat the html too much - // html += QLatin1String(" dir='ltr'"); - } else { + // assume default to not bloat the html too much + // html += QLatin1String(" dir='ltr'"); + if (block.textDirection() == Qt::RightToLeft) html += QLatin1String(" dir='rtl'"); - } QLatin1String style(" style=\""); html += style; diff --git a/src/gui/text/qtextdocumentlayout.cpp b/src/gui/text/qtextdocumentlayout.cpp index eeb66ce..ff14490 100644 --- a/src/gui/text/qtextdocumentlayout.cpp +++ b/src/gui/text/qtextdocumentlayout.cpp @@ -1369,9 +1369,7 @@ void QTextDocumentLayoutPrivate::drawListItem(const QPointF &offset, QPainter *p QTextLine firstLine = layout->lineAt(0); Q_ASSERT(firstLine.isValid()); QPointF pos = (offset + layout->position()).toPoint(); - Qt::LayoutDirection dir = docPrivate->defaultTextOption.textDirection(); - if (blockFormat.hasProperty(QTextFormat::LayoutDirection)) - dir = blockFormat.layoutDirection(); + Qt::LayoutDirection dir = bl.textDirection(); { QRectF textRect = firstLine.naturalTextRect(); pos += textRect.topLeft().toPoint(); @@ -2530,9 +2528,7 @@ void QTextDocumentLayoutPrivate::layoutBlock(const QTextBlock &bl, int blockPosi //QTextFrameData *fd = data(layoutStruct->frame); - Qt::LayoutDirection dir = docPrivate->defaultTextOption.textDirection(); - if (blockFormat.hasProperty(QTextFormat::LayoutDirection)) - dir = blockFormat.layoutDirection(); + Qt::LayoutDirection dir = bl.textDirection(); QFixed extraMargin; if (docPrivate->defaultTextOption.flags() & QTextOption::AddSpaceForLineAndParagraphSeparators) { diff --git a/src/gui/text/qtextlist.cpp b/src/gui/text/qtextlist.cpp index 2986ee7..a0ff520 100644 --- a/src/gui/text/qtextlist.cpp +++ b/src/gui/text/qtextlist.cpp @@ -262,7 +262,7 @@ QString QTextList::itemText(const QTextBlock &blockIt) const default: Q_ASSERT(false); } - if (blockFormat.layoutDirection() == Qt::RightToLeft) + if (blockIt.textDirection() == Qt::RightToLeft) return result.prepend(QLatin1Char('.')); return result + QLatin1Char('.'); } -- cgit v0.12 From 2ae3d17883c0b24f7f4a5a1ea763105a2c8a7342 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Jun 2010 22:12:56 +0200 Subject: correctly initialize the bidi level in the text engine If the text options doesn't specify the layout direction, determine it from the content. Reviewed-by: Simon Hausmann --- src/gui/text/qtextengine.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 3486264..191508c 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1404,7 +1404,20 @@ void QTextEngine::itemize() const #else bool ignore = ignoreBidi; #endif - if (!ignore && option.textDirection() == Qt::LeftToRight) { + + bool rtl = false; + switch (option.textDirection()) { + case Qt::LeftToRight: + break; + case Qt::RightToLeft: + rtl = true; + break; + case Qt::LayoutDirectionAuto: + rtl = layoutData->string.isRightToLeft(); + break; + } + + if (!ignore && !rtl) { ignore = true; const QChar *start = layoutData->string.unicode(); const QChar * const end = start + length; @@ -1420,7 +1433,7 @@ void QTextEngine::itemize() const QVarLengthArray scriptAnalysis(length); QScriptAnalysis *analysis = scriptAnalysis.data(); - QBidiControl control(option.textDirection() == Qt::RightToLeft); + QBidiControl control(rtl); if (ignore) { memset(analysis, 0, length*sizeof(QScriptAnalysis)); -- cgit v0.12 From b69e592b2b8fb3eae75c112e491e3ed90fc0248a Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Jun 2010 23:21:59 +0200 Subject: For an empty line edit the cursor position is depending on input language Ensure the cursor is on the right if the keyboard layout is for a right to left language. Task-number: Part of Qt-3292 Reviewed-by: Simon Hausmann --- src/declarative/graphicsitems/qdeclarativetextinput.cpp | 1 - src/gui/widgets/qlinecontrol_p.h | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 1202101..8d320f4 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -1356,7 +1356,6 @@ void QDeclarativeTextInputPrivate::init() Q_Q(QDeclarativeTextInput); control->setCursorWidth(1); control->setPasswordCharacter(QLatin1Char('*')); - control->setLayoutDirection(Qt::LeftToRight); q->setSmooth(smooth); q->setAcceptedMouseButtons(Qt::LeftButton); q->setFlag(QGraphicsItem::ItemHasNoContents, false); diff --git a/src/gui/widgets/qlinecontrol_p.h b/src/gui/widgets/qlinecontrol_p.h index b419adf..7068f62 100644 --- a/src/gui/widgets/qlinecontrol_p.h +++ b/src/gui/widgets/qlinecontrol_p.h @@ -273,8 +273,11 @@ public: void setPasswordCharacter(const QChar &character) { m_passwordCharacter = character; updateDisplayText(); } Qt::LayoutDirection layoutDirection() const { - if (m_layoutDirection == Qt::LayoutDirectionAuto) + if (m_layoutDirection == Qt::LayoutDirectionAuto) { + if (m_text.isEmpty()) + return QApplication::keyboardInputDirection(); return m_text.isRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight; + } return m_layoutDirection; } void setLayoutDirection(Qt::LayoutDirection direction) -- cgit v0.12 From 726607baf707318de6f685573553d22df4966f61 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Jun 2010 23:23:42 +0200 Subject: consistent handling of directionality in QTextLayout Make sure we use the same method to determine RTL/LTR for the layout everywhere. Task-number: Part of QT-3292 Reviewed-by: Simon Hausmann --- src/gui/text/qtextengine.cpp | 31 +++++++++++++++++++------------ src/gui/text/qtextengine_p.h | 1 + src/gui/text/qtextlayout.cpp | 6 +++--- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 191508c..ac1fffd 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1405,17 +1405,7 @@ void QTextEngine::itemize() const bool ignore = ignoreBidi; #endif - bool rtl = false; - switch (option.textDirection()) { - case Qt::LeftToRight: - break; - case Qt::RightToLeft: - rtl = true; - break; - case Qt::LayoutDirectionAuto: - rtl = layoutData->string.isRightToLeft(); - break; - } + bool rtl = isRightToLeft(); if (!ignore && !rtl) { ignore = true; @@ -1528,6 +1518,23 @@ void QTextEngine::itemize() const resolveAdditionalFormats(); } +bool QTextEngine::isRightToLeft() const +{ + switch (option.textDirection()) { + case Qt::LeftToRight: + return false; + case Qt::RightToLeft: + return true; + default: + break; + } + // this places the cursor in the right position depending on the keyboard layout + if (layoutData->string.isEmpty()) + return QApplication::keyboardInputDirection() == Qt::RightToLeft; + return layoutData->string.isRightToLeft(); +} + + int QTextEngine::findItem(int strPos) const { itemize(); @@ -2524,7 +2531,7 @@ QFixed QTextEngine::calculateTabWidth(int item, QFixed x) const QList tabArray = option.tabs(); if (!tabArray.isEmpty()) { - if (option.textDirection() == Qt::RightToLeft) { // rebase the tabArray positions. + if (isRightToLeft()) { // rebase the tabArray positions. QList newTabs; QList::Iterator iter = tabArray.begin(); while(iter != tabArray.end()) { diff --git a/src/gui/text/qtextengine_p.h b/src/gui/text/qtextengine_p.h index 00b1392..908a0ec 100644 --- a/src/gui/text/qtextengine_p.h +++ b/src/gui/text/qtextengine_p.h @@ -458,6 +458,7 @@ public: void validate() const; void itemize() const; + bool isRightToLeft() const; static void bidiReorder(int numRuns, const quint8 *levels, int *visualOrder); const HB_CharAttributes *attributes() const; diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index f5e252c..ddf9411 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -69,7 +69,7 @@ static inline QFixed leadingSpaceWidth(QTextEngine *eng, const QScriptLine &line if (!line.hasTrailingSpaces || (eng->option.flags() & QTextOption::IncludeTrailingSpaces) || !(eng->option.alignment() & Qt::AlignRight) - || (eng->option.textDirection() != Qt::RightToLeft)) + || !eng->isRightToLeft()) return QFixed(); int pos = line.length; @@ -86,7 +86,7 @@ static QFixed alignLine(QTextEngine *eng, const QScriptLine &line) // if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned. if (!line.justified && line.width != QFIXED_MAX) { int align = eng->option.alignment(); - if (align & Qt::AlignJustify && eng->option.textDirection() == Qt::RightToLeft) + if (align & Qt::AlignJustify && eng->isRightToLeft()) align = Qt::AlignRight; if (align & Qt::AlignRight) x = line.width - (line.textAdvance + leadingSpaceWidth(eng, line)); @@ -1337,7 +1337,7 @@ void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition int itm = d->findItem(cursorPosition - 1); QFixed base = sl.base(); QFixed descent = sl.descent; - bool rightToLeft = (d->option.textDirection() == Qt::RightToLeft); + bool rightToLeft = d->isRightToLeft(); if (itm >= 0) { const QScriptItem &si = d->layoutData->items.at(itm); if (si.ascent > 0) -- cgit v0.12 From 424735f91dbf5847640aca4011a309dbef7b1e31 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 9 Jun 2010 23:00:20 +0200 Subject: Add a isWrittenRightToLeft() method to QLocale. This helps us keeping the code in the key mappers that detect keyboard changes simple and is useful for other cases as well. Task-number: Part of QT-3292 Reviewed-by: Simon Hausmann --- src/corelib/tools/qlocale.cpp | 19 +++++++++++++++++++ src/corelib/tools/qlocale.h | 2 ++ 2 files changed, 21 insertions(+) diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index c000dc8..8f50f2e 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -3478,6 +3478,25 @@ QLocale::MeasurementSystem QLocale::measurementSystem() const } /*! + \since 4.7 + + Returns true if the language is written right to left. +*/ +bool QLocale::isWrittenRightToLeft() const +{ + Language lang = language(); + if (lang == QLocale::Arabic || + lang == QLocale::Hebrew || + lang == QLocale::Persian || + lang == QLocale::Urdu || + lang == QLocale::Syriac) + return true; + + return false; +} + + +/*! \since 4.5 Returns the localized name of the "AM" suffix for times specified using diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index f2fd892..f8b5c55 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -666,6 +666,8 @@ public: MeasurementSystem measurementSystem() const; + bool isWrittenRightToLeft() const; + inline bool operator==(const QLocale &other) const; inline bool operator!=(const QLocale &other) const; -- cgit v0.12 From da603c7c80ea14df18790ae77f5de82880307650 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Sat, 5 Jun 2010 23:15:16 +0200 Subject: Fixed some bugs in detection of keyboard directionality The mapping table on X11 had a few bugs. Implemented rudimentary support on QWS and fixed a tiny issue on Mac. Reviewed-by: Simon Hausmann --- src/gui/inputmethod/qximinputcontext_x11.cpp | 14 +++----------- src/gui/kernel/qkeymapper_mac.cpp | 18 +----------------- src/gui/kernel/qkeymapper_qws.cpp | 2 +- src/gui/kernel/qkeymapper_x11.cpp | 21 ++++++--------------- src/gui/kernel/qkeymapper_x11_p.cpp | 14 +++++++------- 5 files changed, 18 insertions(+), 51 deletions(-) diff --git a/src/gui/inputmethod/qximinputcontext_x11.cpp b/src/gui/inputmethod/qximinputcontext_x11.cpp index d048b36..88f8daf 100644 --- a/src/gui/inputmethod/qximinputcontext_x11.cpp +++ b/src/gui/inputmethod/qximinputcontext_x11.cpp @@ -346,10 +346,7 @@ static XFontSet getFontSet(const QFont &f) extern bool qt_use_rtl_extensions; // from qapplication_x11.cpp #ifndef QT_NO_XKB -extern void q_getLocaleAndDirection(QLocale *locale, - Qt::LayoutDirection *direction, - const QByteArray &layoutName, - const QByteArray &variantName); +extern QLocale q_getKeyboardLocale(const QByteArray &layoutName, const QByteArray &variantName); #endif QXIMInputContext::QXIMInputContext() @@ -407,17 +404,12 @@ QXIMInputContext::QXIMInputContext() QList layoutNames = QByteArray::fromRawData(names[2], qstrlen(names[2])).split(','); QList variantNames = QByteArray::fromRawData(names[3], qstrlen(names[3])).split(','); for (int i = 0; i < qMin(layoutNames.count(), variantNames.count()); ++i ) { - QLocale keyboardInputLocale; - Qt::LayoutDirection keyboardInputDirection; QByteArray variantName = variantNames.at(i); const int dashPos = variantName.indexOf("-"); if (dashPos >= 0) variantName.truncate(dashPos); - q_getLocaleAndDirection(&keyboardInputLocale, - &keyboardInputDirection, - layoutNames.at(i), - variantName); - if (keyboardInputDirection == Qt::RightToLeft) + QLocale keyboardInputLocale = q_getKeyboardLocale(layoutNames.at(i), variantName); + if (keyboardInputLocale.isWrittenRightToLeft()) qt_use_rtl_extensions = true; } } diff --git a/src/gui/kernel/qkeymapper_mac.cpp b/src/gui/kernel/qkeymapper_mac.cpp index a7145d4..885f5ba 100644 --- a/src/gui/kernel/qkeymapper_mac.cpp +++ b/src/gui/kernel/qkeymapper_mac.cpp @@ -672,23 +672,7 @@ QKeyMapperPrivate::updateKeyboard() #endif if (iso639Code) { keyboardInputLocale = QLocale(QCFString::toQString(iso639Code)); - QString monday = keyboardInputLocale.dayName(1); - bool rtl = false; - for (int i = 0; i < monday.length(); ++i) { - switch (monday.at(i).direction()) { - default: - break; - case QChar::DirR: - case QChar::DirAL: - case QChar::DirRLE: - case QChar::DirRLO: - rtl = true; - break; - } - if (rtl) - break; - } - keyboardInputDirection = rtl ? Qt::RightToLeft : Qt::LeftToRight; + keyboardInputDirection = keyboardInputLocale.isWrittenRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight; } else { keyboardInputLocale = QLocale::c(); keyboardInputDirection = Qt::LeftToRight; diff --git a/src/gui/kernel/qkeymapper_qws.cpp b/src/gui/kernel/qkeymapper_qws.cpp index 5b6b1c4..0e9f35a 100644 --- a/src/gui/kernel/qkeymapper_qws.cpp +++ b/src/gui/kernel/qkeymapper_qws.cpp @@ -52,7 +52,7 @@ QT_USE_NAMESPACE QKeyMapperPrivate::QKeyMapperPrivate() { keyboardInputLocale = QLocale::system(); - keyboardInputDirection = Qt::RightToLeft; + keyboardInputDirection = keyboardInputLocale.isWrittenRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight; } QKeyMapperPrivate::~QKeyMapperPrivate() diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/gui/kernel/qkeymapper_x11.cpp index 807959c..f0d548c 100644 --- a/src/gui/kernel/qkeymapper_x11.cpp +++ b/src/gui/kernel/qkeymapper_x11.cpp @@ -80,22 +80,15 @@ QT_BEGIN_NAMESPACE (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF)) #endif -void q_getLocaleAndDirection(QLocale *locale, - Qt::LayoutDirection *direction, - const QByteArray &layoutName, - const QByteArray &variantName) +QLocale q_getKeyboardLocale(const QByteArray &layoutName, const QByteArray &variantName) { int i = 0; while (xkbLayoutData[i].layout != 0) { - if (layoutName == xkbLayoutData[i].layout && variantName == xkbLayoutData[i].variant) { - *locale = QLocale(xkbLayoutData[i].language, xkbLayoutData[i].country); - *direction = xkbLayoutData[i].direction; - return; - } + if (layoutName == xkbLayoutData[i].layout && variantName == xkbLayoutData[i].variant) + return QLocale(xkbLayoutData[i].language, xkbLayoutData[i].country); ++i; } - *locale = QLocale::c(); - *direction = Qt::LeftToRight; + return QLocale::c(); } #endif // QT_NO_XKB @@ -523,10 +516,8 @@ void QKeyMapperPrivate::clearMappings() // if (keyboardLayoutName.isEmpty()) // qWarning("Qt: unable to determine keyboard layout, please talk to qt-bugs@trolltech.com"); ? - q_getLocaleAndDirection(&keyboardInputLocale, - &keyboardInputDirection, - layoutName, - variantName); + keyboardInputLocale = q_getKeyboardLocale(layoutName, variantName); + keyboardInputDirection = keyboardInputLocale.isWrittenRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight; #if 0 qDebug() << "keyboard input locale =" diff --git a/src/gui/kernel/qkeymapper_x11_p.cpp b/src/gui/kernel/qkeymapper_x11_p.cpp index 20fcc86..6308973 100644 --- a/src/gui/kernel/qkeymapper_x11_p.cpp +++ b/src/gui/kernel/qkeymapper_x11_p.cpp @@ -271,13 +271,13 @@ static struct { // name = is:nodeadkeys, description = Iceland { "is", "nodeadkeys", Qt::LeftToRight, QLocale::Icelandic, QLocale::Iceland }, // name = il, description = Israel - { "il", "", Qt::LeftToRight, QLocale::Hebrew, QLocale::Israel }, + { "il", "", Qt::RightToLeft, QLocale::Hebrew, QLocale::Israel }, // name = il:lyx, description = Israel - { "il", "lyx", Qt::LeftToRight, QLocale::Hebrew, QLocale::Israel }, + { "il", "lyx", Qt::RightToLeft, QLocale::Hebrew, QLocale::Israel }, // name = il:si1452, description = Israel - { "il", "si1452", Qt::LeftToRight, QLocale::Hebrew, QLocale::Israel }, + { "il", "si1452", Qt::RightToLeft, QLocale::Hebrew, QLocale::Israel }, // name = il:phonetic, description = Israel - { "il", "phonetic", Qt::LeftToRight, QLocale::Hebrew, QLocale::Israel }, + { "il", "phonetic", Qt::RightToLeft, QLocale::Hebrew, QLocale::Israel }, // name = it, description = Italy { "it", "", Qt::LeftToRight, QLocale::Italian, QLocale::Italy }, // name = it:nodeadkeys, description = Italy @@ -419,11 +419,11 @@ static struct { // name = ch:fr_sundeadkeys, description = Switzerland { "ch", "fr_sundeadkeys", Qt::LeftToRight, QLocale::French, QLocale::Switzerland }, // name = sy, description = Syria - { "sy", "", Qt::RightToLeft, QLocale::Arabic, QLocale::SyrianArabRepublic }, + { "sy", "", Qt::RightToLeft, QLocale::Syriac, QLocale::SyrianArabRepublic }, // name = sy:syc, description = Syria - { "sy", "syc", Qt::RightToLeft, QLocale::Arabic, QLocale::SyrianArabRepublic }, + { "sy", "syc", Qt::RightToLeft, QLocale::Syriac, QLocale::SyrianArabRepublic }, // name = sy:syc_phonetic, description = Syria - { "sy", "syc_phonetic", Qt::RightToLeft, QLocale::Arabic, QLocale::SyrianArabRepublic }, + { "sy", "syc_phonetic", Qt::RightToLeft, QLocale::Syriac, QLocale::SyrianArabRepublic }, // name = tj, description = Tajikistan { "tj", "", Qt::LeftToRight, QLocale::Tajik, QLocale::Tajikistan }, // name = lk, description = Sri Lanka -- cgit v0.12 From 1abf2d6dfafc71f73746b7e69e11e0c8152edb4a Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 10 Jun 2010 00:05:07 +0200 Subject: Rename QLocale::isWrittenRightToLeft() to textDirection() This is more in line with the rest of Qt. Reviewed-by: Simon Hausmann --- src/corelib/tools/qlocale.cpp | 8 ++++---- src/corelib/tools/qlocale.h | 2 +- src/gui/inputmethod/qximinputcontext_x11.cpp | 2 +- src/gui/kernel/qkeymapper_mac.cpp | 2 +- src/gui/kernel/qkeymapper_qws.cpp | 2 +- src/gui/kernel/qkeymapper_x11.cpp | 2 +- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 8f50f2e..a51ee81 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -3480,9 +3480,9 @@ QLocale::MeasurementSystem QLocale::measurementSystem() const /*! \since 4.7 - Returns true if the language is written right to left. + Returns the text direction of the language. */ -bool QLocale::isWrittenRightToLeft() const +Qt::LayoutDirection QLocale::textDirection() const { Language lang = language(); if (lang == QLocale::Arabic || @@ -3490,9 +3490,9 @@ bool QLocale::isWrittenRightToLeft() const lang == QLocale::Persian || lang == QLocale::Urdu || lang == QLocale::Syriac) - return true; + return Qt::RightToLeft; - return false; + return Qt::LeftToRight; } diff --git a/src/corelib/tools/qlocale.h b/src/corelib/tools/qlocale.h index f8b5c55..8b424bb 100644 --- a/src/corelib/tools/qlocale.h +++ b/src/corelib/tools/qlocale.h @@ -666,7 +666,7 @@ public: MeasurementSystem measurementSystem() const; - bool isWrittenRightToLeft() const; + Qt::LayoutDirection textDirection() const; inline bool operator==(const QLocale &other) const; inline bool operator!=(const QLocale &other) const; diff --git a/src/gui/inputmethod/qximinputcontext_x11.cpp b/src/gui/inputmethod/qximinputcontext_x11.cpp index 88f8daf..ed5aa23 100644 --- a/src/gui/inputmethod/qximinputcontext_x11.cpp +++ b/src/gui/inputmethod/qximinputcontext_x11.cpp @@ -409,7 +409,7 @@ QXIMInputContext::QXIMInputContext() if (dashPos >= 0) variantName.truncate(dashPos); QLocale keyboardInputLocale = q_getKeyboardLocale(layoutNames.at(i), variantName); - if (keyboardInputLocale.isWrittenRightToLeft()) + if (keyboardInputLocale.textDirection() == Qt::RightToLeft) qt_use_rtl_extensions = true; } } diff --git a/src/gui/kernel/qkeymapper_mac.cpp b/src/gui/kernel/qkeymapper_mac.cpp index 885f5ba..873b8f9 100644 --- a/src/gui/kernel/qkeymapper_mac.cpp +++ b/src/gui/kernel/qkeymapper_mac.cpp @@ -672,7 +672,7 @@ QKeyMapperPrivate::updateKeyboard() #endif if (iso639Code) { keyboardInputLocale = QLocale(QCFString::toQString(iso639Code)); - keyboardInputDirection = keyboardInputLocale.isWrittenRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight; + keyboardInputDirection = keyboardInputLocale.textDirection(); } else { keyboardInputLocale = QLocale::c(); keyboardInputDirection = Qt::LeftToRight; diff --git a/src/gui/kernel/qkeymapper_qws.cpp b/src/gui/kernel/qkeymapper_qws.cpp index 0e9f35a..63bb46b 100644 --- a/src/gui/kernel/qkeymapper_qws.cpp +++ b/src/gui/kernel/qkeymapper_qws.cpp @@ -52,7 +52,7 @@ QT_USE_NAMESPACE QKeyMapperPrivate::QKeyMapperPrivate() { keyboardInputLocale = QLocale::system(); - keyboardInputDirection = keyboardInputLocale.isWrittenRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight; + keyboardInputDirection = keyboardInputLocale.textDirection(); } QKeyMapperPrivate::~QKeyMapperPrivate() diff --git a/src/gui/kernel/qkeymapper_x11.cpp b/src/gui/kernel/qkeymapper_x11.cpp index f0d548c..825edbc 100644 --- a/src/gui/kernel/qkeymapper_x11.cpp +++ b/src/gui/kernel/qkeymapper_x11.cpp @@ -517,7 +517,7 @@ void QKeyMapperPrivate::clearMappings() // qWarning("Qt: unable to determine keyboard layout, please talk to qt-bugs@trolltech.com"); ? keyboardInputLocale = q_getKeyboardLocale(layoutName, variantName); - keyboardInputDirection = keyboardInputLocale.isWrittenRightToLeft() ? Qt::RightToLeft : Qt::LeftToRight; + keyboardInputDirection = keyboardInputLocale.textDirection(); #if 0 qDebug() << "keyboard input locale =" -- cgit v0.12 From 39e11b3f49fdc01155575f6d909efd92e435d5a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Mon, 7 Jun 2010 17:23:44 +0200 Subject: Optimized 90-, 180-, and 270- rotated blits in raster paint engine. Blitting a 90-degree rotated RGB16 image now takes 40 % of the time it used to on the N900. Task-number: QT-3057 Reviewed-by: Kim --- src/gui/painting/qpaintengine_raster.cpp | 105 +++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp index 48974e8..08e14fb 100644 --- a/src/gui/painting/qpaintengine_raster.cpp +++ b/src/gui/painting/qpaintengine_raster.cpp @@ -68,6 +68,7 @@ // #include #include #include +#include "qmemrotate_p.h" #include "qpaintengine_raster_p.h" // #include "qbezier_p.h" @@ -2521,6 +2522,58 @@ QRectF qt_mapRect_non_normalizing(const QRectF &r, const QTransform &t) return QRectF(r.topLeft() * t, r.bottomRight() * t); } +namespace { + enum RotationType { + Rotation90, + Rotation180, + Rotation270, + NoRotation + }; + + inline RotationType qRotationType(const QTransform &transform) + { + QTransform::TransformationType type = transform.type(); + + if (type > QTransform::TxRotate) + return NoRotation; + + if (type == QTransform::TxRotate && qFuzzyIsNull(transform.m11()) && qFuzzyCompare(transform.m12(), qreal(-1)) + && qFuzzyCompare(transform.m21(), qreal(1)) && qFuzzyIsNull(transform.m22())) + return Rotation90; + + if (type == QTransform::TxScale && qFuzzyCompare(transform.m11(), qreal(-1)) && qFuzzyIsNull(transform.m12()) + && qFuzzyIsNull(transform.m21()) && qFuzzyCompare(transform.m22(), qreal(-1))) + return Rotation180; + + if (type == QTransform::TxRotate && qFuzzyIsNull(transform.m11()) && qFuzzyCompare(transform.m12(), qreal(1)) + && qFuzzyCompare(transform.m21(), qreal(-1)) && qFuzzyIsNull(transform.m22())) + return Rotation270; + + return NoRotation; + } + + template void memRotate(RotationType type, const T *srcBase, int w, int h, int sbpl, T *dstBase, int dbpl) + { + switch (type) { + case Rotation90: + qt_memrotate90(srcBase, w, h, sbpl, dstBase, dbpl); + break; + case Rotation180: + qt_memrotate180(srcBase, w, h, sbpl, dstBase, dbpl); + break; + case Rotation270: + qt_memrotate270(srcBase, w, h, sbpl, dstBase, dbpl); + break; + case NoRotation: + break; + } + } + + inline bool isPixelAligned(const QRectF &rect) { + return QRectF(rect.toRect()) == rect; + } +} + /*! \reimp */ @@ -2582,6 +2635,58 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe const QClipData *clip = d->clip(); + if (s->matrix.type() > QTransform::TxTranslate + && !stretch_sr + && (!clip || clip->hasRectClip) + && s->intOpacity == 256 + && (d->rasterBuffer->compositionMode == QPainter::CompositionMode_SourceOver + || d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source) + && d->rasterBuffer->format == img.format() + && (d->rasterBuffer->format == QImage::Format_RGB16 + || d->rasterBuffer->format == QImage::Format_RGB32 + || (d->rasterBuffer->format == QImage::Format_ARGB32_Premultiplied + && d->rasterBuffer->compositionMode == QPainter::CompositionMode_Source))) + { + RotationType rotationType = qRotationType(s->matrix); + + if (rotationType != NoRotation && img.rect().contains(sr.toAlignedRect())) { + QRectF transformedTargetRect = s->matrix.mapRect(r); + + if ((!(s->renderHints & QPainter::SmoothPixmapTransform) && !(s->renderHints & QPainter::Antialiasing)) + || (isPixelAligned(transformedTargetRect) && isPixelAligned(sr))) + { + QRect clippedTransformedTargetRect = transformedTargetRect.toRect().intersected(clip ? clip->clipRect : d->deviceRect); + if (clippedTransformedTargetRect.isNull()) + return; + + QRectF clippedTargetRect = s->matrix.inverted().mapRect(QRectF(clippedTransformedTargetRect)); + + QRect clippedSourceRect + = QRectF(sr.x() + clippedTargetRect.x() - r.x(), sr.y() + clippedTargetRect.y() - r.y(), + clippedTargetRect.width(), clippedTargetRect.height()).toRect(); + + uint dbpl = d->rasterBuffer->bytesPerLine(); + uint sbpl = img.bytesPerLine(); + + uchar *dst = d->rasterBuffer->buffer(); + uint bpp = img.depth() >> 3; + + const uchar *srcBase = img.bits() + clippedSourceRect.y() * sbpl + clippedSourceRect.x() * bpp; + uchar *dstBase = dst + clippedTransformedTargetRect.y() * dbpl + clippedTransformedTargetRect.x() * bpp; + + uint cw = clippedSourceRect.width(); + uint ch = clippedSourceRect.height(); + + if (d->rasterBuffer->format == QImage::Format_RGB16) + memRotate(rotationType, (quint16 *)srcBase, cw, ch, sbpl, (quint16 *)dstBase, dbpl); + else + memRotate(rotationType, (quint32 *)srcBase, cw, ch, sbpl, (quint32 *)dstBase, dbpl); + + return; + } + } + } + if (s->matrix.type() > QTransform::TxTranslate || stretch_sr) { if (s->flags.fast_images) { -- cgit v0.12 From 7101ae5a0e90d97acf86a444c4d51ca45e7863fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Nilsen?= Date: Fri, 4 Jun 2010 12:12:01 +0200 Subject: QWidget::childAt for masked child widgets doesn't work properly Problem was that we didn't take the children's effective mask into account when checking whether a point was inside or not. This commit is also an optimization since we no longer check the point against the widget's rect twice. Furthermore, unnecessary QRegion operations are completely avoided in the common case. Auto tests included. Task-number: QTBUG-7150 Reviewed-by: paul --- src/gui/kernel/qwidget.cpp | 75 +++++++++++++++++------------ src/gui/kernel/qwidget_p.h | 9 ++++ tests/auto/qwidget/tst_qwidget.cpp | 97 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 31 deletions(-) diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp index ab84a54..492954a 100644 --- a/src/gui/kernel/qwidget.cpp +++ b/src/gui/kernel/qwidget.cpp @@ -67,6 +67,7 @@ # include "qt_mac_p.h" # include "qt_cocoa_helpers_mac_p.h" # include "qmainwindow.h" +# include "qtoolbar.h" #endif #if defined(Q_WS_QWS) # include "qwsdisplay_qws.h" @@ -9716,46 +9717,58 @@ QWidget *QWidget::childAt(const QPoint &p) const QWidget *QWidgetPrivate::childAt_helper(const QPoint &p, bool ignoreChildrenInDestructor) const { - Q_Q(const QWidget); + if (children.isEmpty()) + return 0; + #ifdef Q_WS_MAC + Q_Q(const QWidget); + // Unified tool bars on the Mac require special handling since they live outside + // QMainWindow's geometry(). See commit: 35667fd45ada49269a5987c235fdedfc43e92bb8 bool includeFrame = q->isWindow() && qobject_cast(q) && static_cast(q)->unifiedTitleAndToolBarOnMac(); + if (includeFrame) + return childAtRecursiveHelper(p, ignoreChildrenInDestructor, includeFrame); #endif - if ( -#ifdef Q_WS_MAC - !includeFrame && -#endif - !q->rect().contains(p)) + if (!pointInsideRectAndMask(p)) return 0; + return childAtRecursiveHelper(p, ignoreChildrenInDestructor); +} - for (int i = children.size(); i > 0 ;) { - --i; - QWidget *w = qobject_cast(children.at(i)); - if (w && !w->isWindow() && !w->isHidden() - && (w->geometry().contains(p) -#ifdef Q_WS_MAC - || (includeFrame && w->geometry().contains(qt_mac_nativeMapFromParent(w, p))) +QWidget *QWidgetPrivate::childAtRecursiveHelper(const QPoint &p, bool ignoreChildrenInDestructor, bool includeFrame) const +{ +#ifndef Q_WS_MAC + Q_UNUSED(includeFrame); #endif - )) { - if (ignoreChildrenInDestructor && w->data->in_destructor) - continue; - if (w->testAttribute(Qt::WA_TransparentForMouseEvents)) - continue; - QPoint childPoint = w->mapFromParent(p); -#ifdef Q_WS_MAC - if (includeFrame && !w->geometry().contains(p)) - childPoint = qt_mac_nativeMapFromParent(w, p); -#endif - if (QWidget *t = w->d_func()->childAt_helper(childPoint, ignoreChildrenInDestructor)) - return t; - // if WMouseNoMask is set the widget mask is ignored, if - // the widget has no mask then the WMouseNoMask flag has no - // effect - if (w->testAttribute(Qt::WA_MouseNoMask) || w->mask().contains(childPoint) - || w->mask().isEmpty()) - return w; + for (int i = children.size() - 1; i >= 0; --i) { + QWidget *child = qobject_cast(children.at(i)); + if (!child || child->isWindow() || child->isHidden() || child->testAttribute(Qt::WA_TransparentForMouseEvents) + || (ignoreChildrenInDestructor && child->data->in_destructor)) { + continue; } + + // Map the point 'p' from parent coordinates to child coordinates. + QPoint childPoint = p; +#ifdef Q_WS_MAC + // 'includeFrame' is true if the child's parent is a top-level QMainWindow with an unified tool bar. + // An unified tool bar on the Mac lives outside QMainWindow's geometry(), so a normal + // QWidget::mapFromParent won't do the trick. + if (includeFrame && qobject_cast(child)) + childPoint = qt_mac_nativeMapFromParent(child, p); + else +#endif + childPoint -= child->data->crect.topLeft(); + + // Check if the point hits the child. + if (!child->d_func()->pointInsideRectAndMask(childPoint)) + continue; + + // Do the same for the child's descendants. + if (QWidget *w = child->d_func()->childAtRecursiveHelper(childPoint, ignoreChildrenInDestructor)) + return w; + + // We have found our target; namely the child at position 'p'. + return child; } return 0; } diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 49a2dc8..4247c3a 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -542,7 +542,9 @@ public: bool setMinimumSize_helper(int &minw, int &minh); bool setMaximumSize_helper(int &maxw, int &maxh); void setConstraints_sys(); + bool pointInsideRectAndMask(const QPoint &) const; QWidget *childAt_helper(const QPoint &, bool) const; + QWidget *childAtRecursiveHelper(const QPoint &p, bool, bool includeFrame = false) const; void updateGeometry_helper(bool forceUpdate); void getLayoutItemMargins(int *left, int *top, int *right, int *bottom) const; @@ -968,6 +970,13 @@ inline void QWidgetPrivate::setSharedPainter(QPainter *painter) x->sharedPainter = painter; } +inline bool QWidgetPrivate::pointInsideRectAndMask(const QPoint &p) const +{ + Q_Q(const QWidget); + return q->rect().contains(p) && (!extra || !extra->hasMask || q->testAttribute(Qt::WA_MouseNoMask) + || extra->mask.contains(p)); +} + inline QWidgetBackingStore *QWidgetPrivate::maybeBackingStore() const { Q_Q(const QWidget); diff --git a/tests/auto/qwidget/tst_qwidget.cpp b/tests/auto/qwidget/tst_qwidget.cpp index a1fc607..d76bbfa 100644 --- a/tests/auto/qwidget/tst_qwidget.cpp +++ b/tests/auto/qwidget/tst_qwidget.cpp @@ -404,6 +404,10 @@ private slots: void taskQTBUG_7532_tabOrderWithFocusProxy(); void movedAndResizedAttributes(); + void childAt(); +#ifdef Q_WS_MAC + void childAt_unifiedToolBar(); +#endif private: bool ensureScreenSize(int width, int height); @@ -10347,5 +10351,98 @@ void tst_QWidget::movedAndResizedAttributes() #endif } +void tst_QWidget::childAt() +{ + QWidget parent(0, Qt::FramelessWindowHint); + parent.resize(200, 200); + + QWidget *child = new QWidget(&parent); + child->setPalette(Qt::red); + child->setAutoFillBackground(true); + child->setGeometry(20, 20, 160, 160); + + QWidget *grandChild = new QWidget(child); + grandChild->setPalette(Qt::blue); + grandChild->setAutoFillBackground(true); + grandChild->setGeometry(-20, -20, 220, 220); + + QVERIFY(!parent.childAt(19, 19)); + QVERIFY(!parent.childAt(180, 180)); + QCOMPARE(parent.childAt(20, 20), grandChild); + QCOMPARE(parent.childAt(179, 179), grandChild); + + grandChild->setAttribute(Qt::WA_TransparentForMouseEvents); + QCOMPARE(parent.childAt(20, 20), child); + QCOMPARE(parent.childAt(179, 179), child); + grandChild->setAttribute(Qt::WA_TransparentForMouseEvents, false); + + child->setMask(QRect(50, 50, 60, 60)); + + QVERIFY(!parent.childAt(69, 69)); + QVERIFY(!parent.childAt(130, 130)); + QCOMPARE(parent.childAt(70, 70), grandChild); + QCOMPARE(parent.childAt(129, 129), grandChild); + + child->setAttribute(Qt::WA_MouseNoMask); + QCOMPARE(parent.childAt(69, 69), grandChild); + QCOMPARE(parent.childAt(130, 130), grandChild); + child->setAttribute(Qt::WA_MouseNoMask, false); + + grandChild->setAttribute(Qt::WA_TransparentForMouseEvents); + QCOMPARE(parent.childAt(70, 70), child); + QCOMPARE(parent.childAt(129, 129), child); + grandChild->setAttribute(Qt::WA_TransparentForMouseEvents, false); + + grandChild->setMask(QRect(80, 80, 40, 40)); + + QCOMPARE(parent.childAt(79, 79), child); + QCOMPARE(parent.childAt(120, 120), child); + QCOMPARE(parent.childAt(80, 80), grandChild); + QCOMPARE(parent.childAt(119, 119), grandChild); + + grandChild->setAttribute(Qt::WA_MouseNoMask); + + QCOMPARE(parent.childAt(79, 79), grandChild); + QCOMPARE(parent.childAt(120, 120), grandChild); +} + +#ifdef Q_WS_MAC +void tst_QWidget::childAt_unifiedToolBar() +{ + QLabel *label = new QLabel(QLatin1String("foo")); + QToolBar *toolBar = new QToolBar; + toolBar->addWidget(new QLabel("dummy")); + toolBar->addWidget(label); + + QMainWindow mainWindow; + mainWindow.addToolBar(toolBar); + mainWindow.show(); + + // Calculate the top-left corner of the tool bar and the label (in mainWindow's coordinates). + QPoint labelTopLeft = label->mapTo(&mainWindow, QPoint()); + QPoint toolBarTopLeft = toolBar->mapTo(&mainWindow, QPoint()); + + QCOMPARE(mainWindow.childAt(toolBarTopLeft), static_cast(toolBar)); + QCOMPARE(mainWindow.childAt(labelTopLeft), static_cast(label)); + + // Enable unified tool bars. + mainWindow.setUnifiedTitleAndToolBarOnMac(true); + QTest::qWait(50); + + // The tool bar is now in the "non-client" area of QMainWindow, i.e. + // outside the mainWindow's rect(), and since mapTo et al. doesn't work + // in that case (see commit 35667fd45ada49269a5987c235fdedfc43e92bb8), + // we use mapToGlobal/mapFromGlobal to re-calculate the corners. + QPoint oldToolBarTopLeft = toolBarTopLeft; + toolBarTopLeft = mainWindow.mapFromGlobal(toolBar->mapToGlobal(QPoint())); + QVERIFY(toolBarTopLeft != oldToolBarTopLeft); + QVERIFY(toolBarTopLeft.y() < 0); + labelTopLeft = mainWindow.mapFromGlobal(label->mapToGlobal(QPoint())); + + QCOMPARE(mainWindow.childAt(toolBarTopLeft), static_cast(toolBar)); + QCOMPARE(mainWindow.childAt(labelTopLeft), static_cast(label)); +} +#endif + QTEST_MAIN(tst_QWidget) #include "tst_qwidget.moc" -- cgit v0.12 From fbb3aca27682bfe81c17866f518eae23b3158aef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Samuel=20R=C3=B8dal?= Date: Fri, 11 Jun 2010 10:29:06 +0200 Subject: Compile fix. The PFNGLXCREATECONTEXTATTRIBSARBPROC typedef isn't defined on all GLX 1.3 systems, so we use our own. Reviewed-by: Trond --- src/opengl/qgl_x11.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index 3e71a48..da072c7 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -672,8 +672,12 @@ bool QGLContext::chooseContext(const QGLContext* shareContext) GLX_CONTEXT_PROFILE_MASK_ARB, profile, 0 }; - PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = - (PFNGLXCREATECONTEXTATTRIBSARBPROC) qglx_getProcAddress("glXCreateContextAttribsARB"); + typedef GLXContext ( * Q_PFNGLXCREATECONTEXTATTRIBSARBPROC) + (Display* dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); + + + Q_PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = + (Q_PFNGLXCREATECONTEXTATTRIBSARBPROC) qglx_getProcAddress("glXCreateContextAttribsARB"); if (glXCreateContextAttribs) { int spec[45]; -- cgit v0.12 From 045732d43f38dadc6019e3ca53e547e4bcb31190 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Fri, 11 Jun 2010 10:52:43 +0200 Subject: Fixed an on-exit application crash for GL apps using EGL. Task-number: QT-3498 Reviewed-by: Samuel --- src/opengl/qgl_egl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 44e8ae9..4a89b26 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -190,7 +190,7 @@ void QGLContext::makeCurrent() if (!d->workaroundsCached) { d->workaroundsCached = true; const char *renderer = reinterpret_cast(glGetString(GL_RENDERER)); - if (strstr(renderer, "SGX") || strstr(renderer, "MBX")) { + if (renderer && (strstr(renderer, "SGX") || strstr(renderer, "MBX"))) { // PowerVR MBX/SGX chips needs to clear all buffers when starting to render // a new frame, otherwise there will be a performance penalty to pay for // each frame. -- cgit v0.12 From 3ff9474b8e3812f629869bc349ffb0a7f70c93a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Fri, 11 Jun 2010 12:25:29 +0200 Subject: Fix another potential strstr() crash for EGL based GL apps. Task-number: releated to QT-3498 Reviewed-by: Samuel --- src/opengl/qgl_egl.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/opengl/qgl_egl.cpp b/src/opengl/qgl_egl.cpp index 4a89b26..0a19531 100644 --- a/src/opengl/qgl_egl.cpp +++ b/src/opengl/qgl_egl.cpp @@ -200,7 +200,8 @@ void QGLContext::makeCurrent() // bug which prevents glCopyTexSubImage2D() to work with a POT // or GL_ALPHA texture bound to an FBO. The only way to // identify that driver is to check the EGL version number for it. - if (strstr(eglQueryString(d->eglContext->display(), EGL_VERSION), "1.3")) + const char *egl_version = eglQueryString(d->eglContext->display(), EGL_VERSION); + if (egl_version && strstr(egl_version, "1.3")) d->workaround_brokenFBOReadBack = true; } } -- cgit v0.12 From 9a16161889c7f6c15c4d5679148a28fe51f95abb Mon Sep 17 00:00:00 2001 From: Olivier Goffart Date: Wed, 9 Jun 2010 10:04:50 +0200 Subject: QMetaType: do not crash when registering builtin stream operator It is not required to register builtin operator, but old code might do so if a type was not builtin before. This is the case of QVariant which became builtin only in Qt 4.7 Task-number: QTBUG-11316 Reviewed-by: Gabriel --- src/corelib/kernel/qmetatype.cpp | 2 ++ tests/auto/qmetatype/tst_qmetatype.cpp | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/src/corelib/kernel/qmetatype.cpp b/src/corelib/kernel/qmetatype.cpp index ce9ed58..6ebaaa3 100644 --- a/src/corelib/kernel/qmetatype.cpp +++ b/src/corelib/kernel/qmetatype.cpp @@ -378,6 +378,8 @@ void QMetaType::registerStreamOperators(const char *typeName, SaveOperator saveO void QMetaType::registerStreamOperators(int idx, SaveOperator saveOp, LoadOperator loadOp) { + if (idx < User) + return; //builtin types should not be registered; QVector *ct = customTypes(); if (!ct) return; diff --git a/tests/auto/qmetatype/tst_qmetatype.cpp b/tests/auto/qmetatype/tst_qmetatype.cpp index f4e122f..8558e06 100644 --- a/tests/auto/qmetatype/tst_qmetatype.cpp +++ b/tests/auto/qmetatype/tst_qmetatype.cpp @@ -77,6 +77,7 @@ private slots: void isRegistered_data(); void isRegistered(); void unregisterType(); + void QTBUG11316_registerStreamBuiltin(); }; @@ -318,5 +319,12 @@ void tst_QMetaType::unregisterType() QCOMPARE(QMetaType::isRegistered(typeId), false); } +void tst_QMetaType::QTBUG11316_registerStreamBuiltin() +{ + //should not crash; + qRegisterMetaTypeStreamOperators("QString"); + qRegisterMetaTypeStreamOperators("QVariant"); +} + QTEST_MAIN(tst_QMetaType) #include "tst_qmetatype.moc" -- cgit v0.12 From cde3f39cb75ba69185cca8176ea7126f8441f042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Trond=20Kjern=C3=A5sen?= Date: Fri, 11 Jun 2010 14:47:21 +0200 Subject: Fixed an on-exit crash for apps using GL. If a QGLWidget is left on the heap when the QApplication destructor is called, it will leave the QGLWidget in a broken state. The widget itself is released and set to a non-created state, which the associated QGLContext doesn't get notified about. With this patch the QGLWidget knows when QWidget::destroy() is called and can act acordingly. Task-number: QT-3498, QTBUG-10995 Reviewed-by: Paul --- src/gui/kernel/qwidget_mac.mm | 9 +++++---- src/gui/kernel/qwidget_p.h | 5 +++++ src/gui/kernel/qwidget_qws.cpp | 2 +- src/gui/kernel/qwidget_s60.cpp | 1 + src/gui/kernel/qwidget_win.cpp | 1 + src/gui/kernel/qwidget_x11.cpp | 1 + src/opengl/qgl.cpp | 2 ++ src/opengl/qgl_p.h | 4 ++++ src/opengl/qgl_x11.cpp | 2 +- 9 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm index 1928599..280712a 100644 --- a/src/gui/kernel/qwidget_mac.mm +++ b/src/gui/kernel/qwidget_mac.mm @@ -2688,6 +2688,7 @@ QWidget::macCGHandle() const void QWidget::destroy(bool destroyWindow, bool destroySubWindows) { Q_D(QWidget); + d->aboutToDestroy(); if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); d->deactivateWidgetCleanup(); @@ -3994,10 +3995,10 @@ static void qt_mac_update_widget_position(QWidget *q, QRect oldRect, QRect newRe (oldRect.isValid() == false || newRect.isValid() == false) || // the position update is a part of a drag-and-drop operation - QDragManager::self()->object || - - // we are on Panther (no HIViewSetNeedsDisplayInRect) - QSysInfo::MacintoshVersion < QSysInfo::MV_10_4 + QDragManager::self()->object || + + // we are on Panther (no HIViewSetNeedsDisplayInRect) + QSysInfo::MacintoshVersion < QSysInfo::MV_10_4 ){ HIViewSetFrame(view, &bounds); return; diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h index 4247c3a..587d7fb 100644 --- a/src/gui/kernel/qwidget_p.h +++ b/src/gui/kernel/qwidget_p.h @@ -551,6 +551,11 @@ public: void setLayoutItemMargins(int left, int top, int right, int bottom); void setLayoutItemMargins(QStyle::SubElement element, const QStyleOption *opt = 0); + // aboutToDestroy() is called just before the contents of + // QWidget::destroy() is executed. It's used to signal QWidget + // sub-classes that their internals are about to be released. + virtual void aboutToDestroy() {} + QInputContext *inputContext() const; inline QWidget *effectiveFocusWidget() { QWidget *w = q_func(); diff --git a/src/gui/kernel/qwidget_qws.cpp b/src/gui/kernel/qwidget_qws.cpp index b827e8b..3145136 100644 --- a/src/gui/kernel/qwidget_qws.cpp +++ b/src/gui/kernel/qwidget_qws.cpp @@ -256,7 +256,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool /*destro void QWidget::destroy(bool destroyWindow, bool destroySubWindows) { Q_D(QWidget); - + d->aboutToDestroy(); if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp index 86b858d..68f9470 100644 --- a/src/gui/kernel/qwidget_s60.cpp +++ b/src/gui/kernel/qwidget_s60.cpp @@ -1177,6 +1177,7 @@ void QWidget::setWindowState(Qt::WindowStates newstate) void QWidget::destroy(bool destroyWindow, bool destroySubWindows) { Q_D(QWidget); + d->aboutToDestroy(); if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(geometry()); d->deactivateWidgetCleanup(); diff --git a/src/gui/kernel/qwidget_win.cpp b/src/gui/kernel/qwidget_win.cpp index a7e66bf..9c65aa0 100644 --- a/src/gui/kernel/qwidget_win.cpp +++ b/src/gui/kernel/qwidget_win.cpp @@ -544,6 +544,7 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO void QWidget::destroy(bool destroyWindow, bool destroySubWindows) { Q_D(QWidget); + d->aboutToDestroy(); if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); d->deactivateWidgetCleanup(); diff --git a/src/gui/kernel/qwidget_x11.cpp b/src/gui/kernel/qwidget_x11.cpp index 43f510c..e01489f 100644 --- a/src/gui/kernel/qwidget_x11.cpp +++ b/src/gui/kernel/qwidget_x11.cpp @@ -1023,6 +1023,7 @@ bool QWidgetPrivate::isBackgroundInherited() const void QWidget::destroy(bool destroyWindow, bool destroySubWindows) { Q_D(QWidget); + d->aboutToDestroy(); if (!isWindow() && parentWidget()) parentWidget()->d_func()->invalidateBuffer(d->effectiveRectFor(geometry())); d->deactivateWidgetCleanup(); diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp index 5c5d3d1..b4c85ac 100644 --- a/src/opengl/qgl.cpp +++ b/src/opengl/qgl.cpp @@ -3674,8 +3674,10 @@ QGLWidget::~QGLWidget() bool doRelease = (glcx && glcx->windowCreated()); #endif delete d->glcx; + d->glcx = 0; #if defined(Q_WGL) delete d->olcx; + d->olcx = 0; #endif #if defined(GLX_MESA_release_buffers) && defined(QGL_USE_MESA_EXT) if (doRelease) diff --git a/src/opengl/qgl_p.h b/src/opengl/qgl_p.h index 16c225f..1727a41 100644 --- a/src/opengl/qgl_p.h +++ b/src/opengl/qgl_p.h @@ -177,6 +177,10 @@ public: void initContext(QGLContext *context, const QGLWidget* shareWidget); bool renderCxPm(QPixmap *pixmap); void cleanupColormaps(); + void aboutToDestroy() { + if (glcx) + glcx->reset(); + } QGLContext *glcx; QGLWidgetGLPaintDevice glDevice; diff --git a/src/opengl/qgl_x11.cpp b/src/opengl/qgl_x11.cpp index da072c7..bfb232d 100644 --- a/src/opengl/qgl_x11.cpp +++ b/src/opengl/qgl_x11.cpp @@ -928,7 +928,7 @@ void QGLContext::makeCurrent() } else if (d->paintDevice->devType() == QInternal::Pbuffer) { ok = glXMakeCurrent(xinfo->display(), (GLXPbuffer)d->pbuf, (GLXContext)d->cx); } else if (d->paintDevice->devType() == QInternal::Widget) { - ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)->winId(), (GLXContext)d->cx); + ok = glXMakeCurrent(xinfo->display(), ((QWidget *)d->paintDevice)->internalWinId(), (GLXContext)d->cx); } if (!ok) qWarning("QGLContext::makeCurrent(): Failed."); -- cgit v0.12 From 5a90ecfd34f8959e73cc711337529ce8bada7aa2 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Sun, 13 Jun 2010 23:21:06 +0200 Subject: Updated WebKit to f943ead2759537527faa7f3cb057d995291663b9 Integrated changes: || || QWebPage::findText() does not clear selection when passed empty string || || || [Qt] tests/hybridPixmap fails || || || [Qt] Imperfect dependency for generated SVGNames.cpp || || || [Qt] Typo error in QWebPluginFactory Documentation || || || REGRESSION: [Qt] When dragging onto a page that handles the drag in Javascript it will be a move and not a copy by default || || || [Qt] Add documentation to the QtWebkit bridge || || || [Qt] TextBreakIteratorQt performance || || || [Qt] GraphicsLayer: recaching images creates an unnecessary deep copy || || || SQLStatementErrorCallback's return value needs to be converted to a boolean || || || [QT] QT_BEARER flag is not enabled on S60 properly || --- src/3rdparty/webkit/.tag | 2 +- src/3rdparty/webkit/VERSION | 2 +- src/3rdparty/webkit/WebCore/ChangeLog | 106 +++++++++++ src/3rdparty/webkit/WebCore/WebCore.pri | 16 +- .../js/JSCustomSQLStatementErrorCallback.cpp | 2 +- .../webkit/WebCore/bridge/qt/qt_pixmapruntime.cpp | 11 +- .../webkit/WebCore/bridge/qt/qt_pixmapruntime.h | 3 +- .../webkit/WebCore/bridge/qt/qt_runtime.cpp | 2 +- .../platform/graphics/qt/GraphicsLayerQt.cpp | 1 + .../platform/text/qt/TextBreakIteratorQt.cpp | 64 ++++--- src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp | 20 +- .../webkit/WebKit/qt/Api/qwebpluginfactory.cpp | 4 +- src/3rdparty/webkit/WebKit/qt/ChangeLog | 50 +++++ .../webkit/WebKit/qt/docs/qtwebkit-bridge.qdoc | 100 +++++----- .../webkitsnippets/qtwebkit_bridge_snippets.cpp | 204 +++++++++++++++------ .../WebKit/qt/tests/qwebpage/tst_qwebpage.cpp | 17 ++ 16 files changed, 450 insertions(+), 154 deletions(-) diff --git a/src/3rdparty/webkit/.tag b/src/3rdparty/webkit/.tag index 09a4fe2..125e175 100644 --- a/src/3rdparty/webkit/.tag +++ b/src/3rdparty/webkit/.tag @@ -1 +1 @@ -f943ead2759537527faa7f3cb057d995291663b9 +0f8941d0dd5f947530e1dc55b859d810bba14764 diff --git a/src/3rdparty/webkit/VERSION b/src/3rdparty/webkit/VERSION index a19b85a..6aaae4f 100644 --- a/src/3rdparty/webkit/VERSION +++ b/src/3rdparty/webkit/VERSION @@ -4,4 +4,4 @@ This is a snapshot of the Qt port of WebKit from and has the sha1 checksum - 6db5de6d18c3ab8b74809303e4d79abacfc570a8 + f943ead2759537527faa7f3cb057d995291663b9 diff --git a/src/3rdparty/webkit/WebCore/ChangeLog b/src/3rdparty/webkit/WebCore/ChangeLog index 1d9d739..e04729d 100644 --- a/src/3rdparty/webkit/WebCore/ChangeLog +++ b/src/3rdparty/webkit/WebCore/ChangeLog @@ -1,3 +1,109 @@ +2010-06-13 Noam Rosenthal + + Reviewed by Eric Seidel. + + [Qt] GraphicsLayer: recaching images creates an unnecessary deep copy + https://bugs.webkit.org/show_bug.cgi?id=40535 + + Made sure the painter ends its operation before copying the pixmap. + + No new tests: this is an optimization. + + * platform/graphics/qt/GraphicsLayerQt.cpp: + (WebCore::GraphicsLayerQtImpl::recache): + +2010-03-24 Dumitru Daniliuc + + Reviewed by Dimitri Glazkov. + + Changing the V8 and JSC implementations of + SQLStatementErrorCallback to interpret as false all results that + could be converted to a false boolean. Pretty much a revert of + r54981. + + https://bugs.webkit.org/show_bug.cgi?id=36569 + + * bindings/js/JSCustomSQLStatementErrorCallback.cpp: + (WebCore::JSCustomSQLStatementErrorCallback::handleEvent): + * bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp: + (WebCore::V8CustomSQLStatementErrorCallback::handleEvent): + * bindings/v8/custom/V8CustomVoidCallback.cpp: + (WebCore::invokeCallback): + * bindings/v8/custom/V8CustomVoidCallback.h: + +2010-06-13 Noam Rosenthal + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] tests/hybridPixmap fails + https://bugs.webkit.org/show_bug.cgi?id=37316 + + The problem was that JSC::Instance::createRuntimeObject was never called. + This is fixed by overloading newRuntimeObject and calling Instance::createRuntimeObject + in between, instead of creating the runtime object directly inside the static function + QtPixmapInstance::createRuntimeObject, which had to be renamed as to not overshadow the virtual function. + + This fixes an existing test, tests/hybridPixmap + + * bridge/qt/qt_pixmapruntime.cpp: + (JSC::Bindings::QtPixmapInstance::newRuntimeObject): + (JSC::Bindings::QtPixmapInstance::createPixmapRuntimeObject): + * bridge/qt/qt_pixmapruntime.h: + * bridge/qt/qt_runtime.cpp: + (JSC::Bindings::convertQVariantToValue): + +2010-06-07 Mahesh Kulakrni + + Reviewed by Simon Hausmann. + + [QT] QT_BEARER flag is not enabled on S60 properly + https://bugs.webkit.org/show_bug.cgi?id=39357 + + enable QT_BEARER for all platform based on qtmobility + + bearer module availability or for qt 4.7+ + + * WebCore.pri: + +2010-06-09 Csaba Osztrogonác + + Reviewed by Dirk Schulze. + + [Qt] Imperfect dependency for generated SVGNames.cpp + https://bugs.webkit.org/show_bug.cgi?id=40359 + + * WebCore.pri: Missing dependency added. + +2010-06-08 Kenneth Rohde Christiansen + + Unreviewed Buildbot fix. + + Reset the Qt TextBreakIterator when reusing it. + + * platform/text/qt/TextBreakIteratorQt.cpp: + (WebCore::setUpIterator): + +2010-06-08 Kenneth Rohde Christiansen + + Reviewed by Antti Koivisto. + + [Qt] TextBreakIterator Qt performance + https://bugs.webkit.org/show_bug.cgi?id=39958 + + Rework TextBreakIteratorQt to be more in line with the ICU version. + + We now reuse iterators where ever possible. The string data is compared + with memcmp, which should be faster than using a hash, as you need + to traverse the full buffer in the case the strings don't match, + where as the compare would fail quickly. + + * platform/text/qt/TextBreakIteratorQt.cpp: + (WebCore::TextBreakIterator::TextBreakIterator): + (WebCore::setUpIterator): + (WebCore::wordBreakIterator): + (WebCore::characterBreakIterator): + (WebCore::lineBreakIterator): + (WebCore::sentenceBreakIterator): + 2010-06-07 Jocelyn Turcotte Reviewed by Simon Hausmann. diff --git a/src/3rdparty/webkit/WebCore/WebCore.pri b/src/3rdparty/webkit/WebCore/WebCore.pri index 5f5987f..9debd6a 100644 --- a/src/3rdparty/webkit/WebCore/WebCore.pri +++ b/src/3rdparty/webkit/WebCore/WebCore.pri @@ -101,18 +101,19 @@ greaterThan(QT_MINOR_VERSION, 5) { DEFINES += ENABLE_XSLT=0 } -!CONFIG(QTDIR_build):!contains(DEFINES, ENABLE_QT_BEARER=.) { - symbian: { - exists($${EPOCROOT}epoc32/release/winscw/udeb/QtBearer.lib)| \ - exists($${EPOCROOT}epoc32/release/armv5/lib/QtBearer.lib) { +# Bearer management is part of Qt 4.7 +# for older version, check for mobility with bearer +!contains(DEFINES, ENABLE_QT_BEARER=.) { + !lessThan(QT_MINOR_VERSION, 7) { + DEFINES += ENABLE_QT_BEARER=1 + } else { + load(mobilityconfig) + contains(MOBILITY_CONFIG, bearer) { DEFINES += ENABLE_QT_BEARER=1 } } } -# Bearer management is part of Qt 4.7 -!lessThan(QT_MINOR_VERSION, 7):!contains(DEFINES, ENABLE_QT_BEARER=.):DEFINES += ENABLE_QT_BEARER=1 - # Enable touch event support with Qt 4.6 !lessThan(QT_MINOR_VERSION, 6): DEFINES += ENABLE_TOUCH_EVENTS=1 @@ -593,6 +594,7 @@ contains(DEFINES, ENABLE_SVG=1) { # GENERATOR 5-C: svgnames.output = $${WC_GENERATED_SOURCES_DIR}/SVGNames.cpp svgnames.input = SVG_NAMES + svgnames.depends = $$PWD/svg/svgattrs.in svgnames.wkScript = $$PWD/dom/make_names.pl svgnames.commands = perl -I$$PWD/bindings/scripts $$svgnames.wkScript --tags $$PWD/svg/svgtags.in --attrs $$PWD/svg/svgattrs.in --extraDefines \"$${DEFINES}\" --preprocessor \"$${QMAKE_MOC} -E\" --factory --wrapperFactory --outputDir $$WC_GENERATED_SOURCES_DIR svgnames.wkExtraSources = $${WC_GENERATED_SOURCES_DIR}/SVGElementFactory.cpp $${WC_GENERATED_SOURCES_DIR}/JSSVGElementWrapperFactory.cpp diff --git a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp index 4d5de79..6178509 100644 --- a/src/3rdparty/webkit/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp +++ b/src/3rdparty/webkit/WebCore/bindings/js/JSCustomSQLStatementErrorCallback.cpp @@ -77,7 +77,7 @@ bool JSCustomSQLStatementErrorCallback::handleEvent(SQLTransaction* transaction, // Therefore an exception and returning true are the same thing - so, return true on an exception return true; } - return !result.isFalse(); + return result.toBoolean(exec); } } diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.cpp index 803316d..3e6197f 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.cpp @@ -346,10 +346,17 @@ returnEmptyVariant: return QVariant::fromValue(QImage()); return QVariant(); } -JSObject* QtPixmapInstance::createRuntimeObject(ExecState* exec, PassRefPtr root, const QVariant& data) + +RuntimeObject* QtPixmapInstance::newRuntimeObject(ExecState* exec) +{ + return new(exec) QtPixmapRuntimeObject(exec, this); +} + +JSObject* QtPixmapInstance::createPixmapRuntimeObject(ExecState* exec, PassRefPtr root, const QVariant& data) { JSLock lock(SilenceAssertionsOnly); - return new(exec) QtPixmapRuntimeObject(exec, new QtPixmapInstance(root, data)); + QtPixmapInstance* instance = new QtPixmapInstance(root, data); + return instance->createRuntimeObject(exec); } bool QtPixmapInstance::canHandle(QMetaType::Type hint) diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.h b/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.h index a0e0e26..de1bcee 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.h +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_pixmapruntime.h @@ -42,7 +42,8 @@ public: int height() const; QPixmap toPixmap(); QImage toImage(); - static JSObject* createRuntimeObject(ExecState*, PassRefPtr, const QVariant&); + RuntimeObject* newRuntimeObject(ExecState* exec); + static JSObject* createPixmapRuntimeObject(ExecState*, PassRefPtr, const QVariant&); static QVariant variantFromObject(JSObject*, QMetaType::Type hint); static bool canHandle(QMetaType::Type hint); }; diff --git a/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp b/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp index 4524d97..a39dc7a 100644 --- a/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp +++ b/src/3rdparty/webkit/WebCore/bridge/qt/qt_runtime.cpp @@ -877,7 +877,7 @@ JSValue convertQVariantToValue(ExecState* exec, PassRefPtr root, con } if (QtPixmapInstance::canHandle(static_cast(variant.type()))) - return QtPixmapInstance::createRuntimeObject(exec, root, variant); + return QtPixmapInstance::createPixmapRuntimeObject(exec, root, variant); if (type == qMetaTypeId()) { if (!root->globalObject()->inherits(&JSDOMWindow::s_info)) diff --git a/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp b/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp index be44fca..ad2ec9c 100644 --- a/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/graphics/qt/GraphicsLayerQt.cpp @@ -330,6 +330,7 @@ QPixmap GraphicsLayerQtImpl::recache(const QRegion& regionToUpdate) // Render the actual contents into the cache painter.setCompositionMode(QPainter::CompositionMode_SourceOver); m_layer->paintGraphicsLayerContents(gc, region.boundingRect()); + painter.end(); m_backingStoreKey = QPixmapCache::insert(pixmap); return pixmap; diff --git a/src/3rdparty/webkit/WebCore/platform/text/qt/TextBreakIteratorQt.cpp b/src/3rdparty/webkit/WebCore/platform/text/qt/TextBreakIteratorQt.cpp index 5a8a812..dda443f 100644 --- a/src/3rdparty/webkit/WebCore/platform/text/qt/TextBreakIteratorQt.cpp +++ b/src/3rdparty/webkit/WebCore/platform/text/qt/TextBreakIteratorQt.cpp @@ -33,31 +33,49 @@ namespace WebCore { + static unsigned char buffer[1024]; + class TextBreakIterator : public QTextBoundaryFinder { + public: + TextBreakIterator(QTextBoundaryFinder::BoundaryType type, const UChar* string, int length) + : QTextBoundaryFinder(type, (const QChar*)string, length, buffer, sizeof(buffer)) + , length(length) + , string(string) {} + TextBreakIterator() + : QTextBoundaryFinder() + , length(0) + , string(0) {} + + int length; + const UChar* string; }; - static QTextBoundaryFinder* iterator = 0; - static unsigned char buffer[1024]; - TextBreakIterator* wordBreakIterator(const UChar* string, int length) + TextBreakIterator* setUpIterator(TextBreakIterator& iterator, QTextBoundaryFinder::BoundaryType type, const UChar* string, int length) { if (!string || !length) return 0; - if (!iterator) - iterator = new QTextBoundaryFinder; - *iterator = QTextBoundaryFinder(QTextBoundaryFinder::Word, (const QChar *)string, length, buffer, sizeof(buffer)); - return static_cast(iterator); + if (iterator.isValid() && type == iterator.type() && length == iterator.length + && memcmp(string, iterator.string, length) == 0) { + iterator.toStart(); + return &iterator; + } + + iterator = TextBreakIterator(type, string, length); + + return &iterator; } - TextBreakIterator* characterBreakIterator(const UChar* string, int length) + TextBreakIterator* wordBreakIterator(const UChar* string, int length) { - if (!string || !length) - return 0; - if (!iterator) - iterator = new QTextBoundaryFinder; + static TextBreakIterator staticWordBreakIterator; + return setUpIterator(staticWordBreakIterator, QTextBoundaryFinder::Word, string, length); + } - *iterator = QTextBoundaryFinder(QTextBoundaryFinder::Grapheme, (const QChar *)string, length, buffer, sizeof(buffer)); - return static_cast(iterator); + TextBreakIterator* characterBreakIterator(const UChar* string, int length) + { + static TextBreakIterator staticCharacterBreakIterator; + return setUpIterator(staticCharacterBreakIterator, QTextBoundaryFinder::Grapheme, string, length); } TextBreakIterator* cursorMovementIterator(const UChar* string, int length) @@ -67,25 +85,15 @@ namespace WebCore { TextBreakIterator* lineBreakIterator(const UChar* string, int length) { - static QTextBoundaryFinder *iterator = 0; - if (!string || !length) - return 0; - if (!iterator) - iterator = new QTextBoundaryFinder; - - *iterator = QTextBoundaryFinder(QTextBoundaryFinder::Line, (const QChar *)string, length, buffer, sizeof(buffer)); - return static_cast(iterator); + static TextBreakIterator staticLineBreakIterator; + return setUpIterator(staticLineBreakIterator, QTextBoundaryFinder::Line, string, length); } TextBreakIterator* sentenceBreakIterator(const UChar* string, int length) { - if (!string || !length) - return 0; - if (!iterator) - iterator = new QTextBoundaryFinder; + static TextBreakIterator staticSentenceBreakIterator; + return setUpIterator(staticSentenceBreakIterator, QTextBoundaryFinder::Sentence, string, length); - *iterator = QTextBoundaryFinder(QTextBoundaryFinder::Sentence, (const QChar *)string, length, buffer, sizeof(buffer)); - return static_cast(iterator); } int textBreakFirst(TextBreakIterator* bi) diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp index 2788085..8c7b93d 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpage.cpp @@ -1175,7 +1175,7 @@ void QWebPagePrivate::dragEnterEvent(QGraphicsSceneDragDropEvent* ev) Qt::DropAction action = dragOpToDropAction(page->dragController()->dragEntered(&dragData)); ev->setDropAction(action); if (action != Qt::IgnoreAction) - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1188,7 +1188,7 @@ void QWebPagePrivate::dragEnterEvent(QDragEnterEvent* ev) ev->setDropAction(action); // We must accept this event in order to receive the drag move events that are sent // while the drag and drop action is in progress. - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1218,7 +1218,7 @@ void QWebPagePrivate::dragMoveEvent(QGraphicsSceneDragDropEvent* ev) Qt::DropAction action = dragOpToDropAction(page->dragController()->dragUpdated(&dragData)); ev->setDropAction(action); if (action != Qt::IgnoreAction) - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1232,7 +1232,7 @@ void QWebPagePrivate::dragMoveEvent(QDragMoveEvent* ev) ev->setDropAction(action); // We must accept this event in order to receive the drag move events that are sent // while the drag and drop action is in progress. - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1242,7 +1242,7 @@ void QWebPagePrivate::dropEvent(QGraphicsSceneDragDropEvent* ev) DragData dragData(ev->mimeData(), ev->pos().toPoint(), QCursor::pos(), dropActionToDragOp(ev->possibleActions())); if (page->dragController()->performDrag(&dragData)) - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -1254,7 +1254,7 @@ void QWebPagePrivate::dropEvent(QDropEvent* ev) DragData dragData(ev->mimeData(), ev->pos(), QCursor::pos(), dropActionToDragOp(Qt::DropAction(ev->dropAction()))); if (page->dragController()->performDrag(&dragData)) - ev->accept(); + ev->acceptProposedAction(); #endif } @@ -3267,6 +3267,14 @@ bool QWebPage::findText(const QString &subString, FindFlags options) } else return d->page->markAllMatchesForText(subString, caseSensitivity, true, 0); } else { + if (subString.isEmpty()) { + d->page->mainFrame()->selection()->clear(); + Frame* frame = d->page->mainFrame()->tree()->firstChild(); + while (frame) { + frame->selection()->clear(); + frame = frame->tree()->traverseNextWithWrap(false); + } + } ::FindDirection direction = ::FindDirectionForward; if (options & FindBackward) direction = ::FindDirectionBackward; diff --git a/src/3rdparty/webkit/WebKit/qt/Api/qwebpluginfactory.cpp b/src/3rdparty/webkit/WebKit/qt/Api/qwebpluginfactory.cpp index f715430..b9180be 100644 --- a/src/3rdparty/webkit/WebKit/qt/Api/qwebpluginfactory.cpp +++ b/src/3rdparty/webkit/WebKit/qt/Api/qwebpluginfactory.cpp @@ -63,7 +63,7 @@ /*! \class QWebPluginFactory::Plugin \since 4.4 - \brief the QWebPluginFactory::Plugin structure describes the properties of a plugin a QWebPluginFactory can create. + \brief The QWebPluginFactory::Plugin structure describes the properties of a plugin a QWebPluginFactory can create. \inmodule QtWebKit */ @@ -147,7 +147,7 @@ QWebPluginFactory::~QWebPluginFactory() supported plugins the factory can create. \note Currently, this function is only called when JavaScript programs - access the global \c plugins or \c mimetypes objects. + access the global \c plugins or \c mimetypes objects. */ /*! diff --git a/src/3rdparty/webkit/WebKit/qt/ChangeLog b/src/3rdparty/webkit/WebKit/qt/ChangeLog index 3deb9ac..671acec 100644 --- a/src/3rdparty/webkit/WebKit/qt/ChangeLog +++ b/src/3rdparty/webkit/WebKit/qt/ChangeLog @@ -1,3 +1,53 @@ +2010-06-09 Pierre Rossi + + Reviewed by Kenneth Rohde Christiansen. + + QWebPage::findText() does not clear selection when passed empty string + https://bugs.webkit.org/show_bug.cgi?id=31779 + + * Api/qwebpage.cpp: + (QWebPage::findText): + * tests/qwebpage/tst_qwebpage.cpp: + (tst_QWebPage::findText): + +2010-06-12 No'am Rosenthal + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Add documentation to the QtWebkit bridge + https://bugs.webkit.org/show_bug.cgi?id=35861 + + The previous accepted patch was actually a faulty one; It was hard to trace since it's just a documentation + change. The new patch amends that, with the correct snippets and grammar fixes. + + * docs/qtwebkit-bridge.qdoc: + * docs/webkitsnippets/qtwebkit_bridge_snippets.cpp: + (wrapInFunction): + +2010-06-11 Jesus Sanchez-Palencia + + Reviewed by Kenneth Rohde Christiansen. + + [Qt] Typo error in QWebPluginFactory Documentation + https://bugs.webkit.org/show_bug.cgi?id=40490 + + * Api/qwebpluginfactory.cpp: + +2010-06-10 Andy Shaw + + Reviewed by Simon Hausmann. + + REGRESSION: [Qt] When dragging onto a page that handles the drag in Javascript it will be a move and not a copy by default + https://bugs.webkit.org/show_bug.cgi?id=40401 + + The correct pattern in Qt for Dnd events is to use acceptProposedAction() instead + of accept(). + + * Api/qwebpage.cpp: + (QWebPagePrivate::dragEnterEvent): + (QWebPagePrivate::dragMoveEvent): + (QWebPagePrivate::dropEvent): + 2010-06-02 Tasuku Suzuki Reviewed by Shinichiro Hamaji. diff --git a/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit-bridge.qdoc b/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit-bridge.qdoc index 4f41d29..fa93293 100644 --- a/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit-bridge.qdoc +++ b/src/3rdparty/webkit/WebKit/qt/docs/qtwebkit-bridge.qdoc @@ -7,25 +7,26 @@ \section2 The technology The QtWebKit bridge is a mechanism that extends WebKit's JavaScript environment to access native - objects that are represented as QObjects. It takes advantage of the inherent introspection of the - \l{Qt Object Model}, which has a natural alignment to the way JavaScript worked. + objects that are represented as \l{QObject}s. It takes advantage of the \l{QObject} introspection, + a part of the \l{Qt Object Model}, which makes it easy to integrate with the dynamic JavaScript environment, + for example \l{QObject} properties map directly to JavaScript properties. For example, both JavaScript and QObjects have properties: a construct that represent a getter/setter pair under one name. \section2 Use Cases - There are two main use cases for the QtWebKit bridge. Web content in a native application, and Thin Client. + There are two main use cases for the QtWebKit bridge. Web content in a native application, and Thin Clients. \section3 Web Content in a Native Application This is a common use case in classic Qt application, and a design pattern used by several modern - applications. For example, an application that contains both a media-player, playlist manager, and - a music store. The playlist manager is usually best authored as a classic desktop application, + applications. For example, an application that contains a media-player, playlist manager, and music store. + The playlist manager is usually best authored as a classic desktop application, with the native-looking robust \l{QWidget}s helping with producing that application. The media-player control, which usually looks custom, can be written using \l{The Graphics View framework} or with in a declarative way with \l{QtDeclarative}. The music store, which shows dynamic content - from the internet, and gets modified rapidly, is best authored in HTML and maintained on the server. + from the internet and gets modified rapidly, is best authored in HTML and maintained on the server. With the QtWebKit bridge, that music store component can interact with native parts of the application, for example, if a file needs to be saved to a specific location. @@ -38,7 +39,7 @@ access to native features not usually exposed to the web, or to enable helper components that are best written with C++. - An example for such client is a UI for a video-on-demand service on a TV. The entire content and + An example for such a client is a UI for a video-on-demand service on a TV. The entire content and UI can be kept on the server, served dynamically through HTTP and rendered with WebKit, with additional native components for accessing hardware-specific features like extracting the list of images out of the video. @@ -67,7 +68,7 @@ \section2 Creating the link via QWebFrame By default, no QObjects are accessible through the web environment, for security reasons. - To enable web content access to a native QObject, the application has to explicitly grant it access, + To enable web content access for a native QObject, the application must explicitly grant it access, using the following call: \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 0 @@ -76,13 +77,13 @@ \section2 Using Signals and Slots - Qt Script adapts Qt's central \l{Signals and Slots} feature for + The QtWebKit bridge adapts Qt's central \l{Signals and Slots} feature for scripting. There are three principal ways to use signals and slots - with Qt Script: + with the QtWebKit bridge: \list \i \bold{Hybrid C++/script}: C++ application code connects a - signal to a script function. The script function can, for example, be + signal to a script function. For example, the script function can be a function that the user has typed in, or one that you have read from a file. This approach is useful if you have a QObject but don't want to expose the object itself to the scripting environment; you just @@ -97,7 +98,7 @@ the connections is fully dynamic (script-defined). \i \bold{Purely script-defined}: A script can both define signal - handler functions (effectively "slots written in Qt Script"), + handler functions (effectively "slots written in JavaScript"), \e{and} set up the connections that utilize those handlers. For example, a script can define a function that will handle the QLineEdit::returnPressed() signal, and then connect that signal to the @@ -108,36 +109,36 @@ \section3 Signal to Function Connections - \c{connect(function)} + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 6 In this form of connection, the argument to \c{connect()} is the function to connect to the signal. - \snippet webkitsnippets/doc_src_qtscript.qdoc 2 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 7 - The argument can be a Qt Script function, as in the above + The argument can be a JavaScript function, as in the above example, or it can be a QObject slot, as in the following example: - \snippet webkitsnippets/doc_src_qtscript.qdoc 3 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 8 When the argument is a QObject slot, the argument types of the signal and slot do not necessarily have to be compatible; - the QtWebKit bridge will, if necessary, perform conversion of the signal + If necessary, the QtWebKit bridge will, perform conversion of the signal arguments to match the argument types of the slot. To disconnect from a signal, you invoke the signal's \c{disconnect()} function, passing the function to disconnect as argument: - \snippet webkitsnippets/doc_src_qtscript.qdoc 4 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 9 When a script function is invoked in response to a signal, the \c this object will be the Global Object. \section3 Signal to Member Function Connections - \c{connect(thisObject, function)} + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 10 In this form of the \c{connect()} function, the first argument is the object that will be bound to the variable, \c this, when @@ -148,31 +149,31 @@ \c{clicked} signal; passing the form as the \c this object makes sense in such a case. - \snippet webkitsnippets/doc_src_qtscript.qdoc 5 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 11 To disconnect from the signal, pass the same arguments to \c{disconnect()}: - \snippet webkitsnippets/doc_src_qtscript.qdoc 6 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 12 \section3 Signal to Named Member Function Connections - \c{connect(thisObject, functionName)} + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 14 - In this form of the \c{connect()} function, the first argument is - the object that will be bound to the variable, \c this, when - a function is invoked in response to the signal. The second argument - specifies the name of a function that is connected to the signal, - and this refers to a member function of the object passed as the - first argument (\c thisObject in the above scheme). + This form of the \c{connect()} function requires that the first argument is + the object that will be bound to the variable \c{this} when a function is + invoked in response to the signal. The second argument specifies the + name of a function that is connected to the signal, and this refers to a + member function of the object passed as the first argument (thisObject + in the above scheme). Note that the function is resolved when the connection is made, not when the signal is emitted. - \snippet webkitsnippets/doc_src_qtscript.qdoc 7 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 15 To disconnect from the signal, pass the same arguments to \c{disconnect()}: - \snippet webkitsnippets/doc_src_qtscript.qdoc 8 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 17 \section3 Error Handling @@ -181,14 +182,14 @@ You can obtain an error message from the resulting \c{Error} object. Example: - \snippet webkitsnippets/doc_src_qtscript.qdoc 9 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 18 \section3 Emitting Signals from Scripts To emit a signal from script code, you simply invoke the signal function, passing the relevant arguments: - \snippet webkitsnippets/doc_src_qtscript.qdoc 10 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 19 It is currently not possible to define a new signal in a script; i.e., all signals must be defined by C++ classes. @@ -201,13 +202,13 @@ \c{myOverloadedSlot(int)} and \c{myOverloadedSlot(QString)}, the following script code will behave reasonably: - \snippet webkitsnippets/doc_src_qtscript.qdoc 11 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 20 You can specify a particular overload by using array-style property access with the \l{QMetaObject::normalizedSignature()}{normalized signature} of the C++ function as the property name: - \snippet webkitsnippets/doc_src_qtscript.qdoc 12 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 21 If the overloads have different number of arguments, the QtWebKit bridge will pick the overload with the argument count that best matches the @@ -225,7 +226,7 @@ (it would be meaningless to return values from a slot, as the connected signals don't handle the returned data). To make a non-slot method invokable, simply add the Q_INVOKABLE macro before its definition: - \snippet webkitsnippets/doc_src_qtscript.qdoc 20 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 22 \section2 Accessing Properties @@ -235,11 +236,11 @@ property will automatically be invoked. For example, if your C++ class has a property declared as follows: - \snippet webkitsnippets/doc_src_qtscript.qdoc 13 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 23 then script code can do things like the following: - \snippet webkitsnippets/doc_src_qtscript.qdoc 14 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 24 \section2 Accessing Child QObjects @@ -250,12 +251,12 @@ \c{"okButton"}, you can access this object in script code through the expression - \snippet webkitsnippets/doc_src_qtscript.qdoc 15 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 25 Since \c{objectName} is itself a Q_PROPERTY, you can manipulate the name in script code to, for example, rename an object: - \snippet webkitsnippets/doc_src_qtscript.qdoc 16 + \snippet webkitsnippets/qtwebkit_bridge_snippets.cpp 26 \section2 Data types @@ -283,7 +284,7 @@ \section3 Strings When JavaScript accesses methods or properties that expect a \l{QString}, the QtWebKit bridge - will automatically convert the value to a string (if it's not already a string), using the + will automatically convert the value to a string (if it is not already a string), using the built-in JavaScript toString method. When a QString is passed to JavaScript from a signal or a property, The QtWebKit bridge will @@ -292,7 +293,7 @@ \section3 Date & Time Both \l{QDate}, \l{QTime} and \l{QDateTime} are automatically translated to or from the JavaScript - Date object. If a number is passed as an argument to a method that expects one of the date/time + Date object. If a number were passed as an argument to a method that expects one of the date/time types, the QtWebKit bridge would treat it as a timestamp. If a sting is passed, QtWebKit would try different Qt date parsing functions to find the right one. @@ -314,7 +315,7 @@ \section3 Compound (JSON) objects - JavaScript compound objects, also known as JSON objects, are variables which hold a list + JavaScript compound objects, also known as JSON objects, are variables that hold a list of key-value pairs, where all the keys are strings and the values can have any type. This translates very well to \l{QVariantMap}, which is nothing more than a \l{QMap} of \l{QString} to \l{QVariant}. @@ -334,7 +335,7 @@ a normal JSON object would become a \l{QVariantMap}, and a JavaScript array would become a \l{QVariantList}. Using \l{QVariant}s generously in C++ in that way makes C++ programming feel a bit more like JavaScript programming, - as it adds another level of indirection - passing \l{QVariant}s around is very flexible, as the program can figure out + as it adds another level of indirection. Passing \l{QVariant}s around like this q is very flexible, as the program can figure out the type of argument in runtime just like JavaScript would do, but it also takes away from the type-safety and robust nature of C++. It's recommended to use \l{QVariant}s only for convenience high-level functions, and to keep most of your \l{QObject}s somewhat type-safe. @@ -348,7 +349,7 @@ a \l{QObject}. In general its advised to use care when passing \l{QObject}s as arguments, as those objects don't become owned by - the Javascipt engine; That means that the application developer has to be extra careful not to try to access + the JavaScript engine; That means that the application developer has to be extra careful not to try to access \l{QObject}s that have already been deleted by the native environment. \section3 Pixmaps and Images @@ -401,25 +402,26 @@ \section2 Limiting the Scope of the Hybrid Layer - When using QtWebKit's hybrid features, it's a common pitfall to make the API exposed to JavaScript very rich and + When using QtWebKit's hybrid features, it is a common pitfall to make the API exposed to JavaScript very rich and use all its features. This, however, leads to complexity and can create bugs that are hard to trace. - Instead, it's advisable to keep the hybrid layer small and manageable: create a gate only when + Instead, it is advisable to keep the hybrid layer small and manageable: create a gate only when there's an actual need for it, i.e. there's a new native enabler that requires a direct interface to the application layer. Sometimes new functionality is better handled internally in the native layer or in the web layer; simplicity is your friend. This usually becomes more apparent when the hybrid layer can create or destroy objects, or uses - signals slots or properties with a \l{QObject}* argument. It's advised to be very careful and to treat + signals slots or properties with a \l{QObject}* argument. It is advised to be very careful and to treat an exposed \l{QObject} as a system - with careful attention to memory management and object ownership. \section2 Internet Security - When exposing native object to an open web environment, it's important to understand the security + When exposing native object to an open web environment, it is importwhichant to understand the security implications. Think whether the exposed object enables the web environment access to things that shouldn't be open, and whether the web content loaded by that web page comes from a trusted. In general, when exposing native QObjects that give the web environment access to private information or to functionality that's potentially harmful to the client, such exposure should be balanced by limiting the web page's - access to trusted URLs only with HTTPS and other security measures. + access to trusted URLs only with HTTPS, and by utilizing other measures as part of a security strategy. + */ diff --git a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/qtwebkit_bridge_snippets.cpp b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/qtwebkit_bridge_snippets.cpp index d83ab3f..62eeeca 100644 --- a/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/qtwebkit_bridge_snippets.cpp +++ b/src/3rdparty/webkit/WebKit/qt/docs/webkitsnippets/qtwebkit_bridge_snippets.cpp @@ -2,82 +2,176 @@ void wrapInFunction() { -//! [0] + //! [0] // ... QWebFrame *frame = myWebPage->mainFrame(); frame->addToJavaScriptWindowObject("someNameForMyObject", myObject); // ... -//! [0] + //! [0] #if 0 //! [1] - { - width: ..., - height: ..., - toDataURL: function() { ... }, - assignToHTMLImageElement: function(element) { ... } - } - //! [1] + { + width: ..., + height: ..., + toDataURL: function() { ... }, + assignToHTMLImageElement: function(element) { ... } + } + //! [1] #endif //! [2] - class MyObject : QObject { - Q_OBJECT - Q_PROPERTY(QPixmap myPixmap READ getPixmap) + class MyObject : QObject { + Q_OBJECT + Q_PROPERTY(QPixmap myPixmap READ getPixmap) - public: - QPixmap getPixmap() const; - }; + public: + QPixmap getPixmap() const; + }; - /* ... */ + /* ... */ - MyObject myObject; - myWebPage.mainFrame()->addToJavaScriptWindowObject("myObject", &myObject); + MyObject myObject; + myWebPage.mainFrame()->addToJavaScriptWindowObject("myObject", &myObject); //! [2] - #if 0 - //! [3] - - - - - - - - +#if 0 //! [3] - #endif - //! [4] - class MyObject : QObject { - Q_OBJECT + + + + + + + + + //! [3] +#endif + //! [4] + class MyObject : QObject { + Q_OBJECT - public slots: - void doSomethingWithWebElement(const QWebElement&); - }; + public slots: + void doSomethingWithWebElement(const QWebElement&); + }; - /* ... */ + /* ... */ - MyObject myObject; - myWebPage.mainFrame()->addToJavaScriptWindowObject("myObject", &myObject); + MyObject myObject; + myWebPage.mainFrame()->addToJavaScriptWindowObject("myObject", &myObject); - //! [4] - #if 0 - //! [5] - + //! [4] +#if 0 + //! [5] + - + - Text + Text - - //! [5] - #endif + + //! [5] + //! [6] + connect(function); + //! [6] + //! [7] + function myInterestingScriptFunction() { ... } + ... + myQObject.somethingChanged.connect(myInterestingScriptFunction); + //! [7] + //! [8] + myQObject.somethingChanged.connect(myOtherQObject.doSomething); + //! [8] + //! [9] + myQObject.somethingChanged.disconnect(myInterestingFunction); + myQObject.somethingChanged.disconnect(myOtherQObject.doSomething); + //! [9] + //! [10] + connect(thisObject, function) + //! [10] + //! [11] + var obj = { x: 123 }; + var fun = function() { print(this.x); }; + myQObject.somethingChanged.connect(obj, fun); + //! [11] + //! [12] + myQObject.somethingChanged.disconnect(obj, fun); + //! [12] + //! [13] + connect(function); + //! [13] + //! [14] + connect(thisObject, functionName) + //! [14] + //! [15] + var obj = { x: 123, fun: function() { print(this.x); } }; + myQObject.somethingChanged.connect(obj, "fun"); + //! [15] + //! [16] + connect(function); + //! [16] + //! [17] + myQObject.somethingChanged.disconnect(obj, "fun"); + //! [17] + //! [18] + try { + myQObject.somethingChanged.connect(myQObject, "slotThatDoesntExist"); + } catch (e) { + print(e); + } + //! [18] + //! [19] + myQObject.somethingChanged("hello"); + //! [19] + //! [20] + myQObject.myOverloadedSlot(10); // will call the int overload + myQObject.myOverloadedSlot("10"); // will call the QString overload + //! [20] + //! [21] + myQObject['myOverloadedSlot(int)']("10"); // call int overload; the argument is converted to an int + myQObject['myOverloadedSlot(QString)'](10); // call QString overload; the argument is converted to a string + //! [21] + //! [22] + class MyObject : public QObject + { + Q_OBJECT + + public: + Q_INVOKABLE void thisMethodIsInvokableInQtScript(); + void thisMethodIsNotInvokableInQtScript(); + + ... + }; + //! [22] + //! [23] + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled) + //! [23] + //! [24] + myQObject.enabled = true; + + ... + + myQObject.enabled = !myQObject.enabled; + //! [24] + //! [25] + myQObject.enabled = true; + + ... + + myQObject.enabled = !myQObject.enabled; + //! [25] + //! [26] + myDialog.okButton + myDialog.okButton.objectName = "cancelButton"; + // from now on, myDialog.cancelButton references the button + //! [26] +#endif } diff --git a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp index 27f4b27..0f2ca22 100644 --- a/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp +++ b/src/3rdparty/webkit/WebKit/qt/tests/qwebpage/tst_qwebpage.cpp @@ -122,6 +122,7 @@ private slots: void testJSPrompt(); void showModalDialog(); void testStopScheduledPageRefresh(); + void findText(); private: QWebView* m_view; @@ -2121,5 +2122,21 @@ void tst_QWebPage::testStopScheduledPageRefresh() QCOMPARE(page2.mainFrame()->url().toString(), QString("about:blank")); } +void tst_QWebPage::findText() +{ + m_view->setHtml(QString("
foo bar
")); + m_page->triggerAction(QWebPage::SelectAll); + QVERIFY(!m_page->selectedText().isEmpty()); + m_page->findText(""); + QVERIFY(m_page->selectedText().isEmpty()); + QStringList words = (QStringList() << "foo" << "bar"); + foreach (QString subString, words) { + m_page->findText(subString, QWebPage::FindWrapsAroundDocument); + QCOMPARE(m_page->selectedText(), subString); + m_page->findText(""); + QVERIFY(m_page->selectedText().isEmpty()); + } +} + QTEST_MAIN(tst_QWebPage) #include "tst_qwebpage.moc" -- cgit v0.12 From a75945a402eb2bee7bfa633f3cced735601ad727 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 14 Jun 2010 13:44:43 +0300 Subject: Added prependEpocroot replacement function to platform_paths.prf This function can be used to do smart prepending of epocroot to paths defined by platform_paths.prf, though it'll work for any string. This is useful because paths defined in platform_paths.prf can start either with full epocroot or just slash depending on environment. E.g. exists($$prependEpocroot($$MW_LAYER_PUBLIC_EXPORT_PATH(foobar.h))) { ... } Reviewed-by: Janne Koskinen --- mkspecs/features/symbian/platform_paths.prf | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/mkspecs/features/symbian/platform_paths.prf b/mkspecs/features/symbian/platform_paths.prf index 0e8770d..5c190c8 100644 --- a/mkspecs/features/symbian/platform_paths.prf +++ b/mkspecs/features/symbian/platform_paths.prf @@ -45,8 +45,17 @@ # INCLUDEPATH += $$OS_LAYER_DBUS_SYSTEMINCLUDE # INCLUDEPATH += $$OS_LAYER_LIBUTILITY_SYSTEMINCLUDE # +# These paths are primarily meant to be used as is in bld.inf and .mmp +# files, so they do not contain epocroot when using official symbian +# toolchains (symbian-abld or symbian-sbsv2). +# For makefile based mkspecs, epocroot is prepended to all paths for +# convenience. # -# +# To use paths defined here in other contexts that require epocroot to be +# prepended always, such as exists checks, please use prependEpocroot +# replacement function: +# +# exists($$prependEpocroot($$MW_LAYER_PUBLIC_EXPORT_PATH(foobar.h))) # # ============================================================================== @@ -472,4 +481,13 @@ exists($${EPOCROOT}epoc32/include/platform_paths.prf) { STLLIB_USAGE_CW_FLAGS = "-wchar_t on" STLLIB_USAGE_DEFINES = _WCHAR_T_DECLARED + # Smart prepend of EPOCROOT to a string + defineReplace(prependEpocroot) { + contains(1, ^$${EPOCROOT}) { + return($$1) + } else { + return($${EPOCROOT}$$replace(1,"^/",)) + } + } + } -- cgit v0.12