summaryrefslogtreecommitdiffstats
path: root/src/gui
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui')
-rw-r--r--src/gui/accessible/qaccessible.cpp4
-rw-r--r--src/gui/dialogs/qfiledialog_mac.mm2
-rw-r--r--src/gui/egl/egl.pri52
-rw-r--r--src/gui/egl/qegl_p.h34
-rw-r--r--src/gui/egl/qegl_stub.cpp284
-rw-r--r--src/gui/egl/qeglproperties_stub.cpp148
-rw-r--r--src/gui/graphicsview/qgraphicsitem.cpp37
-rw-r--r--src/gui/graphicsview/qgraphicsitem_p.h10
-rw-r--r--src/gui/graphicsview/qgraphicsproxywidget.cpp13
-rw-r--r--src/gui/graphicsview/qgraphicsscene.cpp50
-rw-r--r--src/gui/graphicsview/qgraphicsscene_p.h6
-rw-r--r--src/gui/graphicsview/qgraphicsview.cpp110
-rw-r--r--src/gui/graphicsview/qgraphicsview_p.h19
-rw-r--r--src/gui/graphicsview/qgraphicswidget.cpp10
-rw-r--r--src/gui/gui.pro3
-rw-r--r--src/gui/image/qicon.cpp21
-rw-r--r--src/gui/image/qicon.h2
-rw-r--r--src/gui/image/qiconengine.cpp20
-rw-r--r--src/gui/image/qiconengine.h5
-rw-r--r--src/gui/image/qiconloader.cpp6
-rw-r--r--src/gui/image/qimagereader.cpp14
-rw-r--r--src/gui/image/qimagewriter.cpp16
-rw-r--r--src/gui/inputmethod/qcoefepinputcontext_s60.cpp2
-rw-r--r--src/gui/inputmethod/qinputcontextfactory.cpp6
-rw-r--r--src/gui/itemviews/qtableview.cpp8
-rw-r--r--src/gui/kernel/qapplication_s60.cpp20
-rw-r--r--src/gui/kernel/qapplication_win.cpp25
-rw-r--r--src/gui/kernel/qcocoamenuloader_mac.mm7
-rw-r--r--src/gui/kernel/qcocoasharedwindowmethods_mac_p.h65
-rw-r--r--src/gui/kernel/qcocoaview_mac.mm3
-rw-r--r--src/gui/kernel/qguiplatformplugin.cpp2
-rw-r--r--src/gui/kernel/qkeymapper_mac.cpp13
-rw-r--r--src/gui/kernel/qkeysequence.cpp3
-rw-r--r--src/gui/kernel/qpalette.cpp2
-rw-r--r--src/gui/kernel/qsoftkeymanager_s60.cpp2
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac.mm131
-rw-r--r--src/gui/kernel/qt_cocoa_helpers_mac_p.h5
-rw-r--r--src/gui/kernel/qt_mac_p.h1
-rw-r--r--src/gui/kernel/qt_s60_p.h3
-rw-r--r--src/gui/kernel/qwidget.cpp29
-rw-r--r--src/gui/kernel/qwidget_mac.mm6
-rw-r--r--src/gui/kernel/qwidget_p.h7
-rw-r--r--src/gui/kernel/qwidget_s60.cpp91
-rw-r--r--src/gui/painting/qbezier.cpp305
-rw-r--r--src/gui/painting/qbezier_p.h9
-rw-r--r--src/gui/painting/qdrawhelper.cpp21
-rw-r--r--src/gui/painting/qgraphicssystemfactory.cpp6
-rw-r--r--src/gui/painting/qpaintengine_mac.cpp8
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp2
-rw-r--r--src/gui/painting/qpaintengineex.cpp3
-rw-r--r--src/gui/painting/qpainterpath.cpp11
-rw-r--r--src/gui/painting/qpathclipper.cpp803
-rw-r--r--src/gui/painting/qpathclipper_p.h30
-rw-r--r--src/gui/painting/qprintengine_ps.cpp25
-rw-r--r--src/gui/painting/qprintengine_win.cpp7
-rw-r--r--src/gui/painting/qwindowsurface_p.h8
-rw-r--r--src/gui/s60framework/qs60mainappui.cpp12
-rw-r--r--src/gui/styles/qcommonstyle.cpp2
-rw-r--r--src/gui/styles/qmacstyle_mac.mm16
-rw-r--r--src/gui/styles/qs60style.cpp114
-rw-r--r--src/gui/styles/qs60style_s60.cpp8
-rw-r--r--src/gui/styles/qstylefactory.cpp2
-rw-r--r--src/gui/styles/qstylesheetstyle.cpp9
-rw-r--r--src/gui/styles/qstylesheetstyle_p.h1
-rw-r--r--src/gui/text/qfont.cpp5
-rw-r--r--src/gui/text/qfontdatabase.cpp14
-rw-r--r--src/gui/text/qfontdatabase_s60.cpp85
-rw-r--r--src/gui/text/qfontengine_mac.mm15
-rw-r--r--src/gui/text/qfontengine_s60.cpp55
-rw-r--r--src/gui/text/qfontengine_s60_p.h12
-rw-r--r--src/gui/text/qtextcontrol.cpp4
-rw-r--r--src/gui/text/qtextdocument.cpp9
-rw-r--r--src/gui/text/qtextodfwriter.cpp12
-rw-r--r--src/gui/widgets/qabstractscrollarea.cpp1
-rw-r--r--src/gui/widgets/qcombobox_p.h2
-rw-r--r--src/gui/widgets/qlinecontrol.cpp2
-rw-r--r--src/gui/widgets/qlineedit.cpp10
-rw-r--r--src/gui/widgets/qmenu.cpp6
-rw-r--r--src/gui/widgets/qmenu_mac.mm24
-rw-r--r--src/gui/widgets/qmenu_symbian.cpp8
-rw-r--r--src/gui/widgets/qtabbar.cpp73
-rw-r--r--src/gui/widgets/qtabbar_p.h2
-rw-r--r--src/gui/widgets/qtabwidget.cpp2
83 files changed, 1828 insertions, 1212 deletions
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index a55a061..0921bdb 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -389,7 +389,7 @@ QT_BEGIN_NAMESPACE
\internal
*/
-#if !defined(QT_NO_LIBRARY) && (!defined(QT_NO_SETTINGS) || !defined(Q_OS_WIN))
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QAccessibleFactoryInterface_iid, QLatin1String("/accessible")))
#endif
@@ -532,7 +532,7 @@ QAccessibleInterface *QAccessible::queryAccessibleInterface(QObject *object)
if (iface)
return iface;
}
-#if !defined(QT_NO_LIBRARY) && (!defined(QT_NO_SETTINGS) || !defined(Q_OS_WIN))
+#ifndef QT_NO_LIBRARY
QAccessibleFactoryInterface *factory = qobject_cast<QAccessibleFactoryInterface*>(loader()->instance(cn));
if (factory) {
iface = factory->create(cn, object);
diff --git a/src/gui/dialogs/qfiledialog_mac.mm b/src/gui/dialogs/qfiledialog_mac.mm
index 14a5f15..28acf24 100644
--- a/src/gui/dialogs/qfiledialog_mac.mm
+++ b/src/gui/dialogs/qfiledialog_mac.mm
@@ -493,7 +493,7 @@ QT_USE_NAMESPACE
for (int i=0; i<mNameFilterDropDownList->size(); ++i) {
QString filter = hideDetails ? [self removeExtensions:filters->at(i)] : filters->at(i);
[mPopUpButton addItemWithTitle:QT_PREPEND_NAMESPACE(qt_mac_QStringToNSString)(filter)];
- if (filters->at(i) == selectedFilter)
+ if (filters->at(i).startsWith(selectedFilter))
[mPopUpButton selectItemAtIndex:i];
}
}
diff --git a/src/gui/egl/egl.pri b/src/gui/egl/egl.pri
index 47032d5..595d135 100644
--- a/src/gui/egl/egl.pri
+++ b/src/gui/egl/egl.pri
@@ -1,28 +1,34 @@
-CONFIG += egl
+contains(QT_CONFIG, egl): {
+ CONFIG += egl
-HEADERS += \
- egl/qegl_p.h \
- egl/qeglcontext_p.h \
- egl/qeglproperties_p.h
+ HEADERS += \
+ egl/qegl_p.h \
+ egl/qeglcontext_p.h \
+ egl/qeglproperties_p.h
-SOURCES += \
- egl/qegl.cpp \
- egl/qeglproperties.cpp
+ SOURCES += \
+ egl/qegl.cpp \
+ egl/qeglproperties.cpp
-wince*: SOURCES += egl/qegl_wince.cpp
+ wince*: SOURCES += egl/qegl_wince.cpp
-unix {
- embedded {
- SOURCES += egl/qegl_qws.cpp
- } else {
- embedded_lite {
- SOURCES += egl/qegl_lite.cpp
- } else {
- symbian {
- SOURCES += egl/qegl_symbian.cpp
- } else {
- SOURCES += egl/qegl_x11.cpp
- }
- }
- }
+ unix {
+ embedded {
+ SOURCES += egl/qegl_qws.cpp
+ } else {
+ embedded_lite {
+ SOURCES += egl/qegl_lite.cpp
+ } else {
+ symbian {
+ SOURCES += egl/qegl_symbian.cpp
+ } else {
+ SOURCES += egl/qegl_x11.cpp
+ }
+ }
+ }
+ }
+} else:symbian {
+ DEFINES += QT_NO_EGL
+ SOURCES += egl/qegl_stub.cpp
+ SOURCES += egl/qeglproperties_stub.cpp
}
diff --git a/src/gui/egl/qegl_p.h b/src/gui/egl/qegl_p.h
index 83bdb5e..4fc1338 100644
--- a/src/gui/egl/qegl_p.h
+++ b/src/gui/egl/qegl_p.h
@@ -55,6 +55,7 @@
QT_BEGIN_INCLUDE_NAMESPACE
+#ifndef QT_NO_EGL
#if defined(QT_OPENGL_ES_2)
# include <GLES2/gl2.h>
#endif
@@ -64,6 +65,23 @@ QT_BEGIN_INCLUDE_NAMESPACE
#else
# include <EGL/egl.h>
#endif
+#else
+
+//types from egltypes.h for compiling stub without EGL headers
+typedef int EGLBoolean;
+typedef int EGLint;
+typedef int EGLenum;
+typedef int NativeDisplayType;
+typedef void* NativeWindowType;
+typedef void* NativePixmapType;
+typedef int EGLDisplay;
+typedef int EGLConfig;
+typedef int EGLSurface;
+typedef int EGLContext;
+typedef int EGLClientBuffer;
+#define EGL_NONE 0x3038 /* Attrib list terminator */
+
+#endif
#if defined(Q_WS_X11)
// If <EGL/egl.h> included <X11/Xlib.h>, then the global namespace
@@ -136,7 +154,13 @@ QT_BEGIN_NAMESPACE
// Declare/define the bits of EGL_KHR_image_base we need:
#if !defined(EGL_KHR_image) && !defined(EGL_KHR_image_base)
+#ifdef Q_OS_SYMBIAN
+//symbian version of eglext.h differs from the khronos reference
+typedef int EGLImageKHR;
+#else
typedef void *EGLImageKHR;
+#endif
+
#define EGL_NO_IMAGE_KHR ((EGLImageKHR)0)
#define EGL_IMAGE_PRESERVED_KHR 0x30D2
#define EGL_KHR_image_base
@@ -169,7 +193,7 @@ namespace QEgl {
Translucent = 0x01,
Renderable = 0x02 // Config will be compatable with the paint engines (VG or GL)
};
- Q_DECLARE_FLAGS(ConfigOptions, ConfigOption);
+ Q_DECLARE_FLAGS(ConfigOptions, ConfigOption)
// Most of the time we use the same config for things like widgets & pixmaps, so rather than
// go through the eglChooseConfig loop every time, we use defaultConfig, which will return
@@ -182,7 +206,11 @@ namespace QEgl {
Q_GUI_EXPORT void dumpAllConfigs();
+#ifdef QT_NO_EGL
+ Q_GUI_EXPORT QString errorString(EGLint code = 0);
+#else
Q_GUI_EXPORT QString errorString(EGLint code = eglGetError());
+#endif
Q_GUI_EXPORT QString extensions();
Q_GUI_EXPORT bool hasExtension(const char* extensionName);
@@ -200,9 +228,9 @@ namespace QEgl {
#ifdef Q_WS_X11
Q_GUI_EXPORT VisualID getCompatibleVisualId(EGLConfig config);
#endif
-};
+}
-Q_DECLARE_OPERATORS_FOR_FLAGS(QEgl::ConfigOptions);
+Q_DECLARE_OPERATORS_FOR_FLAGS(QEgl::ConfigOptions)
QT_END_NAMESPACE
diff --git a/src/gui/egl/qegl_stub.cpp b/src/gui/egl/qegl_stub.cpp
new file mode 100644
index 0000000..86a7aab
--- /dev/null
+++ b/src/gui/egl/qegl_stub.cpp
@@ -0,0 +1,284 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/qpaintdevice.h>
+#include <QtGui/qpixmap.h>
+#include <QtGui/qwidget.h>
+#include <QtCore/qdebug.h>
+
+#include "qegl_p.h"
+#include "qeglcontext_p.h"
+
+
+QT_BEGIN_NAMESPACE
+
+static void noegl(const char *fn)
+{
+ qWarning() << fn << " called, but Qt configured without EGL" << endl;
+}
+
+#define NOEGL noegl(__FUNCTION__);
+
+QEglContext::QEglContext()
+ : apiType(QEgl::OpenGL)
+ , ctx(0)
+ , cfg(QEGL_NO_CONFIG)
+ , currentSurface(0)
+ , current(false)
+ , ownsContext(true)
+ , sharing(false)
+{
+ NOEGL
+}
+
+QEglContext::~QEglContext()
+{
+ NOEGL
+}
+
+bool QEglContext::isValid() const
+{
+ NOEGL
+ return false;
+}
+
+bool QEglContext::isCurrent() const
+{
+ NOEGL
+ return false;
+}
+
+EGLConfig QEgl::defaultConfig(int devType, API api, ConfigOptions options)
+{
+ Q_UNUSED(devType)
+ Q_UNUSED(api)
+ Q_UNUSED(options)
+ NOEGL
+ return QEGL_NO_CONFIG;
+}
+
+
+// Choose a configuration that matches "properties".
+EGLConfig QEgl::chooseConfig(const QEglProperties* properties, QEgl::PixelFormatMatch match)
+{
+ Q_UNUSED(properties)
+ Q_UNUSED(match)
+ NOEGL
+ return QEGL_NO_CONFIG;
+}
+
+bool QEglContext::chooseConfig(const QEglProperties& properties, QEgl::PixelFormatMatch match)
+{
+ Q_UNUSED(properties)
+ Q_UNUSED(match)
+ NOEGL
+ return false;
+}
+
+EGLSurface QEglContext::createSurface(QPaintDevice* device, const QEglProperties *properties)
+{
+ Q_UNUSED(device)
+ Q_UNUSED(properties)
+ NOEGL
+ return 0;
+}
+
+
+// Create the EGLContext.
+bool QEglContext::createContext(QEglContext *shareContext, const QEglProperties *properties)
+{
+ Q_UNUSED(shareContext)
+ Q_UNUSED(properties)
+ NOEGL
+ return false;
+}
+
+// Destroy an EGL surface object. If it was current on this context
+// then call doneCurrent() for it first.
+void QEglContext::destroySurface(EGLSurface surface)
+{
+ Q_UNUSED(surface)
+ NOEGL
+}
+
+// Destroy the context. Note: this does not destroy the surface.
+void QEglContext::destroyContext()
+{
+ NOEGL
+}
+
+bool QEglContext::makeCurrent(EGLSurface surface)
+{
+ Q_UNUSED(surface)
+ NOEGL
+ return false;
+}
+
+bool QEglContext::doneCurrent()
+{
+ NOEGL
+ return false;
+}
+
+// Act as though doneCurrent() was called, but keep the context
+// and the surface active for the moment. This allows makeCurrent()
+// to skip a call to eglMakeCurrent() if we are using the same
+// surface as the last set of painting operations. We leave the
+// currentContext() pointer as-is for now.
+bool QEglContext::lazyDoneCurrent()
+{
+ NOEGL
+ return false;
+}
+
+bool QEglContext::swapBuffers(EGLSurface surface)
+{
+ Q_UNUSED(surface)
+ NOEGL
+ return false;
+}
+
+int QEglContext::configAttrib(int name) const
+{
+ Q_UNUSED(name)
+ NOEGL
+ return 0;
+}
+
+EGLDisplay QEgl::display()
+{
+ NOEGL
+ return 0;
+}
+
+EGLImageKHR QEgl::eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attrib_list)
+{
+ Q_UNUSED(dpy)
+ Q_UNUSED(ctx)
+ Q_UNUSED(target)
+ Q_UNUSED(buffer)
+ Q_UNUSED(attrib_list)
+ NOEGL
+ return 0;
+}
+
+EGLBoolean QEgl::eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR img)
+{
+ Q_UNUSED(dpy)
+ Q_UNUSED(img)
+ NOEGL
+ return 0;
+}
+
+
+#ifndef Q_WS_X11
+EGLSurface QEgl::createSurface(QPaintDevice *device, EGLConfig cfg, const QEglProperties *properties)
+{
+ Q_UNUSED(device)
+ Q_UNUSED(cfg)
+ Q_UNUSED(properties)
+ NOEGL
+ return 0;
+}
+#endif
+
+
+// Return the error string associated with a specific code.
+QString QEgl::errorString(EGLint code)
+{
+ Q_UNUSED(code)
+ NOEGL
+ return QString();
+}
+
+// Dump all of the EGL configurations supported by the system.
+void QEgl::dumpAllConfigs()
+{
+ NOEGL
+}
+
+QString QEgl::extensions()
+{
+ NOEGL
+ return QString();
+}
+
+bool QEgl::hasExtension(const char* extensionName)
+{
+ Q_UNUSED(extensionName)
+ NOEGL
+ return false;
+}
+
+QEglContext *QEglContext::currentContext(QEgl::API api)
+{
+ Q_UNUSED(api)
+ NOEGL
+ return false;
+}
+
+void QEglContext::setCurrentContext(QEgl::API api, QEglContext *context)
+{
+ Q_UNUSED(api)
+ Q_UNUSED(context)
+ NOEGL
+}
+
+EGLNativeDisplayType QEgl::nativeDisplay()
+{
+ NOEGL
+ return 0;
+}
+
+EGLNativeWindowType QEgl::nativeWindow(QWidget* widget)
+{
+ Q_UNUSED(widget)
+ NOEGL
+ return (EGLNativeWindowType)0;
+}
+
+EGLNativePixmapType QEgl::nativePixmap(QPixmap*)
+{
+ NOEGL
+ return (EGLNativePixmapType)0;
+}
+
+QT_END_NAMESPACE
diff --git a/src/gui/egl/qeglproperties_stub.cpp b/src/gui/egl/qeglproperties_stub.cpp
new file mode 100644
index 0000000..2012ebd
--- /dev/null
+++ b/src/gui/egl/qeglproperties_stub.cpp
@@ -0,0 +1,148 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the QtGui module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/qdebug.h>
+#include <QtCore/qstringlist.h>
+
+#include "qeglproperties_p.h"
+#include "qeglcontext_p.h"
+
+QT_BEGIN_NAMESPACE
+
+static void noegl(const char *fn)
+{
+ qWarning() << fn << " called, but Qt configured without EGL" << endl;
+}
+
+#define NOEGL noegl(__FUNCTION__);
+
+// Initialize a property block.
+QEglProperties::QEglProperties()
+{
+ NOEGL
+}
+
+QEglProperties::QEglProperties(EGLConfig cfg)
+{
+ Q_UNUSED(cfg)
+ NOEGL
+}
+
+// Fetch the current value associated with a property.
+int QEglProperties::value(int name) const
+{
+ Q_UNUSED(name)
+ NOEGL
+ return 0;
+}
+
+// Set the value associated with a property, replacing an existing
+// value if there is one.
+void QEglProperties::setValue(int name, int value)
+{
+ Q_UNUSED(name)
+ Q_UNUSED(value)
+ NOEGL
+}
+
+// Remove a property value. Returns false if the property is not present.
+bool QEglProperties::removeValue(int name)
+{
+ Q_UNUSED(name)
+ NOEGL
+ return false;
+}
+
+void QEglProperties::setDeviceType(int devType)
+{
+ Q_UNUSED(devType)
+ NOEGL
+}
+
+
+// Sets the red, green, blue, and alpha sizes based on a pixel format.
+// Normally used to match a configuration request to the screen format.
+void QEglProperties::setPixelFormat(QImage::Format pixelFormat)
+{
+ Q_UNUSED(pixelFormat)
+ NOEGL
+
+}
+
+void QEglProperties::setRenderableType(QEgl::API api)
+{
+ Q_UNUSED(api);
+ NOEGL
+}
+
+// Reduce the complexity of a configuration request to ask for less
+// because the previous request did not result in success. Returns
+// true if the complexity was reduced, or false if no further
+// reductions in complexity are possible.
+bool QEglProperties::reduceConfiguration()
+{
+ NOEGL
+ return false;
+}
+
+static void addTag(QString& str, const QString& tag)
+{
+ Q_UNUSED(str)
+ Q_UNUSED(tag)
+ NOEGL
+}
+
+// Convert a property list to a string suitable for debug output.
+QString QEglProperties::toString() const
+{
+ NOEGL
+ return QString();
+}
+
+void QEglProperties::setPaintDeviceFormat(QPaintDevice *dev)
+{
+ Q_UNUSED(dev)
+ NOEGL
+}
+
+QT_END_NAMESPACE
+
+
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp
index 9759b39..326f130 100644
--- a/src/gui/graphicsview/qgraphicsitem.cpp
+++ b/src/gui/graphicsview/qgraphicsitem.cpp
@@ -1237,6 +1237,8 @@ void QGraphicsItemPrivate::setParentItemHelper(QGraphicsItem *newParent, const Q
}
dirtySceneTransform = 1;
+ if (!inDestructor && (transformData || (newParent && newParent->d_ptr->transformData)))
+ transformChanged();
// Restore the sub focus chain.
if (subFocusItem) {
@@ -3622,6 +3624,7 @@ void QGraphicsItemPrivate::setTransformHelper(const QTransform &transform)
q_ptr->prepareGeometryChange();
transformData->transform = transform;
dirtySceneTransform = 1;
+ transformChanged();
}
/*!
@@ -3812,6 +3815,8 @@ void QGraphicsItem::setRotation(qreal angle)
if (d_ptr->isObject)
emit static_cast<QGraphicsObject *>(this)->rotationChanged();
+
+ d_ptr->transformChanged();
}
/*!
@@ -3876,6 +3881,8 @@ void QGraphicsItem::setScale(qreal factor)
if (d_ptr->isObject)
emit static_cast<QGraphicsObject *>(this)->scaleChanged();
+
+ d_ptr->transformChanged();
}
@@ -3931,6 +3938,7 @@ void QGraphicsItem::setTransformations(const QList<QGraphicsTransform *> &transf
transformations.at(i)->d_func()->setItem(this);
d_ptr->transformData->onlyTransform = false;
d_ptr->dirtySceneTransform = 1;
+ d_ptr->transformChanged();
}
/*!
@@ -3947,6 +3955,7 @@ void QGraphicsItemPrivate::prependGraphicsTransform(QGraphicsTransform *t)
t->d_func()->setItem(q);
transformData->onlyTransform = false;
dirtySceneTransform = 1;
+ transformChanged();
}
/*!
@@ -3963,6 +3972,7 @@ void QGraphicsItemPrivate::appendGraphicsTransform(QGraphicsTransform *t)
t->d_func()->setItem(q);
transformData->onlyTransform = false;
dirtySceneTransform = 1;
+ transformChanged();
}
/*!
@@ -7315,6 +7325,18 @@ void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints)
{
Q_D(QGraphicsItem);
d->imHints = hints;
+ if (!hasFocus())
+ return;
+ d->scene->d_func()->updateInputMethodSensitivityInViews();
+#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN))
+ QWidget *fw = QApplication::focusWidget();
+ if (!fw)
+ return;
+ for (int i = 0 ; i < scene()->views().count() ; ++i)
+ if (scene()->views().at(i) == fw)
+ if (QInputContext *inputContext = fw->inputContext())
+ inputContext->update();
+#endif
}
/*!
@@ -7327,13 +7349,11 @@ void QGraphicsItem::setInputMethodHints(Qt::InputMethodHints hints)
void QGraphicsItem::updateMicroFocus()
{
#if !defined(QT_NO_IM) && (defined(Q_WS_X11) || defined(Q_WS_QWS) || defined(Q_OS_SYMBIAN))
- if (QWidget *fw = qApp->focusWidget()) {
- if (qt_widget_private(fw)->ic || qApp->d_func()->inputContext) {
- if (QInputContext *ic = fw->inputContext()) {
- if (ic)
- ic->update();
- }
- }
+ if (QWidget *fw = QApplication::focusWidget()) {
+ for (int i = 0 ; i < scene()->views().count() ; ++i)
+ if (scene()->views().at(i) == fw)
+ if (QInputContext *inputContext = fw->inputContext())
+ inputContext->update();
#ifndef QT_NO_ACCESSIBILITY
// ##### is this correct
QAccessible::updateAccessibility(fw, 0, QAccessible::StateChanged);
@@ -10086,6 +10106,9 @@ bool QGraphicsTextItem::sceneEvent(QEvent *event)
#endif //QT_NO_IM
}
break;
+ case QEvent::ShortcutOverride:
+ dd->sendControlEvent(event);
+ return true;
default:
break;
}
diff --git a/src/gui/graphicsview/qgraphicsitem_p.h b/src/gui/graphicsview/qgraphicsitem_p.h
index f922842..569a329 100644
--- a/src/gui/graphicsview/qgraphicsitem_p.h
+++ b/src/gui/graphicsview/qgraphicsitem_p.h
@@ -284,6 +284,7 @@ public:
void setEnabledHelper(bool newEnabled, bool explicitly, bool update = true);
bool discardUpdateRequest(bool ignoreVisibleBit = false,
bool ignoreDirtyBit = false, bool ignoreOpacity = false) const;
+ virtual void transformChanged() {}
int depth() const;
#ifndef QT_NO_GRAPHICSEFFECT
enum InvalidateReason {
@@ -844,6 +845,13 @@ inline bool QGraphicsItemPrivate::insertionOrder(QGraphicsItem *a, QGraphicsItem
inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect)
{
QGraphicsItemPrivate *parentp = this;
+#ifndef QT_NO_GRAPHICSEFFECT
+ if (updateBoundingRect && parentp->graphicsEffect && !parentp->inSetPosHelper) {
+ parentp->notifyInvalidated = 1;
+ static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
+ ->source->d_func())->invalidateCache();
+ }
+#endif
while (parentp->parent) {
parentp = parentp->parent->d_ptr.data();
parentp->dirtyChildren = 1;
@@ -860,7 +868,7 @@ inline void QGraphicsItemPrivate::markParentDirty(bool updateBoundingRect)
static_cast<QGraphicsItemEffectSourcePrivate *>(parentp->graphicsEffect->d_func()
->source->d_func())->invalidateCache();
}
- if (parentp->graphicsEffect->isEnabled()) {
+ if (parentp->scene && parentp->graphicsEffect->isEnabled()) {
parentp->dirty = 1;
parentp->fullUpdatePending = 1;
}
diff --git a/src/gui/graphicsview/qgraphicsproxywidget.cpp b/src/gui/graphicsview/qgraphicsproxywidget.cpp
index ad7cf5d..320395e 100644
--- a/src/gui/graphicsview/qgraphicsproxywidget.cpp
+++ b/src/gui/graphicsview/qgraphicsproxywidget.cpp
@@ -975,6 +975,7 @@ bool QGraphicsProxyWidget::eventFilter(QObject *object, QEvent *event)
d->styleChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
}
break;
+#ifndef QT_NO_TOOLTIP
case QEvent::ToolTipChange:
// Propagate tooltip change to the proxy.
if (!d->tooltipChangeMode) {
@@ -983,6 +984,7 @@ bool QGraphicsProxyWidget::eventFilter(QObject *object, QEvent *event)
d->tooltipChangeMode = QGraphicsProxyWidgetPrivate::NoMode;
}
break;
+#endif
default:
break;
}
@@ -1024,9 +1026,18 @@ void QGraphicsProxyWidget::contextMenuEvent(QGraphicsSceneContextMenuEvent *even
// Map event position from us to the receiver
pos = d->mapToReceiver(pos, receiver);
+ QPoint globalPos = receiver->mapToGlobal(pos.toPoint());
+ //If the receiver by-pass the proxy its popups
+ //will be top level QWidgets therefore they need
+ //the screen position. mapToGlobal expect the widget to
+ //have proper coordinates in regards of the windowing system
+ //but it's not true because the widget is embedded.
+ if (bypassGraphicsProxyWidget(receiver))
+ globalPos = event->screenPos();
+
// Send mouse event. ### Doesn't propagate the event.
QContextMenuEvent contextMenuEvent(QContextMenuEvent::Reason(event->reason()),
- pos.toPoint(), receiver->mapToGlobal(pos.toPoint()), event->modifiers());
+ pos.toPoint(), globalPos, event->modifiers());
QApplication::sendEvent(receiver, &contextMenuEvent);
event->setAccepted(contextMenuEvent.isAccepted());
diff --git a/src/gui/graphicsview/qgraphicsscene.cpp b/src/gui/graphicsview/qgraphicsscene.cpp
index bd0f0d8..0d4e48a 100644
--- a/src/gui/graphicsview/qgraphicsscene.cpp
+++ b/src/gui/graphicsview/qgraphicsscene.cpp
@@ -297,6 +297,7 @@ QGraphicsScenePrivate::QGraphicsScenePrivate()
scenePosDescendantsUpdatePending(false),
stickyFocus(false),
hasFocus(false),
+ rectAdjust(2),
focusItem(0),
lastFocusItem(0),
tabFocusFirst(0),
@@ -820,13 +821,13 @@ void QGraphicsScenePrivate::setFocusItemHelper(QGraphicsItem *item,
#endif //QT_NO_IM
}
- if (item) {
+ if (item)
focusItem = item;
+ updateInputMethodSensitivityInViews();
+ if (item) {
QFocusEvent event(QEvent::FocusIn, focusReason);
sendEvent(item, &event);
}
-
- updateInputMethodSensitivityInViews();
}
/*!
@@ -3217,7 +3218,10 @@ void QGraphicsScene::update(const QRectF &rect)
// Update all views.
for (int i = 0; i < d->views.size(); ++i) {
QGraphicsView *view = d->views.at(i);
- view->d_func()->updateRegion(QRegion(view->mapFromScene(rect).boundingRect()));
+ if (view->isTransformed())
+ view->d_func()->updateRectF(view->viewportTransform().mapRect(rect));
+ else
+ view->d_func()->updateRectF(rect);
}
} else {
d->updatedRects << rect;
@@ -4701,11 +4705,11 @@ void QGraphicsScenePrivate::drawSubtreeRecursive(QGraphicsItem *item, QPainter *
if (drawItem) {
const QRectF brect = adjustedItemEffectiveBoundingRect(item);
ENSURE_TRANSFORM_PTR
- QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toRect()
- : transformPtr->mapRect(brect).toRect();
+ QRect viewBoundingRect = translateOnlyTransform ? brect.translated(transformPtr->dx(), transformPtr->dy()).toAlignedRect()
+ : transformPtr->mapRect(brect).toAlignedRect();
+ viewBoundingRect.adjust(-rectAdjust, -rectAdjust, rectAdjust, rectAdjust);
if (widget)
item->d_ptr->paintedViewBoundingRects.insert(widget, viewBoundingRect);
- viewBoundingRect.adjust(-1, -1, 1, 1);
drawItem = exposedRegion ? exposedRegion->intersects(viewBoundingRect)
: !viewBoundingRect.normalized().isEmpty();
if (!drawItem) {
@@ -4954,34 +4958,29 @@ static inline bool updateHelper(QGraphicsViewPrivate *view, QGraphicsItemPrivate
if (itemIsUntransformable) {
const QTransform xform = itemq->deviceTransform(viewq->viewportTransform());
if (!item->hasBoundingRegionGranularity)
- return view->updateRect(xform.mapRect(rect).toRect());
- return view->updateRegion(xform.map(QRegion(rect.toRect())));
+ return view->updateRectF(xform.mapRect(rect));
+ return view->updateRegion(rect, xform);
}
if (item->sceneTransformTranslateOnly && view->identityMatrix) {
const qreal dx = item->sceneTransform.dx();
const qreal dy = item->sceneTransform.dy();
- if (!item->hasBoundingRegionGranularity) {
- QRectF r(rect);
- r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll());
- return view->updateRect(r.toRect());
- }
- QRegion r(rect.toRect());
- r.translate(qRound(dx) - view->horizontalScroll(), qRound(dy) - view->verticalScroll());
- return view->updateRegion(r);
+ QRectF r(rect);
+ r.translate(dx - view->horizontalScroll(), dy - view->verticalScroll());
+ return view->updateRectF(r);
}
if (!viewq->isTransformed()) {
if (!item->hasBoundingRegionGranularity)
- return view->updateRect(item->sceneTransform.mapRect(rect).toRect());
- return view->updateRegion(item->sceneTransform.map(QRegion(rect.toRect())));
+ return view->updateRectF(item->sceneTransform.mapRect(rect));
+ return view->updateRegion(rect, item->sceneTransform);
}
QTransform xform = item->sceneTransform;
xform *= viewq->viewportTransform();
if (!item->hasBoundingRegionGranularity)
- return view->updateRect(xform.mapRect(rect).toRect());
- return view->updateRegion(xform.map(QRegion(rect.toRect())));
+ return view->updateRectF(xform.mapRect(rect));
+ return view->updateRegion(rect, xform);
}
void QGraphicsScenePrivate::processDirtyItemsRecursive(QGraphicsItem *item, bool dirtyAncestorContainsChildren,
@@ -5197,8 +5196,14 @@ void QGraphicsScene::drawItems(QPainter *painter,
// Determine view, expose and flags.
QGraphicsView *view = widget ? qobject_cast<QGraphicsView *>(widget->parentWidget()) : 0;
QRegion *expose = 0;
- if (view)
+ const quint32 oldRectAdjust = d->rectAdjust;
+ if (view) {
expose = &view->d_func()->exposedRegion;
+ if (view->d_func()->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
+ d->rectAdjust = 1;
+ else
+ d->rectAdjust = 2;
+ }
// Find all toplevels, they are already sorted.
QList<QGraphicsItem *> topLevelItems;
@@ -5211,6 +5216,7 @@ void QGraphicsScene::drawItems(QPainter *painter,
}
}
+ d->rectAdjust = oldRectAdjust;
// Reset discovery bits.
for (int i = 0; i < topLevelItems.size(); ++i)
topLevelItems.at(i)->d_ptr->itemDiscovered = 0;
diff --git a/src/gui/graphicsview/qgraphicsscene_p.h b/src/gui/graphicsview/qgraphicsscene_p.h
index 11e250e..0a85f0e 100644
--- a/src/gui/graphicsview/qgraphicsscene_p.h
+++ b/src/gui/graphicsview/qgraphicsscene_p.h
@@ -136,8 +136,10 @@ public:
QBrush backgroundBrush;
QBrush foregroundBrush;
- bool stickyFocus;
- bool hasFocus;
+ quint32 stickyFocus : 1;
+ quint32 hasFocus : 1;
+ quint32 padding : 30;
+ quint32 rectAdjust;
QGraphicsItem *focusItem;
QGraphicsItem *lastFocusItem;
QGraphicsWidget *tabFocusFirst;
diff --git a/src/gui/graphicsview/qgraphicsview.cpp b/src/gui/graphicsview/qgraphicsview.cpp
index a767987..0bba7e9 100644
--- a/src/gui/graphicsview/qgraphicsview.cpp
+++ b/src/gui/graphicsview/qgraphicsview.cpp
@@ -733,11 +733,13 @@ void QGraphicsViewPrivate::_q_unsetViewportCursor()
}
// Restore the original viewport cursor.
- hasStoredOriginalCursor = false;
- if (dragMode == QGraphicsView::ScrollHandDrag)
- viewport->setCursor(Qt::OpenHandCursor);
- else
- viewport->setCursor(originalCursor);
+ if (hasStoredOriginalCursor) {
+ hasStoredOriginalCursor = false;
+ if (dragMode == QGraphicsView::ScrollHandDrag)
+ viewport->setCursor(Qt::OpenHandCursor);
+ else
+ viewport->setCursor(originalCursor);
+ }
}
#endif
@@ -852,10 +854,7 @@ void QGraphicsViewPrivate::processPendingUpdates()
if (fullUpdatePending) {
viewport->update();
} else if (viewportUpdateMode == QGraphicsView::BoundingRectViewportUpdate) {
- if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
- viewport->update(dirtyBoundingRect.adjusted(-1, -1, 1, 1));
- else
- viewport->update(dirtyBoundingRect.adjusted(-2, -2, 2, 2));
+ viewport->update(dirtyBoundingRect);
} else {
viewport->update(dirtyRegion); // Already adjusted in updateRect/Region.
}
@@ -880,46 +879,44 @@ static inline void QRect_unite(QRect *rect, const QRect &other)
}
}
-bool QGraphicsViewPrivate::updateRegion(const QRegion &r)
+bool QGraphicsViewPrivate::updateRegion(const QRectF &rect, const QTransform &xform)
{
- if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate || r.isEmpty())
+ if (rect.isEmpty())
return false;
- const QRect boundingRect = r.boundingRect();
- if (!intersectsViewport(boundingRect, viewport->width(), viewport->height()))
- return false; // Update region outside viewport.
-
- switch (viewportUpdateMode) {
- case QGraphicsView::FullViewportUpdate:
- fullUpdatePending = true;
- viewport->update();
- break;
- case QGraphicsView::BoundingRectViewportUpdate:
- QRect_unite(&dirtyBoundingRect, boundingRect);
- if (containsViewport(dirtyBoundingRect, viewport->width(), viewport->height())) {
- fullUpdatePending = true;
- viewport->update();
- }
- break;
- case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE
- case QGraphicsView::MinimalViewportUpdate:
- {
- const QVector<QRect> &rects = r.rects();
- for (int i = 0; i < rects.size(); ++i) {
- if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
- dirtyRegion += rects.at(i).adjusted(-1, -1, 1, 1);
- else
- dirtyRegion += rects.at(i).adjusted(-2, -2, 2, 2);
- }
- break;
+ if (viewportUpdateMode != QGraphicsView::MinimalViewportUpdate
+ && viewportUpdateMode != QGraphicsView::SmartViewportUpdate) {
+ // No point in updating with QRegion granularity; use the rect instead.
+ return updateRectF(xform.mapRect(rect));
}
- default:
- break;
+
+ // Update mode is either Minimal or Smart, so we have to do a potentially slow operation,
+ // which is clearly documented here: QGraphicsItem::setBoundingRegionGranularity.
+ const QRegion region = xform.map(QRegion(rect.toAlignedRect()));
+ QRect viewRect = region.boundingRect();
+ const bool dontAdjustForAntialiasing = optimizationFlags & QGraphicsView::DontAdjustForAntialiasing;
+ if (dontAdjustForAntialiasing)
+ viewRect.adjust(-1, -1, 1, 1);
+ else
+ viewRect.adjust(-2, -2, 2, 2);
+ if (!intersectsViewport(viewRect, viewport->width(), viewport->height()))
+ return false; // Update region for sure outside viewport.
+
+ const QVector<QRect> &rects = region.rects();
+ for (int i = 0; i < rects.size(); ++i) {
+ viewRect = rects.at(i);
+ if (dontAdjustForAntialiasing)
+ viewRect.adjust(-1, -1, 1, 1);
+ else
+ viewRect.adjust(-2, -2, 2, 2);
+ dirtyRegion += viewRect;
}
return true;
}
+// NB! Assumes the rect 'r' is already aligned and adjusted for antialiasing.
+// For QRectF use updateRectF(const QRectF &) to ensure proper adjustments.
bool QGraphicsViewPrivate::updateRect(const QRect &r)
{
if (fullUpdatePending || viewportUpdateMode == QGraphicsView::NoViewportUpdate
@@ -941,10 +938,7 @@ bool QGraphicsViewPrivate::updateRect(const QRect &r)
break;
case QGraphicsView::SmartViewportUpdate: // ### DEPRECATE
case QGraphicsView::MinimalViewportUpdate:
- if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
- dirtyRegion += r.adjusted(-1, -1, 1, 1);
- else
- dirtyRegion += r.adjusted(-2, -2, 2, 2);
+ dirtyRegion += r;
break;
default:
break;
@@ -1035,10 +1029,28 @@ QList<QGraphicsItem *> QGraphicsViewPrivate::findItems(const QRegion &exposedReg
void QGraphicsViewPrivate::updateInputMethodSensitivity()
{
Q_Q(QGraphicsView);
- bool enabled = scene && scene->focusItem()
- && (scene->focusItem()->flags() & QGraphicsItem::ItemAcceptsInputMethod);
+ QGraphicsItem *focusItem = 0;
+ bool enabled = scene && (focusItem = scene->focusItem())
+ && (focusItem->d_ptr->flags & QGraphicsItem::ItemAcceptsInputMethod);
q->setAttribute(Qt::WA_InputMethodEnabled, enabled);
q->viewport()->setAttribute(Qt::WA_InputMethodEnabled, enabled);
+
+ if (!enabled) {
+ q->setInputMethodHints(0);
+ return;
+ }
+
+ QGraphicsProxyWidget *proxy = focusItem->d_ptr->isWidget && focusItem->d_ptr->isProxyWidget()
+ ? static_cast<QGraphicsProxyWidget *>(focusItem) : 0;
+ if (!proxy) {
+ q->setInputMethodHints(focusItem->inputMethodHints());
+ } else if (QWidget *widget = proxy->widget()) {
+ if (QWidget *fw = widget->focusWidget())
+ widget = fw;
+ q->setInputMethodHints(widget->inputMethodHints());
+ } else {
+ q->setInputMethodHints(0);
+ }
}
/*!
@@ -3383,8 +3395,14 @@ void QGraphicsView::paintEvent(QPaintEvent *event)
// Items
if (!(d->optimizationFlags & IndirectPainting)) {
+ const quint32 oldRectAdjust = d->scene->d_func()->rectAdjust;
+ if (d->optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
+ d->scene->d_func()->rectAdjust = 1;
+ else
+ d->scene->d_func()->rectAdjust = 2;
d->scene->d_func()->drawItems(&painter, viewTransformed ? &viewTransform : 0,
&d->exposedRegion, viewport());
+ d->scene->d_func()->rectAdjust = oldRectAdjust;
// Make sure the painter's world transform is restored correctly when
// drawing without painter state protection (DontSavePainterState).
// We only change the worldTransform() so there's no need to do a full-blown
diff --git a/src/gui/graphicsview/qgraphicsview_p.h b/src/gui/graphicsview/qgraphicsview_p.h
index 729837a..aeff28a 100644
--- a/src/gui/graphicsview/qgraphicsview_p.h
+++ b/src/gui/graphicsview/qgraphicsview_p.h
@@ -183,13 +183,26 @@ public:
else
QCoreApplication::sendPostedEvents(viewport->window(), QEvent::UpdateRequest);
#else
- QCoreApplication::processEvents(QEventLoop::AllEvents | QEventLoop::ExcludeSocketNotifiers
- | QEventLoop::ExcludeUserInputEvents);
+ // At this point either HIViewSetNeedsDisplay (Carbon) or setNeedsDisplay: YES (Cocoa)
+ // is called, which means there's a pending update request. We want to dispatch it
+ // now because otherwise graphics view updates would require two
+ // round-trips in the event loop before the item is painted.
+ extern void qt_mac_dispatchPendingUpdateRequests(QWidget *);
+ qt_mac_dispatchPendingUpdateRequests(viewport->window());
#endif
}
+ inline bool updateRectF(const QRectF &rect)
+ {
+ if (rect.isEmpty())
+ return false;
+ if (optimizationFlags & QGraphicsView::DontAdjustForAntialiasing)
+ return updateRect(rect.toAlignedRect().adjusted(-1, -1, 1, 1));
+ return updateRect(rect.toAlignedRect().adjusted(-2, -2, 2, 2));
+ }
+
bool updateRect(const QRect &rect);
- bool updateRegion(const QRegion &region);
+ bool updateRegion(const QRectF &rect, const QTransform &xform);
bool updateSceneSlotReimplementedChecked;
QRegion exposedRegion;
diff --git a/src/gui/graphicsview/qgraphicswidget.cpp b/src/gui/graphicsview/qgraphicswidget.cpp
index bc8ccb01..06a44b7 100644
--- a/src/gui/graphicsview/qgraphicswidget.cpp
+++ b/src/gui/graphicsview/qgraphicswidget.cpp
@@ -324,11 +324,9 @@ void QGraphicsWidget::resize(const QSizeF &size)
*/
/*!
-
\fn QGraphicsWidget::geometryChanged()
- This signal gets emitted whenever the geometry of the item changes
- \internal
+ This signal gets emitted whenever the geometry is changed in setGeometry().
*/
/*!
@@ -408,12 +406,6 @@ void QGraphicsWidget::setGeometry(const QRectF &rect)
}
/*!
- \fn QGraphicsWidget::geometryChanged()
-
- This signal gets emitted whenever the geometry is changed in setGeometry().
-*/
-
-/*!
\fn QRectF QGraphicsWidget::rect() const
Returns the item's local rect as a QRectF. This function is equivalent
diff --git a/src/gui/gui.pro b/src/gui/gui.pro
index 329a098..b68c9b5 100644
--- a/src/gui/gui.pro
+++ b/src/gui/gui.pro
@@ -40,9 +40,8 @@ include(statemachine/statemachine.pri)
include(math3d/math3d.pri)
include(effects/effects.pri)
-contains(QT_CONFIG, egl): include(egl/egl.pri)
+include(egl/egl.pri)
win32:!wince*: DEFINES += QT_NO_EGL
-
embedded: QT += network
QMAKE_LIBS += $$QMAKE_LIBS_GUI
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index fad51f4..891b1db 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -441,7 +441,7 @@ void QPixmapIconEngine::virtual_hook(int id, void *data)
}
}
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QIconEngineFactoryInterface_iid, QLatin1String("/iconengines"), Qt::CaseInsensitive))
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loaderV2,
@@ -879,6 +879,25 @@ QList<QSize> QIcon::availableSizes(Mode mode, State state) const
}
/*!
+ \since 4.7
+
+ Returns the name used to create the icon, if available.
+
+ Depending on the way the icon was created, it may have an associated
+ name. This is the case for icons created with fromTheme() or icons
+ using a QIconEngine which supports the QIconEngineV2::IconNameHook.
+
+ \sa fromTheme(), QIconEngine
+*/
+QString QIcon::name() const
+{
+ if (!d || !d->engine || d->engine_version < 2)
+ return QString();
+ QIconEngineV2 *engine = static_cast<QIconEngineV2*>(d->engine);
+ return engine->iconName();
+}
+
+/*!
\since 4.6
Sets the search paths for icon themes to \a paths.
diff --git a/src/gui/image/qicon.h b/src/gui/image/qicon.h
index 2812703..faef07b 100644
--- a/src/gui/image/qicon.h
+++ b/src/gui/image/qicon.h
@@ -81,6 +81,8 @@ public:
QSize actualSize(const QSize &size, Mode mode = Normal, State state = Off) const;
+ QString name() const;
+
void paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment = Qt::AlignCenter, Mode mode = Normal, State state = Off) const;
inline void paint(QPainter *painter, int x, int y, int w, int h, Qt::Alignment alignment = Qt::AlignCenter, Mode mode = Normal, State state = Off) const
{ paint(painter, QRect(x, y, w, h), alignment, mode, state); }
diff --git a/src/gui/image/qiconengine.cpp b/src/gui/image/qiconengine.cpp
index 4c7c728..050d48d 100644
--- a/src/gui/image/qiconengine.cpp
+++ b/src/gui/image/qiconengine.cpp
@@ -183,6 +183,10 @@ void QIconEngine::addFile(const QString &/*fileName*/, const QSize &/*size*/, QI
that should be filled with icon sizes. Engines that work in terms
of a scalable, vectorial format normally return an empty list.
+ \value IconNameHook Allows to query the name used to create the
+ icon, for example when instantiating an icon using
+ QIcon::fromTheme().
+
\sa virtual_hook()
*/
@@ -301,4 +305,20 @@ QList<QSize> QIconEngineV2::availableSizes(QIcon::Mode mode, QIcon::State state)
return arg.sizes;
}
+/*!
+ \since 4.7
+
+ Returns the name used to create the engine, if available.
+
+ \note This is a helper method and the actual work is done by
+ virtual_hook() method, hence this method depends on icon engine support
+ and may not work with all icon engines.
+ */
+QString QIconEngineV2::iconName()
+{
+ QString name;
+ virtual_hook(QIconEngineV2::IconNameHook, reinterpret_cast<void*>(&name));
+ return name;
+}
+
QT_END_NAMESPACE
diff --git a/src/gui/image/qiconengine.h b/src/gui/image/qiconengine.h
index 1f9266b..6d8b6ad 100644
--- a/src/gui/image/qiconengine.h
+++ b/src/gui/image/qiconengine.h
@@ -80,7 +80,7 @@ public:
virtual void virtual_hook(int id, void *data);
public:
- enum IconEngineHook { AvailableSizesHook = 1 };
+ enum IconEngineHook { AvailableSizesHook = 1, IconNameHook };
struct AvailableSizesArgument
{
@@ -92,6 +92,9 @@ public:
// ### Qt 5: make this function const and virtual.
QList<QSize> availableSizes(QIcon::Mode mode = QIcon::Normal,
QIcon::State state = QIcon::Off);
+
+ // ### Qt 5: make this function const and virtual.
+ QString iconName();
};
QT_END_NAMESPACE
diff --git a/src/gui/image/qiconloader.cpp b/src/gui/image/qiconloader.cpp
index 72ec2e8..a515ef8 100644
--- a/src/gui/image/qiconloader.cpp
+++ b/src/gui/image/qiconloader.cpp
@@ -554,6 +554,12 @@ void QIconLoaderEngine::virtual_hook(int id, void *data)
}
}
break;
+ case QIconEngineV2::IconNameHook:
+ {
+ QString &name = *reinterpret_cast<QString*>(data);
+ name = m_iconName;
+ }
+ break;
default:
QIconEngineV2::virtual_hook(id, data);
}
diff --git a/src/gui/image/qimagereader.cpp b/src/gui/image/qimagereader.cpp
index 27f9627..93d5cd3 100644
--- a/src/gui/image/qimagereader.cpp
+++ b/src/gui/image/qimagereader.cpp
@@ -144,7 +144,7 @@
QT_BEGIN_NAMESPACE
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats")))
#endif
@@ -205,7 +205,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
QByteArray form = format.toLower();
QImageIOHandler *handler = 0;
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
// check if we have plugins that support the image format
QFactoryLoader *l = loader();
QStringList keys = l->keys();
@@ -217,7 +217,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
<< keys.size() << "plugins available: " << keys;
#endif
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
int suffixPluginIndex = -1;
if (device && format.isEmpty() && autoDetectImageFormat && !ignoresFormatAndExtension) {
// if there's no format, see if \a device is a file, and if so, find
@@ -246,7 +246,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
if (ignoresFormatAndExtension)
testFormat = QByteArray();
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
if (suffixPluginIndex != -1) {
// check if the plugin that claims support for this format can load
// from this device with this format.
@@ -331,7 +331,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
#endif
}
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) {
// check if any of our plugins recognize the file from its contents.
const qint64 pos = device ? device->pos() : 0;
@@ -350,7 +350,7 @@ static QImageIOHandler *createReadHandlerHelper(QIODevice *device,
if (device && !device->isSequential())
device->seek(pos);
}
-#endif
+#endif // QT_NO_LIBRARY
if (!handler && (autoDetectImageFormat || ignoresFormatAndExtension)) {
// check if any of our built-in handlers recognize the file from its
@@ -1414,7 +1414,7 @@ QList<QByteArray> QImageReader::supportedImageFormats()
for (int i = 0; i < _qt_NumFormats; ++i)
formats << _qt_BuiltInFormats[i].extension;
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QFactoryLoader *l = loader();
QStringList keys = l->keys();
diff --git a/src/gui/image/qimagewriter.cpp b/src/gui/image/qimagewriter.cpp
index 503a1b2..552729f 100644
--- a/src/gui/image/qimagewriter.cpp
+++ b/src/gui/image/qimagewriter.cpp
@@ -117,7 +117,7 @@
QT_BEGIN_NAMESPACE
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QImageIOHandlerFactoryInterface_iid, QLatin1String("/imageformats")))
#endif
@@ -129,7 +129,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
QByteArray suffix;
QImageIOHandler *handler = 0;
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
// check if any plugins can write the image
QFactoryLoader *l = loader();
QStringList keys = l->keys();
@@ -142,7 +142,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
// this allows plugins to override our built-in handlers.
if (QFile *file = qobject_cast<QFile *>(device)) {
if (!(suffix = QFileInfo(file->fileName()).suffix().toLower().toLatin1()).isEmpty()) {
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
int index = keys.indexOf(QString::fromLatin1(suffix));
if (index != -1)
suffixPluginIndex = index;
@@ -153,7 +153,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
QByteArray testFormat = !form.isEmpty() ? form : suffix;
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
if (suffixPluginIndex != -1) {
// when format is missing, check if we can find a plugin for the
// suffix.
@@ -161,7 +161,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
if (plugin && (plugin->capabilities(device, suffix) & QImageIOPlugin::CanWrite))
handler = plugin->create(device, suffix);
}
-#endif // Q_NO_LIBRARY
+#endif // QT_NO_LIBRARY
// check if any built-in handlers can write the image
if (!handler && !testFormat.isEmpty()) {
@@ -192,7 +192,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
}
}
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
if (!testFormat.isEmpty()) {
for (int i = 0; i < keys.size(); ++i) {
QImageIOPlugin *plugin = qobject_cast<QImageIOPlugin *>(l->instance(keys.at(i)));
@@ -203,7 +203,7 @@ static QImageIOHandler *createWriteHandlerHelper(QIODevice *device,
}
}
}
-#endif
+#endif // QT_NO_LIBRARY
if (!handler)
return 0;
@@ -670,7 +670,7 @@ QList<QByteArray> QImageWriter::supportedImageFormats()
formats << "png";
#endif
-#if !defined (QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QFactoryLoader *l = loader();
QStringList keys = l->keys();
for (int i = 0; i < keys.count(); ++i) {
diff --git a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
index b42e0ab..610ac3c 100644
--- a/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
+++ b/src/gui/inputmethod/qcoefepinputcontext_s60.cpp
@@ -87,7 +87,7 @@ QCoeFepInputContext::QCoeFepInputContext(QObject *parent)
m_fepState->SetDefaultInputMode( EAknEditorTextInputMode );
m_fepState->SetPermittedInputModes( EAknEditorAllInputModes );
m_fepState->SetDefaultCase( EAknEditorLowerCase );
- m_fepState->SetPermittedCases( EAknEditorLowerCase|EAknEditorUpperCase );
+ m_fepState->SetPermittedCases( EAknEditorAllCaseModes );
m_fepState->SetSpecialCharacterTableResourceId(R_AVKON_SPECIAL_CHARACTER_TABLE_DIALOG);
m_fepState->SetNumericKeymap( EAknEditorStandardNumberModeKeymap );
}
diff --git a/src/gui/inputmethod/qinputcontextfactory.cpp b/src/gui/inputmethod/qinputcontextfactory.cpp
index d47e343..ec8d8e2 100644
--- a/src/gui/inputmethod/qinputcontextfactory.cpp
+++ b/src/gui/inputmethod/qinputcontextfactory.cpp
@@ -81,7 +81,7 @@
QT_BEGIN_NAMESPACE
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QInputContextFactoryInterface_iid, QLatin1String("/inputmethods")))
#endif
@@ -153,7 +153,7 @@ QInputContext *QInputContextFactory::create( const QString& key, QObject *parent
result = new QCoeFepInputContext;
}
#endif
-#if defined(QT_NO_LIBRARY) || defined(QT_NO_SETTINGS)
+#ifdef QT_NO_LIBRARY
Q_UNUSED(key);
#else
if (QInputContextFactoryInterface *factory =
@@ -193,7 +193,7 @@ QStringList QInputContextFactory::keys()
#if defined(Q_WS_S60)
result << QLatin1String("coefep");
#endif
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
result += loader()->keys();
#endif // QT_NO_LIBRARY
return result;
diff --git a/src/gui/itemviews/qtableview.cpp b/src/gui/itemviews/qtableview.cpp
index 80334a6..4492e53 100644
--- a/src/gui/itemviews/qtableview.cpp
+++ b/src/gui/itemviews/qtableview.cpp
@@ -2145,8 +2145,8 @@ int QTableView::sizeHintForRow(int row) const
ensurePolished();
- int left = qMax(0, columnAt(0));
- int right = columnAt(d->viewport->width());
+ int left = qMax(0, d->horizontalHeader->visualIndexAt(0));
+ int right = d->horizontalHeader->visualIndexAt(d->viewport->width());
if (right == -1) // the table don't have enough columns to fill the viewport
right = d->model->columnCount(d->root) - 1;
@@ -2204,8 +2204,8 @@ int QTableView::sizeHintForColumn(int column) const
ensurePolished();
- int top = qMax(0, rowAt(0));
- int bottom = rowAt(d->viewport->height());
+ int top = qMax(0, d->verticalHeader->visualIndexAt(0));
+ int bottom = d->verticalHeader->visualIndexAt(d->viewport->height());
if (!isVisible() || bottom == -1) // the table don't have enough rows to fill the viewport
bottom = d->model->rowCount(d->root) - 1;
diff --git a/src/gui/kernel/qapplication_s60.cpp b/src/gui/kernel/qapplication_s60.cpp
index c735d1f..f4c7304 100644
--- a/src/gui/kernel/qapplication_s60.cpp
+++ b/src/gui/kernel/qapplication_s60.cpp
@@ -73,6 +73,7 @@
# endif
# include <private/qs60mainapplication_p.h>
# include <centralrepository.h>
+# include "qs60mainappui.h"
#endif
#include "private/qstylesheetstyle_p.h"
@@ -439,7 +440,7 @@ void QSymbianControl::translateAdvancedPointerEvent(const TAdvancedPointerEvent
state |= Qt::TouchPointPrimary;
touchPoint.setState(state);
- QPointF screenPos = QPointF(event->iPosition.iX, event->iPosition.iY);
+ QPointF screenPos = qwidget->mapToGlobal(QPoint(event->iPosition.iX, event->iPosition.iY));
touchPoint.setScreenPos(screenPos);
touchPoint.setNormalizedPos(QPointF(screenPos.x() / screenGeometry.width(),
screenPos.y() / screenGeometry.height()));
@@ -539,6 +540,14 @@ void QSymbianControl::HandlePointerEvent(const TPointerEvent& pEvent)
sendMouseEvent(receiver, type, globalPos, button, modifiers);
}
+#ifdef Q_WS_S60
+void QSymbianControl::HandleStatusPaneSizeChange()
+{
+ QS60MainAppUi *s60AppUi = static_cast<QS60MainAppUi *>(S60->appUi());
+ s60AppUi->HandleStatusPaneSizeChange();
+}
+#endif
+
void QSymbianControl::sendMouseEvent(
QWidget *receiver,
QEvent::Type type,
@@ -982,15 +991,6 @@ void QSymbianControl::FocusChanged(TDrawNow /* aDrawNow */)
const TBool isFullscreen = qwidget->windowState() & Qt::WindowFullScreen;
const TBool cbaVisibilityHint = qwidget->windowFlags() & Qt::WindowSoftkeysVisibleHint;
buttonGroup->MakeVisible(visible || (isFullscreen && cbaVisibilityHint));
-
- // Responsiviness
- CEikCba *cba = static_cast<CEikCba *>( buttonGroup->ButtonGroup() ); // downcast from MEikButtonGroup
- TUint cbaFlags = cba->ButtonGroupFlags();
- if(qwidget->windowFlags() & Qt::WindowSoftkeysRespondHint)
- cbaFlags |= EAknCBAFlagRespondWhenInvisible;
- else
- cbaFlags &= ~EAknCBAFlagRespondWhenInvisible;
- cba->SetButtonGroupFlags(cbaFlags);
}
#endif
} else if (QApplication::activeWindow() == qwidget->window()) {
diff --git a/src/gui/kernel/qapplication_win.cpp b/src/gui/kernel/qapplication_win.cpp
index 1d8eb4c..fb2837e 100644
--- a/src/gui/kernel/qapplication_win.cpp
+++ b/src/gui/kernel/qapplication_win.cpp
@@ -79,6 +79,7 @@ extern void qt_wince_hide_taskbar(HWND hwnd); //defined in qguifunctions_wince.c
#include "qlayout.h"
#include "qtooltip.h"
#include "qt_windows.h"
+#include "qscrollbar.h"
#if defined(QT_NON_COMMERCIAL)
#include "qnc_win.h"
#endif
@@ -701,6 +702,21 @@ void QApplicationPrivate::initializeWidgetPaletteHash()
QApplication::setPalette(menu, "QMenuBar");
}
+static void qt_set_windows_updateScrollBar(QWidget *widget)
+{
+ QList<QObject*> children = widget->children();
+ for (int i = 0; i < children.size(); ++i) {
+ QObject *o = children.at(i);
+ if(!o->isWidgetType())
+ continue;
+ if (QWidget *w = static_cast<QWidget *>(o))
+ qt_set_windows_updateScrollBar(w);
+ }
+ if (qobject_cast<QScrollBar*>(widget))
+ widget->updateGeometry();
+}
+
+
/*****************************************************************************
qt_init() - initializes Qt for Windows
*****************************************************************************/
@@ -1930,6 +1946,15 @@ extern "C" LRESULT QT_WIN_CALLBACK QtWndProc(HWND hwnd, UINT message, WPARAM wPa
}
}
}
+ else if (msg.wParam == SPI_SETNONCLIENTMETRICS) {
+ widget = (QETWidget*)QWidget::find(hwnd);
+ if (widget && !widget->parentWidget()) {
+ qt_set_windows_updateScrollBar(widget);
+ QEvent e(QEvent::LayoutRequest);
+ QApplication::sendEvent(widget, &e);
+ }
+ }
+
break;
case WM_PAINT: // paint event
diff --git a/src/gui/kernel/qcocoamenuloader_mac.mm b/src/gui/kernel/qcocoamenuloader_mac.mm
index b58fd7c..8d65aa1 100644
--- a/src/gui/kernel/qcocoamenuloader_mac.mm
+++ b/src/gui/kernel/qcocoamenuloader_mac.mm
@@ -53,6 +53,12 @@
QT_FORWARD_DECLARE_CLASS(QCFString)
QT_FORWARD_DECLARE_CLASS(QString)
+#ifndef QT_NO_TRANSLATION
+ QT_BEGIN_NAMESPACE
+ extern QString qt_mac_applicationmenu_string(int type);
+ QT_END_NAMESPACE
+#endif
+
QT_USE_NAMESPACE
@implementation QT_MANGLE_NAMESPACE(QCocoaMenuLoader)
@@ -226,7 +232,6 @@ QT_USE_NAMESPACE
- (void)qtTranslateApplicationMenu
{
#ifndef QT_NO_TRANSLATION
- extern QString qt_mac_applicationmenu_string(int type);
[servicesItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(0))];
[hideItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(1).arg(qAppName()))];
[hideAllOthersItem setTitle: qt_mac_QStringToNSString(qt_mac_applicationmenu_string(2))];
diff --git a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
index ec00915..8652816 100644
--- a/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
+++ b/src/gui/kernel/qcocoasharedwindowmethods_mac_p.h
@@ -101,6 +101,17 @@ QT_END_NAMESPACE
return !(isPopup || isToolTip || isTool);
}
+- (void)becomeMainWindow
+{
+ [super becomeMainWindow];
+ // Cocoa sometimes tell a hidden window to become the
+ // main window (and as such, show it). This can e.g
+ // happend when the application gets activated. If
+ // this is the case, we tell it to hide again:
+ if (![self isVisible])
+ [self orderOut:self];
+}
+
- (void)toggleToolbarShown:(id)sender
{
macSendToolbarChangeEvent([self QT_MANGLE_NAMESPACE(qt_qwidget)]);
@@ -352,3 +363,57 @@ QT_END_NAMESPACE
}
[super displayIfNeeded];
}
+
+// This is a hack and it should be removed once we find the real cause for
+// the painting problems.
+// We have a static variable that signals if we have been called before or not.
+static bool firstDrawingInvocation = true;
+
+// The method below exists only as a workaround to draw/not draw the baseline
+// in the title bar. This is to support unifiedToolbar look.
+
+// This method is very special. To begin with, it is a
+// method that will get called only if we enable documentMode.
+// Furthermore, it won't get called as a normal method, we swap
+// this method with the normal implementation of drawRect in
+// _NSThemeFrame. When this method is active, its mission is to
+// first call the original drawRect implementation so the widget
+// gets proper painting. After that, it needs to detect if there
+// is a toolbar or not, in order to decide how to handle the unified
+// look. The distinction is important since the presence and
+// visibility of a toolbar change the way we enter into unified mode.
+// When there is a toolbar and that toolbar is visible, the problem
+// is as simple as to tell the toolbar not to draw its baseline.
+// However when there is not toolbar or the toolbar is not visible,
+// we need to draw a line on top of the baseline, because the baseline
+// in that case will belong to the title. For this case we need to draw
+// a line on top of the baseline.
+// As usual, there is a special case. When we first are called, we might
+// need to repaint ourselves one more time. We only need that if we
+// didn't get the activation, i.e. when we are launched via the command
+// line. And this only if the toolbar is visible from the beginning,
+// so we have a special flag that signals if we need to repaint or not.
+- (void)drawRectSpecial:(NSRect)rect
+{
+ // Call the original drawing method.
+ [self drawRectOriginal:rect];
+ NSWindow *window = [self window];
+ NSToolbar *toolbar = [window toolbar];
+ if(!toolbar) {
+ // There is no toolbar, we have to draw a line on top of the line drawn by Cocoa.
+ macDrawRectOnTop((void *)window);
+ } else {
+ if([toolbar isVisible]) {
+ // We tell Cocoa to avoid drawing the line at the end.
+ if(firstDrawingInvocation) {
+ firstDrawingInvocation = false;
+ macSyncDrawingOnFirstInvocation((void *)window);
+ } else
+ [toolbar setShowsBaselineSeparator:NO];
+ } else {
+ // There is a toolbar but it is not visible so
+ // we have to draw a line on top of the line drawn by Cocoa.
+ macDrawRectOnTop((void *)window);
+ }
+ }
+}
diff --git a/src/gui/kernel/qcocoaview_mac.mm b/src/gui/kernel/qcocoaview_mac.mm
index dd12f65..4953c48 100644
--- a/src/gui/kernel/qcocoaview_mac.mm
+++ b/src/gui/kernel/qcocoaview_mac.mm
@@ -1554,7 +1554,8 @@ Qt::DropAction QDragManager::drag(QDrag *o)
qt_button_down = 0;
[dndParams.view release];
[image release];
- dragPrivate()->executed_action = Qt::IgnoreAction;
+ if (dragPrivate())
+ dragPrivate()->executed_action = Qt::IgnoreAction;
object = 0;
Qt::DropAction performedAction(qt_mac_mapNSDragOperation(qMacDnDParams()->performedAction));
// do post drag processing, if required.
diff --git a/src/gui/kernel/qguiplatformplugin.cpp b/src/gui/kernel/qguiplatformplugin.cpp
index 911836d..16a2a2b 100644
--- a/src/gui/kernel/qguiplatformplugin.cpp
+++ b/src/gui/kernel/qguiplatformplugin.cpp
@@ -81,7 +81,7 @@ QGuiPlatformPlugin *qt_guiPlatformPlugin()
static QGuiPlatformPlugin *plugin;
if (!plugin)
{
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QString key = QString::fromLocal8Bit(qgetenv("QT_PLATFORM_PLUGIN"));
#ifdef Q_WS_X11
diff --git a/src/gui/kernel/qkeymapper_mac.cpp b/src/gui/kernel/qkeymapper_mac.cpp
index f259654..a7145d4 100644
--- a/src/gui/kernel/qkeymapper_mac.cpp
+++ b/src/gui/kernel/qkeymapper_mac.cpp
@@ -756,14 +756,23 @@ bool QKeyMapperPrivate::translateKeyEvent(QWidget *widget, EventHandlerCallRef e
return true;
}
- if (qApp->inputContext() && qApp->inputContext()->isComposing()) {
+ QInputContext *currentContext = qApp->inputContext();
+ if (currentContext && currentContext->isComposing()) {
if (ekind == kEventRawKeyDown) {
- QMacInputContext *context = qobject_cast<QMacInputContext*>(qApp->inputContext());
+ QMacInputContext *context = qobject_cast<QMacInputContext*>(currentContext);
if (context)
context->setLastKeydownEvent(event);
}
return false;
}
+ // Once we process the key down , we dont need to send the saved event again from
+ // kEventTextInputUnicodeForKeyEvent, so clear it.
+ if (currentContext && ekind == kEventRawKeyDown) {
+ QMacInputContext *context = qobject_cast<QMacInputContext*>(currentContext);
+ if (context)
+ context->setLastKeydownEvent(0);
+ }
+
//get modifiers
Qt::KeyboardModifiers modifiers;
int qtKey;
diff --git a/src/gui/kernel/qkeysequence.cpp b/src/gui/kernel/qkeysequence.cpp
index 9efcc4e..931bc33 100644
--- a/src/gui/kernel/qkeysequence.cpp
+++ b/src/gui/kernel/qkeysequence.cpp
@@ -390,6 +390,9 @@ static const struct {
int key;
const char* name;
} keyname[] = {
+ //: This and all following "incomprehensible" strings in QShortcut context
+ //: are key names. Please use the localized names appearing on actual
+ //: keyboards or whatever is commonly used.
{ Qt::Key_Space, QT_TRANSLATE_NOOP("QShortcut", "Space") },
{ Qt::Key_Escape, QT_TRANSLATE_NOOP("QShortcut", "Esc") },
{ Qt::Key_Tab, QT_TRANSLATE_NOOP("QShortcut", "Tab") },
diff --git a/src/gui/kernel/qpalette.cpp b/src/gui/kernel/qpalette.cpp
index 6e8c90e..98e8f66 100644
--- a/src/gui/kernel/qpalette.cpp
+++ b/src/gui/kernel/qpalette.cpp
@@ -795,7 +795,7 @@ const QBrush &QPalette::brush(ColorGroup gr, ColorRole cr) const
/*!
\fn void QPalette::setColor(ColorGroup group, ColorRole role, const QColor &color)
- Sets the brush in the specified color \a group, used for the given
+ Sets the color in the specified color \a group, used for the given
color \a role, to the specified solid \a color.
\sa setBrush() color() ColorRole
diff --git a/src/gui/kernel/qsoftkeymanager_s60.cpp b/src/gui/kernel/qsoftkeymanager_s60.cpp
index e4990b1..6325d95 100644
--- a/src/gui/kernel/qsoftkeymanager_s60.cpp
+++ b/src/gui/kernel/qsoftkeymanager_s60.cpp
@@ -79,6 +79,8 @@ bool QSoftKeyManagerPrivateS60::skipCbaUpdate()
// Note: Cannot use IsDisplayingMenuOrDialog since CBA update can be triggered before
// menu/dialog CBA is actually displayed i.e. it is being costructed.
CEikButtonGroupContainer *appUiCba = S60->buttonGroupContainer();
+ if (!appUiCba)
+ return true;
// CEikButtonGroupContainer::Current returns 0 if CBA is not visible at all
CEikButtonGroupContainer *currentCba = CEikButtonGroupContainer::Current();
// Check if softkey need to be update even they are not visible
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac.mm b/src/gui/kernel/qt_cocoa_helpers_mac.mm
index a05c7d5..8cef03c 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac.mm
+++ b/src/gui/kernel/qt_cocoa_helpers_mac.mm
@@ -1163,15 +1163,81 @@ void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::H
#endif
}
+#if QT_MAC_USE_COCOA
+void qt_mac_replaceDrawRect(void * /*OSWindowRef */window, QWidgetPrivate *widget)
+{
+ QMacCocoaAutoReleasePool pool;
+ OSWindowRef theWindow = static_cast<OSWindowRef>(window);
+ if(!theWindow)
+ return;
+ id theClass = [[[theWindow contentView] superview] class];
+ // What we do here is basically to add a new selector to NSThemeFrame called
+ // "drawRectOriginal:" which will contain the original implementation of
+ // "drawRect:". After that we get the new implementation from QCocoaWindow
+ // and exchange them. The new implementation is called drawRectSpecial.
+ // We cannot just add the method because it might have been added before and since
+ // we cannot remove a method once it has been added we need to ask QCocoaWindow if
+ // we did the swap or not.
+ if(!widget->drawRectOriginalAdded) {
+ Method m2 = class_getInstanceMethod(theClass, @selector(drawRect:));
+ if(!m2) {
+ // This case is pretty extreme, no drawRect means no drawing!
+ return;
+ }
+ class_addMethod(theClass, @selector(drawRectOriginal:), method_getImplementation(m2), method_getTypeEncoding(m2));
+ widget->drawRectOriginalAdded = true;
+ }
+ if(widget->originalDrawMethod) {
+ Method m0 = class_getInstanceMethod([theWindow class], @selector(drawRectSpecial:));
+ if(!m0) {
+ // Ok, this means the methods were never swapped. Just ignore
+ return;
+ }
+ Method m1 = class_getInstanceMethod(theClass, @selector(drawRect:));
+ if(!m1) {
+ // Ok, this means the methods were never swapped. Just ignore
+ return;
+ }
+ // We have the original method here. Proceed and swap the methods.
+ method_exchangeImplementations(m1, m0);
+ widget->originalDrawMethod = false;
+ [window display];
+ }
+}
+
+void qt_mac_replaceDrawRectOriginal(void * /*OSWindowRef */window, QWidgetPrivate *widget)
+{
+ QMacCocoaAutoReleasePool pool;
+ OSWindowRef theWindow = static_cast<OSWindowRef>(window);
+ id theClass = [[[theWindow contentView] superview] class];
+ // Now we need to revert the methods to their original state.
+ // We cannot remove the method, so we just keep track of it in QCocoaWindow.
+ Method m0 = class_getInstanceMethod([theWindow class], @selector(drawRectSpecial:));
+ if(!m0) {
+ // Ok, this means the methods were never swapped. Just ignore
+ return;
+ }
+ Method m1 = class_getInstanceMethod(theClass, @selector(drawRect:));
+ if(!m1) {
+ // Ok, this means the methods were never swapped. Just ignore
+ return;
+ }
+ method_exchangeImplementations(m1, m0);
+ widget->originalDrawMethod = true;
+ [window display];
+}
+#endif // QT_MAC_USE_COCOA
+
void qt_mac_showBaseLineSeparator(void * /*OSWindowRef */window, bool show)
{
+ if(!window)
+ return;
#if QT_MAC_USE_COCOA
QMacCocoaAutoReleasePool pool;
OSWindowRef theWindow = static_cast<OSWindowRef>(window);
NSToolbar *macToolbar = [theWindow toolbar];
- if (macToolbar)
- [macToolbar setShowsBaselineSeparator: show];
-#endif
+ [macToolbar setShowsBaselineSeparator:show];
+#endif // QT_MAC_USE_COCOA
}
QStringList qt_mac_NSArrayToQStringList(void *nsarray)
@@ -1233,6 +1299,17 @@ CGContextRef qt_mac_graphicsContextFor(QWidget *widget)
return context;
}
+void qt_mac_dispatchPendingUpdateRequests(QWidget *widget)
+{
+ if (!widget)
+ return;
+#ifndef QT_MAC_USE_COCOA
+ HIViewRender(qt_mac_nativeview_for(widget));
+#else
+ [qt_mac_nativeview_for(widget) displayIfNeeded];
+#endif
+}
+
CGFloat qt_mac_get_scalefactor()
{
#ifndef QT_MAC_USE_COCOA
@@ -1403,4 +1480,52 @@ void qt_mac_post_retranslateAppMenu()
#endif
}
+#ifdef QT_MAC_USE_COCOA
+// This method implements the magic for the drawRectSpecial method.
+// We draw a line at the upper edge of the content view in order to
+// override the title baseline.
+void macDrawRectOnTop(void * /*OSWindowRef */window)
+{
+ OSWindowRef theWindow = static_cast<OSWindowRef>(window);
+ NSView *contentView = [theWindow contentView];
+ if(!contentView)
+ return;
+ // Get coordinates of the content view
+ NSRect contentRect = [contentView frame];
+ // Draw a line on top of the already drawn line.
+ // We need to check if we are active or not to use the proper color.
+ if([window isKeyWindow] || [window isMainWindow]) {
+ [[NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0] set];
+ } else {
+ [[NSColor colorWithCalibratedRed:1.0 green:1.0 blue:1.0 alpha:1.0] set];
+ }
+ NSPoint origin = NSMakePoint(0, contentRect.size.height);
+ NSPoint end = NSMakePoint(contentRect.size.width, contentRect.size.height);
+ [NSBezierPath strokeLineFromPoint:origin toPoint:end];
+}
+
+// This method will (or at least should) get called only once.
+// Its mission is to find out if we are active or not. If we are active
+// we assume that we were launched via finder, otherwise we assume
+// we were called from the command line. The distinction is important,
+// since in the first case we don't need to trigger a paintEvent, while
+// in the second case we do.
+void macSyncDrawingOnFirstInvocation(void * /*OSWindowRef */window)
+{
+ OSWindowRef theWindow = static_cast<OSWindowRef>(window);
+ NSApplication *application = [NSApplication sharedApplication];
+ NSToolbar *toolbar = [window toolbar];
+ if([application isActive]) {
+ // Launched from finder
+ [toolbar setShowsBaselineSeparator:NO];
+ } else {
+ // Launched from commandline
+ [toolbar setVisible:false];
+ [toolbar setShowsBaselineSeparator:NO];
+ [toolbar setVisible:true];
+ [theWindow display];
+ }
+}
+#endif // QT_MAC_USE_COCOA
+
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qt_cocoa_helpers_mac_p.h b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
index 3fd62a4..5db121a 100644
--- a/src/gui/kernel/qt_cocoa_helpers_mac_p.h
+++ b/src/gui/kernel/qt_cocoa_helpers_mac_p.h
@@ -131,6 +131,8 @@ void macWindowSetHasShadow( void * /*OSWindowRef*/ window, bool hasShadow );
void macWindowFlush(void * /*OSWindowRef*/ window);
void macSendToolbarChangeEvent(QWidget *widget);
void qt_mac_updateContentBorderMetricts(void * /*OSWindowRef */window, const ::HIContentBorderMetrics &metrics);
+void qt_mac_replaceDrawRect(void * /*OSWindowRef */window, QWidgetPrivate *widget);
+void qt_mac_replaceDrawRectOriginal(void * /*OSWindowRef */window, QWidgetPrivate *widget);
void qt_mac_showBaseLineSeparator(void * /*OSWindowRef */window, bool show);
void * /*NSImage */qt_mac_create_nsimage(const QPixmap &pm);
void qt_mac_update_mouseTracking(QWidget *widget);
@@ -140,6 +142,9 @@ void qt_dispatchTabletProximityEvent(void * /*NSEvent * */ tabletEvent);
#ifdef QT_MAC_USE_COCOA
bool qt_dispatchKeyEventWithCocoa(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent);
void qt_cocoaChangeOverrideCursor(const QCursor &cursor);
+// These methods exists only for supporting unified mode.
+void macDrawRectOnTop(void * /*OSWindowRef */ window);
+void macSyncDrawingOnFirstInvocation(void * /*OSWindowRef */window);
#endif
void qt_mac_menu_collapseSeparators(void * /*NSMenu */ menu, bool collapse);
bool qt_dispatchKeyEvent(void * /*NSEvent * */ keyEvent, QWidget *widgetToGetEvent);
diff --git a/src/gui/kernel/qt_mac_p.h b/src/gui/kernel/qt_mac_p.h
index 7bfb257..3341ce1 100644
--- a/src/gui/kernel/qt_mac_p.h
+++ b/src/gui/kernel/qt_mac_p.h
@@ -57,6 +57,7 @@
#ifdef __OBJC__
#include <Cocoa/Cocoa.h>
+#include <objc/runtime.h>
#endif
#include <CoreServices/CoreServices.h>
diff --git a/src/gui/kernel/qt_s60_p.h b/src/gui/kernel/qt_s60_p.h
index a714221..58da302 100644
--- a/src/gui/kernel/qt_s60_p.h
+++ b/src/gui/kernel/qt_s60_p.h
@@ -155,7 +155,7 @@ class QLongTapTimer;
class QSymbianControl : public CCoeControl, public QAbstractLongTapObserver
#ifdef Q_WS_S60
-, public MAknFadedComponent
+, public MAknFadedComponent, public MEikStatusPaneObserver
#endif
{
public:
@@ -183,6 +183,7 @@ public:
#ifdef Q_WS_S60
void FadeBehindPopup(bool fade){ popupFader.FadeBehindPopup( this, this, fade); }
+ void HandleStatusPaneSizeChange();
protected: // from MAknFadedComponent
TInt CountFadedComponents() {return 1;}
diff --git a/src/gui/kernel/qwidget.cpp b/src/gui/kernel/qwidget.cpp
index 3a0f3c7..2c9730b 100644
--- a/src/gui/kernel/qwidget.cpp
+++ b/src/gui/kernel/qwidget.cpp
@@ -223,6 +223,11 @@ QWidgetPrivate::QWidgetPrivate(int version)
isWidget = true;
memset(high_attributes, 0, sizeof(high_attributes));
+#if QT_MAC_USE_COCOA
+ drawRectOriginalAdded = false;
+ originalDrawMethod = true;
+ changeMethods = false;
+#endif // QT_MAC_USE_COCOA
#ifdef QWIDGET_EXTRA_DEBUG
static int count = 0;
qDebug() << "widgets" << ++count;
@@ -7334,7 +7339,7 @@ void QWidgetPrivate::hide_helper()
bool isEmbedded = false;
#if !defined QT_NO_GRAPHICSVIEW
- isEmbedded = q->isWindow() && nearestGraphicsProxyWidget(q->parentWidget()) != 0;
+ isEmbedded = q->isWindow() && !bypassGraphicsProxyWidget(q) && nearestGraphicsProxyWidget(q->parentWidget()) != 0;
#else
Q_UNUSED(isEmbedded);
#endif
@@ -12349,6 +12354,28 @@ void QWidgetPrivate::_q_delayedDestroy(WId winId)
}
#endif
+#if QT_MAC_USE_COCOA
+void QWidgetPrivate::syncUnifiedMode() {
+ // The whole purpose of this method is to keep the unifiedToolbar in sync.
+ // That means making sure we either exchange the drawing methods or we let
+ // the toolbar know that it does not require to draw the baseline.
+ Q_Q(QWidget);
+ // This function makes sense only if this is a top level
+ if(!q->isWindow())
+ return;
+ OSWindowRef window = qt_mac_window_for(q);
+ if(changeMethods) {
+ // Ok, we are in documentMode.
+ if(originalDrawMethod)
+ qt_mac_replaceDrawRect(window, this);
+ } else {
+ if(!originalDrawMethod)
+ qt_mac_replaceDrawRectOriginal(window, this);
+ }
+}
+
+#endif // QT_MAC_USE_COCOA
+
QT_END_NAMESPACE
#include "moc_qwidget.cpp"
diff --git a/src/gui/kernel/qwidget_mac.mm b/src/gui/kernel/qwidget_mac.mm
index d7cd2eb..e29b755 100644
--- a/src/gui/kernel/qwidget_mac.mm
+++ b/src/gui/kernel/qwidget_mac.mm
@@ -2300,6 +2300,12 @@ void QWidgetPrivate::finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ voidWin
if (q->testAttribute(Qt::WA_DropSiteRegistered))
registerDropSite(true);
transferChildren();
+
+ // Tell Cocoa explicit that we wan't the view to receive key events
+ // (regardless of focus policy) because this is how it works on other
+ // platforms (and in the carbon port):
+ if (!qApp->focusWidget())
+ [windowRef makeFirstResponder:nsview];
}
if (topExtra->posFromMove) {
diff --git a/src/gui/kernel/qwidget_p.h b/src/gui/kernel/qwidget_p.h
index 1d79666..b5376a4 100644
--- a/src/gui/kernel/qwidget_p.h
+++ b/src/gui/kernel/qwidget_p.h
@@ -778,6 +778,13 @@ public:
void finishCreateWindow_sys_Cocoa(void * /*NSWindow * */ windowRef);
void syncCocoaMask();
void finishCocoaMaskSetup();
+ void syncUnifiedMode();
+ // Did we add the drawRectOriginal method?
+ bool drawRectOriginalAdded;
+ // Is the original drawRect method available?
+ bool originalDrawMethod;
+ // Do we need to change the methods?
+ bool changeMethods;
#endif
void determineWindowClass();
void transferChildren();
diff --git a/src/gui/kernel/qwidget_s60.cpp b/src/gui/kernel/qwidget_s60.cpp
index bfa7050..a0429d3 100644
--- a/src/gui/kernel/qwidget_s60.cpp
+++ b/src/gui/kernel/qwidget_s60.cpp
@@ -387,16 +387,7 @@ void QWidgetPrivate::create_sys(WId window, bool /* initializeWindow */, bool de
| EPointerFilterMove | EPointerFilterDrag, 0);
drawableWindow->EnableVisibilityChangeEvents();
- if (!isOpaque) {
- RWindow *const window = static_cast<RWindow *>(drawableWindow);
-#ifdef Q_SYMBIAN_SEMITRANSPARENT_BG_SURFACE
- window->SetSurfaceTransparency(true);
-#else
- const TDisplayMode displayMode = static_cast<TDisplayMode>(window->SetRequiredDisplayMode(EColor16MA));
- if (window->SetTransparencyAlphaChannel() == KErrNone)
- window->SetBackgroundColor(TRgb(255, 255, 255, 0));
-#endif
- }
+ s60UpdateIsOpaque();
}
q->setAttribute(Qt::WA_WState_Created);
@@ -488,6 +479,47 @@ void QWidgetPrivate::show_sys()
QSymbianControl *id = static_cast<QSymbianControl *>(q->internalWinId());
+#ifdef Q_WS_S60
+ // Lazily initialize the S60 screen furniture when the first window is shown.
+ if (!QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)
+ && !S60->buttonGroupContainer() && !S60->statusPane()) {
+
+ bool isFullscreen = q->windowState() & Qt::WindowFullScreen;
+ bool cbaRequested = q->windowFlags() & Qt::WindowSoftkeysVisibleHint;
+
+ // If the window is fullscreen and has not explicitly requested that the CBA be visible
+ // we delay the creation even more.
+ if ((!isFullscreen || cbaRequested) && !q->testAttribute(Qt::WA_DontShowOnScreen)) {
+
+ // Create the status pane and CBA here
+ CEikAppUi *ui = static_cast<CEikAppUi *>(S60->appUi());
+ MEikAppUiFactory *factory = CEikonEnv::Static()->AppUiFactory();
+ TRAP_IGNORE(factory->ReadAppInfoResourceL(0, ui));
+ if (S60->buttonGroupContainer())
+ S60->buttonGroupContainer()->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
+
+ if (S60->statusPane()) {
+ // Use QDesktopWidget as the status pane observer to proxy for the AppUi.
+ // Can't use AppUi directly because it privately inherits from MEikStatusPaneObserver.
+ QSymbianControl *desktopControl = static_cast<QSymbianControl *>(QApplication::desktop()->winId());
+ S60->statusPane()->SetObserver(desktopControl);
+
+ // Hide the status pane if fullscreen OR
+ // Fill client area if maximized OR
+ // Put window below status pane unless the window has an explicit position.
+ if (isFullscreen) {
+ S60->statusPane()->MakeVisible(false);
+ } else if (q->windowState() & Qt::WindowMaximized) {
+ TRect r = static_cast<CEikAppUi*>(S60->appUi())->ClientRect();
+ id->SetExtent(r.iTl, r.Size());
+ } else if (!q->testAttribute(Qt::WA_Moved)) {
+ id->SetPosition(static_cast<CEikAppUi*>(S60->appUi())->ClientRect().iTl);
+ }
+ }
+ }
+ }
+#endif
+
id->MakeVisible(true);
if(q->isWindow())
@@ -1063,6 +1095,9 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
return;
if (isWindow()) {
+ createWinId();
+ Q_ASSERT(testAttribute(Qt::WA_WState_Created));
+
const bool wasResized = testAttribute(Qt::WA_Resized);
const bool wasMoved = testAttribute(Qt::WA_Moved);
@@ -1088,35 +1123,35 @@ void QWidget::setWindowState(Qt::WindowStates newstate)
if (buttonGroup) {
// Visibility
buttonGroup->MakeVisible(visible || (isFullscreen && cbaRequested));
-
- // Responsiviness
- CEikCba *cba = static_cast<CEikCba *>( buttonGroup->ButtonGroup() ); // downcast from MEikButtonGroup
- TUint cbaFlags = cba->ButtonGroupFlags();
- if(windowFlags() & Qt::WindowSoftkeysRespondHint)
- cbaFlags |= EAknCBAFlagRespondWhenInvisible;
- else
- cbaFlags &= ~EAknCBAFlagRespondWhenInvisible;
- cba->SetButtonGroupFlags(cbaFlags);
}
#endif // Q_WS_S60
- createWinId();
- Q_ASSERT(testAttribute(Qt::WA_WState_Created));
// Ensure the initial size is valid, since we store it as normalGeometry below.
if (!wasResized && !isVisible())
adjustSize();
QTLWExtra *top = d->topData();
- const QRect normalGeometry = (top->normalGeometry.width() < 0) ? geometry() : top->normalGeometry;
-
+ QRect normalGeometry = (top->normalGeometry.width() < 0) ? geometry() : top->normalGeometry;
const bool cbaVisibilityHint = windowFlags() & Qt::WindowSoftkeysVisibleHint;
- if (newstate & Qt::WindowFullScreen && !cbaVisibilityHint)
- setGeometry(qApp->desktop()->screenGeometry(this));
- else if (newstate & Qt::WindowMaximized || ((newstate & Qt::WindowFullScreen) && cbaVisibilityHint))
- setGeometry(qApp->desktop()->availableGeometry(this));
- else
+ if (newstate & Qt::WindowFullScreen && !cbaVisibilityHint) {
+ window->SetExtentToWholeScreen();
+ } else if (newstate & Qt::WindowMaximized || ((newstate & Qt::WindowFullScreen) && cbaVisibilityHint)) {
+ TRect maxExtent = qt_QRect2TRect(qApp->desktop()->availableGeometry(this));
+ window->SetExtent(maxExtent.iTl, maxExtent.Size());
+ } else {
+#ifdef Q_WS_S60
+ // With delayed creation of S60 app panes, the normalGeometry calculated above is not
+ // accurate because it did not consider the status pane. This means that when returning
+ // normal mode after showing the status pane, the geometry would overlap so we should
+ // move it if it never had an explicit position.
+ if (!wasMoved && statusPane && visible) {
+ TPoint tl = static_cast<CEikAppUi*>(S60->appUi())->ClientRect().iTl;
+ normalGeometry.setTopLeft(QPoint(tl.iX, tl.iY));
+ }
+#endif
setGeometry(normalGeometry);
+ }
//restore normal geometry
top->normalGeometry = normalGeometry;
diff --git a/src/gui/painting/qbezier.cpp b/src/gui/painting/qbezier.cpp
index a08c79e..7ff2a37 100644
--- a/src/gui/painting/qbezier.cpp
+++ b/src/gui/painting/qbezier.cpp
@@ -612,88 +612,6 @@ give_up:
return o - curveSegments;
}
-#if 0
-static inline bool IntersectBB(const QBezier &a, const QBezier &b)
-{
- return a.bounds().intersects(b.bounds());
-}
-#else
-static int IntersectBB(const QBezier &a, const QBezier &b)
-{
- // Compute bounding box for a
- qreal minax, maxax, minay, maxay;
- if (a.x1 > a.x4) // These are the most likely to be extremal
- minax = a.x4, maxax = a.x1;
- else
- minax = a.x1, maxax = a.x4;
-
- if (a.x3 < minax)
- minax = a.x3;
- else if (a.x3 > maxax)
- maxax = a.x3;
-
- if (a.x2 < minax)
- minax = a.x2;
- else if (a.x2 > maxax)
- maxax = a.x2;
-
- if (a.y1 > a.y4)
- minay = a.y4, maxay = a.y1;
- else
- minay = a.y1, maxay = a.y4;
-
- if (a.y3 < minay)
- minay = a.y3;
- else if (a.y3 > maxay)
- maxay = a.y3;
-
- if (a.y2 < minay)
- minay = a.y2;
- else if (a.y2 > maxay)
- maxay = a.y2;
-
- // Compute bounding box for b
- qreal minbx, maxbx, minby, maxby;
- if (b.x1 > b.x4)
- minbx = b.x4, maxbx = b.x1;
- else
- minbx = b.x1, maxbx = b.x4;
-
- if (b.x3 < minbx)
- minbx = b.x3;
- else if (b.x3 > maxbx)
- maxbx = b.x3;
-
- if (b.x2 < minbx)
- minbx = b.x2;
- else if (b.x2 > maxbx)
- maxbx = b.x2;
-
- if (b.y1 > b.y4)
- minby = b.y4, maxby = b.y1;
- else
- minby = b.y1, maxby = b.y4;
-
- if (b.y3 < minby)
- minby = b.y3;
- else if (b.y3 > maxby)
- maxby = b.y3;
-
- if (b.y2 < minby)
- minby = b.y2;
- else if (b.y2 > maxby)
- maxby = b.y2;
-
- // Test bounding box of b against bounding box of a
- if ((minax > maxbx) || (minay > maxby) // Not >= : need boundary case
- || (minbx > maxax) || (minby > maxay))
- return 0; // they don't intersect
- else
- return 1; // they intersect
-}
-#endif
-
-
#ifdef QDEBUG_BEZIER
static QDebug operator<<(QDebug dbg, const QBezier &bz)
{
@@ -705,193 +623,6 @@ static QDebug operator<<(QDebug dbg, const QBezier &bz)
}
#endif
-static bool RecursivelyIntersect(const QBezier &a, qreal t0, qreal t1, int deptha,
- const QBezier &b, qreal u0, qreal u1, int depthb,
- QVector<QPair<qreal, qreal> > *t)
-{
-#ifdef QDEBUG_BEZIER
- static int I = 0;
- int currentD = I;
- fprintf(stderr, "%d) t0 = %lf, t1 = %lf, deptha = %d\n"
- "u0 = %lf, u1 = %lf, depthb = %d\n", I++, t0, t1, deptha,
- u0, u1, depthb);
-#endif
- if (deptha > 0) {
- QBezier A[2];
- a.split(&A[0], &A[1]);
- qreal tmid = (t0+t1)*0.5;
- //qDebug()<<"\t1)"<<A[0];
- //qDebug()<<"\t2)"<<A[1];
- deptha--;
- if (depthb > 0) {
- QBezier B[2];
- b.split(&B[0], &B[1]);
- //qDebug()<<"\t3)"<<B[0];
- //qDebug()<<"\t4)"<<B[1];
- qreal umid = (u0+u1)*0.5;
- depthb--;
- if (IntersectBB(A[0], B[0])) {
- //fprintf(stderr, "\t 1 from %d\n", currentD);
- if (RecursivelyIntersect(A[0], t0, tmid, deptha,
- B[0], u0, umid, depthb,
- t) && !t)
- return true;
- }
- if (IntersectBB(A[1], B[0])) {
- //fprintf(stderr, "\t 2 from %d\n", currentD);
- if (RecursivelyIntersect(A[1], tmid, t1, deptha,
- B[0], u0, umid, depthb,
- t) && !t)
- return true;
- }
- if (IntersectBB(A[0], B[1])) {
- //fprintf(stderr, "\t 3 from %d\n", currentD);
- if (RecursivelyIntersect(A[0], t0, tmid, deptha,
- B[1], umid, u1, depthb,
- t) && !t)
- return true;
- }
- if (IntersectBB(A[1], B[1])) {
- //fprintf(stderr, "\t 4 from %d\n", currentD);
- if (RecursivelyIntersect(A[1], tmid, t1, deptha,
- B[1], umid, u1, depthb,
- t) && !t)
- return true;
- }
- return t ? !t->isEmpty() : false;
- } else {
- if (IntersectBB(A[0], b)) {
- //fprintf(stderr, "\t 5 from %d\n", currentD);
- if (RecursivelyIntersect(A[0], t0, tmid, deptha,
- b, u0, u1, depthb,
- t) && !t)
- return true;
- }
- if (IntersectBB(A[1], b)) {
- //fprintf(stderr, "\t 6 from %d\n", currentD);
- if (RecursivelyIntersect(A[1], tmid, t1, deptha,
- b, u0, u1, depthb,
- t) && !t)
- return true;
- }
- return t ? !t->isEmpty() : false;
- }
- } else {
- if (depthb > 0) {
- QBezier B[2];
- b.split(&B[0], &B[1]);
- qreal umid = (u0 + u1)*0.5;
- depthb--;
- if (IntersectBB(a, B[0])) {
- //fprintf(stderr, "\t 7 from %d\n", currentD);
- if (RecursivelyIntersect(a, t0, t1, deptha,
- B[0], u0, umid, depthb,
- t) && !t)
- return true;
- }
- if (IntersectBB(a, B[1])) {
- //fprintf(stderr, "\t 8 from %d\n", currentD);
- if (RecursivelyIntersect(a, t0, t1, deptha,
- B[1], umid, u1, depthb,
- t) && !t)
- return true;
- }
- return t ? !t->isEmpty() : false;
- }
- else {
- // Both segments are fully subdivided; now do line segments
- qreal xlk = a.x4 - a.x1;
- qreal ylk = a.y4 - a.y1;
- qreal xnm = b.x4 - b.x1;
- qreal ynm = b.y4 - b.y1;
- qreal xmk = b.x1 - a.x1;
- qreal ymk = b.y1 - a.y1;
- qreal det = xnm * ylk - ynm * xlk;
- if (1.0 + det == 1.0) {
- return false;
- } else {
- qreal detinv = 1.0 / det;
- qreal rs = (xnm * ymk - ynm *xmk) * detinv;
- qreal rt = (xlk * ymk - ylk * xmk) * detinv;
- if ((rs < 0.0) || (rs > 1.0) || (rt < 0.0) || (rt > 1.0))
- return false;
-
- if (t) {
- const qreal alpha_a = t0 + rs * (t1 - t0);
- const qreal alpha_b = u0 + rt * (u1 - u0);
-
- *t << qMakePair(alpha_a, alpha_b);
- }
-
- return true;
- }
- }
- }
-}
-
-QVector< QPair<qreal, qreal> > QBezier::findIntersections(const QBezier &a, const QBezier &b)
-{
- QVector< QPair<qreal, qreal> > v(2);
- findIntersections(a, b, &v);
- return v;
-}
-
-bool QBezier::findIntersections(const QBezier &a, const QBezier &b,
- QVector<QPair<qreal, qreal> > *t)
-{
- if (IntersectBB(a, b)) {
- QPointF la1(qFabs((a.x3 - a.x2) - (a.x2 - a.x1)),
- qFabs((a.y3 - a.y2) - (a.y2 - a.y1)));
- QPointF la2(qFabs((a.x4 - a.x3) - (a.x3 - a.x2)),
- qFabs((a.y4 - a.y3) - (a.y3 - a.y2)));
- QPointF la;
- if (la1.x() > la2.x()) la.setX(la1.x()); else la.setX(la2.x());
- if (la1.y() > la2.y()) la.setY(la1.y()); else la.setY(la2.y());
- QPointF lb1(qFabs((b.x3 - b.x2) - (b.x2 - b.x1)),
- qFabs((b.y3 - b.y2) - (b.y2 - b.y1)));
- QPointF lb2(qFabs((b.x4 - b.x3) - (b.x3 - b.x2)),
- qFabs((b.y4 - b.y3) - (b.y3 - b.y2)));
- QPointF lb;
- if (lb1.x() > lb2.x()) lb.setX(lb1.x()); else lb.setX(lb2.x());
- if (lb1.y() > lb2.y()) lb.setY(lb1.y()); else lb.setY(lb2.y());
- qreal l0;
- if (la.x() > la.y())
- l0 = la.x();
- else
- l0 = la.y();
- int ra;
- if (l0 * 0.75 * M_SQRT2 + 1.0 == 1.0)
- ra = 0;
- else
- ra = qCeil(log4(M_SQRT2 * 6.0 / 8.0 * INV_EPS * l0));
- if (lb.x() > lb.y())
- l0 = lb.x();
- else
- l0 = lb.y();
- int rb;
- if (l0 * 0.75 * M_SQRT2 + 1.0 == 1.0)
- rb = 0;
- else
- rb = qCeil(log4(M_SQRT2 * 6.0 / 8.0 * INV_EPS * l0));
-
- // if qreal is float then halve the number of subdivisions
- if (sizeof(qreal) == 4) {
- ra /= 2;
- rb /= 2;
- }
-
- return RecursivelyIntersect(a, 0., 1., ra, b, 0., 1., rb, t);
- }
-
- //Don't sort here because it breaks the orders of corresponding
- // intersections points. this way t's at the same locations correspond
- // to the same intersection point.
- //qSort(parameters[0].begin(), parameters[0].end(), qLess<qreal>());
- //qSort(parameters[1].begin(), parameters[1].end(), qLess<qreal>());
-
- return false;
-}
-
static inline void splitBezierAt(const QBezier &bez, qreal t,
QBezier *left, QBezier *right)
{
@@ -920,42 +651,6 @@ static inline void splitBezierAt(const QBezier &bez, qreal t,
right->y4 = bez.y4;
}
-QVector< QList<QBezier> > QBezier::splitAtIntersections(QBezier &b)
-{
- QVector< QList<QBezier> > curves(2);
-
- QVector< QPair<qreal, qreal> > allInters = findIntersections(*this, b);
-
- QList<qreal> inters1;
- QList<qreal> inters2;
-
- for (int i = 0; i < allInters.size(); ++i) {
- inters1 << allInters[i].first;
- inters2 << allInters[i].second;
- }
-
- qSort(inters1.begin(), inters1.end(), qLess<qreal>());
- qSort(inters2.begin(), inters2.end(), qLess<qreal>());
-
- Q_ASSERT(inters1.count() == inters2.count());
-
- int i;
- for (i = 0; i < inters1.count(); ++i) {
- qreal t1 = inters1.at(i);
- qreal t2 = inters2.at(i);
-
- QBezier curve1, curve2;
- parameterSplitLeft(t1, &curve1);
- b.parameterSplitLeft(t2, &curve2);
- curves[0].append(curve1);
- curves[0].append(curve2);
- }
- curves[0].append(*this);
- curves[1].append(b);
-
- return curves;
-}
-
qreal QBezier::length(qreal error) const
{
qreal length = 0.0;
diff --git a/src/gui/painting/qbezier_p.h b/src/gui/painting/qbezier_p.h
index f015ea8..846635f 100644
--- a/src/gui/painting/qbezier_p.h
+++ b/src/gui/painting/qbezier_p.h
@@ -111,16 +111,7 @@ public:
int shifted(QBezier *curveSegments, int maxSegmets,
qreal offset, float threshold) const;
- QVector< QList<QBezier> > splitAtIntersections(QBezier &a);
-
QBezier bezierOnInterval(qreal t0, qreal t1) const;
-
- static QVector< QPair<qreal, qreal> > findIntersections(const QBezier &a,
- const QBezier &b);
-
- static bool findIntersections(const QBezier &a, const QBezier &b,
- QVector<QPair<qreal, qreal> > *t);
-
QBezier getSubRange(qreal t0, qreal t1) const;
qreal x1, y1, x2, y2, x3, y3, x4, y4;
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index b440fce..bfa1136 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -674,6 +674,11 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
int image_width = data->texture.width;
int image_height = data->texture.height;
+ int image_x1 = data->texture.x1;
+ int image_y1 = data->texture.y1;
+ int image_x2 = data->texture.x2;
+ int image_y2 = data->texture.y2;
+
const qreal cx = x + 0.5;
const qreal cy = y + 0.5;
@@ -708,17 +713,17 @@ const uint * QT_FASTCALL fetchTransformedBilinear(uint *buffer, const Operator *
y2 = y1 + 1;
y2 %= image_height;
} else {
- if (x1 < 0) {
- x2 = x1 = 0;
- } else if (x1 >= image_width - 1) {
- x2 = x1 = image_width - 1;
+ if (x1 < image_x1) {
+ x2 = x1 = image_x1;
+ } else if (x1 >= image_x2 - 1) {
+ x2 = x1 = image_x2 - 1;
} else {
x2 = x1 + 1;
}
- if (y1 < 0) {
- y2 = y1 = 0;
- } else if (y1 >= image_height - 1) {
- y2 = y1 = image_height - 1;
+ if (y1 < image_y1) {
+ y2 = y1 = image_y1;
+ } else if (y1 >= image_y2 - 1) {
+ y2 = y1 = image_y2 - 1;
} else {
y2 = y1 + 1;
}
diff --git a/src/gui/painting/qgraphicssystemfactory.cpp b/src/gui/painting/qgraphicssystemfactory.cpp
index 29f24a3..3c09894 100644
--- a/src/gui/painting/qgraphicssystemfactory.cpp
+++ b/src/gui/painting/qgraphicssystemfactory.cpp
@@ -50,7 +50,7 @@
QT_BEGIN_NAMESPACE
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QGraphicsSystemFactoryInterface_iid, QLatin1String("/graphicssystems"), Qt::CaseInsensitive))
#endif
@@ -79,7 +79,7 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key)
else if (system.isEmpty() || system == QLatin1String("native"))
return 0;
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
if (!ret) {
if (QGraphicsSystemFactoryInterface *factory = qobject_cast<QGraphicsSystemFactoryInterface*>(loader()->instance(system)))
ret = factory->create(system);
@@ -100,7 +100,7 @@ QGraphicsSystem *QGraphicsSystemFactory::create(const QString& key)
*/
QStringList QGraphicsSystemFactory::keys()
{
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
QStringList list = loader()->keys();
#else
QStringList list;
diff --git a/src/gui/painting/qpaintengine_mac.cpp b/src/gui/painting/qpaintengine_mac.cpp
index ac2fcf4..14ba94e 100644
--- a/src/gui/painting/qpaintengine_mac.cpp
+++ b/src/gui/painting/qpaintengine_mac.cpp
@@ -118,9 +118,10 @@ QMacCGContext::QMacCGContext(QPainter *p)
QRegion clip = p->paintEngine()->systemClip();
QTransform native = p->deviceTransform();
QTransform logical = p->combinedTransform();
+
if (p->hasClipping()) {
QRegion r = p->clipRegion();
- r.translate(native.dx() - logical.dx(), native.dy() - logical.dy());
+ r.translate(native.dx(), native.dy());
if (clip.isEmpty())
clip = r;
else
@@ -128,10 +129,7 @@ QMacCGContext::QMacCGContext(QPainter *p)
}
qt_mac_clip_cg(context, clip, 0);
- QPainterState *state = static_cast<QPainterState *>(pe->state);
- Q_ASSERT(state);
- if (!state->redirectionMatrix.isIdentity())
- CGContextTranslateCTM(context, state->redirectionMatrix.dx(), state->redirectionMatrix.dy());
+ CGContextTranslateCTM(context, native.dx(), native.dy());
}
}
CGContextRetain(context);
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index d734deb..6afa4e1 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -2554,7 +2554,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
int sr_t = qFloor(sr.top());
int sr_b = qCeil(sr.bottom()) - 1;
- if (!s->flags.antialiased && sr_l == sr_r && sr_t == sr_b) {
+ if (s->matrix.type() <= QTransform::TxScale && !s->flags.antialiased && sr_l == sr_r && sr_t == sr_b) {
// as fillRect will apply the aliased coordinate delta we need to
// subtract it here as we don't use it for image drawing
QTransform old = s->matrix;
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index 9366513..a78cafb 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -974,6 +974,9 @@ void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, con
void QPaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount,
const QPixmap &pixmap, QPainter::PixmapFragmentHints /*hints*/)
{
+ if (pixmap.isNull())
+ return;
+
qreal oldOpacity = state()->opacity;
QTransform oldTransform = state()->matrix;
diff --git a/src/gui/painting/qpainterpath.cpp b/src/gui/painting/qpainterpath.cpp
index f78de34..f5a698e 100644
--- a/src/gui/painting/qpainterpath.cpp
+++ b/src/gui/painting/qpainterpath.cpp
@@ -1914,7 +1914,7 @@ static bool qt_painterpath_check_crossing(const QPainterPath *path, const QRectF
case QPainterPath::MoveToElement:
if (i > 0
- && qFuzzyCompare(last_pt.x(), last_start.y())
+ && qFuzzyCompare(last_pt.x(), last_start.x())
&& qFuzzyCompare(last_pt.y(), last_start.y())
&& qt_painterpath_isect_line_rect(last_pt.x(), last_pt.y(),
last_start.x(), last_start.y(), rect))
@@ -3167,6 +3167,8 @@ void QPainterPath::addRoundRect(const QRectF &r, int xRnd, int yRnd)
Set operations on paths will treat the paths as areas. Non-closed
paths will be treated as implicitly closed.
+ Bezier curves may be flattened to line segments due to numerical instability of
+ doing bezier curve intersections.
\sa intersected(), subtracted()
*/
@@ -3182,6 +3184,8 @@ QPainterPath QPainterPath::united(const QPainterPath &p) const
\since 4.3
Returns a path which is the intersection of this path's fill area and \a p's fill area.
+ Bezier curves may be flattened to line segments due to numerical instability of
+ doing bezier curve intersections.
*/
QPainterPath QPainterPath::intersected(const QPainterPath &p) const
{
@@ -3198,7 +3202,8 @@ QPainterPath QPainterPath::intersected(const QPainterPath &p) const
Set operations on paths will treat the paths as areas. Non-closed
paths will be treated as implicitly closed.
-
+ Bezier curves may be flattened to line segments due to numerical instability of
+ doing bezier curve intersections.
*/
QPainterPath QPainterPath::subtracted(const QPainterPath &p) const
{
@@ -3227,6 +3232,8 @@ QPainterPath QPainterPath::subtractedInverted(const QPainterPath &p) const
Returns a simplified version of this path. This implies merging all subpaths that intersect,
and returning a path containing no intersecting edges. Consecutive parallel lines will also
be merged. The simplified path will always use the default fill rule, Qt::OddEvenFill.
+ Bezier curves may be flattened to line segments due to numerical instability of
+ doing bezier curve intersections.
*/
QPainterPath QPainterPath::simplified() const
{
diff --git a/src/gui/painting/qpathclipper.cpp b/src/gui/painting/qpathclipper.cpp
index 00e74ba..c910024 100644
--- a/src/gui/painting/qpathclipper.cpp
+++ b/src/gui/painting/qpathclipper.cpp
@@ -43,6 +43,7 @@
#include <private/qbezier_p.h>
#include <private/qdatabuffer_p.h>
+#include <private/qnumeric_p.h>
#include <qmath.h>
/**
@@ -105,22 +106,9 @@ public:
bool hasIntersections(const QPathSegments &a, const QPathSegments &b) const;
private:
- void intersectBeziers(const QBezier &one, const QBezier &two, QVector<QPair<qreal, qreal> > &t, QDataBuffer<QIntersection> &intersections);
- void intersectLines(const QLineF &a, const QLineF &b, QDataBuffer<QIntersection> &intersections);
-
- bool beziersIntersect(const QBezier &one, const QBezier &two) const;
bool linesIntersect(const QLineF &a, const QLineF &b) const;
};
-bool QIntersectionFinder::beziersIntersect(const QBezier &one, const QBezier &two) const
-{
- return (comparePoints(one.pt1(), two.pt1()) && comparePoints(one.pt2(), two.pt2())
- && comparePoints(one.pt3(), two.pt3()) && comparePoints(one.pt4(), two.pt4()))
- || (comparePoints(one.pt1(), two.pt4()) && comparePoints(one.pt2(), two.pt3())
- && comparePoints(one.pt3(), two.pt2()) && comparePoints(one.pt4(), two.pt1()))
- || QBezier::findIntersections(one, two, 0);
-}
-
bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const
{
const QPointF p1 = a.p1();
@@ -174,11 +162,6 @@ bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const
return false;
}
- // if the lines are not parallel and share a common end point, then they
- // don't intersect
- if (p1_equals_q1 || p1_equals_q2 || p2_equals_q1 || p2_equals_q2)
- return false;
-
const qreal invPar = 1 / par;
const qreal tp = (qDelta.y() * (q1.x() - p1.x()) -
@@ -193,49 +176,223 @@ bool QIntersectionFinder::linesIntersect(const QLineF &a, const QLineF &b) const
return tq >= 0 && tq <= 1;
}
-void QIntersectionFinder::intersectBeziers(const QBezier &one, const QBezier &two, QVector<QPair<qreal, qreal> > &t, QDataBuffer<QIntersection> &intersections)
+bool QIntersectionFinder::hasIntersections(const QPathSegments &a, const QPathSegments &b) const
{
- if ((comparePoints(one.pt1(), two.pt1()) && comparePoints(one.pt2(), two.pt2())
- && comparePoints(one.pt3(), two.pt3()) && comparePoints(one.pt4(), two.pt4()))
- || (comparePoints(one.pt1(), two.pt4()) && comparePoints(one.pt2(), two.pt3())
- && comparePoints(one.pt3(), two.pt2()) && comparePoints(one.pt4(), two.pt1()))) {
+ if (a.segments() == 0 || b.segments() == 0)
+ return false;
- return;
+ const QRectF &rb0 = b.elementBounds(0);
+
+ qreal minX = rb0.left();
+ qreal minY = rb0.top();
+ qreal maxX = rb0.right();
+ qreal maxY = rb0.bottom();
+
+ for (int i = 1; i < b.segments(); ++i) {
+ const QRectF &r = b.elementBounds(i);
+ minX = qMin(minX, r.left());
+ minY = qMin(minY, r.top());
+ maxX = qMax(maxX, r.right());
+ maxY = qMax(maxY, r.bottom());
}
- t.clear();
+ QRectF rb(minX, minY, maxX - minX, maxY - minY);
- if (!QBezier::findIntersections(one, two, &t))
- return;
+ for (int i = 0; i < a.segments(); ++i) {
+ const QRectF &r1 = a.elementBounds(i);
- int count = t.size();
-
- for (int i = 0; i < count; ++i) {
- qreal alpha_p = t.at(i).first;
- qreal alpha_q = t.at(i).second;
-
- QPointF pt;
- if (qFuzzyIsNull(alpha_p)) {
- pt = one.pt1();
- } else if (qFuzzyIsNull(alpha_p - 1)) {
- pt = one.pt4();
- } else if (qFuzzyIsNull(alpha_q)) {
- pt = two.pt1();
- } else if (qFuzzyIsNull(alpha_q - 1)) {
- pt = two.pt4();
- } else {
- pt = one.pointAt(alpha_p);
+ if (r1.left() > rb.right() || rb.left() > r1.right())
+ continue;
+ if (r1.top() > rb.bottom() || rb.top() > r1.bottom())
+ continue;
+
+ for (int j = 0; j < b.segments(); ++j) {
+ const QRectF &r2 = b.elementBounds(j);
+
+ if (r1.left() > r2.right() || r2.left() > r1.right())
+ continue;
+ if (r1.top() > r2.bottom() || r2.top() > r1.bottom())
+ continue;
+
+ if (linesIntersect(a.lineAt(i), b.lineAt(j)))
+ return true;
}
+ }
- QIntersection intersection;
- intersection.alphaA = alpha_p;
- intersection.alphaB = alpha_q;
- intersection.pos = pt;
- intersections.add(intersection);
+ return false;
+}
+
+namespace {
+struct TreeNode
+{
+ qreal splitLeft;
+ qreal splitRight;
+ bool leaf;
+
+ int lowestLeftIndex;
+ int lowestRightIndex;
+
+ union {
+ struct {
+ int first;
+ int last;
+ } interval;
+ struct {
+ int left;
+ int right;
+ } children;
+ } index;
+};
+
+struct RectF
+{
+ qreal x1;
+ qreal y1;
+ qreal x2;
+ qreal y2;
+};
+
+class SegmentTree
+{
+public:
+ SegmentTree(QPathSegments &segments);
+
+ QRectF boundingRect() const;
+
+ void produceIntersections(int segment);
+
+private:
+ TreeNode buildTree(int first, int last, int depth, const RectF &bounds);
+
+ void produceIntersectionsLeaf(const TreeNode &node, int segment);
+ void produceIntersections(const TreeNode &node, int segment, const RectF &segmentBounds, const RectF &nodeBounds, int axis);
+ void intersectLines(const QLineF &a, const QLineF &b, QDataBuffer<QIntersection> &intersections);
+
+ QPathSegments &m_segments;
+ QVector<int> m_index;
+
+ RectF m_bounds;
+
+ QVector<TreeNode> m_tree;
+ QDataBuffer<QIntersection> m_intersections;
+};
+
+SegmentTree::SegmentTree(QPathSegments &segments)
+ : m_segments(segments)
+{
+ m_bounds.x1 = qt_inf();
+ m_bounds.y1 = qt_inf();
+ m_bounds.x2 = -qt_inf();
+ m_bounds.y2 = -qt_inf();
+
+ m_index.resize(m_segments.segments());
+
+ for (int i = 0; i < m_index.size(); ++i) {
+ m_index[i] = i;
+
+ const QRectF &segmentBounds = m_segments.elementBounds(i);
+
+ if (segmentBounds.left() < m_bounds.x1)
+ m_bounds.x1 = segmentBounds.left();
+ if (segmentBounds.top() < m_bounds.y1)
+ m_bounds.y1 = segmentBounds.top();
+ if (segmentBounds.right() > m_bounds.x2)
+ m_bounds.x2 = segmentBounds.right();
+ if (segmentBounds.bottom() > m_bounds.y2)
+ m_bounds.y2 = segmentBounds.bottom();
}
+
+ m_tree.resize(1);
+
+ TreeNode root = buildTree(0, m_index.size(), 0, m_bounds);
+ m_tree[0] = root;
+}
+
+QRectF SegmentTree::boundingRect() const
+{
+ return QRectF(QPointF(m_bounds.x1, m_bounds.y1),
+ QPointF(m_bounds.x2, m_bounds.y2));
+}
+
+static inline qreal coordinate(const QPointF &pos, int axis)
+{
+ return axis == 0 ? pos.x() : pos.y();
}
-void QIntersectionFinder::intersectLines(const QLineF &a, const QLineF &b, QDataBuffer<QIntersection> &intersections)
+TreeNode SegmentTree::buildTree(int first, int last, int depth, const RectF &bounds)
+{
+ if (depth >= 24 || (last - first) <= 10) {
+ TreeNode node;
+ node.leaf = true;
+ node.index.interval.first = first;
+ node.index.interval.last = last;
+
+ return node;
+ }
+
+ int splitAxis = (depth & 1);
+
+ TreeNode node;
+ node.leaf = false;
+
+ qreal split = 0.5f * ((&bounds.x1)[splitAxis] + (&bounds.x2)[splitAxis]);
+
+ node.splitLeft = (&bounds.x1)[splitAxis];
+ node.splitRight = (&bounds.x2)[splitAxis];
+
+ node.lowestLeftIndex = INT_MAX;
+ node.lowestRightIndex = INT_MAX;
+
+ const int treeSize = m_tree.size();
+
+ node.index.children.left = treeSize;
+ node.index.children.right = treeSize + 1;
+
+ m_tree.resize(treeSize + 2);
+
+ int l = first;
+ int r = last - 1;
+
+ // partition into left and right sets
+ while (l <= r) {
+ const int index = m_index.at(l);
+ const QRectF &segmentBounds = m_segments.elementBounds(index);
+
+ qreal lowCoordinate = coordinate(segmentBounds.topLeft(), splitAxis);
+
+ if (coordinate(segmentBounds.center(), splitAxis) < split) {
+ qreal highCoordinate = coordinate(segmentBounds.bottomRight(), splitAxis);
+ if (highCoordinate > node.splitLeft)
+ node.splitLeft = highCoordinate;
+ if (index < node.lowestLeftIndex)
+ node.lowestLeftIndex = index;
+ ++l;
+ } else {
+ if (lowCoordinate < node.splitRight)
+ node.splitRight = lowCoordinate;
+ if (index < node.lowestRightIndex)
+ node.lowestRightIndex = index;
+ qSwap(m_index[l], m_index[r]);
+ --r;
+ }
+ }
+
+ RectF lbounds = bounds;
+ (&lbounds.x2)[splitAxis] = node.splitLeft;
+
+ RectF rbounds = bounds;
+ (&rbounds.x1)[splitAxis] = node.splitRight;
+
+ TreeNode left = buildTree(first, l, depth + 1, lbounds);
+ m_tree[node.index.children.left] = left;
+
+ TreeNode right = buildTree(l, last, depth + 1, rbounds);
+ m_tree[node.index.children.right] = right;
+
+ return node;
+}
+
+void SegmentTree::intersectLines(const QLineF &a, const QLineF &b, QDataBuffer<QIntersection> &intersections)
{
const QPointF p1 = a.p1();
const QPointF p2 = a.p2();
@@ -357,149 +514,86 @@ void QIntersectionFinder::intersectLines(const QLineF &a, const QLineF &b, QData
intersections.add(intersection);
}
-static const QBezier bezierFromLine(const QLineF &line)
+void SegmentTree::produceIntersections(int segment)
{
- const QPointF p1 = line.p1();
- const QPointF p2 = line.p2();
- const QPointF delta = (p2 - p1) / 3;
- return QBezier::fromPoints(p1, p1 + delta, p1 + 2 * delta, p2);
-}
-
-bool QIntersectionFinder::hasIntersections(const QPathSegments &a, const QPathSegments &b) const
-{
- QBezier tempA;
- QBezier tempB;
-
- if (a.segments() == 0 || b.segments() == 0)
- return false;
+ const QRectF &segmentBounds = m_segments.elementBounds(segment);
- const QRectF &rb0 = b.elementBounds(0);
-
- qreal minX = rb0.left();
- qreal minY = rb0.top();
- qreal maxX = rb0.right();
- qreal maxY = rb0.bottom();
+ RectF sbounds;
+ sbounds.x1 = segmentBounds.left();
+ sbounds.y1 = segmentBounds.top();
+ sbounds.x2 = segmentBounds.right();
+ sbounds.y2 = segmentBounds.bottom();
- for (int i = 1; i < b.segments(); ++i) {
- const QRectF &r = b.elementBounds(i);
- minX = qMin(minX, r.left());
- minY = qMin(minY, r.top());
- maxX = qMax(maxX, r.right());
- maxY = qMax(maxY, r.bottom());
- }
+ produceIntersections(m_tree.at(0), segment, sbounds, m_bounds, 0);
+}
- QRectF rb(minX, minY, maxX - minX, maxY - minY);
+void SegmentTree::produceIntersectionsLeaf(const TreeNode &node, int segment)
+{
+ const QRectF &r1 = m_segments.elementBounds(segment);
+ const QLineF lineA = m_segments.lineAt(segment);
- for (int i = 0; i < a.segments(); ++i) {
- const QBezier *bezierA = a.bezierAt(i);
- bool isBezierA = bezierA != 0;
+ for (int i = node.index.interval.first; i < node.index.interval.last; ++i) {
+ const int other = m_index.at(i);
+ if (other >= segment)
+ continue;
- const QRectF &r1 = a.elementBounds(i);
+ const QRectF &r2 = m_segments.elementBounds(other);
- if (r1.left() > rb.right() || rb.left() > r1.right())
+ if (r1.left() > r2.right() || r2.left() > r1.right())
continue;
- if (r1.top() > rb.bottom() || rb.top() > r1.bottom())
+ if (r1.top() > r2.bottom() || r2.top() > r1.bottom())
continue;
- for (int j = 0; j < b.segments(); ++j) {
- const QRectF &r2 = b.elementBounds(j);
+ m_intersections.reset();
- if (r1.left() > r2.right() || r2.left() > r1.right())
- continue;
- if (r1.top() > r2.bottom() || r2.top() > r1.bottom())
- continue;
+ const QLineF lineB = m_segments.lineAt(other);
- bool isBezierB = b.bezierAt(j) != 0;
+ intersectLines(lineA, lineB, m_intersections);
- if (isBezierA || isBezierB) {
- const QBezier *bezierB;
- if (isBezierB) {
- bezierB = b.bezierAt(j);
- } else {
- tempB = bezierFromLine(b.lineAt(j));
- bezierB = &tempB;
- }
+ for (int k = 0; k < m_intersections.size(); ++k) {
+ QPathSegments::Intersection i_isect, j_isect;
+ i_isect.vertex = j_isect.vertex = m_segments.addPoint(m_intersections.at(k).pos);
- if (!bezierA) {
- tempA = bezierFromLine(a.lineAt(i));
- bezierA = &tempA;
- }
+ i_isect.t = m_intersections.at(k).alphaA;
+ j_isect.t = m_intersections.at(k).alphaB;
- if (beziersIntersect(*bezierA, *bezierB))
- return true;
- } else {
- if (linesIntersect(a.lineAt(i), b.lineAt(j)))
- return true;
- }
+ i_isect.next = 0;
+ j_isect.next = 0;
+
+ m_segments.addIntersection(segment, i_isect);
+ m_segments.addIntersection(other, j_isect);
}
}
-
- return false;
}
-void QIntersectionFinder::produceIntersections(QPathSegments &segments)
+void SegmentTree::produceIntersections(const TreeNode &node, int segment, const RectF &segmentBounds, const RectF &nodeBounds, int axis)
{
- QBezier tempA;
- QBezier tempB;
-
- QVector<QPair<qreal, qreal> > t;
- QDataBuffer<QIntersection> intersections;
-
- for (int i = 0; i < segments.segments(); ++i) {
- const QBezier *bezierA = segments.bezierAt(i);
- bool isBezierA = bezierA != 0;
-
- const QRectF &r1 = segments.elementBounds(i);
-
- for (int j = 0; j < i; ++j) {
- const QRectF &r2 = segments.elementBounds(j);
-
- if (r1.left() > r2.right() || r2.left() > r1.right())
- continue;
- if (r1.top() > r2.bottom() || r2.top() > r1.bottom())
- continue;
+ if (node.leaf) {
+ produceIntersectionsLeaf(node, segment);
+ return;
+ }
- intersections.reset();
+ RectF lbounds = nodeBounds;
+ (&lbounds.x2)[axis] = node.splitLeft;
- bool isBezierB = segments.bezierAt(j) != 0;
+ RectF rbounds = nodeBounds;
+ (&rbounds.x1)[axis] = node.splitRight;
- if (isBezierA || isBezierB) {
- const QBezier *bezierB;
- if (isBezierB) {
- bezierB = segments.bezierAt(j);
- } else {
- tempB = bezierFromLine(segments.lineAt(j));
- bezierB = &tempB;
- }
+ if (segment > node.lowestLeftIndex && (&segmentBounds.x1)[axis] <= node.splitLeft)
+ produceIntersections(m_tree.at(node.index.children.left), segment, segmentBounds, lbounds, !axis);
- if (!bezierA) {
- tempA = bezierFromLine(segments.lineAt(i));
- bezierA = &tempA;
- }
-
- intersectBeziers(*bezierA, *bezierB, t, intersections);
- } else {
- const QLineF lineA = segments.lineAt(i);
- const QLineF lineB = segments.lineAt(j);
-
- intersectLines(lineA, lineB, intersections);
- }
-
- for (int k = 0; k < intersections.size(); ++k) {
- QPathSegments::Intersection i_isect, j_isect;
- i_isect.vertex = j_isect.vertex = segments.addPoint(intersections.at(k).pos);
+ if (segment > node.lowestRightIndex && (&segmentBounds.x2)[axis] >= node.splitRight)
+ produceIntersections(m_tree.at(node.index.children.right), segment, segmentBounds, rbounds, !axis);
+}
- i_isect.t = intersections.at(k).alphaA;
- j_isect.t = intersections.at(k).alphaB;
+}
- i_isect.next = 0;
- j_isect.next = 0;
+void QIntersectionFinder::produceIntersections(QPathSegments &segments)
+{
+ SegmentTree tree(segments);
- segments.addIntersection(i, i_isect);
- segments.addIntersection(j, j_isect);
- }
- }
- }
+ for (int i = 0; i < segments.segments(); ++i)
+ tree.produceIntersections(i);
}
class QKdPointTree
@@ -731,53 +825,34 @@ void QWingedEdge::intersectAndAdd()
qSort(intersections.data(), intersections.data() + intersections.size());
- const QBezier *bezier = m_segments.bezierAt(i);
- if (bezier) {
- int first = m_segments.segmentAt(i).va;
- int second = m_segments.segmentAt(i).vb;
-
- qreal alpha = 0.0;
- int last = first;
- for (int j = 0; j < intersections.size(); ++j) {
- const QPathSegments::Intersection &isect = intersections.at(j);
-
- addBezierEdge(bezier, last, isect.vertex, alpha, isect.t, pathId);
-
- alpha = isect.t;
- last = isect.vertex;
- }
-
- addBezierEdge(bezier, last, second, alpha, 1.0, pathId);
- } else {
- int first = m_segments.segmentAt(i).va;
- int second = m_segments.segmentAt(i).vb;
-
- int last = first;
- for (int j = 0; j < intersections.size(); ++j) {
- const QPathSegments::Intersection &isect = intersections.at(j);
-
- QPathEdge *ep = edge(addEdge(last, isect.vertex));
-
- if (ep) {
- const int dir = m_segments.pointAt(last).y() < m_segments.pointAt(isect.vertex).y() ? 1 : -1;
- if (pathId == 0)
- ep->windingA += dir;
- else
- ep->windingB += dir;
- }
+ int first = m_segments.segmentAt(i).va;
+ int second = m_segments.segmentAt(i).vb;
- last = isect.vertex;
- }
+ int last = first;
+ for (int j = 0; j < intersections.size(); ++j) {
+ const QPathSegments::Intersection &isect = intersections.at(j);
- QPathEdge *ep = edge(addEdge(last, second));
+ QPathEdge *ep = edge(addEdge(last, isect.vertex));
if (ep) {
- const int dir = m_segments.pointAt(last).y() < m_segments.pointAt(second).y() ? 1 : -1;
+ const int dir = m_segments.pointAt(last).y() < m_segments.pointAt(isect.vertex).y() ? 1 : -1;
if (pathId == 0)
ep->windingA += dir;
else
ep->windingB += dir;
}
+
+ last = isect.vertex;
+ }
+
+ QPathEdge *ep = edge(addEdge(last, second));
+
+ if (ep) {
+ const int dir = m_segments.pointAt(last).y() < m_segments.pointAt(second).y() ? 1 : -1;
+ if (pathId == 0)
+ ep->windingA += dir;
+ else
+ ep->windingB += dir;
}
}
}
@@ -832,7 +907,6 @@ static bool isLine(const QBezier &bezier)
void QPathSegments::setPath(const QPainterPath &path)
{
m_points.reset();
- m_beziers.reset();
m_intersections.reset();
m_segments.reset();
@@ -879,8 +953,25 @@ void QPathSegments::addPath(const QPainterPath &path)
if (isLine(bezier)) {
m_segments << Segment(m_pathId, last, current);
} else {
- m_segments << Segment(m_pathId, last, current, m_beziers.size());
- m_beziers << bezier;
+ QRectF bounds = bezier.bounds();
+
+ // threshold based on similar algorithm as in qtriangulatingstroker.cpp
+ int threshold = qMin<float>(64, qMax(bounds.width(), bounds.height()) * (2 * qreal(3.14) / 6));
+
+ if (threshold < 3) threshold = 3;
+ qreal one_over_threshold_minus_1 = qreal(1) / (threshold - 1);
+
+ for (int t = 1; t < threshold - 1; ++t) {
+ currentPoint = bezier.pointAt(t * one_over_threshold_minus_1);
+
+ int index = m_points.size();
+ m_segments << Segment(m_pathId, last, index);
+ last = index;
+
+ m_points << currentPoint;
+ }
+
+ m_segments << Segment(m_pathId, last, current);
}
}
last = current;
@@ -896,24 +987,19 @@ void QPathSegments::addPath(const QPainterPath &path)
m_segments << Segment(m_pathId, last, lastMoveTo);
for (int i = firstSegment; i < m_segments.size(); ++i) {
- const QBezier *bezier = bezierAt(i);
- if (bezier) {
- m_segments.at(i).bounds = bezier->bounds();
- } else {
- const QLineF line = lineAt(i);
+ const QLineF line = lineAt(i);
- qreal x1 = line.p1().x();
- qreal y1 = line.p1().y();
- qreal x2 = line.p2().x();
- qreal y2 = line.p2().y();
+ qreal x1 = line.p1().x();
+ qreal y1 = line.p1().y();
+ qreal x2 = line.p2().x();
+ qreal y2 = line.p2().y();
- if (x2 < x1)
- qSwap(x1, x2);
- if (y2 < y1)
- qSwap(y1, y2);
+ if (x2 < x1)
+ qSwap(x1, x2);
+ if (y2 < y1)
+ qSwap(y1, y2);
- m_segments.at(i).bounds = QRectF(x1, y1, x2 - x1, y2 - y1);
- }
+ m_segments.at(i).bounds = QRectF(x1, y1, x2 - x1, y2 - y1);
}
++m_pathId;
@@ -948,28 +1034,17 @@ static inline QPointF tangentAt(const QWingedEdge &list, int vi, int ei)
const QPathEdge *ep = list.edge(ei);
Q_ASSERT(ep);
- qreal t;
qreal sign;
if (ep->first == vi) {
- t = ep->t0;
sign = 1;
} else {
- t = ep->t1;
sign = -1;
}
- QPointF normal;
- if (ep->bezier) {
- normal = ep->bezier->derivedAt(t);
-
- if (qFuzzyIsNull(normal.x()) && qFuzzyIsNull(normal.y()))
- normal = ep->bezier->secondDerivedAt(t);
- } else {
- const QPointF a = *list.vertex(ep->first);
- const QPointF b = *list.vertex(ep->second);
- normal = b - a;
- }
+ const QPointF a = *list.vertex(ep->first);
+ const QPointF b = *list.vertex(ep->second);
+ QPointF normal = b - a;
return normalize(sign * normal);
}
@@ -979,83 +1054,9 @@ static inline QPointF midPoint(const QWingedEdge &list, int ei)
const QPathEdge *ep = list.edge(ei);
Q_ASSERT(ep);
- if (ep->bezier) {
- return ep->bezier->pointAt(0.5 * (ep->t0 + ep->t1));
- } else {
- const QPointF a = *list.vertex(ep->first);
- const QPointF b = *list.vertex(ep->second);
- return a + 0.5 * (b - a);
- }
-}
-
-static QBezier transform(const QBezier &bezier, const QPointF &xAxis, const QPointF &yAxis, const QPointF &origin)
-{
- QPointF points[4] = {
- bezier.pt1(),
- bezier.pt2(),
- bezier.pt3(),
- bezier.pt4()
- };
-
- for (int i = 0; i < 4; ++i) {
- const QPointF p = points[i] - origin;
-
- points[i].rx() = dot(xAxis, p);
- points[i].ry() = dot(yAxis, p);
- }
-
- return QBezier::fromPoints(points[0], points[1], points[2], points[3]);
-}
-
-static bool isLeftOf(const QWingedEdge &list, int vi, int ai, int bi)
-{
- const QPathEdge *ap = list.edge(ai);
- const QPathEdge *bp = list.edge(bi);
-
- Q_ASSERT(ap);
- Q_ASSERT(bp);
-
- if (!(ap->bezier || bp->bezier))
- return false;
-
- const QPointF tangent = tangentAt(list, vi, ai);
- const QPointF normal(tangent.y(), -tangent.x());
-
- const QPointF origin = *list.vertex(vi);
-
- const QPointF dpA = midPoint(list, ai) - origin;
- const QPointF dpB = midPoint(list, bi) - origin;
-
- qreal xA = dot(normal, dpA);
- qreal xB = dot(normal, dpB);
-
- if (xA <= 0 && xB >= 0)
- return true;
-
- if (xA >= 0 && xB <= 0)
- return false;
-
- if (!ap->bezier)
- return xB > 0;
-
- if (!bp->bezier)
- return xA < 0;
-
- // both are beziers on the same side of the tangent
-
- // transform the beziers into the local coordinate system
- // such that positive y is along the tangent, and positive x is along the normal
-
- QBezier bezierA = transform(*ap->bezier, normal, tangent, origin);
- QBezier bezierB = transform(*bp->bezier, normal, tangent, origin);
-
- qreal y = qMin(bezierA.pointAt(0.5 * (ap->t0 + ap->t1)).y(),
- bezierB.pointAt(0.5 * (bp->t0 + bp->t1)).y());
-
- xA = bezierA.pointAt(bezierA.tForY(ap->t0, ap->t1, y)).x();
- xB = bezierB.pointAt(bezierB.tForY(bp->t0, bp->t1, y)).x();
-
- return xA < xB;
+ const QPointF a = *list.vertex(ep->first);
+ const QPointF b = *list.vertex(ep->second);
+ return a + 0.5 * (b - a);
}
QWingedEdge::TraversalStatus QWingedEdge::findInsertStatus(int vi, int ei) const
@@ -1084,7 +1085,6 @@ QWingedEdge::TraversalStatus QWingedEdge::findInsertStatus(int vi, int ei) const
status.flip();
Q_ASSERT(edge(status.edge)->vertex(status.direction) == vi);
-
qreal d2 = delta(vi, ei, status.edge);
#ifdef QDEBUG_CLIPPER
@@ -1092,8 +1092,7 @@ QWingedEdge::TraversalStatus QWingedEdge::findInsertStatus(int vi, int ei) const
qDebug() << "Delta to edge" << status.edge << d2 << ", angles: " << op->angle << op->invAngle;
#endif
- if (!(qFuzzyIsNull(d2) && isLeftOf(*this, vi, status.edge, ei))
- && (d2 < d || (qFuzzyCompare(d2, d) && isLeftOf(*this, vi, status.edge, position)))) {
+ if (d2 < d) {
position = status.edge;
d = d2;
}
@@ -1210,15 +1209,15 @@ static qreal computeAngle(const QPointF &v)
#endif
}
-int QWingedEdge::addEdge(const QPointF &a, const QPointF &b, const QBezier *bezier, qreal t0, qreal t1)
+int QWingedEdge::addEdge(const QPointF &a, const QPointF &b)
{
int fi = insert(a);
int si = insert(b);
- return addEdge(fi, si, bezier, t0, t1);
+ return addEdge(fi, si);
}
-int QWingedEdge::addEdge(int fi, int si, const QBezier *bezier, qreal t0, qreal t1)
+int QWingedEdge::addEdge(int fi, int si)
{
if (fi == si)
return -1;
@@ -1236,29 +1235,11 @@ int QWingedEdge::addEdge(int fi, int si, const QBezier *bezier, qreal t0, qreal
QPathEdge *ep = edge(ei);
- ep->bezier = bezier;
- ep->t0 = t0;
- ep->t1 = t1;
-
- if (bezier) {
- QPointF aTangent = bezier->derivedAt(t0);
- QPointF bTangent = -bezier->derivedAt(t1);
-
- if (qFuzzyIsNull(aTangent.x()) && qFuzzyIsNull(aTangent.y()))
- aTangent = bezier->secondDerivedAt(t0);
-
- if (qFuzzyIsNull(bTangent.x()) && qFuzzyIsNull(bTangent.y()))
- bTangent = bezier->secondDerivedAt(t1);
-
- ep->angle = computeAngle(aTangent);
- ep->invAngle = computeAngle(bTangent);
- } else {
- const QPointF tangent = QPointF(*sp) - QPointF(*fp);
- ep->angle = computeAngle(tangent);
- ep->invAngle = ep->angle + 64;
- if (ep->invAngle >= 128)
- ep->invAngle -= 128;
- }
+ const QPointF tangent = QPointF(*sp) - QPointF(*fp);
+ ep->angle = computeAngle(tangent);
+ ep->invAngle = ep->angle + 64;
+ if (ep->invAngle >= 128)
+ ep->invAngle -= 128;
QPathVertex *vertices[2] = { fp, sp };
QPathEdge::Direction dirs[2] = { QPathEdge::Backward, QPathEdge::Forward };
@@ -1313,74 +1294,6 @@ int QWingedEdge::addEdge(int fi, int si, const QBezier *bezier, qreal t0, qreal
return ei;
}
-void QWingedEdge::addBezierEdge(const QBezier *bezier, int vertexA, int vertexB, qreal alphaA, qreal alphaB, int path)
-{
- if (qFuzzyCompare(alphaA, alphaB))
- return;
-
- qreal alphaMid = (alphaA + alphaB) * 0.5;
-
- qreal s0 = 0;
- qreal s1 = 1;
- int count = bezier->stationaryYPoints(s0, s1);
-
- m_splitPoints.clear();
- m_splitPoints << alphaA;
- m_splitPoints << alphaMid;
- m_splitPoints << alphaB;
-
- if (count > 0 && !qFuzzyCompare(s0, alphaA) && !qFuzzyCompare(s0, alphaMid) && !qFuzzyCompare(s0, alphaB) && s0 > alphaA && s0 < alphaB)
- m_splitPoints << s0;
-
- if (count > 1 && !qFuzzyCompare(s1, alphaA) && !qFuzzyCompare(s1, alphaMid) && !qFuzzyCompare(s1, alphaB) && s1 > alphaA && s1 < alphaB)
- m_splitPoints << s1;
-
- if (count > 0)
- qSort(m_splitPoints.begin(), m_splitPoints.end());
-
- int last = vertexA;
- for (int i = 0; i < m_splitPoints.size() - 1; ++i) {
- const qreal t0 = m_splitPoints[i];
- const qreal t1 = m_splitPoints[i+1];
-
- int current;
- if ((i + 1) == (m_splitPoints.size() - 1)) {
- current = vertexB;
- } else {
- current = insert(bezier->pointAt(t1));
- }
-
- QPathEdge *ep = edge(addEdge(last, current, bezier, t0, t1));
-
- if (ep) {
- const int dir = m_vertices.at(last).y < m_vertices.at(current).y ? 1 : -1;
- if (path == 0)
- ep->windingA += dir;
- else
- ep->windingB += dir;
- }
-
- last = current;
- }
-}
-
-void QWingedEdge::addBezierEdge(const QBezier *bezier, const QPointF &a, const QPointF &b, qreal alphaA, qreal alphaB, int path)
-{
- if (qFuzzyCompare(alphaA, alphaB))
- return;
-
- if (comparePoints(a, b)) {
- int v = insert(a);
-
- addBezierEdge(bezier, v, v, alphaA, alphaB, path);
- } else {
- int va = insert(a);
- int vb = insert(b);
-
- addBezierEdge(bezier, va, vb, alphaA, alphaB, path);
- }
-}
-
int QWingedEdge::insert(const QPathVertex &vertex)
{
if (!m_vertices.isEmpty()) {
@@ -1429,37 +1342,12 @@ static void add(QPainterPath &path, const QWingedEdge &list, int edge, QPathEdge
status.traversal = traversal;
status.direction = QPathEdge::Forward;
- const QBezier *bezier = 0;
- qreal t0 = 1;
- qreal t1 = 0;
- bool forward = true;
-
path.moveTo(*list.vertex(list.edge(edge)->first));
do {
const QPathEdge *ep = list.edge(status.edge);
- if (ep->bezier != bezier || (bezier && t0 != ep->t1 && t1 != ep->t0)) {
- if (bezier) {
- QBezier sub = bezier->bezierOnInterval(t0, t1);
-
- if (forward)
- path.cubicTo(sub.pt2(), sub.pt3(), sub.pt4());
- else
- path.cubicTo(sub.pt3(), sub.pt2(), sub.pt1());
- }
-
- bezier = ep->bezier;
- t0 = 1;
- t1 = 0;
- forward = status.direction == QPathEdge::Forward;
- }
-
- if (ep->bezier) {
- t0 = qMin(t0, ep->t0);
- t1 = qMax(t1, ep->t1);
- } else
- addLineTo(path, *list.vertex(ep->vertex(status.direction)));
+ addLineTo(path, *list.vertex(ep->vertex(status.direction)));
if (status.traversal == QPathEdge::LeftTraversal)
ep->flag &= ~16;
@@ -1468,14 +1356,6 @@ static void add(QPainterPath &path, const QWingedEdge &list, int edge, QPathEdge
status = list.next(status);
} while (status.edge != edge);
-
- if (bezier) {
- QBezier sub = bezier->bezierOnInterval(t0, t1);
- if (forward)
- path.cubicTo(sub.pt2(), sub.pt3(), sub.pt4());
- else
- path.cubicTo(sub.pt3(), sub.pt2(), sub.pt1());
- }
}
void QWingedEdge::simplify()
@@ -1937,25 +1817,10 @@ bool QWingedEdge::isInside(qreal x, qreal y) const
QPointF b = *vertex(ep->second);
if ((a.y() < y && b.y() > y) || (a.y() > y && b.y() < y)) {
- if (ep->bezier) {
- qreal maxX = qMax(a.x(), qMax(b.x(), qMax(ep->bezier->x2, ep->bezier->x3)));
- qreal minX = qMin(a.x(), qMin(b.x(), qMin(ep->bezier->x2, ep->bezier->x3)));
-
- if (minX > x) {
- winding += w;
- } else if (maxX > x) {
- const qreal t = ep->bezier->tForY(ep->t0, ep->t1, y);
- const qreal intersection = ep->bezier->pointAt(t).x();
-
- if (intersection > x)
- winding += w;
- }
- } else {
- qreal intersectionX = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y());
+ qreal intersectionX = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y());
- if (intersectionX > x)
- winding += w;
- }
+ if (intersectionX > x)
+ winding += w;
}
}
@@ -1971,17 +1836,9 @@ static QVector<QCrossingEdge> findCrossings(const QWingedEdge &list, qreal y)
QPointF b = *list.vertex(edge->second);
if ((a.y() < y && b.y() > y) || (a.y() > y && b.y() < y)) {
- if (edge->bezier) {
- const qreal t = edge->bezier->tForY(edge->t0, edge->t1, y);
- const qreal intersection = edge->bezier->pointAt(t).x();
-
- const QCrossingEdge edge = { i, intersection };
- crossings << edge;
- } else {
- const qreal intersection = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y());
- const QCrossingEdge edge = { i, intersection };
- crossings << edge;
- }
+ const qreal intersection = a.x() + (b.x() - a.x()) * (y - a.y()) / (b.y() - a.y());
+ const QCrossingEdge edge = { i, intersection };
+ crossings << edge;
}
}
return crossings;
diff --git a/src/gui/painting/qpathclipper_p.h b/src/gui/painting/qpathclipper_p.h
index b42dc1d..7962400 100644
--- a/src/gui/painting/qpathclipper_p.h
+++ b/src/gui/painting/qpathclipper_p.h
@@ -151,10 +151,6 @@ public:
qreal angle;
qreal invAngle;
- const QBezier *bezier;
- qreal t0;
- qreal t1;
-
int next(Traversal traversal, Direction direction) const;
void setNext(Traversal traversal, Direction direction, int next);
@@ -182,9 +178,8 @@ public:
};
struct Segment {
- Segment(int pathId, int vertexA, int vertexB, int bezierIndex = -1)
+ Segment(int pathId, int vertexA, int vertexB)
: path(pathId)
- , bezier(bezierIndex)
, va(vertexA)
, vb(vertexB)
, intersection(-1)
@@ -192,7 +187,6 @@ public:
}
int path;
- int bezier;
// vertices
int va;
@@ -216,7 +210,6 @@ public:
const Segment &segmentAt(int index) const;
const QLineF lineAt(int index) const;
- const QBezier *bezierAt(int index) const;
const QRectF &elementBounds(int index) const;
int pathId(int index) const;
@@ -231,7 +224,6 @@ public:
private:
QDataBuffer<QPointF> m_points;
QDataBuffer<Segment> m_segments;
- QDataBuffer<QBezier> m_beziers;
QDataBuffer<Intersection> m_intersections;
int m_pathId;
@@ -272,8 +264,8 @@ public:
TraversalStatus next(const TraversalStatus &status) const;
- int addEdge(const QPointF &a, const QPointF &b, const QBezier *bezier = 0, qreal t0 = 0, qreal t1 = 1);
- int addEdge(int vertexA, int vertexB, const QBezier *bezier = 0, qreal t0 = 0, qreal t1 = 1);
+ int addEdge(const QPointF &a, const QPointF &b);
+ int addEdge(int vertexA, int vertexB);
bool isInside(qreal x, qreal y) const;
@@ -285,11 +277,7 @@ private:
void printNode(int i, FILE *handle);
- QBezier bezierFromIndex(int index) const;
-
void removeEdge(int ei);
- void addBezierEdge(const QBezier *bezier, const QPointF &a, const QPointF &b, qreal alphaA, qreal alphaB, int path);
- void addBezierEdge(const QBezier *bezier, int vertexA, int vertexB, qreal alphaA, qreal alphaB, int path);
int insert(const QPathVertex &vertex);
TraversalStatus findInsertStatus(int vertex, int edge) const;
@@ -312,9 +300,6 @@ inline QPathEdge::QPathEdge(int a, int b)
, second(b)
, angle(0)
, invAngle(0)
- , bezier(0)
- , t0(0)
- , t1(0)
{
m_next[0][0] = -1;
m_next[1][0] = -1;
@@ -396,15 +381,6 @@ inline const QLineF QPathSegments::lineAt(int index) const
return QLineF(m_points.at(segment.va), m_points.at(segment.vb));
}
-inline const QBezier *QPathSegments::bezierAt(int index) const
-{
- const Segment &segment = m_segments.at(index);
- if (segment.bezier >= 0)
- return &m_beziers.at(segment.bezier);
- else
- return 0;
-}
-
inline const QRectF &QPathSegments::elementBounds(int index) const
{
return m_segments.at(index).bounds;
diff --git a/src/gui/painting/qprintengine_ps.cpp b/src/gui/painting/qprintengine_ps.cpp
index ac94de3..28e9a7a 100644
--- a/src/gui/painting/qprintengine_ps.cpp
+++ b/src/gui/painting/qprintengine_ps.cpp
@@ -485,7 +485,6 @@ void QPSPrintEnginePrivate::emitHeader(bool finished)
QByteArray header;
QPdf::ByteStream s(&header);
- s << "%!PS-Adobe-1.0";
qreal scale = 72. / ((qreal) q->metric(QPaintDevice::PdmDpiY));
QRect pageRect = this->pageRect();
@@ -497,28 +496,32 @@ void QPSPrintEnginePrivate::emitHeader(bool finished)
int width = pageRect.width();
int height = pageRect.height();
if (finished && pageCount == 1 && copies == 1 &&
- ((fullPage && qt_gen_epsf) || (outputFileName.endsWith(QLatin1String(".eps"))))
- ) {
+ ((fullPage && qt_gen_epsf) || (outputFileName.endsWith(QLatin1String(".eps")))))
+ {
+ // According to the EPSF 3.0 spec it is required that the PS
+ // version is PS-Adobe-3.0
+ s << "%!PS-Adobe-3.0";
if (!boundingBox.isValid())
boundingBox.setRect(0, 0, width, height);
if (orientation == QPrinter::Landscape) {
if (!fullPage)
boundingBox.translate(-mleft, -mtop);
s << " EPSF-3.0\n%%BoundingBox: "
- << (int)(printer->height() - boundingBox.bottom())*scale // llx
- << (int)(printer->width() - boundingBox.right())*scale - 1 // lly
- << (int)(printer->height() - boundingBox.top())*scale + 1 // urx
- << (int)(printer->width() - boundingBox.left())*scale; // ury
+ << int((printer->height() - boundingBox.bottom())*scale) // llx
+ << int((printer->width() - boundingBox.right())*scale - 1) // lly
+ << int((printer->height() - boundingBox.top())*scale + 1) // urx
+ << int((printer->width() - boundingBox.left())*scale); // ury
} else {
if (!fullPage)
boundingBox.translate(mleft, -mtop);
s << " EPSF-3.0\n%%BoundingBox: "
- << (int)(boundingBox.left())*scale
- << (int)(printer->height() - boundingBox.bottom())*scale - 1
- << (int)(boundingBox.right())*scale + 1
- << (int)(printer->height() - boundingBox.top())*scale;
+ << int((boundingBox.left())*scale)
+ << int((printer->height() - boundingBox.bottom())*scale - 1)
+ << int((boundingBox.right())*scale + 1)
+ << int((printer->height() - boundingBox.top())*scale);
}
} else {
+ s << "%!PS-Adobe-1.0";
int w = width + (fullPage ? 0 : mleft + mright);
int h = height + (fullPage ? 0 : mtop + mbottom);
w = (int)(w*scale);
diff --git a/src/gui/painting/qprintengine_win.cpp b/src/gui/painting/qprintengine_win.cpp
index ea9dc5d..dd4de99 100644
--- a/src/gui/painting/qprintengine_win.cpp
+++ b/src/gui/painting/qprintengine_win.cpp
@@ -965,12 +965,13 @@ void QWin32PrintEnginePrivate::queryDefault()
return;
QStringList info = output.split(QLatin1Char(','));
- if (info.size() > 0) {
+ int infoSize = info.size();
+ if (infoSize > 0) {
if (name.isEmpty())
name = info.at(0);
- if (program.isEmpty())
+ if (program.isEmpty() && infoSize > 1)
program = info.at(1);
- if (port.isEmpty())
+ if (port.isEmpty() && infoSize > 2)
port = info.at(2);
}
}
diff --git a/src/gui/painting/qwindowsurface_p.h b/src/gui/painting/qwindowsurface_p.h
index b9db92c..512cb97 100644
--- a/src/gui/painting/qwindowsurface_p.h
+++ b/src/gui/painting/qwindowsurface_p.h
@@ -74,8 +74,12 @@ public:
QWidget *window() const;
virtual QPaintDevice *paintDevice() = 0;
- virtual void flush(QWidget *widget, const QRegion &region,
- const QPoint &offset) = 0;
+
+ // 'widget' can be a child widget, in which case 'region' is in child widget coordinates and
+ // offset is the (child) widget's offset in relation to the window surface. On QWS, 'offset'
+ // can be larger than just the offset from the top-level widget as there may also be window
+ // decorations which are painted into the window surface.
+ virtual void flush(QWidget *widget, const QRegion &region, const QPoint &offset) = 0;
#if !defined(Q_WS_LITE)
virtual void setGeometry(const QRect &rect);
QRect geometry() const;
diff --git a/src/gui/s60framework/qs60mainappui.cpp b/src/gui/s60framework/qs60mainappui.cpp
index 3b5b9d3..feffc9f 100644
--- a/src/gui/s60framework/qs60mainappui.cpp
+++ b/src/gui/s60framework/qs60mainappui.cpp
@@ -112,16 +112,10 @@ void QS60MainAppUi::ConstructL()
// ENoAppResourceFile and ENonStandardResourceFile makes UI to work without
// resource files in most SDKs. S60 3rd FP1 public seems to require resource file
// even these flags are defined
- TInt flags = CAknAppUi::EAknEnableSkin;
- if (QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)) {
- flags |= CAknAppUi::ENoScreenFurniture | CAknAppUi::ENonStandardResourceFile;
- }
+ TInt flags = CAknAppUi::EAknEnableSkin
+ | CAknAppUi::ENoScreenFurniture
+ | CAknAppUi::ENonStandardResourceFile;
BaseConstructL(flags);
-
- if (!QApplication::testAttribute(Qt::AA_S60DontConstructApplicationPanes)) {
- CEikButtonGroupContainer* nativeContainer = Cba();
- nativeContainer->SetCommandSetL(R_AVKON_SOFTKEYS_EMPTY_WITH_IDS);
- }
}
/*!
diff --git a/src/gui/styles/qcommonstyle.cpp b/src/gui/styles/qcommonstyle.cpp
index b0e2d37..8036728 100644
--- a/src/gui/styles/qcommonstyle.cpp
+++ b/src/gui/styles/qcommonstyle.cpp
@@ -981,7 +981,7 @@ void QCommonStylePrivate::viewItemDrawText(QPainter *p, const QStyleOptionViewIt
qreal y = position.y() + line.y() + line.ascent();
p->save();
p->setFont(option->font);
- p->drawText(int(x), int(y), elidedText);
+ p->drawText(QPointF(x, y), elidedText);
p->restore();
break;
}
diff --git a/src/gui/styles/qmacstyle_mac.mm b/src/gui/styles/qmacstyle_mac.mm
index 074dd89..f5b0b0c 100644
--- a/src/gui/styles/qmacstyle_mac.mm
+++ b/src/gui/styles/qmacstyle_mac.mm
@@ -2143,7 +2143,7 @@ int QMacStyle::pixelMetric(PixelMetric metric, const QStyleOption *opt, const QW
if (qstyleoption_cast<const QStyleOptionComboBox *>(opt) != 0)
ret = 0;
else
- ret = QWindowsStyle::pixelMetric(metric, opt, widget);
+ ret = 1;
break;
case PM_MaximumDragDistance:
ret = -1;
@@ -3099,14 +3099,16 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
HIRect hirect = qt_hirectForQRect(opt->rect);
HIThemeDrawButton(&hirect, &bi, cg, kHIThemeOrientationNormal, 0);
break; }
+
case PE_Frame: {
QPen oldPen = p->pen();
- QPen newPen;
- newPen.setBrush(opt->palette.dark());
- p->setPen(newPen);
+ p->setPen(opt->palette.base().color().darker(140));
p->drawRect(opt->rect.adjusted(0, 0, -1, -1));
+ p->setPen(opt->palette.base().color().darker(180));
+ p->drawLine(opt->rect.topLeft(), opt->rect.topRight());
p->setPen(oldPen);
break; }
+
case PE_FrameLineEdit:
if (const QStyleOptionFrame *frame = qstyleoption_cast<const QStyleOptionFrame *>(opt)) {
if (frame->state & State_Sunken) {
@@ -3279,10 +3281,14 @@ void QMacStyle::drawControl(ControlElement ce, const QStyleOption *opt, QPainter
if (header->orientation == Qt::Horizontal){
switch (header->position) {
case QStyleOptionHeader::Beginning:
+ ir.adjust(-1, -1, 0, 0);
break;
case QStyleOptionHeader::Middle:
+ ir.adjust(-1, -1, 0, 0);
+ break;
+ case QStyleOptionHeader::OnlyOneSection:
case QStyleOptionHeader::End:
- ir.adjust(-1, 0, 0, 0);
+ ir.adjust(-1, -1, 1, 0);
break;
default:
break;
diff --git a/src/gui/styles/qs60style.cpp b/src/gui/styles/qs60style.cpp
index 7587343..20297ae 100644
--- a/src/gui/styles/qs60style.cpp
+++ b/src/gui/styles/qs60style.cpp
@@ -92,10 +92,10 @@ static const qreal goldenRatio = 1.618;
const layoutHeader QS60StylePrivate::m_layoutHeaders[] = {
// *** generated layout data ***
-{240,320,1,17,"QVGA Landscape"},
-{320,240,1,17,"QVGA Portrait"},
-{360,640,1,17,"NHD Landscape"},
-{640,360,1,17,"NHD Portrait"},
+{240,320,1,18,"QVGA Landscape"},
+{320,240,1,18,"QVGA Portrait"},
+{360,640,1,18,"NHD Landscape"},
+{640,360,1,18,"NHD Portrait"},
{352,800,1,12,"E90 Landscape"}
// *** End of generated data ***
};
@@ -104,11 +104,11 @@ const int QS60StylePrivate::m_numberOfLayouts =
const short QS60StylePrivate::data[][MAX_PIXELMETRICS] = {
// *** generated pixel metrics ***
-{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,0,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1, 106},
-{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,0,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1, 106},
-{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,0,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,13,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1, 135},
-{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,0,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,12,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1, 135},
-{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,0,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1, 106}
+{5,0,-909,0,0,2,0,0,-1,7,12,19,13,13,6,200,-909,-909,-909,20,13,2,0,0,21,7,18,30,3,3,1,-909,-909,0,1,0,0,12,20,15,15,18,18,1,115,18,0,-909,-909,-909,-909,0,0,16,2,-909,0,0,-909,16,-909,-909,-909,-909,32,18,55,24,55,4,4,4,9,13,-909,5,51,11,5,0,3,3,6,8,3,3,-909,2,-909,-909,-909,-909,5,5,3,1, 106},
+{5,0,-909,0,0,1,0,0,-1,8,14,22,15,15,7,164,-909,-909,-909,19,15,2,0,0,21,8,27,28,4,4,1,-909,-909,0,7,6,0,13,23,17,17,21,21,7,115,21,0,-909,-909,-909,-909,0,0,15,1,-909,0,0,-909,15,-909,-909,-909,-909,32,21,65,27,65,3,3,5,10,15,-909,5,58,13,5,0,4,4,7,9,4,4,-909,2,-909,-909,-909,-909,6,6,3,1, 106},
+{7,0,-909,0,0,2,0,0,-1,25,69,28,19,19,9,258,-909,-909,-909,23,19,26,0,0,32,25,72,44,5,5,2,-909,-909,0,7,21,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,25,2,-909,0,0,-909,25,-909,-909,-909,-909,87,27,77,35,77,13,13,6,8,19,-909,7,74,19,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1, 135},
+{7,0,-909,0,0,2,0,0,-1,25,68,28,19,19,9,258,-909,-909,-909,31,19,6,0,0,32,25,60,52,5,5,2,-909,-909,0,7,32,0,17,29,22,22,27,27,7,173,29,0,-909,-909,-909,-909,0,0,26,2,-909,0,0,-909,26,-909,-909,-909,-909,87,27,96,35,96,12,12,6,8,19,-909,7,74,22,7,0,5,5,8,12,5,5,-909,3,-909,-909,-909,-909,7,7,3,1, 135},
+{7,0,-909,0,0,2,0,0,-1,10,20,27,18,18,9,301,-909,-909,-909,29,18,5,0,0,35,7,32,30,5,5,2,-909,-909,0,2,8,0,16,28,21,21,26,26,2,170,26,0,-909,-909,-909,-909,0,0,21,6,-909,0,0,-909,-909,-909,-909,-909,-909,54,26,265,34,265,5,5,6,3,18,-909,7,72,19,7,0,5,6,8,11,6,5,-909,2,-909,-909,-909,-909,5,5,3,1, 106}
// *** End of generated data ***
};
@@ -651,6 +651,8 @@ void QS60StylePrivate::setFont(QWidget *widget) const
fontCategory = QS60StyleEnums::FC_Title;
} else if (qobject_cast<QMessageBox *>(widget)){
fontCategory = QS60StyleEnums::FC_Primary;
+ } else if (qobject_cast<QMenu *>(widget)){
+ fontCategory = QS60StyleEnums::FC_Primary;
}
if (fontCategory != QS60StyleEnums::FC_Undefined) {
const bool resolveFontSize = widget->testAttribute(Qt::WA_SetFont)
@@ -1544,18 +1546,35 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
const int tabOverlap =
QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness;
-
- if (skinElement==QS60StylePrivate::SE_TabBarTabEastInactive||
- skinElement==QS60StylePrivate::SE_TabBarTabEastActive||
- skinElement==QS60StylePrivate::SE_TabBarTabWestInactive||
- skinElement==QS60StylePrivate::SE_TabBarTabWestActive){
- optionTabAdj.rect.adjust(0, 0, 0, tabOverlap);
- } else {
- if (directionMirrored)
- optionTabAdj.rect.adjust(-tabOverlap, 0, 0, 0);
+ const bool usesScrollButtons =
+ (widget) ? (qobject_cast<const QTabBar*>(widget))->usesScrollButtons() : false;
+ const int roomForScrollButton =
+ usesScrollButtons ? QS60StylePrivate::pixelMetric(PM_TabBarScrollButtonWidth) : 0;
+
+ // adjust for overlapping tabs and scrollbuttons, if necessary
+ if (skinElement == QS60StylePrivate::SE_TabBarTabEastInactive ||
+ skinElement == QS60StylePrivate::SE_TabBarTabEastActive ||
+ skinElement == QS60StylePrivate::SE_TabBarTabWestInactive ||
+ skinElement == QS60StylePrivate::SE_TabBarTabWestActive){
+ if (optionTabAdj.position == QStyleOptionTabV3::Beginning)
+ optionTabAdj.rect.adjust(0, roomForScrollButton, 0, tabOverlap);
+ else if (optionTabAdj.position == QStyleOptionTabV3::End)
+ optionTabAdj.rect.adjust(0, 0, 0, tabOverlap);
else
- optionTabAdj.rect.adjust(0, 0, tabOverlap, 0);
+ optionTabAdj.rect.adjust(0, 0, 0, tabOverlap);
+ } else {
+ if (directionMirrored) {
+ if (optionTabAdj.position == QStyleOptionTabV3::Beginning)
+ optionTabAdj.rect.adjust(-tabOverlap, 0, -roomForScrollButton, 0);
+ else
+ optionTabAdj.rect.adjust(-tabOverlap, 0, 0, 0);
+ } else {
+ if (optionTabAdj.position == QStyleOptionTabV3::Beginning)
+ optionTabAdj.rect.adjust(roomForScrollButton, 0, tabOverlap, 0);
+ else
+ optionTabAdj.rect.adjust(0, 0, tabOverlap, 0);
}
+ }
}
QS60StylePrivate::drawSkinElement(skinElement, painter, optionTabAdj.rect, flags);
}
@@ -1568,7 +1587,10 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
const int borderThickness = QS60StylePrivate::pixelMetric(PM_DefaultFrameWidth);
const int tabOverlap =
QS60StylePrivate::pixelMetric(PM_TabBarTabOverlap) - borderThickness;
- const QRect windowRect = painter->window();
+ const bool usesScrollButtons =
+ (widget) ? (qobject_cast<const QTabBar*>(widget))->usesScrollButtons() : false;
+ const int roomForScrollButton =
+ usesScrollButtons ? QS60StylePrivate::pixelMetric(PM_TabBarScrollButtonWidth) : 0;
switch (tab->shape) {
case QTabBar::TriangularWest:
@@ -1603,6 +1625,17 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
|| optionTab.shape == QTabBar::TriangularEast
|| optionTab.shape == QTabBar::TriangularWest;
+ //make room for scrollbuttons
+ if (!verticalTabs) {
+ if ((tab->position == QStyleOptionTabV3::Beginning && !directionMirrored))
+ tr.adjust(roomForScrollButton, 0, 0, 0);
+ else if ((tab->position == QStyleOptionTabV3::Beginning && directionMirrored))
+ tr.adjust(0, 0, -roomForScrollButton, 0);
+ } else {
+ if (tab->position == QStyleOptionTabV3::Beginning)
+ tr.adjust(0, roomForScrollButton, 0, 0);
+ }
+
if (verticalTabs) {
painter->save();
int newX, newY, newRotation;
@@ -1634,9 +1667,10 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
alignment |= Qt::TextHideMnemonic;
if (!optionTab.icon.isNull()) {
QSize iconSize = optionTab.iconSize;
- int iconExtent = pixelMetric(PM_TabBarIconSize);
- if (iconSize.height() > iconExtent || iconSize.width() > iconExtent)
+ if (!iconSize.isValid()) {
+ const int iconExtent = pixelMetric(PM_TabBarIconSize);
iconSize = QSize(iconExtent, iconExtent);
+ }
QPixmap tabIcon = optionTab.icon.pixmap(iconSize,
(optionTab.state & State_Enabled) ? QIcon::Normal : QIcon::Disabled);
if (tab->text.isEmpty())
@@ -1744,6 +1778,9 @@ void QS60Style::drawControl(ControlElement element, const QStyleOption *option,
optionCheckBox.QStyleOptionMenuItem::operator=(*menuItem);
optionCheckBox.rect.setWidth(pixelMetric(PM_IndicatorWidth));
optionCheckBox.rect.setHeight(pixelMetric(PM_IndicatorHeight));
+ optionCheckBox.rect.moveCenter(QPoint(
+ optionCheckBox.rect.center().x(),
+ menuItem->rect.center().y()));
const int moveByX = optionCheckBox.rect.width() + vSpacing;
if (optionMenuItem.direction == Qt::LeftToRight) {
textRect.translate(moveByX, 0);
@@ -2424,6 +2461,10 @@ int QS60Style::pixelMetric(PixelMetric metric, const QStyleOption *option, const
if (metricValue == KNotFound)
metricValue = QCommonStyle::pixelMetric(metric, option, widget);
+ // Menu scrollers should be set to zero height for combobox popups
+ if (metric == PM_MenuScrollerHeight && !qobject_cast<const QMenu *>(widget))
+ metricValue = 0;
+
//if layout direction is mirrored, switch left and right border margins
if (option && option->direction == Qt::RightToLeft) {
if (metric == PM_LayoutLeftMargin)
@@ -2481,9 +2522,29 @@ QSize QS60Style::sizeFromContents(ContentsType ct, const QStyleOption *opt,
sz = QCommonStyle::sizeFromContents(ct, opt, csz, widget);
if (naviPaneSize.height() > sz.height())
sz.setHeight(naviPaneSize.height());
+ // Adjust beginning tabbar item size, if scrollbuttons are used. This is to ensure that the
+ // tabbar item content fits, since scrollbuttons are making beginning tabbar item smaller.
+ int scrollButtonSize = 0;
+ if (const QTabBar *tabBar = qobject_cast<const QTabBar *>(widget))
+ scrollButtonSize = tabBar->usesScrollButtons() ? pixelMetric(PM_TabBarScrollButtonWidth) : 0;
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
+ const bool verticalTabs = tab->shape == QTabBar::RoundedEast
+ || tab->shape == QTabBar::RoundedWest
+ || tab->shape == QTabBar::TriangularEast
+ || tab->shape == QTabBar::TriangularWest;
+ if (tab->position == QStyleOptionTab::Beginning)
+ sz += QSize(verticalTabs ? 0 : scrollButtonSize, !verticalTabs ? 0 : scrollButtonSize);
+ }
}
break;
+ case CT_MenuItem:
case CT_ItemViewItem:
+ if (const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(opt)) {
+ if (menuItem->menuItemType == QStyleOptionMenuItem::Separator) {
+ sz = QSize();
+ break;
+ }
+ }
sz = QCommonStyle::sizeFromContents( ct, opt, csz, widget);
if (QS60StylePrivate::isTouchSupported())
//Make itemview easier to use in touch devices
@@ -2564,6 +2625,9 @@ int QS60Style::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget *w
case SH_Menu_SelectionWrap:
retValue = true;
break;
+ case SH_Menu_MouseTracking:
+ retValue = true;
+ break;
case SH_ItemView_ShowDecorationSelected:
retValue = true;
break;
@@ -3150,6 +3214,12 @@ bool QS60Style::event(QEvent *e)
#ifdef QT_KEYPAD_NAVIGATION
case QEvent::FocusIn:
if (QWidget *focusWidget = QApplication::focusWidget()) {
+
+ // Menus and combobox popups do not draw focus frame around them
+ if (qobject_cast<QComboBoxListView *>(focusWidget) ||
+ qobject_cast<QMenu *>(focusWidget))
+ break;
+
if (!d->m_focusFrame)
d->m_focusFrame = new QFocusFrame(focusWidget);
d->m_focusFrame->setWidget(focusWidget);
diff --git a/src/gui/styles/qs60style_s60.cpp b/src/gui/styles/qs60style_s60.cpp
index 58a7159..55aa6b0 100644
--- a/src/gui/styles/qs60style_s60.cpp
+++ b/src/gui/styles/qs60style_s60.cpp
@@ -310,7 +310,7 @@ const partMapEntry QS60StyleModeSpecifics::m_partMap[] = {
/* SP_QsnFrPopupSideB */ {KAknsIIDQsnFrPopupSideB, ENoDraw, ES60_All, -1,-1},
/* SP_QsnFrPopupSideL */ {KAknsIIDQsnFrPopupSideL, ENoDraw, ES60_All, -1,-1},
/* SP_QsnFrPopupSideR */ {KAknsIIDQsnFrPopupSideR, ENoDraw, ES60_All, -1,-1},
- /* SP_QsnFrPopupCenter */ {KAknsIIDQsnFrPopupCenter, ENoDraw, ES60_All, -1,-1},
+ /* SP_QsnFrPopupCenter */ {KAknsIIDQsnFrPopupCenterSubmenu, ENoDraw, ES60_All, -1,-1},
// ToolTip graphics different in 3.1 vs. 3.2+.
/* SP_QsnFrPopupPreviewCornerTl */ {KAknsIIDQsnFrPopupCornerTl, ENoDraw, ES60_3_1, EAknsMajorSkin, 0x19c5}, /* KAknsIIDQsnFrPopupPreviewCornerTl */
@@ -919,7 +919,7 @@ QPixmap QS60StyleModeSpecifics::createSkinnedGraphicsLX(QS60StylePrivate::SkinFr
result = fromFbsBitmap(frame, NULL, flags, targetSize);
}
} else {
- TDisplayMode maskDepth = EGray2;
+ TDisplayMode maskDepth = EGray256;
// Query the skin item for possible frame graphics mask details.
if (skinInstance) {
CAknsMaskedBitmapItemData* skinMaskedBmp = static_cast<CAknsMaskedBitmapItemData*>(
@@ -983,6 +983,10 @@ void QS60StyleModeSpecifics::frameIdAndCenterId(QS60StylePrivate::SkinFrameEleme
frameId.Set(KAknsIIDQsnFrPopupSub);
}
break;
+ case QS60StylePrivate::SF_PopupBackground:
+ centerId.Set(KAknsIIDQsnFrPopupCenterSubmenu);
+ frameId.Set(KAknsIIDQsnFrPopupSub);
+ break;
case QS60StylePrivate::SF_PanelBackground:
// remove center piece for panel graphics, so that only border is drawn
centerId.Set(KAknsIIDNone);
diff --git a/src/gui/styles/qstylefactory.cpp b/src/gui/styles/qstylefactory.cpp
index 0dbb21f..9009878 100644
--- a/src/gui/styles/qstylefactory.cpp
+++ b/src/gui/styles/qstylefactory.cpp
@@ -81,7 +81,7 @@ QT_BEGIN_INCLUDE_NAMESPACE
QT_END_INCLUDE_NAMESPACE
#endif
-#if !defined(QT_NO_LIBRARY) && !defined(QT_NO_SETTINGS)
+#ifndef QT_NO_LIBRARY
Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
(QStyleFactoryInterface_iid, QLatin1String("/styles"), Qt::CaseInsensitive))
#endif
diff --git a/src/gui/styles/qstylesheetstyle.cpp b/src/gui/styles/qstylesheetstyle.cpp
index 81b923b..515b6c7 100644
--- a/src/gui/styles/qstylesheetstyle.cpp
+++ b/src/gui/styles/qstylesheetstyle.cpp
@@ -1539,7 +1539,9 @@ QVector<QCss::StyleRule> QStyleSheetStyle::styleRules(const QWidget *w) const
QHash<const void *, StyleSheet>::const_iterator defaultCacheIt = styleSheetCache->constFind(baseStyle());
if (defaultCacheIt == styleSheetCache->constEnd()) {
defaultSs = getDefaultStyleSheet();
- styleSheetCache->insert(baseStyle(), defaultSs);
+ QStyle *bs = baseStyle();
+ styleSheetCache->insert(bs, defaultSs);
+ QObject::connect(bs, SIGNAL(destroyed(QObject*)), this, SLOT(styleDestroyed(QObject*)), Qt::UniqueConnection);
} else {
defaultSs = defaultCacheIt.value();
}
@@ -2666,6 +2668,11 @@ void QStyleSheetStyle::widgetDestroyed(QObject *o)
autoFillDisabledWidgets->remove((const QWidget *)o);
}
+void QStyleSheetStyle::styleDestroyed(QObject *o)
+{
+ styleSheetCache->remove(o);
+}
+
/*!
* Make sure that the cache will be clean by connecting destroyed if needed.
* return false if the widget is not stylable;
diff --git a/src/gui/styles/qstylesheetstyle_p.h b/src/gui/styles/qstylesheetstyle_p.h
index 50abef9..fd81437 100644
--- a/src/gui/styles/qstylesheetstyle_p.h
+++ b/src/gui/styles/qstylesheetstyle_p.h
@@ -147,6 +147,7 @@ protected:
private Q_SLOTS:
void widgetDestroyed(QObject *);
+ void styleDestroyed(QObject *);
private:
int refcount;
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index ee31fa2..dcab1ee 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -2642,10 +2642,8 @@ void QFontCache::cleanup()
} QT_CATCH (const std::bad_alloc &) {
// no cache - just ignore
}
- if (cache && cache->hasLocalData()) {
- cache->localData()->clear();
+ if (cache && cache->hasLocalData())
cache->setLocalData(0);
- }
}
#endif // QT_NO_THREAD
@@ -2657,6 +2655,7 @@ QFontCache::QFontCache()
QFontCache::~QFontCache()
{
+ clear();
{
EngineDataCache::ConstIterator it = engineDataCache.constBegin(),
end = engineDataCache.constEnd();
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index fbade23..0daf7b6 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -600,10 +600,10 @@ static QList<QFontDatabase::WritingSystem> determineWritingSystemsFromTrueTypeBi
#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
// class with virtual destructor, derived in qfontdatabase_s60.cpp
-class QFontDatabaseS60Store
+class QSymbianFontDatabaseExtras
{
public:
- virtual ~QFontDatabaseS60Store() {}
+ virtual ~QSymbianFontDatabaseExtras() {}
};
#endif
@@ -616,7 +616,7 @@ public:
, stream(0)
#endif
#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
- , s60Store(0)
+ , symbianExtras(0)
#endif
{ }
~QFontDatabasePrivate() {
@@ -630,9 +630,9 @@ public:
families = 0;
count = 0;
#if defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
- if (s60Store) {
- delete s60Store;
- s60Store = 0;
+ if (symbianExtras) {
+ delete symbianExtras;
+ symbianExtras = 0;
}
#endif
// don't clear the memory fonts!
@@ -677,7 +677,7 @@ public:
QDataStream *stream;
QStringList fallbackFamilies;
#elif defined(Q_OS_SYMBIAN) && defined(QT_NO_FREETYPE)
- const QFontDatabaseS60Store *s60Store;
+ const QSymbianFontDatabaseExtras *symbianExtras;
#endif
};
diff --git a/src/gui/text/qfontdatabase_s60.cpp b/src/gui/text/qfontdatabase_s60.cpp
index ef5e0c4..95774f9 100644
--- a/src/gui/text/qfontdatabase_s60.cpp
+++ b/src/gui/text/qfontdatabase_s60.cpp
@@ -92,24 +92,32 @@ QFileInfoList alternativeFilePaths(const QString &path, const QStringList &nameF
}
#if defined(QT_NO_FREETYPE)
-class QFontDatabaseS60StoreImplementation : public QFontDatabaseS60Store
+class QSymbianFontDatabaseExtrasImplementation : public QSymbianFontDatabaseExtras
{
public:
- QFontDatabaseS60StoreImplementation();
- ~QFontDatabaseS60StoreImplementation();
+ QSymbianFontDatabaseExtrasImplementation();
+ ~QSymbianFontDatabaseExtrasImplementation();
- const QFontEngineS60Extensions *extension(const QString &typeface) const;
+ const QSymbianTypeFaceExtras *extras(const QString &typeface, bool bold, bool italic) const;
private:
RHeap* m_heap;
CFontStore *m_store;
COpenFontRasterizer *m_rasterizer;
- mutable QHash<QString, const QFontEngineS60Extensions *> m_extensions;
+ mutable QList<const QSymbianTypeFaceExtras *> m_extras;
+ mutable QHash<QString, const QSymbianTypeFaceExtras *> m_extrasHash;
};
-QFontDatabaseS60StoreImplementation::QFontDatabaseS60StoreImplementation()
+QSymbianFontDatabaseExtrasImplementation::QSymbianFontDatabaseExtrasImplementation()
{
- m_heap = User::ChunkHeap(NULL, 0x1000, 0x100000);
+ QStringList filters;
+ filters.append(QLatin1String("*.ttf"));
+ filters.append(QLatin1String("*.ccc"));
+ const QFileInfoList fontFiles = alternativeFilePaths(QLatin1String("resource\\Fonts"), filters);
+
+ const TInt heapMinLength = 0x1000;
+ const TInt heapMaxLength = qMax(0x20000 * fontFiles.count(), heapMinLength);
+ m_heap = User::ChunkHeap(NULL, heapMinLength, heapMaxLength);
QT_TRAP_THROWING(
m_store = CFontStore::NewL(m_heap);
m_rasterizer = COpenFontRasterizer::NewL(TUid::Uid(0x101F7F5E));
@@ -117,20 +125,17 @@ QFontDatabaseS60StoreImplementation::QFontDatabaseS60StoreImplementation()
m_store->InstallRasterizerL(m_rasterizer);
CleanupStack::Pop(m_rasterizer););
- QStringList filters;
- filters.append(QString::fromLatin1("*.ttf"));
- filters.append(QString::fromLatin1("*.ccc"));
- const QFileInfoList fontFiles = alternativeFilePaths(QString::fromLatin1("resource\\Fonts"), filters);
foreach (const QFileInfo &fontFileInfo, fontFiles) {
const QString fontFile = QDir::toNativeSeparators(fontFileInfo.absoluteFilePath());
TPtrC fontFilePtr(qt_QString2TPtrC(fontFile));
QT_TRAP_THROWING(m_store->AddFileL(fontFilePtr));
}
}
-QFontDatabaseS60StoreImplementation::~QFontDatabaseS60StoreImplementation()
+
+QSymbianFontDatabaseExtrasImplementation::~QSymbianFontDatabaseExtrasImplementation()
{
- typedef QHash<QString, const QFontEngineS60Extensions *>::iterator iterator;
- for (iterator p = m_extensions.begin(); p != m_extensions.end(); ++p) {
+ typedef QList<const QSymbianTypeFaceExtras *>::iterator iterator;
+ for (iterator p = m_extras.begin(); p != m_extras.end(); ++p) {
m_store->ReleaseFont((*p)->fontOwner());
delete *p;
}
@@ -156,13 +161,18 @@ COpenFont* OpenFontFromBitmapFont(const CBitmapFont* aBitmapFont)
}
#endif // FNTSTORE_H_INLINES_SUPPORT_FMM
-const QFontEngineS60Extensions *QFontDatabaseS60StoreImplementation::extension(const QString &typeface) const
+const QSymbianTypeFaceExtras *QSymbianFontDatabaseExtrasImplementation::extras(const QString &typeface,
+ bool bold, bool italic) const
{
- if (!m_extensions.contains(typeface)) {
+ const QString searchKey = typeface + QString::number(int(bold)) + QString::number(int(italic));
+ if (!m_extrasHash.contains(searchKey)) {
CFont* font = NULL;
- TFontSpec spec(qt_QString2TPtrC(typeface), 1);
- spec.iHeight = 1;
- const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, spec);
+ TFontSpec searchSpec(qt_QString2TPtrC(typeface), 1);
+ if (bold)
+ searchSpec.iFontStyle.SetStrokeWeight(EStrokeWeightBold);
+ if (italic)
+ searchSpec.iFontStyle.SetPosture(EPostureItalic);
+ const TInt err = m_store->GetNearestFontToDesignHeightInPixels(font, searchSpec);
Q_ASSERT(err == KErrNone && font);
const CBitmapFont *bitmapFont = static_cast<CBitmapFont*>(font);
COpenFont *openFont =
@@ -171,9 +181,20 @@ const QFontEngineS60Extensions *QFontDatabaseS60StoreImplementation::extension(c
#else
OpenFontFromBitmapFont(bitmapFont);
#endif // FNTSTORE_H_INLINES_SUPPORT_FMM
- m_extensions.insert(typeface, new QFontEngineS60Extensions(font, openFont));
+ const TOpenFontFaceAttrib* const attrib = openFont->FaceAttrib();
+ const QString foundKey =
+ QString((const QChar*)attrib->FullName().Ptr(), attrib->FullName().Length());
+ if (!m_extrasHash.contains(foundKey)) {
+ QSymbianTypeFaceExtras *extras = new QSymbianTypeFaceExtras(font, openFont);
+ m_extras.append(extras);
+ m_extrasHash.insert(searchKey, extras);
+ m_extrasHash.insert(foundKey, extras);
+ } else {
+ m_store->ReleaseFont(font);
+ m_extrasHash.insert(searchKey, m_extrasHash.value(foundKey));
+ }
}
- return m_extensions.value(typeface);
+ return m_extrasHash.value(searchKey);
}
#else
class QFontEngineFTS60 : public QFontEngineFT
@@ -240,14 +261,14 @@ static void initializeDb()
return;
#if defined(QT_NO_FREETYPE)
- if (!db->s60Store)
- db->s60Store = new QFontDatabaseS60StoreImplementation;
+ if (!db->symbianExtras)
+ db->symbianExtras = new QSymbianFontDatabaseExtrasImplementation;
QSymbianFbsHeapLock lock(QSymbianFbsHeapLock::Unlock);
const int numTypeFaces = QS60Data::screenDevice()->NumTypefaces();
- const QFontDatabaseS60StoreImplementation *store =
- static_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store);
+ const QSymbianFontDatabaseExtrasImplementation *dbExtras =
+ static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
bool fontAdded = false;
for (int i = 0; i < numTypeFaces; i++) {
TTypefaceSupport typefaceSupport;
@@ -273,8 +294,9 @@ static void initializeDb()
style->smoothScalable = typefaceSupport.iIsScalable;
style->pixelSize(0, true);
- const QFontEngineS60Extensions *extension = store->extension(familyName);
- const QByteArray os2Table = extension->getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
+ const QSymbianTypeFaceExtras *typeFaceExtras =
+ dbExtras->extras(familyName, faceAttrib.IsBold(), faceAttrib.IsItalic());
+ const QByteArray os2Table = typeFaceExtras->getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
const unsigned char* data = reinterpret_cast<const unsigned char*>(os2Table.constData());
const unsigned char* ulUnicodeRange = data + 42;
quint32 unicodeRange[4] = {
@@ -394,10 +416,11 @@ QFontEngine *QFontDatabase::findFont(int script, const QFontPrivate *, const QFo
QFontDef request = req;
request.family = fontFamily;
#if defined(QT_NO_FREETYPE)
- const QFontDatabaseS60StoreImplementation *store =
- static_cast<const QFontDatabaseS60StoreImplementation*>(db->s60Store);
- const QFontEngineS60Extensions *extension = store->extension(fontFamily);
- fe = new QFontEngineS60(request, extension);
+ const QSymbianFontDatabaseExtrasImplementation *dbExtras =
+ static_cast<const QSymbianFontDatabaseExtrasImplementation*>(db->symbianExtras);
+ const QSymbianTypeFaceExtras *typeFaceExtras =
+ dbExtras->extras(fontFamily, request.weight > QFont::Normal, request.style != QFont::StyleNormal);
+ fe = new QFontEngineS60(request, typeFaceExtras);
#else
QFontEngine::FaceId faceId;
const QtFontFamily * const reqQtFontFamily = db->family(fontFamily);
diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm
index 0bfdbc0..a6510cb 100644
--- a/src/gui/text/qfontengine_mac.mm
+++ b/src/gui/text/qfontengine_mac.mm
@@ -226,8 +226,19 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay
QFixed *outAdvances_y = glyphs->advances_y;
glyph_t *initialGlyph = outGlyphs;
- if (arraySize == 0)
- return false;
+ if (arraySize == 0) {
+ // CoreText failed to shape the text we gave it, so we assume one glyph
+ // per character and build a list of invalid glyphs with zero advance
+ *nglyphs = len;
+ for (int i = 0; i < len; ++i) {
+ outGlyphs[i] = 0;
+ logClusters[i] = i;
+ outAdvances_x[i] = QFixed();
+ outAdvances_y[i] = QFixed();
+ outAttributes[i].clusterStart = true;
+ }
+ return true;
+ }
const bool rtl = (CTRunGetStatus(static_cast<CTRunRef>(CFArrayGetValueAtIndex(array, 0))) & kCTRunStatusRightToLeft);
diff --git a/src/gui/text/qfontengine_s60.cpp b/src/gui/text/qfontengine_s60.cpp
index c9ff661..93f02ff 100644
--- a/src/gui/text/qfontengine_s60.cpp
+++ b/src/gui/text/qfontengine_s60.cpp
@@ -53,22 +53,19 @@
QT_BEGIN_NAMESPACE
-QFontEngineS60Extensions::QFontEngineS60Extensions(CFont* fontOwner, COpenFont *font)
+QSymbianTypeFaceExtras::QSymbianTypeFaceExtras(CFont* fontOwner, COpenFont *font)
: m_font(font)
, m_cmap(0)
, m_symbolCMap(false)
, m_fontOwner(fontOwner)
{
- TAny *shapingExtension = NULL;
- m_font->ExtendedInterface(KUidOpenFontShapingExtension, shapingExtension);
- m_shapingExtension = static_cast<MOpenFontShapingExtension*>(shapingExtension);
TAny *trueTypeExtension = NULL;
m_font->ExtendedInterface(KUidOpenFontTrueTypeExtension, trueTypeExtension);
m_trueTypeExtension = static_cast<MOpenFontTrueTypeExtension*>(trueTypeExtension);
- Q_ASSERT(m_shapingExtension && m_trueTypeExtension);
+ Q_ASSERT(m_trueTypeExtension);
}
-QByteArray QFontEngineS60Extensions::getSfntTable(uint tag) const
+QByteArray QSymbianTypeFaceExtras::getSfntTable(uint tag) const
{
Q_ASSERT(m_trueTypeExtension->HasTrueTypeTable(tag));
TInt error = KErrNone;
@@ -79,7 +76,7 @@ QByteArray QFontEngineS60Extensions::getSfntTable(uint tag) const
return result;
}
-bool QFontEngineS60Extensions::getSfntTableData(uint tag, uchar *buffer, uint *length) const
+bool QSymbianTypeFaceExtras::getSfntTableData(uint tag, uchar *buffer, uint *length) const
{
if (!m_trueTypeExtension->HasTrueTypeTable(tag))
return false;
@@ -104,7 +101,7 @@ bool QFontEngineS60Extensions::getSfntTableData(uint tag, uchar *buffer, uint *l
return result;
}
-const unsigned char *QFontEngineS60Extensions::cmap() const
+const unsigned char *QSymbianTypeFaceExtras::cmap() const
{
if (!m_cmap) {
m_cmapTable = getSfntTable(MAKE_TAG('c', 'm', 'a', 'p'));
@@ -114,27 +111,7 @@ const unsigned char *QFontEngineS60Extensions::cmap() const
return m_cmap;
}
-QPainterPath QFontEngineS60Extensions::glyphOutline(glyph_t glyph) const
-{
- QPainterPath result;
- QPolygonF polygon;
- TInt glyphIndex = glyph;
- TInt pointNumber = 0;
- TInt x, y;
- while (m_shapingExtension->GlyphPointInFontUnits(glyphIndex, pointNumber++, x, y)) {
- const QPointF point(qreal(x) / 0xffff, qreal(y) / 0xffff);
- if (polygon.contains(point)) {
- result.addPolygon(polygon);
- result.closeSubpath();
- polygon.clear();
- } else {
- polygon.append(point);
- }
- }
- return result;
-}
-
-CFont *QFontEngineS60Extensions::fontOwner() const
+CFont *QSymbianTypeFaceExtras::fontOwner() const
{
return m_fontOwner;
}
@@ -192,8 +169,8 @@ void QFontEngineS60::releaseFont(CFont *&font)
}
}
-QFontEngineS60::QFontEngineS60(const QFontDef &request, const QFontEngineS60Extensions *extensions)
- : m_extensions(extensions)
+QFontEngineS60::QFontEngineS60(const QFontDef &request, const QSymbianTypeFaceExtras *extras)
+ : m_extras(extras)
, m_originalFont(0)
, m_originalFontSizeInPixels((request.pixelSize >= 0)?
request.pixelSize:pointsToPixels(request.pointSize))
@@ -220,10 +197,12 @@ bool QFontEngineS60::stringToCMap(const QChar *characters, int len, QGlyphLayout
}
HB_Glyph *g = glyphs->glyphs;
- const unsigned char* cmap = m_extensions->cmap();
+ const unsigned char* cmap = m_extras->cmap();
+ const bool isRtl = (flags & QTextEngine::RightToLeft);
for (int i = 0; i < len; ++i) {
const unsigned int uc = getChar(characters, i, len);
- *g++ = QFontEngine::getTrueTypeGlyphIndex(cmap, uc);
+ *g++ = QFontEngine::getTrueTypeGlyphIndex(cmap,
+ isRtl ? QChar::mirroredChar(uc) : uc);
}
glyphs->numGlyphs = g - glyphs->glyphs;
@@ -241,8 +220,8 @@ void QFontEngineS60::recalcAdvances(QGlyphLayout *glyphs, QTextEngine::ShaperFla
Q_UNUSED(flags);
for (int i = 0; i < glyphs->numGlyphs; i++) {
const glyph_metrics_t bbox = boundingBox_const(glyphs->glyphs[i]);
- glyphs->advances_x[i] = glyphs->offsets[i].x = bbox.xoff;
- glyphs->advances_y[i] = glyphs->offsets[i].y = bbox.yoff;
+ glyphs->advances_x[i] = bbox.xoff;
+ glyphs->advances_y[i] = bbox.yoff;
}
}
@@ -337,7 +316,7 @@ const char *QFontEngineS60::name() const
bool QFontEngineS60::canRender(const QChar *string, int len)
{
- const unsigned char *cmap = m_extensions->cmap();
+ const unsigned char *cmap = m_extras->cmap();
for (int i = 0; i < len; ++i) {
const unsigned int uc = getChar(string, i, len);
if (QFontEngine::getTrueTypeGlyphIndex(cmap, uc) == 0)
@@ -348,12 +327,12 @@ bool QFontEngineS60::canRender(const QChar *string, int len)
QByteArray QFontEngineS60::getSfntTable(uint tag) const
{
- return m_extensions->getSfntTable(tag);
+ return m_extras->getSfntTable(tag);
}
bool QFontEngineS60::getSfntTableData(uint tag, uchar *buffer, uint *length) const
{
- return m_extensions->getSfntTableData(tag, buffer, length);
+ return m_extras->getSfntTableData(tag, buffer, length);
}
QFontEngine::Type QFontEngineS60::type() const
diff --git a/src/gui/text/qfontengine_s60_p.h b/src/gui/text/qfontengine_s60_p.h
index a80af4d..6883730 100644
--- a/src/gui/text/qfontengine_s60_p.h
+++ b/src/gui/text/qfontengine_s60_p.h
@@ -62,21 +62,19 @@ class CFont;
QT_BEGIN_NAMESPACE
-// ..gives us access to truetype tables, UTF-16<->GlyphID mapping, and glyph outlines
-class QFontEngineS60Extensions
+// ..gives us access to truetype tables
+class QSymbianTypeFaceExtras
{
public:
- QFontEngineS60Extensions(CFont* fontOwner, COpenFont *font);
+ QSymbianTypeFaceExtras(CFont* fontOwner, COpenFont *font);
QByteArray getSfntTable(uint tag) const;
bool getSfntTableData(uint tag, uchar *buffer, uint *length) const;
const unsigned char *cmap() const;
- QPainterPath glyphOutline(glyph_t glyph) const;
CFont *fontOwner() const;
private:
COpenFont *m_font;
- const MOpenFontShapingExtension *m_shapingExtension;
mutable MOpenFontTrueTypeExtension *m_trueTypeExtension;
mutable const unsigned char *m_cmap;
mutable bool m_symbolCMap;
@@ -87,7 +85,7 @@ private:
class QFontEngineS60 : public QFontEngine
{
public:
- QFontEngineS60(const QFontDef &fontDef, const QFontEngineS60Extensions *extensions);
+ QFontEngineS60(const QFontDef &fontDef, const QSymbianTypeFaceExtras *extras);
~QFontEngineS60();
bool stringToCMap(const QChar *str, int len, QGlyphLayout *glyphs, int *nglyphs, QTextEngine::ShaperFlags flags) const;
@@ -128,7 +126,7 @@ private:
CFont *fontWithSize(qreal size) const;
static void releaseFont(CFont *&font);
- const QFontEngineS60Extensions *m_extensions;
+ const QSymbianTypeFaceExtras *m_extras;
CFont* m_originalFont;
const qreal m_originalFontSizeInPixels;
CFont* m_scaledFont;
diff --git a/src/gui/text/qtextcontrol.cpp b/src/gui/text/qtextcontrol.cpp
index 3c596e5..a2ee659 100644
--- a/src/gui/text/qtextcontrol.cpp
+++ b/src/gui/text/qtextcontrol.cpp
@@ -885,8 +885,10 @@ void QTextControl::processEvent(QEvent *e, const QPointF &coordinateOffset, QWid
void QTextControl::processEvent(QEvent *e, const QMatrix &matrix, QWidget *contextWidget)
{
Q_D(QTextControl);
- if (d->interactionFlags & Qt::NoTextInteraction)
+ if (d->interactionFlags == Qt::NoTextInteraction) {
+ e->ignore();
return;
+ }
d->contextWidget = contextWidget;
diff --git a/src/gui/text/qtextdocument.cpp b/src/gui/text/qtextdocument.cpp
index 3e556a7..afba678 100644
--- a/src/gui/text/qtextdocument.cpp
+++ b/src/gui/text/qtextdocument.cpp
@@ -1704,7 +1704,7 @@ void QTextDocument::print(QPrinter *printer) const
return;
const QTextDocument *doc = this;
- QTextDocument *clonedDoc = 0;
+ QScopedPointer<QTextDocument> clonedDoc;
(void)doc->documentLayout(); // make sure that there is a layout
QRectF body = QRectF(QPointF(0, 0), d->pageSize);
@@ -1737,7 +1737,7 @@ void QTextDocument::print(QPrinter *printer) const
printerPageSize.height() / scaledPageSize.height());
} else {
doc = clone(const_cast<QTextDocument *>(this));
- clonedDoc = const_cast<QTextDocument *>(doc);
+ clonedDoc.reset(const_cast<QTextDocument *>(doc));
for (QTextBlock srcBlock = firstBlock(), dstBlock = clonedDoc->firstBlock();
srcBlock.isValid() && dstBlock.isValid();
@@ -1812,7 +1812,7 @@ void QTextDocument::print(QPrinter *printer) const
for (int j = 0; j < pageCopies; ++j) {
if (printer->printerState() == QPrinter::Aborted
|| printer->printerState() == QPrinter::Error)
- goto UserCanceled;
+ return;
printPage(page, &p, doc, body, pageNumberPos);
if (j < pageCopies - 1)
printer->newPage();
@@ -1832,9 +1832,6 @@ void QTextDocument::print(QPrinter *printer) const
if ( i < docCopies - 1)
printer->newPage();
}
-
-UserCanceled:
- delete clonedDoc;
}
#endif
diff --git a/src/gui/text/qtextodfwriter.cpp b/src/gui/text/qtextodfwriter.cpp
index d369bff0..7992de5 100644
--- a/src/gui/text/qtextodfwriter.cpp
+++ b/src/gui/text/qtextodfwriter.cpp
@@ -493,10 +493,10 @@ void QTextOdfWriter::writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat
format.nonBreakableLines() ? QString::fromLatin1("true") : QString::fromLatin1("false"));
if (format.hasProperty(QTextFormat::TabPositions)) {
QList<QTextOption::Tab> tabs = format.tabPositions();
- writer.writeStartElement(styleNS, QString::fromLatin1("style-tab-stops"));
+ writer.writeStartElement(styleNS, QString::fromLatin1("tab-stops"));
QList<QTextOption::Tab>::Iterator iterator = tabs.begin();
while(iterator != tabs.end()) {
- writer.writeEmptyElement(styleNS, QString::fromLatin1("style-tab-stop"));
+ writer.writeEmptyElement(styleNS, QString::fromLatin1("tab-stop"));
writer.writeAttribute(styleNS, QString::fromLatin1("position"), pixelToPoint(iterator->position) );
QString type;
switch(iterator->type) {
@@ -511,7 +511,7 @@ void QTextOdfWriter::writeBlockFormat(QXmlStreamWriter &writer, QTextBlockFormat
++iterator;
}
- writer.writeEndElement(); // style-tab-stops
+ writer.writeEndElement(); // tab-stops
}
writer.writeEndElement(); // paragraph-properties
@@ -698,11 +698,11 @@ void QTextOdfWriter::writeTableCellFormat(QXmlStreamWriter &writer, QTextTableCe
if (padding > 0)
writer.writeAttribute(foNS, QString::fromLatin1("padding-top"), pixelToPoint(padding));
if (format.bottomPadding() > 0)
- writer.writeAttribute(foNS, QString::fromLatin1("padding-top"), pixelToPoint(format.bottomPadding()));
+ writer.writeAttribute(foNS, QString::fromLatin1("padding-bottom"), pixelToPoint(format.bottomPadding()));
if (format.leftPadding() > 0)
- writer.writeAttribute(foNS, QString::fromLatin1("padding-top"), pixelToPoint(format.leftPadding()));
+ writer.writeAttribute(foNS, QString::fromLatin1("padding-left"), pixelToPoint(format.leftPadding()));
if (format.rightPadding() > 0)
- writer.writeAttribute(foNS, QString::fromLatin1("padding-top"), pixelToPoint(format.rightPadding()));
+ writer.writeAttribute(foNS, QString::fromLatin1("padding-right"), pixelToPoint(format.rightPadding()));
}
if (format.hasProperty(QTextFormat::TextVerticalAlignment)) {
diff --git a/src/gui/widgets/qabstractscrollarea.cpp b/src/gui/widgets/qabstractscrollarea.cpp
index 73ec53e..8cffebd 100644
--- a/src/gui/widgets/qabstractscrollarea.cpp
+++ b/src/gui/widgets/qabstractscrollarea.cpp
@@ -983,6 +983,7 @@ bool QAbstractScrollArea::event(QEvent *e)
case QEvent::StyleChange:
case QEvent::LayoutDirectionChange:
case QEvent::ApplicationLayoutDirectionChange:
+ case QEvent::LayoutRequest:
d->layoutChildren();
// fall through
default:
diff --git a/src/gui/widgets/qcombobox_p.h b/src/gui/widgets/qcombobox_p.h
index 92d85cc..29a628c 100644
--- a/src/gui/widgets/qcombobox_p.h
+++ b/src/gui/widgets/qcombobox_p.h
@@ -200,7 +200,9 @@ protected:
menuOpt.menuItemType = QStyleOptionMenuItem::Scroller;
if (sliderAction == QAbstractSlider::SliderSingleStepAdd)
menuOpt.state |= QStyle::State_DownArrow;
+#ifndef Q_WS_S60
p.eraseRect(rect());
+#endif
style()->drawControl(QStyle::CE_MenuScroller, &menuOpt, &p);
}
diff --git a/src/gui/widgets/qlinecontrol.cpp b/src/gui/widgets/qlinecontrol.cpp
index e9f5983..6ed621b 100644
--- a/src/gui/widgets/qlinecontrol.cpp
+++ b/src/gui/widgets/qlinecontrol.cpp
@@ -1350,6 +1350,7 @@ bool QLineControl::processEvent(QEvent* ev)
#endif
switch(ev->type()){
#ifndef QT_NO_GRAPHICSVIEW
+ case QEvent::GraphicsSceneMouseDoubleClick:
case QEvent::GraphicsSceneMouseMove:
case QEvent::GraphicsSceneMouseRelease:
case QEvent::GraphicsSceneMousePress:{
@@ -1439,6 +1440,7 @@ void QLineControl::processMouseEvent(QMouseEvent* ev)
moveCursor(cursor, mark);
break;
}
+ case QEvent::GraphicsSceneMouseDoubleClick:
case QEvent::MouseButtonDblClick:
if (ev->button() == Qt::LeftButton) {
selectWordAtPos(xToPos(ev->pos().x()));
diff --git a/src/gui/widgets/qlineedit.cpp b/src/gui/widgets/qlineedit.cpp
index 655fc61..c1c4abf 100644
--- a/src/gui/widgets/qlineedit.cpp
+++ b/src/gui/widgets/qlineedit.cpp
@@ -740,8 +740,14 @@ bool QLineEdit::validateAndSet(const QString &newText, int newPos,
setText(oldText);
return false;
}
- setCursorPosition(newPos);
- setSelection(qMin(newMarkAnchor, newMarkDrag), qAbs(newMarkAnchor - newMarkDrag));
+ int selstart = qMin(newMarkAnchor, newMarkDrag);
+ int sellength = qAbs(newMarkAnchor - newMarkDrag);
+ if (selstart == newPos) {
+ selstart = qMax(newMarkAnchor, newMarkDrag);
+ sellength = -sellength;
+ }
+ //setSelection also set the position
+ setSelection(selstart, sellength);
return true;
}
#endif //QT3_SUPPORT
diff --git a/src/gui/widgets/qmenu.cpp b/src/gui/widgets/qmenu.cpp
index f9b132e..f84059d 100644
--- a/src/gui/widgets/qmenu.cpp
+++ b/src/gui/widgets/qmenu.cpp
@@ -1834,7 +1834,7 @@ void QMenu::popup(const QPoint &p, QAction *atAction)
QSize size = sizeHint();
QRect screen;
#ifndef QT_NO_GRAPHICSVIEW
- bool isEmbedded = d->nearestGraphicsProxyWidget(this);
+ bool isEmbedded = !bypassGraphicsProxyWidget(this) && d->nearestGraphicsProxyWidget(this);
if (isEmbedded)
screen = d->popupGeometry(this);
else
@@ -2803,7 +2803,9 @@ void QMenu::mouseMoveEvent(QMouseEvent *e)
QAction *action = d->actionAt(e->pos());
if (!action) {
- if (d->hasHadMouse)
+ if (d->hasHadMouse
+ && (!d->currentAction
+ || !(d->currentAction->menu() && d->currentAction->menu()->isVisible())))
d->setCurrentAction(0);
return;
} else if(e->buttons()) {
diff --git a/src/gui/widgets/qmenu_mac.mm b/src/gui/widgets/qmenu_mac.mm
index 6a0eb53..aaa113b 100644
--- a/src/gui/widgets/qmenu_mac.mm
+++ b/src/gui/widgets/qmenu_mac.mm
@@ -665,6 +665,7 @@ void qt_mac_set_modal_state_helper_recursive(OSMenuRef menu, OSMenuRef merge, bo
}
}
#else
+ bool modalWindowOnScreen = qApp->activeModalWidget() != 0;
for (NSMenuItem *item in [menu itemArray]) {
OSMenuRef submenu = [item submenu];
if (submenu != merge) {
@@ -674,10 +675,20 @@ void qt_mac_set_modal_state_helper_recursive(OSMenuRef menu, OSMenuRef merge, bo
// The item should follow what the QAction has.
if ([item tag]) {
QAction *action = reinterpret_cast<QAction *>([item tag]);
- syncNSMenuItemEnabled(item, action->isEnabled());
- } else {
- syncNSMenuItemEnabled(item, YES);
- }
+ syncNSMenuItemEnabled(item, action->isEnabled());
+ } else {
+ syncNSMenuItemEnabled(item, YES);
+ }
+ // We sneak in some extra code here to handle a menu problem:
+ // If there is no window on screen, we cannot set 'nil' as
+ // menu item target, because then cocoa will disable the item
+ // (guess it assumes that there will be no first responder to
+ // catch the trigger anyway?) OTOH, If we have a modal window,
+ // then setting the menu loader as target will make cocoa not
+ // deliver the trigger because the loader is then seen as modally
+ // shaddowed). So either way there are shortcomings. Instead, we
+ // decide the target as late as possible:
+ [item setTarget:modalWindowOnScreen ? nil : getMenuLoader()];
} else {
syncNSMenuItemEnabled(item, NO);
}
@@ -1820,7 +1831,7 @@ void QMenuBarPrivate::macDestroyMenuBar()
menubars()->remove(tlw);
mac_menubar = 0;
- if (qt_mac_current_menubar.qmenubar == q) {
+ if (!qt_mac_current_menubar.qmenubar || qt_mac_current_menubar.qmenubar == q) {
#ifdef QT_MAC_USE_COCOA
QT_MANGLE_NAMESPACE(QCocoaMenuLoader) *loader = getMenuLoader();
[loader removeActionsFromAppMenu];
@@ -2055,6 +2066,7 @@ bool QMenuBarPrivate::macUpdateMenuBarImmediatly()
cancelAllMenuTracking();
QWidget *w = findWindowThatShouldDisplayMenubar();
QMenuBar *mb = findMenubarForWindow(w);
+ extern bool qt_mac_app_fullscreen; //qapplication_mac.mm
// We need to see if we are in full screen mode, if so we need to
// switch the full screen mode to be able to show or hide the menubar.
@@ -2063,12 +2075,14 @@ bool QMenuBarPrivate::macUpdateMenuBarImmediatly()
if(w->isFullScreen()) {
// Ok, switch to showing the menubar when hovering over it.
SetSystemUIMode(kUIModeAllHidden, kUIOptionAutoShowMenuBar);
+ qt_mac_app_fullscreen = true;
}
} else if(w) {
// Removing a menubar
if(w->isFullScreen()) {
// Ok, switch to not showing the menubar when hovering on it
SetSystemUIMode(kUIModeAllHidden, 0);
+ qt_mac_app_fullscreen = true;
}
}
diff --git a/src/gui/widgets/qmenu_symbian.cpp b/src/gui/widgets/qmenu_symbian.cpp
index 4a9cfed..ab2bdea 100644
--- a/src/gui/widgets/qmenu_symbian.cpp
+++ b/src/gui/widgets/qmenu_symbian.cpp
@@ -149,8 +149,12 @@ static void qt_symbian_insert_action(QSymbianMenuAction* action, QList<SymbianMe
"Too many menu actions");
const int underlineShortCut = QApplication::style()->styleHint(QStyle::SH_UnderlineShortcut);
- QString iconText = action->action->iconText();
- TPtrC menuItemText = qt_QString2TPtrC( underlineShortCut ? action->action->text() : iconText);
+ QString actionText;
+ if (underlineShortCut)
+ actionText = action->action->text().left(CEikMenuPaneItem::SData::ENominalTextLength);
+ else
+ actionText = action->action->iconText().left(CEikMenuPaneItem::SData::ENominalTextLength);
+ TPtrC menuItemText = qt_QString2TPtrC(actionText);
if (action->action->menu()) {
SymbianMenuItem* menuItem = new SymbianMenuItem();
menuItem->menuItemData.iCascadeId = action->command;
diff --git a/src/gui/widgets/qtabbar.cpp b/src/gui/widgets/qtabbar.cpp
index 7559311..d692307 100644
--- a/src/gui/widgets/qtabbar.cpp
+++ b/src/gui/widgets/qtabbar.cpp
@@ -67,8 +67,13 @@
#include <private/qt_cocoa_helpers_mac_p.h>
#endif
+#ifndef QT_NO_STYLE_S60
+#include "qs60style.h"
+#endif
+
QT_BEGIN_NAMESPACE
+
inline static bool verticalTabs(QTabBar::Shape shape)
{
return shape == QTabBar::RoundedWest
@@ -95,9 +100,20 @@ void QTabBarPrivate::updateMacBorderMetrics()
metrics.left = 0;
metrics.right = 0;
qt_mac_updateContentBorderMetricts(window, metrics);
-
- // hide the base line separator if the tabs have docuemnt mode enabled (Cocoa)
- qt_mac_showBaseLineSeparator(window, !documentMode);
+#if QT_MAC_USE_COCOA
+ // In Cocoa we need to keep track of the drawRect method.
+ // If documentMode is enabled we need to change it, unless
+ // a toolbar is present.
+ // Notice that all the information is kept in the window,
+ // that's why we get the private widget for it instead of
+ // the private widget for this widget.
+ QWidgetPrivate *privateWidget = qt_widget_private(q->window());
+ if(privateWidget)
+ privateWidget->changeMethods = documentMode;
+ // Since in Cocoa there is no simple way to remove the baseline, so we just ask the
+ // top level to do the magic for us.
+ privateWidget->syncUnifiedMode();
+#endif // QT_MAC_USE_COCOA
}
#endif
}
@@ -478,6 +494,9 @@ void QTabBarPrivate::layoutTabs()
if (useScrollButtons && tabList.count() && last > available) {
int extra = extraWidth();
+#ifndef QT_NO_STYLE_S60
+ QS60Style *s60Style = qobject_cast<QS60Style*>(QApplication::style());
+#endif
if (!vertTabs) {
Qt::LayoutDirection ld = q->layoutDirection();
QRect arrows = QStyle::visualRect(ld, q->rect(),
@@ -485,25 +504,57 @@ void QTabBarPrivate::layoutTabs()
int buttonOverlap = q->style()->pixelMetric(QStyle::PM_TabBar_ScrollButtonOverlap, 0, q);
if (ld == Qt::LeftToRight) {
+// In S60style, tab scroll buttons are layoutted separately, on the sides of the tabbar.
+#ifndef QT_NO_STYLE_S60
+ if (s60Style) {
+ rightB->setGeometry(arrows.left() + extra / 2, arrows.top(), extra / 2, arrows.height());
+ leftB->setGeometry(0, arrows.top(), extra / 2, arrows.height());
+ } else {
+#endif
leftB->setGeometry(arrows.left(), arrows.top(), extra/2, arrows.height());
rightB->setGeometry(arrows.right() - extra/2 + buttonOverlap, arrows.top(),
extra/2, arrows.height());
+#ifndef QT_NO_STYLE_S60
+ }
+#endif
leftB->setArrowType(Qt::LeftArrow);
rightB->setArrowType(Qt::RightArrow);
} else {
+#ifndef QT_NO_STYLE_S60
+ if (s60Style) {
+ rightB->setGeometry(arrows.left() + extra / 2, arrows.top(), extra / 2, arrows.height());
+ leftB->setGeometry(0, arrows.top(), extra / 2, arrows.height());
+ } else {
+#endif
rightB->setGeometry(arrows.left(), arrows.top(), extra/2, arrows.height());
leftB->setGeometry(arrows.right() - extra/2 + buttonOverlap, arrows.top(),
extra/2, arrows.height());
+#ifndef QT_NO_STYLE_S60
+ }
+#endif
rightB->setArrowType(Qt::LeftArrow);
leftB->setArrowType(Qt::RightArrow);
}
} else {
+#ifndef QT_NO_STYLE_S60
+ if (s60Style) {
+ QRect arrows = QRect(0, 0, size.width(), available );
+ leftB->setGeometry(arrows.left(), arrows.top(), arrows.width(), extra / 2);
+ leftB->setArrowType(Qt::UpArrow);
+ rightB->setGeometry(arrows.left(), arrows.bottom() - extra / 2 + 1,
+ arrows.width(), extra / 2);
+ rightB->setArrowType(Qt::DownArrow);
+ } else {
+#endif
QRect arrows = QRect(0, available - extra, size.width(), extra );
leftB->setGeometry(arrows.left(), arrows.top(), arrows.width(), extra/2);
leftB->setArrowType(Qt::UpArrow);
rightB->setGeometry(arrows.left(), arrows.bottom() - extra/2 + 1,
arrows.width(), extra/2);
rightB->setArrowType(Qt::DownArrow);
+#ifndef QT_NO_STYLE_S60
+ }
+#endif
}
leftB->setEnabled(scrollOffset > 0);
rightB->setEnabled(last - scrollOffset >= available - extra);
@@ -580,16 +631,10 @@ void QTabBarPrivate::layoutTab(int index)
}
}
-void QTabBarPrivate::layoutWidgets(int index)
+void QTabBarPrivate::layoutWidgets(int start)
{
Q_Q(QTabBar);
- int start = 0;
- int end = q->count();
- if (index != -1) {
- start = qMax(index, 0);
- end = qMin(end, start + 1);
- }
- for (int i = start; i < end; ++i) {
+ for (int i = start; i < q->count(); ++i) {
layoutTab(i);
}
}
@@ -1171,8 +1216,9 @@ void QTabBar::setCurrentIndex(int index)
update();
d->makeVisible(index);
d->tabList[index].lastTab = oldIndex;
- d->layoutWidgets(oldIndex);
- d->layoutWidgets(index);
+ if (oldIndex >= 0 && oldIndex < count())
+ d->layoutTab(oldIndex);
+ d->layoutTab(index);
#ifdef QT3_SUPPORT
emit selected(index);
#endif
@@ -2198,6 +2244,7 @@ bool QTabBar::documentMode() const
void QTabBar::setDocumentMode(bool enabled)
{
Q_D(QTabBar);
+
d->documentMode = enabled;
d->updateMacBorderMetrics();
}
diff --git a/src/gui/widgets/qtabbar_p.h b/src/gui/widgets/qtabbar_p.h
index 83636e6..37741f7 100644
--- a/src/gui/widgets/qtabbar_p.h
+++ b/src/gui/widgets/qtabbar_p.h
@@ -178,7 +178,7 @@ public:
void refresh();
void layoutTabs();
- void layoutWidgets(int index = -1);
+ void layoutWidgets(int start = 0);
void layoutTab(int index);
void updateMacBorderMetrics();
void setupMovableTab();
diff --git a/src/gui/widgets/qtabwidget.cpp b/src/gui/widgets/qtabwidget.cpp
index 047a905..4a61935 100644
--- a/src/gui/widgets/qtabwidget.cpp
+++ b/src/gui/widgets/qtabwidget.cpp
@@ -542,6 +542,8 @@ void QTabWidget::setTabEnabled(int index, bool enable)
{
Q_D(QTabWidget);
d->tabs->setTabEnabled(index, enable);
+ if (QWidget *widget = d->stack->widget(index))
+ widget->setEnabled(enable);
}
/*!