summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/cocoa
diff options
context:
space:
mode:
authorMorten Johan Sorvig <morten.sorvig@digia.com>2012-11-01 12:59:11 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2012-11-15 16:03:57 +0100
commit65866bcff560abcab329958ce1980284a81ced94 (patch)
treea481f6854838cc0111992c59aaecbc3d8ee536e2 /src/plugins/platforms/cocoa
parent2ca6606dca44253df49f4805028a9878e4fa0237 (diff)
Implement EditableText accessibility for Mac.
Change-Id: Ibe03975bafc5a6a420b3bd69dfaa93dbf65c9958 Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
Diffstat (limited to 'src/plugins/platforms/cocoa')
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.h16
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm86
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm21
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm3
4 files changed, 121 insertions, 5 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.h b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
index ad2267c6bf..e2a64331ac 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.h
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.h
@@ -44,6 +44,18 @@
#include <Cocoa/Cocoa.h>
#include <QtGui>
+#include <qpa/qplatformaccessibility.h>
+
+class QCococaAccessibility : public QPlatformAccessibility
+{
+public:
+ QCococaAccessibility();
+ ~QCococaAccessibility();
+ void notifyAccessibilityUpdate(QAccessibleEvent *event);
+ void setRootObject(QObject *o);
+ void initialize();
+ void cleanup();
+};
namespace QCocoaAccessible {
@@ -52,9 +64,9 @@ namespace QCocoaAccessible {
Cocoa accessibility is implemented in the following files:
+ - qcocoaaccessibility (this file) : QCocoaAccessibility "plugin", conversion and helper functions.
- qnsviewaccessibility : Root accessibility implementation for QNSView
- qcocoaaccessibilityelement : Cocoa accessibility protocol wrapper for QAccessibleInterface
- - qcocoaaccessibility (this file) : Conversion and helper functions.
The accessibility implementation wraps QAccessibleInterfaces in QCocoaAccessibleElements, which
implements the cocoa accessibility protocol. The root QAccessibleInterface (the one returned
@@ -70,6 +82,8 @@ bool shouldBeIgnrored(QAccessibleInterface *interface);
NSString *getTranslatedAction(const QString &qtAction);
NSMutableArray *createTranslatedActionsList(const QStringList &qtActions);
QString translateAction(NSString *nsAction);
+bool hasValueAttribute(QAccessibleInterface *interface);
+id getValueAttribute(QAccessibleInterface *interface);
}
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index 4b897fc211..2a03829b7a 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -39,6 +39,58 @@
**
****************************************************************************/
#include "qcocoaaccessibility.h"
+#include "qcocoaaccessibilityelement.h"
+#include <qaccessible.h>
+#include <qaccessible2.h>
+#include <private/qcore_mac_p.h>
+
+QCococaAccessibility::QCococaAccessibility()
+{
+
+}
+
+QCococaAccessibility::~QCococaAccessibility()
+{
+
+}
+
+void QCococaAccessibility::notifyAccessibilityUpdate(QAccessibleEvent *event)
+{
+ QObject *object = event->object();
+ if (!object)
+ return;
+
+ QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(object);
+ if (!interface)
+ return;
+
+ switch (event->type()) {
+ case QAccessible::TextInserted :
+ case QAccessible::TextRemoved :
+ case QAccessible::TextUpdated : {
+ QCocoaAccessibleElement *element = [QCocoaAccessibleElement elementWithInterface : interface parent : nil];
+ NSAccessibilityPostNotification(element, NSAccessibilityValueChangedNotification);
+ break; }
+ default:
+ delete interface;
+ break;
+ }
+}
+
+void QCococaAccessibility::setRootObject(QObject *o)
+{
+ Q_UNUSED(o)
+}
+
+void QCococaAccessibility::initialize()
+{
+
+}
+
+void QCococaAccessibility::cleanup()
+{
+
+}
namespace QCocoaAccessible {
@@ -218,4 +270,38 @@ QString translateAction(NSString *nsAction)
return QString();
}
+bool hasValueAttribute(QAccessibleInterface *interface)
+{
+ const QAccessible::Role qtrole = interface->role();
+ if (qtrole == QAccessible::EditableText) {
+ return true;
+ }
+
+ return false;
+}
+
+id getValueAttribute(QAccessibleInterface *interface)
+{
+ const QAccessible::Role qtrole = interface->role();
+ if (qtrole == QAccessible::EditableText) {
+ if (QAccessibleTextInterface *textInterface = interface->textInterface()) {
+ // VoiceOver will read out the entire text string at once when returning
+ // text as a value. For large text edits the size of the returned string
+ // needs to be limited and text range attributes need to be used instead.
+ // NSTextEdit returns the first sentence as the value, Do the same here:
+ int begin = 0;
+ int end = textInterface->characterCount();
+ // ### call to textAfterOffset hangs. Booo!
+ //if (textInterface->characterCount() > 0)
+ // textInterface->textAfterOffset(0, QAccessible2::SentenceBoundary, &begin, &end);
+
+ QString text = textInterface->text(begin, end);
+ //qDebug() << "text" << begin << end << text;
+ return QCFString::toNSString(text);
+ }
+ }
+
+ return nil;
+}
+
} // namespace QCocoaAccessible
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index c39290357e..cc1d393029 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -96,9 +96,9 @@ static QAccessibleInterface *acast(void *ptr)
// attributes
- (NSArray *)accessibilityAttributeNames {
- static NSArray *attributes = nil;
- if (attributes == nil) {
- attributes = [[NSArray alloc] initWithObjects:
+ static NSArray *defaultAttributes = nil;
+ if (defaultAttributes == nil) {
+ defaultAttributes = [[NSArray alloc] initWithObjects:
NSAccessibilityRoleAttribute,
NSAccessibilityRoleDescriptionAttribute,
NSAccessibilityChildrenAttribute,
@@ -112,6 +112,14 @@ static QAccessibleInterface *acast(void *ptr)
NSAccessibilityEnabledAttribute,
nil];
}
+
+ NSMutableArray *attributes = [[NSMutableArray alloc] initWithCapacity : [defaultAttributes count]];
+ [attributes addObjectsFromArray : defaultAttributes];
+
+ if (QCocoaAccessible::hasValueAttribute(acast(accessibleInterface))) {
+ [attributes addObject : NSAccessibilityValueAttribute];
+ }
+
return attributes;
}
@@ -153,6 +161,13 @@ static QAccessibleInterface *acast(void *ptr)
return QCFString::toNSString(acast(accessibleInterface)->text(QAccessible::Name));
} else if ([attribute isEqualToString:NSAccessibilityEnabledAttribute]) {
return [NSNumber numberWithBool:!acast(accessibleInterface)->state().disabled];
+ } else if ([attribute isEqualToString:NSAccessibilityValueAttribute]) {
+ // VoiceOver asks for the value attribute for all elements. Return nil
+ // if we don't want the element to have a value attribute.
+ if (!QCocoaAccessible::hasValueAttribute(acast(accessibleInterface)))
+ return nil;
+
+ return QCocoaAccessible::getValueAttribute(acast(accessibleInterface));
}
return nil;
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index a361027b49..83c3efb2c6 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -53,6 +53,7 @@
#include "qcocoatheme.h"
#include "qcocoainputcontext.h"
#include "qmacmime.h"
+#include "qcocoaaccessibility.h"
#include <qpa/qplatformaccessibility.h>
#include <QtCore/qcoreapplication.h>
@@ -180,7 +181,7 @@ QCocoaIntegration::QCocoaIntegration()
, mEventDispatcher(new QCocoaEventDispatcher())
, mInputContext(new QCocoaInputContext)
#ifndef QT_NO_ACCESSIBILITY
- , mAccessibility(new QPlatformAccessibility)
+ , mAccessibility(new QCococaAccessibility)
#endif
, mCocoaClipboard(new QCocoaClipboard)
, mCocoaDrag(new QCocoaDrag)