summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java37
-rw-r--r--src/corelib/global/qlogging.cpp80
-rw-r--r--src/gui/accessible/qaccessiblecache.cpp2
-rw-r--r--src/gui/accessible/qaccessiblecache_mac.mm10
-rw-r--r--src/gui/accessible/qaccessiblecache_p.h14
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp48
-rw-r--r--src/plugins/imageformats/ico/ico.json2
-rw-r--r--src/plugins/imageformats/ico/main.cpp2
-rw-r--r--src/plugins/imageformats/ico/qicohandler.cpp10
-rw-r--r--src/plugins/platforms/android/qandroidplatformbackingstore.h2
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h6
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm16
-rw-r--r--src/plugins/platforms/cocoa/qnsviewaccessibility.mm2
-rw-r--r--src/plugins/platforms/ios/ios.pro8
-rw-r--r--src/plugins/platforms/ios/qiosintegration.h3
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm12
-rw-r--r--src/plugins/platforms/ios/qiosplatformaccessibility.h60
-rw-r--r--src/plugins/platforms/ios/qiosplatformaccessibility.mm85
-rw-r--r--src/plugins/platforms/ios/qioswindow.h2
-rw-r--r--src/plugins/platforms/ios/qioswindow.mm73
-rw-r--r--src/plugins/platforms/ios/quiaccessibilityelement.h58
-rw-r--r--src/plugins/platforms/ios/quiaccessibilityelement.mm194
-rw-r--r--src/plugins/platforms/ios/quiview.h2
-rw-r--r--src/tools/rcc/main.cpp52
-rw-r--r--src/tools/rcc/rcc.cpp157
-rw-r--r--src/tools/rcc/rcc.h11
-rw-r--r--src/widgets/itemviews/qtableview.cpp9
29 files changed, 782 insertions, 181 deletions
diff --git a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
index 38eb9c4570..e6005b9a88 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/ExtractStyle.java
@@ -1496,6 +1496,42 @@ public class ExtractStyle {
}
}
+ void extractCalendar(SimpleJsonWriter writer, String styleName, String qtClass)
+ {
+ JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
+ try {
+ Class<?> attrClass = Class.forName("android.R$attr");
+ int styleId = attrClass.getDeclaredField(styleName).getInt(null);
+
+ int[] styleAttrs = (int[]) styleableClass.getDeclaredField("CalendarView").get(null);
+ TypedArray a = m_theme.obtainStyledAttributes(null, styleAttrs, styleId, 0);
+
+ Drawable d = a.getDrawable(getField(styleableClass,"CalendarView_selectedDateVerticalBar"));
+ if (d != null)
+ json.put("CalendarView_selectedDateVerticalBar", getDrawable(d, styleName + "_CalendarView_selectedDateVerticalBar"));
+
+ int dateTextAppearance = a.getResourceId(styleableClass.getDeclaredField("CalendarView_dateTextAppearance").getInt(null), -1);
+ json.put("CalendarView_dateTextAppearance", extractTextAppearanceInformations(styleName, null, null, dateTextAppearance, styleId));
+
+ int weekDayTextAppearance = a.getResourceId(styleableClass.getDeclaredField("CalendarView_weekDayTextAppearance").getInt(null), -1);
+ json.put("CalendarView_weekDayTextAppearance", extractTextAppearanceInformations(styleName, null, null, weekDayTextAppearance, styleId));
+
+ json.put("CalendarView_firstDayOfWeek", a.getInt(getField(styleableClass, "CalendarView_firstDayOfWeek"), 0));
+ json.put("CalendarView_focusedMonthDateColor", a.getColor(getField(styleableClass, "CalendarView_focusedMonthDateColor"), 0));
+ json.put("CalendarView_selectedWeekBackgroundColor", a.getColor(getField(styleableClass, "CalendarView_selectedWeekBackgroundColor"), 0));
+ json.put("CalendarView_showWeekNumber", a.getBoolean(getField(styleableClass, "CalendarView_showWeekNumber"), true));
+ json.put("CalendarView_shownWeekCount", a.getInt(getField(styleableClass, "CalendarView_shownWeekCount"), 6));
+ json.put("CalendarView_unfocusedMonthDateColor", a.getColor(getField(styleableClass, "CalendarView_unfocusedMonthDateColor"), 0));
+ json.put("CalendarView_weekNumberColor", a.getColor(getField(styleableClass, "CalendarView_weekNumberColor"), 0));
+ json.put("CalendarView_weekSeparatorLineColor", a.getColor(getField(styleableClass, "CalendarView_weekSeparatorLineColor"), 0));
+
+ a.recycle();
+ writer.name(styleName).value(json);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
void extractToolBar(SimpleJsonWriter writer, String styleName, String qtClass)
{
JSONObject json = extractTextAppearanceInformations(styleName, qtClass, null, -1);
@@ -1570,6 +1606,7 @@ public class ExtractStyle {
extractItemsStyle(jsonWriter);
extractCompoundButton(jsonWriter, "buttonStyleToggle", null);
if (Build.VERSION.SDK_INT > 10) {
+ extractCalendar(jsonWriter, "calendarViewStyle", "QCalendarWidget");
extractToolBar(jsonWriter, "actionBarStyle", "QToolBar");
jsonWriter.name("actionButtonStyle").value(extractTextAppearanceInformations("actionButtonStyle", "QToolButton", null, -1));
}
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 4a602e4b2b..8bbf146e11 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -171,89 +171,15 @@ static inline void convert_to_wchar_t_elided(wchar_t *d, size_t space, const cha
}
#endif
-#if !defined(QT_NO_EXCEPTIONS)
-/*!
- \internal
- Uses a local buffer to output the message. Not locale safe + cuts off
- everything after character 255, but will work in out of memory situations.
- Stop the execution afterwards.
-*/
-static void qEmergencyOut(QtMsgType msgType, const char *msg, va_list ap) Q_DECL_NOEXCEPT
-{
- char emergency_buf[256] = { '\0' };
- emergency_buf[sizeof emergency_buf - 1] = '\0';
-#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB) && (defined(Q_OS_WINCE) || defined(Q_OS_WINRT)) \
- || defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR)
- wchar_t emergency_bufL[sizeof emergency_buf];
-#endif
-
- if (msg)
- qvsnprintf(emergency_buf, sizeof emergency_buf - 1, msg, ap);
-
-#if defined(Q_OS_WIN) && defined(QT_BUILD_CORE_LIB)
-# if defined(Q_OS_WINCE) || defined(Q_OS_WINRT)
- convert_to_wchar_t_elided(emergency_bufL, sizeof emergency_buf, emergency_buf);
- OutputDebugStringW(emergency_bufL);
-# else
- if (qWinLogToStderr()) {
- fprintf(stderr, "%s\n", emergency_buf);
- fflush(stderr);
- } else {
- OutputDebugStringA(emergency_buf);
- }
-# endif
-#else
- fprintf(stderr, "%s\n", emergency_buf);
- fflush(stderr);
-#endif
-
- if (isFatal(msgType)) {
-#if defined(Q_CC_MSVC) && defined(QT_DEBUG) && defined(_DEBUG) && defined(_CRT_ERROR)
- // get the current report mode
- int reportMode = _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_WNDW);
- _CrtSetReportMode(_CRT_ERROR, reportMode);
-# ifndef Q_OS_WINCE // otherwise already converted to wchar_t above
- convert_to_wchar_t_elided(emergency_bufL, sizeof emergency_buf, emergency_buf);
-# endif
- int ret = _CrtDbgReportW(_CRT_ERROR, _CRT_WIDE(__FILE__), __LINE__,
- _CRT_WIDE(QT_VERSION_STR),
- emergency_bufL);
- if (ret == 1)
- _CrtDbgBreak();
-#endif
-
-#if (defined(Q_OS_UNIX) || defined(Q_CC_MINGW))
- abort(); // trap; generates core dump
-#else
- exit(1); // goodbye cruel world
-#endif
- }
-}
-#endif
-
/*!
\internal
*/
static void qt_message(QtMsgType msgType, const QMessageLogContext &context, const char *msg,
va_list ap, QString &buf)
{
-#if !defined(QT_NO_EXCEPTIONS)
- if (std::uncaught_exception()) {
- qEmergencyOut(msgType, msg, ap);
- return;
- }
-#endif
- if (msg) {
- QT_TRY {
- buf = QString().vsprintf(msg, ap);
- } QT_CATCH(const std::bad_alloc &) {
-#if !defined(QT_NO_EXCEPTIONS)
- qEmergencyOut(msgType, msg, ap);
- // don't rethrow - we use qWarning and friends in destructors.
- return;
-#endif
- }
- }
+
+ if (msg)
+ buf = QString().vsprintf(msg, ap);
qt_message_print(msgType, context, buf);
}
diff --git a/src/gui/accessible/qaccessiblecache.cpp b/src/gui/accessible/qaccessiblecache.cpp
index 09c155515e..96dde1ea3f 100644
--- a/src/gui/accessible/qaccessiblecache.cpp
+++ b/src/gui/accessible/qaccessiblecache.cpp
@@ -121,7 +121,7 @@ void QAccessibleCache::deleteInterface(QAccessible::Id id, QObject *obj)
objectToId.remove(obj);
delete iface;
-#ifdef Q_OS_MACX
+#ifdef Q_OS_MAC
removeCocoaElement(id);
#endif
}
diff --git a/src/gui/accessible/qaccessiblecache_mac.mm b/src/gui/accessible/qaccessiblecache_mac.mm
index 861423af7d..bc6d0712d6 100644
--- a/src/gui/accessible/qaccessiblecache_mac.mm
+++ b/src/gui/accessible/qaccessiblecache_mac.mm
@@ -41,27 +41,23 @@
#include "qaccessiblecache_p.h"
-#ifdef Q_OS_OSX
-
QT_BEGIN_NAMESPACE
-void QAccessibleCache::insertElement(QAccessible::Id axid, QCocoaAccessibleElement *element) const
+void QAccessibleCache::insertElement(QAccessible::Id axid, QMacAccessibilityElement *element) const
{
cocoaElements[axid] = element;
}
void QAccessibleCache::removeCocoaElement(QAccessible::Id axid)
{
- QCocoaAccessibleElement *element = elementForId(axid);
+ QMacAccessibilityElement *element = elementForId(axid);
[element invalidate];
cocoaElements.remove(axid);
}
-QCocoaAccessibleElement *QAccessibleCache::elementForId(QAccessible::Id axid) const
+QMacAccessibilityElement *QAccessibleCache::elementForId(QAccessible::Id axid) const
{
return cocoaElements.value(axid);
}
QT_END_NAMESPACE
-
-#endif
diff --git a/src/gui/accessible/qaccessiblecache_p.h b/src/gui/accessible/qaccessiblecache_p.h
index 30b023cfbd..3ca62709b1 100644
--- a/src/gui/accessible/qaccessiblecache_p.h
+++ b/src/gui/accessible/qaccessiblecache_p.h
@@ -59,7 +59,9 @@
#include "qaccessible.h"
-Q_FORWARD_DECLARE_OBJC_CLASS(QCocoaAccessibleElement);
+#ifdef Q_OS_MAC
+ Q_FORWARD_DECLARE_OBJC_CLASS(QMacAccessibilityElement);
+#endif
QT_BEGIN_NAMESPACE
@@ -73,9 +75,9 @@ public:
QAccessible::Id insert(QObject *object, QAccessibleInterface *iface) const;
void deleteInterface(QAccessible::Id id, QObject *obj = 0);
-#ifdef Q_OS_OSX
- QCocoaAccessibleElement *elementForId(QAccessible::Id axid) const;
- void insertElement(QAccessible::Id axid, QCocoaAccessibleElement *element) const;
+#ifdef Q_OS_MAC
+ QMacAccessibilityElement *elementForId(QAccessible::Id axid) const;
+ void insertElement(QAccessible::Id axid, QMacAccessibilityElement *element) const;
#endif
private Q_SLOTS:
@@ -87,9 +89,9 @@ private:
mutable QHash<QAccessible::Id, QAccessibleInterface *> idToInterface;
mutable QHash<QObject *, QAccessible::Id> objectToId;
-#ifdef Q_OS_OSX
+#ifdef Q_OS_MAC
void removeCocoaElement(QAccessible::Id axid);
- mutable QHash<QAccessible::Id, QCocoaAccessibleElement *> cocoaElements;
+ mutable QHash<QAccessible::Id, QMacAccessibilityElement *> cocoaElements;
#endif
friend class QAccessible;
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index a6feda8732..231e475111 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -1119,6 +1119,14 @@ Q_GUI_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format,
Will try to return a premultiplied ARBG32 or RGB32 image. Since 5.2 it will fall back to
a premultiplied RGBA8888 or RGBx8888 image when reading to ARGB32 is not supported.
+
+ For multisampled framebuffer objects the samples are resolved using the
+ \c{GL_EXT_framebuffer_blit} extension. If the extension is not available, the contents
+ of the returned image is undefined.
+
+ For singlesampled framebuffers the contents is retrieved via \c glReadPixels. This is
+ a potentially expensive and inefficient operation. Therefore it is recommended that
+ this function is used as seldom as possible.
*/
QImage QOpenGLFramebufferObject::toImage() const
{
@@ -1126,6 +1134,19 @@ QImage QOpenGLFramebufferObject::toImage() const
if (!d->valid)
return QImage();
+ QOpenGLContext *ctx = QOpenGLContext::currentContext();
+ if (!ctx) {
+ qWarning("QOpenGLFramebufferObject::toImage() called without a current context");
+ return QImage();
+ }
+
+ GLuint prevFbo = 0;
+ ctx->functions()->glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *) &prevFbo);
+
+ if (prevFbo != d->fbo())
+ const_cast<QOpenGLFramebufferObject *>(this)->bind();
+
+ QImage image;
// qt_gl_read_framebuffer doesn't work on a multisample FBO
if (format().samples() != 0) {
QOpenGLFramebufferObject temp(size(), QOpenGLFramebufferObjectFormat());
@@ -1133,15 +1154,13 @@ QImage QOpenGLFramebufferObject::toImage() const
QRect rect(QPoint(0, 0), size());
blitFramebuffer(&temp, rect, const_cast<QOpenGLFramebufferObject *>(this), rect);
- return temp.toImage();
+ image = temp.toImage();
+ } else {
+ image = qt_gl_read_framebuffer(d->size, format().internalTextureFormat() != GL_RGB, true);
}
- bool wasBound = isBound();
- if (!wasBound)
- const_cast<QOpenGLFramebufferObject *>(this)->bind();
- QImage image = qt_gl_read_framebuffer(d->size, format().internalTextureFormat() != GL_RGB, true);
- if (!wasBound)
- const_cast<QOpenGLFramebufferObject *>(this)->release();
+ if (prevFbo != d->fbo())
+ ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, prevFbo);
return image;
}
@@ -1213,6 +1232,8 @@ QOpenGLFramebufferObject::Attachment QOpenGLFramebufferObject::attachment() cons
This can be used to free or reattach the depth and stencil buffer
attachments as needed.
+
+ \note This function alters the current framebuffer binding.
*/
void QOpenGLFramebufferObject::setAttachment(QOpenGLFramebufferObject::Attachment attachment)
{
@@ -1296,6 +1317,9 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target,
If \a source or \a target is 0, the default framebuffer will be used
instead of a framebuffer object as source or target respectively.
+ This function will have no effect unless hasOpenGLFramebufferBlit() returns
+ true.
+
The \a buffers parameter should be a mask consisting of any combination of
\c GL_COLOR_BUFFER_BIT, \c GL_DEPTH_BUFFER_BIT, and
\c GL_STENCIL_BUFFER_BIT. Any buffer type that is not present both
@@ -1312,10 +1336,7 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target,
have different sizes. The sizes must also be the same if any of the
framebuffer objects are multisample framebuffers.
- Note that the scissor test will restrict the blit area if enabled.
-
- This function will have no effect unless hasOpenGLFramebufferBlit() returns
- true.
+ \note The scissor test will restrict the blit area if enabled.
\sa hasOpenGLFramebufferBlit()
*/
@@ -1332,6 +1353,9 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target,
if (!extensions.hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit))
return;
+ GLuint prevFbo = 0;
+ ctx->functions()->glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *) &prevFbo);
+
const int sx0 = sourceRect.left();
const int sx1 = sourceRect.left() + sourceRect.width();
const int sy0 = sourceRect.top();
@@ -1348,6 +1372,8 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target,
extensions.glBlitFramebuffer(sx0, sy0, sx1, sy1,
tx0, ty0, tx1, ty1,
buffers, filter);
+
+ ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, prevFbo); // sets both READ and DRAW
}
QT_END_NAMESPACE
diff --git a/src/plugins/imageformats/ico/ico.json b/src/plugins/imageformats/ico/ico.json
index bd46e07e54..14093ee471 100644
--- a/src/plugins/imageformats/ico/ico.json
+++ b/src/plugins/imageformats/ico/ico.json
@@ -1,4 +1,4 @@
{
- "Keys": [ "ico" ],
+ "Keys": [ "ico", "cur" ],
"MimeTypes": [ "image/vnd.microsoft.icon" ]
}
diff --git a/src/plugins/imageformats/ico/main.cpp b/src/plugins/imageformats/ico/main.cpp
index 05e6e1885c..2ff2f36fdc 100644
--- a/src/plugins/imageformats/ico/main.cpp
+++ b/src/plugins/imageformats/ico/main.cpp
@@ -47,7 +47,7 @@ QT_BEGIN_NAMESPACE
QImageIOPlugin::Capabilities QICOPlugin::capabilities(QIODevice *device, const QByteArray &format) const
{
- if (format == "ico")
+ if (format == "ico" || format == "cur")
return Capabilities(CanRead | CanWrite);
if (!format.isEmpty())
return 0;
diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp
index 77bb727a51..b65bcdfacb 100644
--- a/src/plugins/imageformats/ico/qicohandler.cpp
+++ b/src/plugins/imageformats/ico/qicohandler.cpp
@@ -75,7 +75,7 @@ typedef struct
typedef struct
{
quint16 idReserved; // Reserved
- quint16 idType; // resource type (1 for icons)
+ quint16 idType; // resource type (1 for icons, 2 for cursors)
quint16 idCount; // how many images?
ICONDIRENTRY idEntries[1]; // the entries for each image
} ICONDIR, *LPICONDIR;
@@ -275,10 +275,10 @@ bool ICOReader::canRead(QIODevice *iodev)
readBytes += ICONDIRENTRY_SIZE;
// ICO format does not have a magic identifier, so we read 6 different values, which will hopefully be enough to identify the file.
if ( ikonDir.idReserved == 0
- && ikonDir.idType == 1
+ && (ikonDir.idType == 1 || ikonDir.idType == 2)
&& ikonDir.idEntries[0].bReserved == 0
- && ikonDir.idEntries[0].wPlanes <= 1
- && ikonDir.idEntries[0].wBitCount <= 32 // Bits per pixel
+ && (ikonDir.idEntries[0].wPlanes <= 1 || ikonDir.idType == 2)
+ && (ikonDir.idEntries[0].wBitCount <= 32 || ikonDir.idType == 2) // Bits per pixel
&& ikonDir.idEntries[0].dwBytesInRes >= 40 // Must be over 40, since sizeof (infoheader) == 40
) {
isProbablyICO = true;
@@ -339,7 +339,7 @@ bool ICOReader::readHeader()
if (iod && !headerRead) {
startpos = iod->pos();
if (readIconDir(iod, &iconDir)) {
- if (iconDir.idReserved == 0 || iconDir.idType == 1)
+ if (iconDir.idReserved == 0 && (iconDir.idType == 1 || iconDir.idType == 2))
headerRead = true;
}
}
diff --git a/src/plugins/platforms/android/qandroidplatformbackingstore.h b/src/plugins/platforms/android/qandroidplatformbackingstore.h
index 4c24e129c3..c51ebe879d 100644
--- a/src/plugins/platforms/android/qandroidplatformbackingstore.h
+++ b/src/plugins/platforms/android/qandroidplatformbackingstore.h
@@ -55,7 +55,7 @@ public:
virtual QPaintDevice *paintDevice();
virtual void flush(QWindow *window, const QRegion &region, const QPoint &offset);
virtual void resize(const QSize &size, const QRegion &staticContents);
- const QImage image() { return m_image; }
+ QImage toImage() const { return m_image; }
void setBackingStore(QWindow *window);
protected:
QImage m_image;
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index 11472ce1da..e67a039ff4 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -323,7 +323,7 @@ void QAndroidPlatformScreen::doRedraw()
QRect windowRect = targetRect.translated(-window->geometry().topLeft());
QAndroidPlatformBackingStore *backingStore = static_cast<QAndroidPlatformRasterWindow *>(window)->backingStore();
if (backingStore)
- compositePainter.drawImage(targetRect.topLeft(), backingStore->image(), windowRect);
+ compositePainter.drawImage(targetRect.topLeft(), backingStore->toImage(), windowRect);
}
}
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index 72045a1bbb..ca660488b9 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -55,7 +55,7 @@ QCocoaAccessibility::~QCocoaAccessibility()
void QCocoaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
{
- QCocoaAccessibleElement *element = [QCocoaAccessibleElement elementWithId: event->uniqueId()];
+ QMacAccessibilityElement *element = [QMacAccessibilityElement elementWithId: event->uniqueId()];
if (!element) {
qWarning() << "QCocoaAccessibility::notifyAccessibilityUpdate: invalid element";
return;
@@ -244,7 +244,7 @@ NSArray *unignoredChildren(QAccessibleInterface *interface)
QAccessible::Id childId = QAccessible::uniqueId(child);
//qDebug() << " kid: " << childId << child;
- QCocoaAccessibleElement *element = [QCocoaAccessibleElement elementWithId: childId];
+ QMacAccessibilityElement *element = [QMacAccessibilityElement elementWithId: childId];
if (element)
[kids addObject: element];
else
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
index babaab5ae2..ca34deceef 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.h
@@ -48,15 +48,15 @@
#import <qaccessible.h>
-@class QCocoaAccessibleElement;
+Q_FORWARD_DECLARE_OBJC_CLASS(QMacAccessibilityElement);
-@interface QCocoaAccessibleElement : NSObject {
+@interface QMacAccessibilityElement : NSObject {
NSString *role;
QAccessible::Id axid;
}
- (id)initWithId:(QAccessible::Id)anId;
-+ (QCocoaAccessibleElement *)elementWithId:(QAccessible::Id)anId;
++ (QMacAccessibilityElement *)elementWithId:(QAccessible::Id)anId;
@end
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index 078dc67cad..b309df6242 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -48,7 +48,7 @@
#import <AppKit/NSAccessibility.h>
-@implementation QCocoaAccessibleElement
+@implementation QMacAccessibilityElement
- (id)initWithId:(QAccessible::Id)anId
{
@@ -72,7 +72,7 @@
QAccessibleCache *cache = QAccessibleCache::instance();
- QCocoaAccessibleElement *element = cache->elementForId(anId);
+ QMacAccessibilityElement *element = cache->elementForId(anId);
if (!element) {
QAccessibleInterface *iface = QAccessible::accessibleInterface(anId);
Q_ASSERT(iface);
@@ -95,8 +95,8 @@
}
- (BOOL)isEqual:(id)object {
- if ([object isKindOfClass:[QCocoaAccessibleElement class]]) {
- QCocoaAccessibleElement *other = object;
+ if ([object isKindOfClass:[QMacAccessibilityElement class]]) {
+ QMacAccessibilityElement *other = object;
return other->axid == axid;
} else {
return NO;
@@ -196,7 +196,7 @@
}
QAccessible::Id parentId = QAccessible::uniqueId(parent);
- return [QCocoaAccessibleElement elementWithId: parentId];
+ return [QMacAccessibilityElement elementWithId: parentId];
}
@@ -345,7 +345,7 @@
}
if ([attribute isEqualToString: NSAccessibilityLineForIndexParameterizedAttribute]) {
int index = [parameter intValue];
- NSNumber *ln = [QCocoaAccessibleElement lineNumberForIndex: index forText: iface->text(QAccessible::Value)];
+ NSNumber *ln = [QMacAccessibilityElement lineNumberForIndex: index forText: iface->text(QAccessible::Value)];
return ln;
}
if ([attribute isEqualToString: NSAccessibilityRangeForLineParameterizedAttribute]) {
@@ -504,7 +504,7 @@
QAccessible::Id childId = QAccessible::uniqueId(childInterface);
// hit a child, forward to child accessible interface.
- QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithId:childId];
+ QMacAccessibilityElement *accessibleElement = [QMacAccessibilityElement elementWithId:childId];
if (accessibleElement)
return NSAccessibilityUnignoredAncestor(accessibleElement);
return NSAccessibilityUnignoredAncestor(self);
@@ -521,7 +521,7 @@
QAccessibleInterface *childInterface = iface->focusChild();
if (childInterface) {
QAccessible::Id childAxid = QAccessible::uniqueId(childInterface);
- QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement elementWithId:childAxid];
+ QMacAccessibilityElement *accessibleElement = [QMacAccessibilityElement elementWithId:childAxid];
return NSAccessibilityUnignoredAncestor(accessibleElement);
}
diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
index d18a01b11c..a02b074771 100644
--- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
@@ -59,7 +59,7 @@
return nil;
QAccessible::Id childId = QAccessible::uniqueId(m_window->accessibleRoot());
- return [QCocoaAccessibleElement elementWithId: childId];
+ return [QMacAccessibilityElement elementWithId: childId];
}
// The QNSView is a container that the user does not interact directly with:
diff --git a/src/plugins/platforms/ios/ios.pro b/src/plugins/platforms/ios/ios.pro
index ffc4ff9b12..57d4ac1770 100644
--- a/src/plugins/platforms/ios/ios.pro
+++ b/src/plugins/platforms/ios/ios.pro
@@ -23,7 +23,9 @@ OBJECTIVE_SOURCES = \
qiostheme.mm \
qiosglobal.mm \
qiosservices.mm \
- qiosclipboard.mm
+ qiosclipboard.mm \
+ quiaccessibilityelement.mm \
+ qiosplatformaccessibility.mm \
HEADERS = \
qiosintegration.h \
@@ -40,7 +42,9 @@ HEADERS = \
qiosglobal.h \
qiosservices.h \
quiview.h \
- qiosclipboard.h
+ qiosclipboard.h \
+ quiaccessibilityelement.h \
+ qiosplatformaccessibility.h \
OTHER_FILES = \
quiview_textinput.mm
diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h
index 956c112399..733c8dc270 100644
--- a/src/plugins/platforms/ios/qiosintegration.h
+++ b/src/plugins/platforms/ios/qiosintegration.h
@@ -82,6 +82,8 @@ public:
void *nativeResourceForWindow(const QByteArray &resource, QWindow *window);
QTouchDevice *touchDevice();
+ QPlatformAccessibility *accessibility() const Q_DECL_OVERRIDE;
+
private:
QPlatformFontDatabase *m_fontDatabase;
QPlatformClipboard *m_clipboard;
@@ -90,6 +92,7 @@ private:
QTouchDevice *m_touchDevice;
QIOSApplicationState m_applicationState;
QIOSServices *m_platformServices;
+ mutable QPlatformAccessibility *m_accessibility;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index 0fe7adff9f..3334e3a094 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -45,6 +45,7 @@
#include "qioswindow.h"
#include "qiosbackingstore.h"
#include "qiosscreen.h"
+#include "qiosplatformaccessibility.h"
#include "qioscontext.h"
#include "qiosclipboard.h"
#include "qiosinputcontext.h"
@@ -67,6 +68,7 @@ QIOSIntegration::QIOSIntegration()
, m_inputContext(new QIOSInputContext)
, m_screen(new QIOSScreen(QIOSScreen::MainScreen))
, m_platformServices(new QIOSServices)
+ , m_accessibility(0)
{
if (![UIApplication sharedApplication]) {
qWarning()
@@ -106,6 +108,9 @@ QIOSIntegration::~QIOSIntegration()
delete m_platformServices;
m_platformServices = 0;
+
+ delete m_accessibility;
+ m_accessibility = 0;
}
bool QIOSIntegration::hasCapability(Capability cap) const
@@ -229,4 +234,11 @@ QTouchDevice *QIOSIntegration::touchDevice()
return m_touchDevice;
}
+QPlatformAccessibility *QIOSIntegration::accessibility() const
+{
+ if (!m_accessibility)
+ m_accessibility = new QIOSPlatformAccessibility;
+ return m_accessibility;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/qiosplatformaccessibility.h b/src/plugins/platforms/ios/qiosplatformaccessibility.h
new file mode 100644
index 0000000000..beb0d006e1
--- /dev/null
+++ b/src/plugins/platforms/ios/qiosplatformaccessibility.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QIOSPLATFORMACCESSIBILITY_H
+#define QIOSPLATFORMACCESSIBILITY_H
+
+#include <qpa/qplatformaccessibility.h>
+
+QT_BEGIN_NAMESPACE
+
+class QIOSPlatformAccessibility: public QPlatformAccessibility
+{
+public:
+ QIOSPlatformAccessibility();
+ ~QIOSPlatformAccessibility();
+
+ virtual void notifyAccessibilityUpdate(QAccessibleEvent *event);
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/plugins/platforms/ios/qiosplatformaccessibility.mm b/src/plugins/platforms/ios/qiosplatformaccessibility.mm
new file mode 100644
index 0000000000..db579ba559
--- /dev/null
+++ b/src/plugins/platforms/ios/qiosplatformaccessibility.mm
@@ -0,0 +1,85 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qiosplatformaccessibility.h"
+
+#include <QtGui/QtGui>
+#include "qioswindow.h"
+
+QIOSPlatformAccessibility::QIOSPlatformAccessibility()
+{}
+
+QIOSPlatformAccessibility::~QIOSPlatformAccessibility()
+{}
+
+
+void invalidateCache(QAccessibleInterface *iface)
+{
+ if (!iface || !iface->isValid()) {
+ qWarning() << "invalid accessible interface: " << iface;
+ return;
+ }
+
+ QWindow *win = 0;
+ QAccessibleInterface *parent = iface;
+ do {
+ win = parent->window();
+ parent = parent->parent();
+ } while (!win && parent);
+ Q_ASSERT(win && win->handle());
+ QIOSWindow *window = static_cast<QIOSWindow*>(win->handle());
+ window->clearAccessibleCache();
+}
+
+
+void QIOSPlatformAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
+{
+ switch (event->type()) {
+ case QAccessible::ObjectCreated:
+ case QAccessible::ObjectShow:
+ case QAccessible::ObjectHide:
+ case QAccessible::ObjectDestroyed:
+ invalidateCache(event->accessibleInterface());
+ break;
+ default:
+ break;
+ }
+}
diff --git a/src/plugins/platforms/ios/qioswindow.h b/src/plugins/platforms/ios/qioswindow.h
index 6b6892e6e4..bcff3e202c 100644
--- a/src/plugins/platforms/ios/qioswindow.h
+++ b/src/plugins/platforms/ios/qioswindow.h
@@ -87,6 +87,8 @@ public:
WId winId() const { return WId(m_view); };
+ void clearAccessibleCache();
+
private:
void applicationStateChanged(Qt::ApplicationState state);
void applyGeometry(const QRect &rect);
diff --git a/src/plugins/platforms/ios/qioswindow.mm b/src/plugins/platforms/ios/qioswindow.mm
index 6f5c96cfc1..3ed2bbe1a1 100644
--- a/src/plugins/platforms/ios/qioswindow.mm
+++ b/src/plugins/platforms/ios/qioswindow.mm
@@ -52,6 +52,9 @@
#include <QtGui/private/qwindow_p.h>
#include <qpa/qplatformintegration.h>
+#include "qiosplatformaccessibility.h"
+#import "quiaccessibilityelement.h"
+
#import <QuartzCore/CAEAGLLayer.h>
#include <QtGui/QKeyEvent>
@@ -82,9 +85,74 @@
if (self = [self initWithFrame:toCGRect(window->geometry())])
m_qioswindow = window;
+ m_accessibleElements = [[NSMutableArray alloc] init];
return self;
}
+- (void)createAccessibleElement:(QAccessibleInterface *)iface
+{
+ if (!iface || iface->state().invisible)
+ return;
+ QAccessible::Id accessibleId = QAccessible::uniqueId(iface);
+ UIAccessibilityElement *elem = [[QMacAccessibilityElement alloc] initWithId: accessibleId withAccessibilityContainer: self];
+ [m_accessibleElements addObject: elem];
+}
+
+- (void)createAccessibleContainer:(QAccessibleInterface *)iface
+{
+ if (!iface)
+ return;
+
+ if (iface->childCount() == 0) {
+ [self createAccessibleElement: iface];
+ } else {
+ for (int i = 0; i < iface->childCount(); ++i)
+ [self createAccessibleContainer: iface->child(i)];
+ }
+}
+
+- (void)initAccessibility
+{
+ static bool init = false;
+ if (!init)
+ QGuiApplicationPrivate::platformIntegration()->accessibility()->setActive(true);
+ init = true;
+
+ if ([m_accessibleElements count])
+ return;
+
+ QWindow *win = m_qioswindow->window();
+ QAccessibleInterface *iface = win->accessibleRoot();
+ if (iface)
+ [self createAccessibleContainer: iface];
+}
+
+- (void)clearAccessibleCache
+{
+ [m_accessibleElements removeAllObjects];
+ UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, @"");
+}
+
+// this is a container, returning yes here means the functions below will never be called
+- (BOOL)isAccessibilityElement {
+ return NO;
+}
+
+- (NSInteger)accessibilityElementCount {
+ [self initAccessibility];
+ return [m_accessibleElements count];
+}
+
+- (id)accessibilityElementAtIndex:(NSInteger)index {
+ [self initAccessibility];
+ return m_accessibleElements[index];
+}
+
+- (NSInteger)indexOfAccessibilityElement:(id)element {
+ [self initAccessibility];
+ return [m_accessibleElements indexOfObject:element];
+}
+
- (id)initWithFrame:(CGRect)frame
{
if ((self = [super initWithFrame:frame])) {
@@ -634,6 +702,11 @@ qreal QIOSWindow::devicePixelRatio() const
return m_view.contentScaleFactor;
}
+void QIOSWindow::clearAccessibleCache()
+{
+ [m_view clearAccessibleCache];
+}
+
#include "moc_qioswindow.cpp"
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.h b/src/plugins/platforms/ios/quiaccessibilityelement.h
new file mode 100644
index 0000000000..7c5a930e86
--- /dev/null
+++ b/src/plugins/platforms/ios/quiaccessibilityelement.h
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QUIACCESSIBILITYELEMENT_H
+#define QUIACCESSIBILITYELEMENT_H
+
+#import <UIKit/UIKit.h>
+#import <QtGui/QtGui>
+
+@interface QMacAccessibilityElement : UIAccessibilityElement
+{}
+
+@property (readonly) QAccessible::Id axid;
+
+- (id) initWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view;
++ (QMacAccessibilityElement *) elementWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view;
+
+@end
+
+#endif
diff --git a/src/plugins/platforms/ios/quiaccessibilityelement.mm b/src/plugins/platforms/ios/quiaccessibilityelement.mm
new file mode 100644
index 0000000000..c9e9e34cbd
--- /dev/null
+++ b/src/plugins/platforms/ios/quiaccessibilityelement.mm
@@ -0,0 +1,194 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** 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, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "quiaccessibilityelement.h"
+
+#include "private/qaccessiblecache_p.h"
+
+@implementation QMacAccessibilityElement
+
+- (id) initWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view
+{
+ Q_ASSERT((int)anId < 0);
+ self = [super initWithAccessibilityContainer: view];
+ if (self)
+ _axid = anId;
+
+ return self;
+}
+
++ (id) elementWithId: (QAccessible::Id) anId withAccessibilityContainer: (id) view
+{
+ Q_ASSERT(anId);
+ if (!anId)
+ return nil;
+
+ QAccessibleCache *cache = QAccessibleCache::instance();
+
+ QMacAccessibilityElement *element = cache->elementForId(anId);
+ if (!element) {
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(anId);
+ Q_ASSERT(iface);
+ element = [[self alloc] initWithId:anId withAccessibilityContainer: view];
+ cache->insertElement(anId, element);
+ }
+ return element;
+}
+
+- (void) invalidate
+{
+ [self release];
+}
+
+- (BOOL) isAccessibilityElement
+{
+ return YES;
+}
+
+- (NSString*) accessibilityLabel
+{
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
+ if (!iface) {
+ qWarning() << "invalid accessible interface for: " << self.axid;
+ return @"";
+ }
+
+ return iface->text(QAccessible::Name).toNSString();
+}
+
+- (NSString*) accessibilityHint
+{
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
+ if (!iface) {
+ qWarning() << "invalid accessible interface for: " << self.axid;
+ return @"";
+ }
+ return iface->text(QAccessible::Description).toNSString();
+}
+
+- (NSString*) accessibilityValue
+{
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
+ if (!iface) {
+ qWarning() << "invalid accessible interface for: " << self.axid;
+ return @"";
+ }
+
+ QAccessible::State state = iface->state();
+
+ if (state.checkable)
+ return state.checked ? @"checked" : @"unchecked"; // FIXME: translation
+
+ QAccessibleValueInterface *val = iface->valueInterface();
+ if (val) {
+ return val->currentValue().toString().toNSString();
+ } else if (QAccessibleTextInterface *text = iface->textInterface()) {
+ // FIXME doesn't work?
+ return text->text(0, text->characterCount() - 1).toNSString();
+ }
+
+ return [super accessibilityHint];
+}
+
+- (CGRect) accessibilityFrame
+{
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
+ if (!iface) {
+ qWarning() << "invalid accessible interface for: " << self.axid;
+ return CGRect();
+ }
+
+ QRect rect = iface->rect();
+ return CGRectMake(rect.x(), rect.y(), rect.width(), rect.height());
+}
+
+- (UIAccessibilityTraits) accessibilityTraits
+{
+ UIAccessibilityTraits traits = UIAccessibilityTraitNone;
+
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
+ if (!iface) {
+ qWarning() << "invalid accessible interface for: " << self.axid;
+ return traits;
+ }
+ QAccessible::State state = iface->state();
+ if (state.disabled)
+ traits |= UIAccessibilityTraitNotEnabled;
+
+ if (iface->role() == QAccessible::Button)
+ traits |= UIAccessibilityTraitButton;
+
+ if (iface->valueInterface())
+ traits |= UIAccessibilityTraitAdjustable;
+
+ return traits;
+}
+
+- (BOOL) accessibilityActivate
+{
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
+ if (QAccessibleActionInterface *action = iface->actionInterface()) {
+ if (action->actionNames().contains(QAccessibleActionInterface::pressAction())) {
+ action->doAction(QAccessibleActionInterface::pressAction());
+ return YES;
+ } else if (action->actionNames().contains(QAccessibleActionInterface::showMenuAction())) {
+ action->doAction(QAccessibleActionInterface::showMenuAction());
+ return YES;
+ }
+ }
+ return NO; // fall back to sending mouse clicks
+}
+
+- (void) accessibilityIncrement
+{
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
+ if (QAccessibleActionInterface *action = iface->actionInterface())
+ action->doAction(QAccessibleActionInterface::increaseAction());
+}
+
+- (void) accessibilityDecrement
+{
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(self.axid);
+ if (QAccessibleActionInterface *action = iface->actionInterface())
+ action->doAction(QAccessibleActionInterface::decreaseAction());
+}
+
+@end
diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h
index 575dedab89..91c4fc9dde 100644
--- a/src/plugins/platforms/ios/quiview.h
+++ b/src/plugins/platforms/ios/quiview.h
@@ -57,6 +57,8 @@
int m_nextTouchId;
QString m_markedText;
BOOL m_inSendEventToFocusObject;
+
+ NSMutableArray *m_accessibleElements;
}
@property(nonatomic, assign) id<UITextInputDelegate> inputDelegate;
diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp
index 972c59ef2e..99833101d2 100644
--- a/src/tools/rcc/main.cpp
+++ b/src/tools/rcc/main.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the tools applications of the Qt Toolkit.
@@ -123,6 +123,11 @@ int runRcc(int argc, char *argv[])
outputOption.setValueName(QStringLiteral("file"));
parser.addOption(outputOption);
+ QCommandLineOption tempOption(QStringList() << QStringLiteral("t") << QStringLiteral("temp"));
+ tempOption.setDescription(QStringLiteral("Use temporary <file> for big resources."));
+ tempOption.setValueName(QStringLiteral("file"));
+ parser.addOption(tempOption);
+
QCommandLineOption nameOption(QStringLiteral("name"), QStringLiteral("Create an external initialization function with <name>."), QStringLiteral("name"));
parser.addOption(nameOption);
@@ -141,6 +146,9 @@ int runRcc(int argc, char *argv[])
QCommandLineOption binaryOption(QStringLiteral("binary"), QStringLiteral("Output a binary file for use as a dynamic resource."));
parser.addOption(binaryOption);
+ QCommandLineOption passOption(QStringLiteral("pass"), QStringLiteral("Pass number for big resources"), QStringLiteral("number"));
+ parser.addOption(passOption);
+
QCommandLineOption namespaceOption(QStringLiteral("namespace"), QStringLiteral("Turn off namespace macros."));
parser.addOption(namespaceOption);
@@ -161,7 +169,6 @@ int runRcc(int argc, char *argv[])
QString errorMsg;
RCCResourceLibrary library;
- QString outFilename = parser.value(outputOption);
if (parser.isSet(nameOption))
library.setInitName(parser.value(nameOption));
if (parser.isSet(rootOption)) {
@@ -178,6 +185,14 @@ int runRcc(int argc, char *argv[])
library.setCompressThreshold(parser.value(thresholdOption).toInt());
if (parser.isSet(binaryOption))
library.setFormat(RCCResourceLibrary::Binary);
+ if (parser.isSet(passOption)) {
+ if (parser.value(passOption) == QStringLiteral("1"))
+ library.setFormat(RCCResourceLibrary::Pass1);
+ else if (parser.value(passOption) == QStringLiteral("2"))
+ library.setFormat(RCCResourceLibrary::Pass2);
+ else
+ errorMsg = QLatin1String("Pass number must be 1 or 2");
+ }
if (parser.isSet(namespaceOption))
library.setUseNameSpace(!library.useNameSpace());
if (parser.isSet(verboseOption))
@@ -194,6 +209,9 @@ int runRcc(int argc, char *argv[])
}
}
+ QString outFilename = parser.value(outputOption);
+ QString tempFilename = parser.value(tempOption);
+
if (projectRequested) {
return createProject(outFilename);
}
@@ -217,11 +235,21 @@ int runRcc(int argc, char *argv[])
if (!library.readFiles(list, errorDevice))
return 1;
- // open output
QFile out;
- QIODevice::OpenMode mode = QIODevice::WriteOnly;
- if (library.format() == RCCResourceLibrary::C_Code)
- mode |= QIODevice::Text;
+
+ // open output
+ QIODevice::OpenMode mode = QIODevice::NotOpen;
+ switch (library.format()) {
+ case RCCResourceLibrary::C_Code:
+ case RCCResourceLibrary::Pass1:
+ mode = QIODevice::WriteOnly | QIODevice::Text;
+ break;
+ case RCCResourceLibrary::Pass2:
+ case RCCResourceLibrary::Binary:
+ mode = QIODevice::WriteOnly;
+ break;
+ }
+
if (outFilename.isEmpty() || outFilename == QLatin1String("-")) {
// using this overload close() only flushes.
@@ -245,7 +273,17 @@ int runRcc(int argc, char *argv[])
return 0;
}
- return library.output(out, errorDevice) ? 0 : 1;
+ QFile temp;
+ if (!tempFilename.isEmpty()) {
+ temp.setFileName(tempFilename);
+ if (!temp.open(QIODevice::ReadOnly)) {
+ const QString msg = QString::fromUtf8("Unable to open temporary file %1 for reading: %2\n")
+ .arg(outFilename).arg(out.errorString());
+ errorDevice.write(msg.toUtf8());
+ return 1;
+ }
+ }
+ return library.output(out, temp, errorDevice) ? 0 : 1;
}
Q_CORE_EXPORT extern QBasicAtomicInt qt_qhash_seed; // from qhash.cpp
diff --git a/src/tools/rcc/rcc.cpp b/src/tools/rcc/rcc.cpp
index 0d0c4ea444..d460109a9b 100644
--- a/src/tools/rcc/rcc.cpp
+++ b/src/tools/rcc/rcc.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the tools applications of the Qt Toolkit.
@@ -77,7 +77,11 @@ void RCCResourceLibrary::write(const char *str, int len)
void RCCResourceLibrary::writeByteArray(const QByteArray &other)
{
- m_out.append(other);
+ if (m_format == Pass2) {
+ m_outDevice->write(other);
+ } else {
+ m_out.append(other);
+ }
}
static inline QString msgOpenReadFailed(const QString &fname, const QString &why)
@@ -164,9 +168,10 @@ QString RCCFileInfo::resourceName() const
void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
{
- const bool text = (lib.m_format == RCCResourceLibrary::C_Code);
+ const bool text = lib.m_format == RCCResourceLibrary::C_Code;
+ const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
//some info
- if (text) {
+ if (text || pass1) {
if (m_language != QLocale::C) {
lib.writeString(" // ");
lib.writeByteArray(resourceName().toLocal8Bit());
@@ -209,14 +214,17 @@ void RCCFileInfo::writeDataInfo(RCCResourceLibrary &lib)
//data offset
lib.writeNumber4(m_dataOffset);
}
- if (text)
+ if (text || pass1)
lib.writeChar('\n');
}
qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
QString *errorMessage)
{
- const bool text = (lib.m_format == RCCResourceLibrary::C_Code);
+ const bool text = lib.m_format == RCCResourceLibrary::C_Code;
+ const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
+ const bool pass2 = lib.m_format == RCCResourceLibrary::Pass2;
+ const bool binary = lib.m_format == RCCResourceLibrary::Binary;
//capture the offset
m_dataOffset = offset;
@@ -244,7 +252,7 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
#endif // QT_NO_COMPRESS
// some info
- if (text) {
+ if (text || pass1) {
lib.writeString(" // ");
lib.writeByteArray(m_fileInfo.absoluteFilePath().toLocal8Bit());
lib.writeString("\n ");
@@ -252,8 +260,9 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
// write the length
- lib.writeNumber4(data.size());
- if (text)
+ if (text || binary || pass2)
+ lib.writeNumber4(data.size());
+ if (text || pass1)
lib.writeString("\n ");
offset += 4;
@@ -267,27 +276,27 @@ qint64 RCCFileInfo::writeDataBlob(RCCResourceLibrary &lib, qint64 offset,
j = 16;
}
}
- } else {
- for (int i = data.size(); --i >= 0; )
- lib.writeChar(*p++);
+ } else if (binary || pass2) {
+ lib.writeByteArray(data);
}
offset += data.size();
// done
- if (text)
+ if (text || pass1)
lib.writeString("\n ");
return offset;
}
qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
{
- const bool text = (lib.m_format == RCCResourceLibrary::C_Code);
+ const bool text = lib.m_format == RCCResourceLibrary::C_Code;
+ const bool pass1 = lib.m_format == RCCResourceLibrary::Pass1;
// capture the offset
m_nameOffset = offset;
// some info
- if (text) {
+ if (text || pass1) {
lib.writeString(" // ");
lib.writeByteArray(m_name.toLocal8Bit());
lib.writeString("\n ");
@@ -295,13 +304,13 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
// write the length
lib.writeNumber2(m_name.length());
- if (text)
+ if (text || pass1)
lib.writeString("\n ");
offset += 2;
// write the hash
lib.writeNumber4(qt_hash(m_name));
- if (text)
+ if (text || pass1)
lib.writeString("\n ");
offset += 4;
@@ -309,13 +318,13 @@ qint64 RCCFileInfo::writeDataName(RCCResourceLibrary &lib, qint64 offset)
const QChar *unicode = m_name.unicode();
for (int i = 0; i < m_name.length(); ++i) {
lib.writeNumber2(unicode[i].unicode());
- if (text && i % 16 == 0)
+ if ((text || pass1) && i % 16 == 0)
lib.writeString("\n ");
}
offset += m_name.length()*2;
// done
- if (text)
+ if (text || pass1)
lib.writeString("\n ");
return offset;
}
@@ -349,7 +358,8 @@ RCCResourceLibrary::RCCResourceLibrary()
m_namesOffset(0),
m_dataOffset(0),
m_useNameSpace(CONSTANT_USENAMESPACE),
- m_errorDevice(0)
+ m_errorDevice(0),
+ m_outDevice(0)
{
m_out.reserve(30 * 1000 * 1000);
}
@@ -717,9 +727,39 @@ RCCResourceLibrary::ResourceDataFileMap RCCResourceLibrary::resourceDataFileMap(
return rc;
}
-bool RCCResourceLibrary::output(QIODevice &outDevice, QIODevice &errorDevice)
+bool RCCResourceLibrary::output(QIODevice &outDevice, QIODevice &tempDevice, QIODevice &errorDevice)
{
m_errorDevice = &errorDevice;
+
+ const char pattern[] = { 'Q', 'R', 'C', '_', 'D', 'A', 'T', 'A' };
+ if (m_format == Pass2) {
+ char c;
+ for (int i = 0; i < 8; ) {
+ if (!tempDevice.getChar(&c)) {
+ m_errorDevice->write("No data signature found\n");
+ return false;
+ }
+ if (c == pattern[i]) {
+ ++i;
+ } else {
+ for (int k = 0; k < i; ++k)
+ outDevice.putChar(pattern[k]);
+ outDevice.putChar(c);
+ i = 0;
+ }
+ }
+
+ m_outDevice = &outDevice;
+ quint64 start = outDevice.pos();
+ writeDataBlobs();
+ quint64 len = outDevice.pos() - start;
+
+ tempDevice.seek(tempDevice.pos() + len - 8);
+ outDevice.write(tempDevice.readAll());
+
+ return true;
+ }
+
//write out
if (m_verbose)
m_errorDevice->write("Outputting code\n");
@@ -776,7 +816,12 @@ void RCCResourceLibrary::writeNumber2(quint16 number)
void RCCResourceLibrary::writeNumber4(quint32 number)
{
- if (m_format == RCCResourceLibrary::Binary) {
+ if (m_format == RCCResourceLibrary::Pass2) {
+ m_outDevice->putChar(char(number >> 24));
+ m_outDevice->putChar(char(number >> 16));
+ m_outDevice->putChar(char(number >> 8));
+ m_outDevice->putChar(char(number));
+ } else if (m_format == RCCResourceLibrary::Binary) {
writeChar(number >> 24);
writeChar(number >> 16);
writeChar(number >> 8);
@@ -791,7 +836,7 @@ void RCCResourceLibrary::writeNumber4(quint32 number)
bool RCCResourceLibrary::writeHeader()
{
- if (m_format == C_Code) {
+ if (m_format == C_Code || m_format == Pass1) {
writeString("/****************************************************************************\n");
writeString("** Resource object code\n");
writeString("**\n");
@@ -800,7 +845,6 @@ bool RCCResourceLibrary::writeHeader()
writeString("\n**\n");
writeString("** WARNING! All changes made in this file will be lost!\n");
writeString( "*****************************************************************************/\n\n");
- writeString("#include <QtCore/qglobal.h>\n\n");
} else if (m_format == Binary) {
writeString("qres");
writeNumber4(0);
@@ -814,15 +858,16 @@ bool RCCResourceLibrary::writeHeader()
bool RCCResourceLibrary::writeDataBlobs()
{
Q_ASSERT(m_errorDevice);
- if (m_format == C_Code)
+ if (m_format == C_Code) {
writeString("static const unsigned char qt_resource_data[] = {\n");
- else if (m_format == Binary)
+ } else if (m_format == Binary) {
m_dataOffset = m_out.size();
- QStack<RCCFileInfo*> pending;
+ }
if (!m_root)
return false;
+ QStack<RCCFileInfo*> pending;
pending.push(m_root);
qint64 offset = 0;
QString errorMessage;
@@ -844,12 +889,17 @@ bool RCCResourceLibrary::writeDataBlobs()
}
if (m_format == C_Code)
writeString("\n};\n\n");
+ else if (m_format == Pass1) {
+ writeString("\nstatic const unsigned char qt_resource_data[");
+ writeByteArray(QByteArray::number(offset));
+ writeString("] = { 'Q', 'R', 'C', '_', 'D', 'A', 'T', 'A' };\n\n");
+ }
return true;
}
bool RCCResourceLibrary::writeDataNames()
{
- if (m_format == C_Code)
+ if (m_format == C_Code || m_format == Pass1)
writeString("static const unsigned char qt_resource_name[] = {\n");
else if (m_format == Binary)
m_namesOffset = m_out.size();
@@ -877,7 +927,7 @@ bool RCCResourceLibrary::writeDataNames()
}
}
}
- if (m_format == C_Code)
+ if (m_format == C_Code || m_format == Pass1)
writeString("\n};\n\n");
return true;
}
@@ -889,7 +939,7 @@ static bool qt_rcc_compare_hash(const RCCFileInfo *left, const RCCFileInfo *righ
bool RCCResourceLibrary::writeDataStructure()
{
- if (m_format == C_Code)
+ if (m_format == C_Code || m_format == Pass1)
writeString("static const unsigned char qt_resource_struct[] = {\n");
else if (m_format == Binary)
m_treeOffset = m_out.size();
@@ -936,7 +986,7 @@ bool RCCResourceLibrary::writeDataStructure()
pending.push(child);
}
}
- if (m_format == C_Code)
+ if (m_format == C_Code || m_format == Pass1)
writeString("\n};\n\n");
return true;
@@ -966,7 +1016,7 @@ void RCCResourceLibrary::writeAddNamespaceFunction(const QByteArray &name)
bool RCCResourceLibrary::writeInitializer()
{
- if (m_format == C_Code) {
+ if (m_format == C_Code || m_format == Pass1) {
//write("\nQT_BEGIN_NAMESPACE\n");
QString initNameStr = m_initName;
if (!initNameStr.isEmpty()) {
@@ -976,18 +1026,36 @@ bool RCCResourceLibrary::writeInitializer()
QByteArray initName = initNameStr.toLatin1();
//init
- if (m_useNameSpace)
- writeString("QT_BEGIN_NAMESPACE\n\n");
+ if (m_useNameSpace) {
+ writeString("#ifdef QT_NAMESPACE\n"
+ "# define QT_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name\n"
+ "# define QT_MANGLE_NAMESPACE0(x) x\n"
+ "# define QT_MANGLE_NAMESPACE1(a, b) a##_##b\n"
+ "# define QT_MANGLE_NAMESPACE2(a, b) QT_MANGLE_NAMESPACE1(a,b)\n"
+ "# define QT_MANGLE_NAMESPACE(name) QT_MANGLE_NAMESPACE2( \\\n"
+ " QT_MANGLE_NAMESPACE0(name), QT_MANGLE_NAMESPACE0(QT_NAMESPACE))\n"
+ "#else\n"
+ "# define QT_PREPEND_NAMESPACE(name) name\n"
+ "# define QT_MANGLE_NAMESPACE(name) name\n"
+ "#endif\n\n");
+
+ writeString("#ifdef QT_NAMESPACE\n"
+ "namespace QT_NAMESPACE {\n"
+ "#endif\n\n");
+ }
+
if (m_root) {
- writeString("extern Q_CORE_EXPORT bool qRegisterResourceData\n "
+ writeString("bool qRegisterResourceData"
"(int, const unsigned char *, "
"const unsigned char *, const unsigned char *);\n\n");
- writeString("extern Q_CORE_EXPORT bool qUnregisterResourceData\n "
+ writeString("bool qUnregisterResourceData"
"(int, const unsigned char *, "
"const unsigned char *, const unsigned char *);\n\n");
}
+
if (m_useNameSpace)
- writeString("QT_END_NAMESPACE\n\n\n");
+ writeString("#ifdef QT_NAMESPACE\n}\n#endif\n\n");
+
QByteArray initResources = "qInitResources";
initResources += initName;
writeString("int ");
@@ -1002,9 +1070,6 @@ bool RCCResourceLibrary::writeInitializer()
}
writeString(" return 1;\n");
writeString("}\n\n");
- writeString("Q_CONSTRUCTOR_FUNCTION(");
- writeMangleNamespaceFunction(initResources);
- writeString(")\n\n");
//cleanup
QByteArray cleanResources = "qCleanupResources";
@@ -1020,9 +1085,15 @@ bool RCCResourceLibrary::writeInitializer()
}
writeString(" return 1;\n");
writeString("}\n\n");
- writeString("Q_DESTRUCTOR_FUNCTION(");
- writeMangleNamespaceFunction(cleanResources);
- writeString(")\n\n");
+
+ writeByteArray(
+ "namespace {\n"
+ " struct initializer {\n"
+ " initializer() { QT_MANGLE_NAMESPACE(" + initResources + ")(); }\n"
+ " ~initializer() { QT_MANGLE_NAMESPACE(" + cleanResources + ")(); }\n"
+ " } dummy;\n"
+ "}\n");
+
} else if (m_format == Binary) {
int i = 4;
char *p = m_out.data();
diff --git a/src/tools/rcc/rcc.h b/src/tools/rcc/rcc.h
index 7e16fe038d..1b15c8bb87 100644
--- a/src/tools/rcc/rcc.h
+++ b/src/tools/rcc/rcc.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the tools applications of the Qt Toolkit.
@@ -64,11 +64,11 @@ public:
RCCResourceLibrary();
~RCCResourceLibrary();
- bool output(QIODevice &out, QIODevice &errorDevice);
+ bool output(QIODevice &outDevice, QIODevice &tempDevice, QIODevice &errorDevice);
bool readFiles(bool ignoreErrors, QIODevice &errorDevice);
- enum Format { Binary, C_Code };
+ enum Format { Binary, C_Code, Pass1, Pass2 };
void setFormat(Format f) { m_format = f; }
Format format() const { return m_format; }
@@ -87,6 +87,9 @@ public:
void setInitName(const QString &name) { m_initName = name; }
QString initName() const { return m_initName; }
+ void setOutputName(const QString &name) { m_outputName = name; }
+ QString outputName() const { return m_outputName; }
+
void setCompressLevel(int c) { m_compressLevel = c; }
int compressLevel() const { return m_compressLevel; }
@@ -137,6 +140,7 @@ private:
QStringList m_fileNames;
QString m_resourceRoot;
QString m_initName;
+ QString m_outputName;
Format m_format;
bool m_verbose;
int m_compressLevel;
@@ -147,6 +151,7 @@ private:
bool m_useNameSpace;
QStringList m_failedResources;
QIODevice *m_errorDevice;
+ QIODevice *m_outDevice;
QByteArray m_out;
};
diff --git a/src/widgets/itemviews/qtableview.cpp b/src/widgets/itemviews/qtableview.cpp
index a252428a81..2bf4c62593 100644
--- a/src/widgets/itemviews/qtableview.cpp
+++ b/src/widgets/itemviews/qtableview.cpp
@@ -1821,8 +1821,15 @@ QModelIndex QTableView::moveCursor(CursorAction cursorAction, Qt::KeyboardModifi
return QModelIndex();
QModelIndex result = d->model->index(logicalRow, logicalColumn, d->root);
- if (!d->isRowHidden(logicalRow) && !d->isColumnHidden(logicalColumn) && d->isIndexEnabled(result))
+ if (!d->isRowHidden(logicalRow) && !d->isColumnHidden(logicalColumn) && d->isIndexEnabled(result)) {
+ if (d->hasSpans()) {
+ QSpanCollection::Span span = d->span(result.row(), result.column());
+ if (span.width() > 1 || span.height() > 1) {
+ result = d->model->sibling(span.top(), span.left(), result);
+ }
+ }
return result;
+ }
return QModelIndex();
}